Repository: ollama/ollama
Pull request: prompt: Don't trim whitespace from prompts

New lines can be an important part of a user's prompt and trimming it can alter the results. We previously only trimmed prompts with images but refactoring brought this behavior to all prompts, where it became more noticeable.

The /generate endpoint adds less whitespace and therefore doesn't need to trim it out - this brings the same behavior to /chat.

Thanks to @gabe-l-hart for spotting the issue!

Fixes #7795

Changed files:
filename: server/prompt.go
patch: @@ -114,7 +114,6 @@ func chatPrompt(ctx context.Context, m *Model, tokenize tokenizeFunc, opts *api.
 					ID:   len(images),
 					Data: i,
 				}
-				imgPrompt = " "
 			}
 
 			imgTag := fmt.Sprintf("[img-%d]", imgData.ID)
@@ -126,7 +125,7 @@ func chatPrompt(ctx context.Context, m *Model, tokenize tokenizeFunc, opts *api.
 
 			images = append(images, imgData)
 		}
-		msgs[currMsgIdx+cnt].Content = strings.TrimSpace(prefix + imgPrompt + prompt)
+		msgs[currMsgIdx+cnt].Content = prefix + imgPrompt + prompt
 	}
 
 	// truncate any messages that do not fit into the context window

filename: server/prompt_test.go
patch: @@ -95,7 +95,7 @@ func TestChatPrompt(t *testing.T) {
 				{Role: "user", Content: "A test. And a thumping good one at that, I'd wager.", Images: []api.ImageData{[]byte("something")}},
 			},
 			expect: expect{
-				prompt: "[img-0] A test. And a thumping good one at that, I'd wager. ",
+				prompt: "[img-0]A test. And a thumping good one at that, I'd wager. ",
 				images: [][]byte{
 					[]byte("something"),
 				},
@@ -111,7 +111,7 @@ func TestChatPrompt(t *testing.T) {
 				{Role: "user", Content: "A test. And a thumping good one at that, I'd wager.", Images: []api.ImageData{[]byte("somethingelse")}},
 			},
 			expect: expect{
-				prompt: "[img-0] A test. And a thumping good one at that, I'd wager. ",
+				prompt: "[img-0]A test. And a thumping good one at that, I'd wager. ",
 				images: [][]byte{
 					[]byte("somethingelse"),
 				},
@@ -127,7 +127,7 @@ func TestChatPrompt(t *testing.T) {
 				{Role: "user", Content: "A test. And a thumping good one at that, I'd wager.", Images: []api.ImageData{[]byte("somethingelse")}},
 			},
 			expect: expect{
-				prompt: "[img-0] You're a test, Harry! I-I'm a what? [img-1] A test. And a thumping good one at that, I'd wager. ",
+				prompt: "[img-0]You're a test, Harry! I-I'm a what? [img-1]A test. And a thumping good one at that, I'd wager. ",
 				images: [][]byte{
 					[]byte("something"),
 					[]byte("somethingelse"),
@@ -144,7 +144,7 @@ func TestChatPrompt(t *testing.T) {
 				{Role: "user", Content: "A test. And a thumping good one at that, I'd wager.", Images: []api.ImageData{[]byte("somethingelse")}},
 			},
 			expect: expect{
-				prompt: "You're a test, Harry! [img-0] I-I'm a what? [img-1] A test. And a thumping good one at that, I'd wager. ",
+				prompt: "You're a test, Harry! [img-0] I-I'm a what? [img-1]A test. And a thumping good one at that, I'd wager. ",
 				images: [][]byte{
 					[]byte("something"),
 					[]byte("somethingelse"),
@@ -224,7 +224,7 @@ func TestChatPrompt(t *testing.T) {
 				{Role: "user", Content: "Compare these two pictures of hotdogs", Images: []api.ImageData{[]byte("one hotdog"), []byte("two hotdogs")}},
 			},
 			expect: expect{
-				prompt: "[img-0][img-1] Compare these two pictures of hotdogs ",
+				prompt: "[img-0][img-1]Compare these two pictures of hotdogs ",
 				images: [][]byte{[]byte("one hotdog"), []byte("two hotdogs")},
 			},
 		},