Skip to content

Commit 5c83d3a

Browse files
committed
fix: address PR review comments for native Ollama handler
- Remove unused imports (getApiRequestTimeout) and constants (OLLAMA_TIMEOUT_MS) - Call fetchModel() in createMessage and completePrompt to load model info - Fix image handling to use raw base64 strings instead of data URLs - Remove commented-out OllamaHandler import - Properly separate text and images in message conversion
1 parent 606dd44 commit 5c83d3a

File tree

2 files changed

+22
-24
lines changed

2 files changed

+22
-24
lines changed

src/api/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
VertexHandler,
1414
AnthropicVertexHandler,
1515
OpenAiHandler,
16-
// OllamaHandler, // Replaced with NativeOllamaHandler
1716
LmStudioHandler,
1817
GeminiHandler,
1918
OpenAiNativeHandler,

src/api/providers/native-ollama.ts

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { ApiStream } from "../transform/stream"
55
import { BaseProvider } from "./base-provider"
66
import type { ApiHandlerOptions } from "../../shared/api"
77
import { getOllamaModels } from "./fetchers/ollama"
8-
import { getApiRequestTimeout } from "./utils/timeout-config"
98
import { XmlMatcher } from "../../utils/xml-matcher"
109
import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
1110

@@ -49,10 +48,9 @@ function convertToOllamaMessages(anthropicMessages: Anthropic.Messages.MessagePa
4948
?.map((part) => {
5049
if (part.type === "image") {
5150
// Handle base64 images only (Anthropic SDK uses base64)
51+
// Ollama expects raw base64 strings, not data URLs
5252
if ("source" in part && part.source.type === "base64") {
53-
toolResultImages.push(
54-
`data:${part.source.media_type};base64,${part.source.data}`,
55-
)
53+
toolResultImages.push(part.source.data)
5654
}
5755
return "(see following user message for image)"
5856
}
@@ -69,20 +67,24 @@ function convertToOllamaMessages(anthropicMessages: Anthropic.Messages.MessagePa
6967

7068
// Process non-tool messages
7169
if (nonToolMessages.length > 0) {
70+
// Separate text and images for Ollama
71+
const textContent = nonToolMessages
72+
.filter((part) => part.type === "text")
73+
.map((part) => part.text)
74+
.join("\n")
75+
76+
const imageData: string[] = []
77+
nonToolMessages.forEach((part) => {
78+
if (part.type === "image" && "source" in part && part.source.type === "base64") {
79+
// Ollama expects raw base64 strings, not data URLs
80+
imageData.push(part.source.data)
81+
}
82+
})
83+
7284
ollamaMessages.push({
7385
role: "user",
74-
content: nonToolMessages
75-
.map((part) => {
76-
if (part.type === "image") {
77-
// Handle base64 images only (Anthropic SDK uses base64)
78-
if ("source" in part && part.source.type === "base64") {
79-
return `data:${part.source.media_type};base64,${part.source.data}`
80-
}
81-
return ""
82-
}
83-
return part.text
84-
})
85-
.join("\n"),
86+
content: textContent,
87+
images: imageData.length > 0 ? imageData : undefined,
8688
})
8789
}
8890
} else if (anthropicMessage.role === "assistant") {
@@ -125,8 +127,6 @@ function convertToOllamaMessages(anthropicMessages: Anthropic.Messages.MessagePa
125127
return ollamaMessages
126128
}
127129

128-
const OLLAMA_TIMEOUT_MS = 3_600_000
129-
130130
export class NativeOllamaHandler extends BaseProvider implements SingleCompletionHandler {
131131
protected options: ApiHandlerOptions
132132
private client: Ollama | undefined
@@ -157,7 +157,7 @@ export class NativeOllamaHandler extends BaseProvider implements SingleCompletio
157157
metadata?: ApiHandlerCreateMessageMetadata,
158158
): ApiStream {
159159
const client = this.ensureClient()
160-
const modelId = this.getModel().id
160+
const { id: modelId, info: modelInfo } = await this.fetchModel()
161161
const useR1Format = modelId.toLowerCase().includes("deepseek-r1")
162162

163163
const ollamaMessages: Message[] = [
@@ -176,13 +176,12 @@ export class NativeOllamaHandler extends BaseProvider implements SingleCompletio
176176

177177
try {
178178
// Create the actual API request promise
179-
const model = this.getModel()
180179
const stream = await client.chat({
181-
model: model.id,
180+
model: modelId,
182181
messages: ollamaMessages,
183182
stream: true,
184183
options: {
185-
num_ctx: model.info.contextWindow,
184+
num_ctx: modelInfo.contextWindow,
186185
temperature: this.options.modelTemperature ?? (useR1Format ? DEEP_SEEK_DEFAULT_TEMPERATURE : 0),
187186
},
188187
})
@@ -263,7 +262,7 @@ export class NativeOllamaHandler extends BaseProvider implements SingleCompletio
263262
async completePrompt(prompt: string): Promise<string> {
264263
try {
265264
const client = this.ensureClient()
266-
const modelId = this.getModel().id
265+
const { id: modelId } = await this.fetchModel()
267266
const useR1Format = modelId.toLowerCase().includes("deepseek-r1")
268267

269268
const response = await client.chat({

0 commit comments

Comments
 (0)