@providerprotocol/ai 0.0.22 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +188 -6
- package/dist/anthropic/index.d.ts +1 -1
- package/dist/anthropic/index.js +95 -36
- package/dist/anthropic/index.js.map +1 -1
- package/dist/{chunk-7WYBJPJJ.js → chunk-55X3W2MN.js} +4 -3
- package/dist/chunk-55X3W2MN.js.map +1 -0
- package/dist/{chunk-M4BMM5IB.js → chunk-6AZVUI6H.js} +20 -4
- package/dist/chunk-6AZVUI6H.js.map +1 -0
- package/dist/chunk-73IIE3QT.js +120 -0
- package/dist/chunk-73IIE3QT.js.map +1 -0
- package/dist/{chunk-RFWLEFAB.js → chunk-QNJO7DSD.js} +61 -16
- package/dist/chunk-QNJO7DSD.js.map +1 -0
- package/dist/{chunk-RS7C25LS.js → chunk-SBCATNHA.js} +9 -5
- package/dist/chunk-SBCATNHA.js.map +1 -0
- package/dist/{chunk-NWS5IKNR.js → chunk-TOJCZMVU.js} +3 -12
- package/dist/chunk-TOJCZMVU.js.map +1 -0
- package/dist/{chunk-I2VHCGQE.js → chunk-Z6DKC37J.js} +6 -5
- package/dist/chunk-Z6DKC37J.js.map +1 -0
- package/dist/google/index.d.ts +36 -4
- package/dist/google/index.js +98 -53
- package/dist/google/index.js.map +1 -1
- package/dist/http/index.d.ts +2 -2
- package/dist/http/index.js +4 -4
- package/dist/index.d.ts +8 -6
- package/dist/index.js +92 -122
- package/dist/index.js.map +1 -1
- package/dist/ollama/index.d.ts +5 -2
- package/dist/ollama/index.js +47 -36
- package/dist/ollama/index.js.map +1 -1
- package/dist/openai/index.d.ts +1 -1
- package/dist/openai/index.js +117 -56
- package/dist/openai/index.js.map +1 -1
- package/dist/openrouter/index.d.ts +1 -1
- package/dist/openrouter/index.js +58 -53
- package/dist/openrouter/index.js.map +1 -1
- package/dist/{provider-DWEAzeM5.d.ts → provider-x4RocsnK.d.ts} +199 -54
- package/dist/proxy/index.d.ts +2 -2
- package/dist/proxy/index.js +11 -9
- package/dist/proxy/index.js.map +1 -1
- package/dist/{retry-DmPmqZL6.d.ts → retry-DTfjXXPh.d.ts} +1 -1
- package/dist/{stream-DbkLOIbJ.d.ts → stream-ITNFNnO4.d.ts} +95 -38
- package/dist/xai/index.d.ts +1 -1
- package/dist/xai/index.js +221 -97
- package/dist/xai/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-7WYBJPJJ.js.map +0 -1
- package/dist/chunk-I2VHCGQE.js.map +0 -1
- package/dist/chunk-M4BMM5IB.js.map +0 -1
- package/dist/chunk-NWS5IKNR.js.map +0 -1
- package/dist/chunk-RFWLEFAB.js.map +0 -1
- package/dist/chunk-RS7C25LS.js.map +0 -1
package/dist/ollama/index.js
CHANGED
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseJsonResponse
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-Z6DKC37J.js";
|
|
4
|
+
import {
|
|
5
|
+
StreamEventType
|
|
6
|
+
} from "../chunk-73IIE3QT.js";
|
|
4
7
|
import {
|
|
5
8
|
AssistantMessage,
|
|
6
9
|
createProvider,
|
|
7
10
|
isAssistantMessage,
|
|
8
11
|
isToolResultMessage,
|
|
9
12
|
isUserMessage
|
|
10
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-6AZVUI6H.js";
|
|
11
14
|
import {
|
|
12
15
|
resolveApiKey
|
|
13
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-55X3W2MN.js";
|
|
14
17
|
import {
|
|
18
|
+
ErrorCode,
|
|
19
|
+
ModalityType,
|
|
15
20
|
UPPError,
|
|
16
21
|
doFetch,
|
|
17
22
|
doStreamFetch,
|
|
18
23
|
normalizeHttpError,
|
|
19
24
|
toError
|
|
20
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-QNJO7DSD.js";
|
|
21
26
|
|
|
22
27
|
// src/providers/ollama/transform.ts
|
|
23
28
|
function transformRequest(request, modelId) {
|
|
@@ -54,9 +59,9 @@ function normalizeSystem(system) {
|
|
|
54
59
|
if (!Array.isArray(system)) {
|
|
55
60
|
throw new UPPError(
|
|
56
61
|
"System prompt must be a string or an array of text blocks",
|
|
57
|
-
|
|
62
|
+
ErrorCode.InvalidRequest,
|
|
58
63
|
"ollama",
|
|
59
|
-
|
|
64
|
+
ModalityType.LLM
|
|
60
65
|
);
|
|
61
66
|
}
|
|
62
67
|
const texts = [];
|
|
@@ -64,18 +69,18 @@ function normalizeSystem(system) {
|
|
|
64
69
|
if (!block || typeof block !== "object" || !("text" in block)) {
|
|
65
70
|
throw new UPPError(
|
|
66
71
|
"System prompt array must contain objects with a text field",
|
|
67
|
-
|
|
72
|
+
ErrorCode.InvalidRequest,
|
|
68
73
|
"ollama",
|
|
69
|
-
|
|
74
|
+
ModalityType.LLM
|
|
70
75
|
);
|
|
71
76
|
}
|
|
72
77
|
const textValue = block.text;
|
|
73
78
|
if (typeof textValue !== "string") {
|
|
74
79
|
throw new UPPError(
|
|
75
80
|
"System prompt text must be a string",
|
|
76
|
-
|
|
81
|
+
ErrorCode.InvalidRequest,
|
|
77
82
|
"ollama",
|
|
78
|
-
|
|
83
|
+
ModalityType.LLM
|
|
79
84
|
);
|
|
80
85
|
}
|
|
81
86
|
if (textValue.length > 0) {
|
|
@@ -123,7 +128,7 @@ function transformMessages(messages, system) {
|
|
|
123
128
|
}
|
|
124
129
|
ollamaMessages.push(message);
|
|
125
130
|
} else if (isAssistantMessage(msg)) {
|
|
126
|
-
const textContent = msg.content.filter((block) => block.type === "text").map((block) => block.text).join("\n");
|
|
131
|
+
const textContent = msg.content.filter((block) => block.type === "text").map((block) => block.text).join("\n").replace(/<think>[\s\S]*?<\/think>/g, "").trim();
|
|
127
132
|
const message = {
|
|
128
133
|
role: "assistant",
|
|
129
134
|
content: textContent
|
|
@@ -166,11 +171,14 @@ function transformTool(tool) {
|
|
|
166
171
|
};
|
|
167
172
|
}
|
|
168
173
|
function transformResponse(data) {
|
|
169
|
-
const
|
|
174
|
+
const content = [];
|
|
170
175
|
const toolCalls = [];
|
|
171
176
|
let structuredData;
|
|
177
|
+
if (data.message.thinking) {
|
|
178
|
+
content.push({ type: "reasoning", text: data.message.thinking });
|
|
179
|
+
}
|
|
172
180
|
if (data.message.content) {
|
|
173
|
-
|
|
181
|
+
content.push({ type: "text", text: data.message.content });
|
|
174
182
|
try {
|
|
175
183
|
structuredData = JSON.parse(data.message.content);
|
|
176
184
|
} catch {
|
|
@@ -187,7 +195,7 @@ function transformResponse(data) {
|
|
|
187
195
|
}
|
|
188
196
|
}
|
|
189
197
|
const message = new AssistantMessage(
|
|
190
|
-
|
|
198
|
+
content,
|
|
191
199
|
toolCalls.length > 0 ? toolCalls : void 0,
|
|
192
200
|
{
|
|
193
201
|
metadata: {
|
|
@@ -246,14 +254,14 @@ function transformStreamChunk(chunk, state) {
|
|
|
246
254
|
if (state.isFirstChunk) {
|
|
247
255
|
state.model = chunk.model;
|
|
248
256
|
state.createdAt = chunk.created_at;
|
|
249
|
-
events.push({ type:
|
|
257
|
+
events.push({ type: StreamEventType.MessageStart, index: 0, delta: {} });
|
|
250
258
|
state.isFirstChunk = false;
|
|
251
259
|
}
|
|
252
260
|
if (chunk.message) {
|
|
253
261
|
if (chunk.message.content) {
|
|
254
262
|
state.content += chunk.message.content;
|
|
255
263
|
events.push({
|
|
256
|
-
type:
|
|
264
|
+
type: StreamEventType.TextDelta,
|
|
257
265
|
index: 0,
|
|
258
266
|
delta: { text: chunk.message.content }
|
|
259
267
|
});
|
|
@@ -261,7 +269,7 @@ function transformStreamChunk(chunk, state) {
|
|
|
261
269
|
if (chunk.message.thinking) {
|
|
262
270
|
state.thinking += chunk.message.thinking;
|
|
263
271
|
events.push({
|
|
264
|
-
type:
|
|
272
|
+
type: StreamEventType.ReasoningDelta,
|
|
265
273
|
index: 0,
|
|
266
274
|
delta: { text: chunk.message.thinking }
|
|
267
275
|
});
|
|
@@ -273,7 +281,7 @@ function transformStreamChunk(chunk, state) {
|
|
|
273
281
|
args: call.function.arguments
|
|
274
282
|
});
|
|
275
283
|
events.push({
|
|
276
|
-
type:
|
|
284
|
+
type: StreamEventType.ToolCallDelta,
|
|
277
285
|
index: state.toolCalls.length - 1,
|
|
278
286
|
delta: {
|
|
279
287
|
toolCallId: call.function.name,
|
|
@@ -289,16 +297,19 @@ function transformStreamChunk(chunk, state) {
|
|
|
289
297
|
state.promptEvalCount = chunk.prompt_eval_count ?? 0;
|
|
290
298
|
state.evalCount = chunk.eval_count ?? 0;
|
|
291
299
|
state.totalDuration = chunk.total_duration ?? 0;
|
|
292
|
-
events.push({ type:
|
|
300
|
+
events.push({ type: StreamEventType.MessageStop, index: 0, delta: {} });
|
|
293
301
|
}
|
|
294
302
|
return events;
|
|
295
303
|
}
|
|
296
304
|
function buildResponseFromState(state) {
|
|
297
|
-
const
|
|
305
|
+
const content = [];
|
|
298
306
|
const toolCalls = [];
|
|
299
307
|
let structuredData;
|
|
308
|
+
if (state.thinking) {
|
|
309
|
+
content.push({ type: "reasoning", text: state.thinking });
|
|
310
|
+
}
|
|
300
311
|
if (state.content) {
|
|
301
|
-
|
|
312
|
+
content.push({ type: "text", text: state.content });
|
|
302
313
|
try {
|
|
303
314
|
structuredData = JSON.parse(state.content);
|
|
304
315
|
} catch {
|
|
@@ -312,7 +323,7 @@ function buildResponseFromState(state) {
|
|
|
312
323
|
});
|
|
313
324
|
}
|
|
314
325
|
const message = new AssistantMessage(
|
|
315
|
-
|
|
326
|
+
content,
|
|
316
327
|
toolCalls.length > 0 ? toolCalls : void 0,
|
|
317
328
|
{
|
|
318
329
|
metadata: {
|
|
@@ -377,9 +388,9 @@ async function* parseOllamaStream(body) {
|
|
|
377
388
|
} catch (error) {
|
|
378
389
|
throw new UPPError(
|
|
379
390
|
"Invalid JSON in Ollama stream",
|
|
380
|
-
|
|
391
|
+
ErrorCode.InvalidResponse,
|
|
381
392
|
"ollama",
|
|
382
|
-
|
|
393
|
+
ModalityType.LLM,
|
|
383
394
|
void 0,
|
|
384
395
|
toError(error)
|
|
385
396
|
);
|
|
@@ -394,9 +405,9 @@ async function* parseOllamaStream(body) {
|
|
|
394
405
|
} catch (error) {
|
|
395
406
|
throw new UPPError(
|
|
396
407
|
"Invalid JSON in Ollama stream",
|
|
397
|
-
|
|
408
|
+
ErrorCode.InvalidResponse,
|
|
398
409
|
"ollama",
|
|
399
|
-
|
|
410
|
+
ModalityType.LLM,
|
|
400
411
|
void 0,
|
|
401
412
|
toError(error)
|
|
402
413
|
);
|
|
@@ -416,9 +427,9 @@ function createLLMHandler() {
|
|
|
416
427
|
if (!providerRef) {
|
|
417
428
|
throw new UPPError(
|
|
418
429
|
"Provider reference not set. Handler must be used with createProvider().",
|
|
419
|
-
|
|
430
|
+
ErrorCode.InvalidRequest,
|
|
420
431
|
"ollama",
|
|
421
|
-
|
|
432
|
+
ModalityType.LLM
|
|
422
433
|
);
|
|
423
434
|
}
|
|
424
435
|
const model = {
|
|
@@ -527,9 +538,9 @@ function createLLMHandler() {
|
|
|
527
538
|
if (!response.body) {
|
|
528
539
|
const error = new UPPError(
|
|
529
540
|
"No response body for streaming request",
|
|
530
|
-
|
|
541
|
+
ErrorCode.ProviderError,
|
|
531
542
|
"ollama",
|
|
532
|
-
|
|
543
|
+
ModalityType.LLM
|
|
533
544
|
);
|
|
534
545
|
responseReject(error);
|
|
535
546
|
throw error;
|
|
@@ -538,9 +549,9 @@ function createLLMHandler() {
|
|
|
538
549
|
if ("error" in chunk && typeof chunk.error === "string") {
|
|
539
550
|
const error = new UPPError(
|
|
540
551
|
chunk.error,
|
|
541
|
-
|
|
552
|
+
ErrorCode.ProviderError,
|
|
542
553
|
"ollama",
|
|
543
|
-
|
|
554
|
+
ModalityType.LLM
|
|
544
555
|
);
|
|
545
556
|
responseReject(error);
|
|
546
557
|
throw error;
|
|
@@ -583,9 +594,9 @@ function createEmbeddingHandler() {
|
|
|
583
594
|
if (!providerRef) {
|
|
584
595
|
throw new UPPError(
|
|
585
596
|
"Provider reference not set. Handler must be used with createProvider().",
|
|
586
|
-
|
|
597
|
+
ErrorCode.InvalidRequest,
|
|
587
598
|
"ollama",
|
|
588
|
-
|
|
599
|
+
ModalityType.Embedding
|
|
589
600
|
);
|
|
590
601
|
}
|
|
591
602
|
const model = {
|
|
@@ -608,9 +619,9 @@ function createEmbeddingHandler() {
|
|
|
608
619
|
}
|
|
609
620
|
throw new UPPError(
|
|
610
621
|
"Ollama embeddings only support text input",
|
|
611
|
-
|
|
622
|
+
ErrorCode.InvalidRequest,
|
|
612
623
|
"ollama",
|
|
613
|
-
|
|
624
|
+
ModalityType.Embedding
|
|
614
625
|
);
|
|
615
626
|
});
|
|
616
627
|
const body = {
|
package/dist/ollama/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/ollama/transform.ts","../../src/providers/ollama/llm.ts","../../src/providers/ollama/embed.ts","../../src/providers/ollama/index.ts"],"sourcesContent":["/**\n * @fileoverview Transformation utilities for Ollama provider.\n *\n * This module handles bidirectional transformation between the Unified Provider\n * Protocol (UPP) format and Ollama's native API format. It includes:\n *\n * - Request transformation (UPP to Ollama)\n * - Response transformation (Ollama to UPP)\n * - Stream chunk processing\n * - Message format conversion\n *\n * @module providers/ollama/transform\n */\n\nimport type { LLMRequest, LLMResponse } from '../../types/llm.ts';\nimport type { Message } from '../../types/messages.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { Tool, ToolCall } from '../../types/tool.ts';\nimport type { TokenUsage } from '../../types/turn.ts';\nimport type { ContentBlock, TextBlock, ImageBlock } from '../../types/content.ts';\nimport {\n AssistantMessage,\n isUserMessage,\n isAssistantMessage,\n isToolResultMessage,\n} from '../../types/messages.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport type {\n OllamaLLMParams,\n OllamaRequest,\n OllamaMessage,\n OllamaTool,\n OllamaResponse,\n OllamaStreamChunk,\n OllamaToolCall,\n OllamaOptions,\n} from './types.ts';\n\n/**\n * Transforms a UPP LLM request into Ollama's native API format.\n *\n * This function handles the mapping between UPP's unified request structure\n * and Ollama's specific requirements, including:\n *\n * - Converting messages to Ollama's message format\n * - Mapping model parameters to Ollama's nested `options` structure\n * - Handling top-level parameters like `keep_alive` and `think`\n * - Converting tools to Ollama's function format\n * - Setting up structured output via the `format` field\n *\n * Parameters are spread to allow pass-through of any Ollama API fields,\n * enabling developers to use new API features without library updates.\n *\n * @typeParam TParams - The parameter type extending OllamaLLMParams\n * @param request - The UPP-format LLM request\n * @param modelId - The Ollama model identifier (e.g., 'llama3.2', 'mistral')\n * @returns The transformed Ollama API request body\n *\n * @example\n * ```typescript\n * const ollamaRequest = transformRequest(\n * {\n * messages: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],\n * config: {},\n * params: { temperature: 0.7 }\n * },\n * 'llama3.2'\n * );\n * ```\n */\nexport function transformRequest<TParams extends OllamaLLMParams>(\n request: LLMRequest<TParams>,\n modelId: string\n): OllamaRequest {\n const params = (request.params ?? {}) as OllamaLLMParams;\n\n // Extract top-level params vs options params\n const {\n keep_alive,\n think,\n logprobs,\n top_logprobs,\n ...optionsParams\n } = params;\n\n // Spread params to pass through all fields, then set required fields\n const ollamaRequest: OllamaRequest = {\n model: modelId,\n messages: transformMessages(request.messages, request.system),\n };\n\n // Add top-level params if provided\n if (keep_alive !== undefined) ollamaRequest.keep_alive = keep_alive;\n if (think !== undefined) ollamaRequest.think = think;\n if (logprobs !== undefined) ollamaRequest.logprobs = logprobs;\n if (top_logprobs !== undefined) ollamaRequest.top_logprobs = top_logprobs;\n\n // Spread remaining params into options to pass through all model parameters\n if (Object.keys(optionsParams).length > 0) {\n ollamaRequest.options = optionsParams as OllamaOptions;\n }\n\n // Tools come from request, not params\n if (request.tools && request.tools.length > 0) {\n ollamaRequest.tools = request.tools.map(transformTool);\n }\n\n // Structured output via format field\n if (request.structure) {\n ollamaRequest.format = request.structure as unknown as Record<string, unknown>;\n }\n\n return ollamaRequest;\n}\n\n/**\n * Normalizes system prompt to string.\n * Converts array format to concatenated string for providers that only support strings.\n */\nfunction normalizeSystem(system: string | unknown[] | undefined): string | undefined {\n if (system === undefined || system === null) return undefined;\n if (typeof system === 'string') return system;\n if (!Array.isArray(system)) {\n throw new UPPError(\n 'System prompt must be a string or an array of text blocks',\n 'INVALID_REQUEST',\n 'ollama',\n 'llm'\n );\n }\n\n const texts: string[] = [];\n for (const block of system) {\n if (!block || typeof block !== 'object' || !('text' in block)) {\n throw new UPPError(\n 'System prompt array must contain objects with a text field',\n 'INVALID_REQUEST',\n 'ollama',\n 'llm'\n );\n }\n const textValue = (block as { text?: unknown }).text;\n if (typeof textValue !== 'string') {\n throw new UPPError(\n 'System prompt text must be a string',\n 'INVALID_REQUEST',\n 'ollama',\n 'llm'\n );\n }\n if (textValue.length > 0) {\n texts.push(textValue);\n }\n }\n\n return texts.length > 0 ? texts.join('\\n\\n') : undefined;\n}\n\n/**\n * Transforms UPP messages to Ollama's message format.\n *\n * Handles conversion of:\n * - User messages with text and image content\n * - Assistant messages with text and tool calls\n * - Tool result messages\n * - System prompts (prepended as first message)\n *\n * Image handling:\n * - Base64 images are passed directly\n * - Byte arrays are converted to base64\n * - URL images are converted to text placeholders (Ollama limitation)\n *\n * @param messages - Array of UPP messages to transform\n * @param system - Optional system prompt (string or array, normalized to string)\n * @returns Array of Ollama-formatted messages\n */\nfunction transformMessages(messages: Message[], system?: string | unknown[]): OllamaMessage[] {\n const ollamaMessages: OllamaMessage[] = [];\n const normalizedSystem = normalizeSystem(system);\n\n // System prompt as first message\n if (normalizedSystem) {\n ollamaMessages.push({\n role: 'system',\n content: normalizedSystem,\n });\n }\n\n for (const msg of messages) {\n if (isUserMessage(msg)) {\n const textContent: string[] = [];\n const images: string[] = [];\n\n for (const block of msg.content) {\n if (block.type === 'text') {\n textContent.push(block.text);\n } else if (block.type === 'image') {\n const imageBlock = block as ImageBlock;\n if (imageBlock.source.type === 'base64') {\n images.push(imageBlock.source.data);\n } else if (imageBlock.source.type === 'bytes') {\n // Convert bytes to base64\n const base64 = btoa(\n Array.from(imageBlock.source.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n images.push(base64);\n } else if (imageBlock.source.type === 'url') {\n // Ollama doesn't support URL images directly\n // Would need to fetch and convert, for now just add as text\n textContent.push(`[Image: ${imageBlock.source.url}]`);\n }\n }\n }\n\n const message: OllamaMessage = {\n role: 'user',\n content: textContent.join('\\n'),\n };\n\n if (images.length > 0) {\n message.images = images;\n }\n\n ollamaMessages.push(message);\n } else if (isAssistantMessage(msg)) {\n const textContent = msg.content\n .filter((block): block is TextBlock => block.type === 'text')\n .map((block) => block.text)\n .join('\\n');\n\n const message: OllamaMessage = {\n role: 'assistant',\n content: textContent,\n };\n\n // Add tool calls if present\n if (msg.toolCalls && msg.toolCalls.length > 0) {\n message.tool_calls = msg.toolCalls.map((call) => ({\n function: {\n name: call.toolName,\n arguments: call.arguments,\n },\n }));\n }\n\n ollamaMessages.push(message);\n } else if (isToolResultMessage(msg)) {\n // Tool results are sent as 'tool' role messages\n for (const result of msg.results) {\n ollamaMessages.push({\n role: 'tool',\n tool_name: result.toolCallId, // In our UPP, toolCallId maps to tool name for Ollama\n content:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n });\n }\n }\n }\n\n return ollamaMessages;\n}\n\n/**\n * Transforms a UPP tool definition to Ollama's function format.\n *\n * Ollama uses the OpenAI-style function calling format with a\n * `type: 'function'` wrapper around the function definition.\n *\n * @param tool - The UPP tool definition\n * @returns The Ollama-formatted tool definition\n */\nfunction transformTool(tool: Tool): OllamaTool {\n return {\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: {\n type: 'object',\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n ...(tool.parameters.additionalProperties !== undefined\n ? { additionalProperties: tool.parameters.additionalProperties }\n : {}),\n },\n },\n };\n}\n\n/**\n * Transforms an Ollama API response to the UPP LLMResponse format.\n *\n * This function extracts and normalizes:\n * - Text content from the assistant message\n * - Tool calls with their arguments\n * - Token usage statistics (prompt + completion tokens)\n * - Stop reason mapping (stop -> end_turn, length -> max_tokens)\n * - Ollama-specific metadata (timings, model info, thinking content)\n *\n * For structured output requests, the response content is automatically\n * parsed as JSON and stored in the `data` field.\n *\n * @param data - The raw Ollama API response\n * @returns The normalized UPP LLM response\n */\nexport function transformResponse(data: OllamaResponse): LLMResponse {\n const textContent: TextBlock[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n\n // Add main content\n if (data.message.content) {\n textContent.push({ type: 'text', text: data.message.content });\n\n // Try to parse as JSON for structured output\n try {\n structuredData = JSON.parse(data.message.content);\n } catch {\n // Not valid JSON - that's fine, might not be structured output\n }\n }\n\n // Extract tool calls\n if (data.message.tool_calls) {\n for (const call of data.message.tool_calls) {\n toolCalls.push({\n toolCallId: call.function.name, // Ollama doesn't have separate IDs, use name\n toolName: call.function.name,\n arguments: call.function.arguments,\n });\n }\n }\n\n const message = new AssistantMessage(\n textContent,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n metadata: {\n ollama: {\n model: data.model,\n created_at: data.created_at,\n done_reason: data.done_reason,\n thinking: data.message.thinking,\n total_duration: data.total_duration,\n load_duration: data.load_duration,\n prompt_eval_duration: data.prompt_eval_duration,\n eval_duration: data.eval_duration,\n logprobs: data.logprobs,\n },\n },\n }\n );\n\n // Calculate token usage (Ollama doesn't support API-level prompt caching)\n const usage: TokenUsage = {\n inputTokens: data.prompt_eval_count ?? 0,\n outputTokens: data.eval_count ?? 0,\n totalTokens: (data.prompt_eval_count ?? 0) + (data.eval_count ?? 0),\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n };\n\n // Map done_reason to standard stop reason\n let stopReason = 'end_turn';\n if (data.done_reason === 'length') {\n stopReason = 'max_tokens';\n } else if (data.done_reason === 'stop') {\n stopReason = 'end_turn';\n } else if (toolCalls.length > 0) {\n stopReason = 'tool_use';\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n\n/**\n * Mutable state object for accumulating data during stream processing.\n *\n * As streaming chunks arrive, this state object accumulates content,\n * tool calls, and metadata. Once the stream completes (indicated by\n * `done: true`), this state is used to build the final LLMResponse.\n */\nexport interface StreamState {\n /** The model name from the stream. */\n model: string;\n /** Accumulated text content from all chunks. */\n content: string;\n /** Accumulated thinking/reasoning content (for models with think mode). */\n thinking: string;\n /** Tool calls extracted from the stream. */\n toolCalls: Array<{ name: string; args: Record<string, unknown> }>;\n /** The reason the generation stopped (stop, length, etc.). */\n doneReason: string | null;\n /** Number of tokens in the prompt evaluation. */\n promptEvalCount: number;\n /** Number of tokens generated in the response. */\n evalCount: number;\n /** Total generation duration in nanoseconds. */\n totalDuration: number;\n /** Whether we're still waiting for the first chunk. */\n isFirstChunk: boolean;\n /** ISO timestamp when the response was created. */\n createdAt: string;\n}\n\n/**\n * Creates an initial empty stream state for accumulating streaming responses.\n *\n * @returns A fresh StreamState object with default values\n */\nexport function createStreamState(): StreamState {\n return {\n model: '',\n content: '',\n thinking: '',\n toolCalls: [],\n doneReason: null,\n promptEvalCount: 0,\n evalCount: 0,\n totalDuration: 0,\n isFirstChunk: true,\n createdAt: '',\n };\n}\n\n/**\n * Transforms an Ollama stream chunk into UPP StreamEvents.\n *\n * Each Ollama chunk may produce zero or more UPP events:\n * - First chunk: `message_start` event\n * - Content chunks: `text_delta` events\n * - Thinking chunks: `reasoning_delta` events\n * - Tool call chunks: `tool_call_delta` events\n * - Final chunk (done=true): `message_stop` event\n *\n * The function also updates the provided state object with accumulated\n * content and metadata for building the final response.\n *\n * @param chunk - The raw Ollama stream chunk\n * @param state - Mutable state object to accumulate data\n * @returns Array of UPP stream events (may be empty)\n */\nexport function transformStreamChunk(\n chunk: OllamaStreamChunk,\n state: StreamState\n): StreamEvent[] {\n const events: StreamEvent[] = [];\n\n // First chunk - emit message start\n if (state.isFirstChunk) {\n state.model = chunk.model;\n state.createdAt = chunk.created_at;\n events.push({ type: 'message_start', index: 0, delta: {} });\n state.isFirstChunk = false;\n }\n\n // Process message content\n if (chunk.message) {\n // Text content delta\n if (chunk.message.content) {\n state.content += chunk.message.content;\n events.push({\n type: 'text_delta',\n index: 0,\n delta: { text: chunk.message.content },\n });\n }\n\n // Thinking content delta\n if (chunk.message.thinking) {\n state.thinking += chunk.message.thinking;\n events.push({\n type: 'reasoning_delta',\n index: 0,\n delta: { text: chunk.message.thinking },\n });\n }\n\n // Tool calls (typically come in final chunk)\n if (chunk.message.tool_calls) {\n for (const call of chunk.message.tool_calls) {\n state.toolCalls.push({\n name: call.function.name,\n args: call.function.arguments,\n });\n events.push({\n type: 'tool_call_delta',\n index: state.toolCalls.length - 1,\n delta: {\n toolCallId: call.function.name,\n toolName: call.function.name,\n argumentsJson: JSON.stringify(call.function.arguments),\n },\n });\n }\n }\n }\n\n // Final chunk with metrics\n if (chunk.done) {\n state.doneReason = chunk.done_reason ?? null;\n state.promptEvalCount = chunk.prompt_eval_count ?? 0;\n state.evalCount = chunk.eval_count ?? 0;\n state.totalDuration = chunk.total_duration ?? 0;\n events.push({ type: 'message_stop', index: 0, delta: {} });\n }\n\n return events;\n}\n\n/**\n * Builds a complete LLMResponse from accumulated stream state.\n *\n * Called after the stream completes to construct the final response object\n * with all accumulated content, tool calls, usage statistics, and metadata.\n *\n * For structured output, attempts to parse the accumulated content as JSON\n * and stores it in the `data` field if successful.\n *\n * @param state - The accumulated stream state\n * @returns The complete UPP LLM response\n */\nexport function buildResponseFromState(state: StreamState): LLMResponse {\n const textContent: TextBlock[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n\n if (state.content) {\n textContent.push({ type: 'text', text: state.content });\n\n // Try to parse as JSON for structured output\n try {\n structuredData = JSON.parse(state.content);\n } catch {\n // Not valid JSON - that's fine\n }\n }\n\n for (const tc of state.toolCalls) {\n toolCalls.push({\n toolCallId: tc.name,\n toolName: tc.name,\n arguments: tc.args,\n });\n }\n\n const message = new AssistantMessage(\n textContent,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n metadata: {\n ollama: {\n model: state.model,\n created_at: state.createdAt,\n done_reason: state.doneReason,\n thinking: state.thinking || undefined,\n total_duration: state.totalDuration,\n },\n },\n }\n );\n\n // Ollama doesn't support API-level prompt caching\n const usage: TokenUsage = {\n inputTokens: state.promptEvalCount,\n outputTokens: state.evalCount,\n totalTokens: state.promptEvalCount + state.evalCount,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n };\n\n // Map done_reason to standard stop reason\n let stopReason = 'end_turn';\n if (state.doneReason === 'length') {\n stopReason = 'max_tokens';\n } else if (toolCalls.length > 0) {\n stopReason = 'tool_use';\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n","/**\n * @fileoverview Ollama LLM handler implementation.\n *\n * This module provides the core LLM functionality for the Ollama provider,\n * including both synchronous completion and streaming capabilities. It\n * communicates with Ollama's native `/api/chat` endpoint.\n *\n * @module providers/ollama/llm\n */\n\nimport type {\n LLMHandler,\n BoundLLMModel,\n LLMRequest,\n LLMResponse,\n LLMStreamResult,\n LLMCapabilities,\n} from '../../types/llm.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { toError } from '../../utils/error.ts';\nimport type { OllamaLLMParams, OllamaResponse, OllamaStreamChunk } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamChunk,\n createStreamState,\n buildResponseFromState,\n} from './transform.ts';\n\n/** Default Ollama server URL for local installations. */\nconst OLLAMA_DEFAULT_URL = 'http://localhost:11434';\n\n/**\n * Capability flags for the Ollama provider.\n *\n * **Important:** Tool calling is intentionally disabled. Ollama recommends\n * using their OpenAI-compatible API (`/v1/chat/completions`) for function\n * calling. To use tools with Ollama, configure the OpenAI provider with\n * `baseUrl` pointed to your Ollama instance.\n */\nconst OLLAMA_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: false,\n structuredOutput: true,\n imageInput: true,\n videoInput: false,\n audioInput: false,\n};\n\n/**\n * Parses Ollama's newline-delimited JSON (NDJSON) stream format.\n *\n * Ollama uses NDJSON where each line is a complete JSON object representing\n * a streaming chunk. This generator reads the stream incrementally, buffering\n * incomplete lines and yielding parsed chunks as they become available.\n *\n * @param body - The raw ReadableStream from the fetch response\n * @yields Parsed Ollama stream chunks\n */\nasync function* parseOllamaStream(\n body: ReadableStream<Uint8Array>\n): AsyncGenerator<OllamaStreamChunk, void, unknown> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete lines (Ollama uses newline-delimited JSON)\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? ''; // Keep incomplete line in buffer\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n try {\n const chunk = JSON.parse(trimmed) as OllamaStreamChunk;\n yield chunk;\n } catch (error) {\n throw new UPPError(\n 'Invalid JSON in Ollama stream',\n 'INVALID_RESPONSE',\n 'ollama',\n 'llm',\n undefined,\n toError(error)\n );\n }\n }\n }\n\n buffer += decoder.decode();\n // Process any remaining buffer\n if (buffer.trim()) {\n try {\n const chunk = JSON.parse(buffer.trim()) as OllamaStreamChunk;\n yield chunk;\n } catch (error) {\n throw new UPPError(\n 'Invalid JSON in Ollama stream',\n 'INVALID_RESPONSE',\n 'ollama',\n 'llm',\n undefined,\n toError(error)\n );\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Creates the Ollama LLM handler for chat completions.\n *\n * This factory function creates an LLM handler that communicates with\n * Ollama's `/api/chat` endpoint. The handler supports both synchronous\n * completions and streaming responses.\n *\n * The handler is designed to be used with `createProvider()` which injects\n * the provider reference after construction.\n *\n * @returns An LLM handler configured for Ollama\n *\n * @example\n * ```typescript\n * const handler = createLLMHandler();\n * const provider = createProvider({\n * name: 'ollama',\n * version: '1.0.0',\n * handlers: { llm: handler }\n * });\n * ```\n */\nexport function createLLMHandler(): LLMHandler<OllamaLLMParams> {\n let providerRef: LLMProvider<OllamaLLMParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<OllamaLLMParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<OllamaLLMParams> {\n // Use the injected provider reference (set by createProvider)\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n 'INVALID_REQUEST',\n 'ollama',\n 'llm'\n );\n }\n\n const model: BoundLLMModel<OllamaLLMParams> = {\n modelId,\n capabilities: OLLAMA_CAPABILITIES,\n\n get provider(): LLMProvider<OllamaLLMParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<OllamaLLMParams>): Promise<LLMResponse> {\n // Ollama doesn't require an API key by default, but may use one for auth\n let apiKey: string | undefined;\n try {\n apiKey = await resolveApiKey(\n request.config,\n 'OLLAMA_API_KEY',\n 'ollama',\n 'llm'\n );\n } catch {\n // API key is optional for Ollama\n }\n\n const baseUrl = request.config.baseUrl ?? OLLAMA_DEFAULT_URL;\n const url = `${baseUrl}/api/chat`;\n const body = transformRequest(request, modelId);\n body.stream = false;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (apiKey) {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'ollama',\n 'llm'\n );\n\n const data = await parseJsonResponse<OllamaResponse>(response, 'ollama', 'llm');\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<OllamaLLMParams>): LLMStreamResult {\n const state = createStreamState();\n let responseResolve: (value: LLMResponse) => void;\n let responseReject: (error: Error) => void;\n\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n responseResolve = resolve;\n responseReject = reject;\n });\n\n async function* generateEvents(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n // Ollama doesn't require an API key by default\n let apiKey: string | undefined;\n try {\n apiKey = await resolveApiKey(\n request.config,\n 'OLLAMA_API_KEY',\n 'ollama',\n 'llm'\n );\n } catch {\n // API key is optional for Ollama\n }\n\n const baseUrl = request.config.baseUrl ?? OLLAMA_DEFAULT_URL;\n const url = `${baseUrl}/api/chat`;\n const body = transformRequest(request, modelId);\n body.stream = true;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (apiKey) {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doStreamFetch(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'ollama',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'ollama', 'llm');\n responseReject(error);\n throw error;\n }\n\n if (!response.body) {\n const error = new UPPError(\n 'No response body for streaming request',\n 'PROVIDER_ERROR',\n 'ollama',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n // Parse Ollama's newline-delimited JSON stream\n for await (const chunk of parseOllamaStream(response.body)) {\n // Check for error in chunk\n if ('error' in chunk && typeof (chunk as Record<string, unknown>).error === 'string') {\n const error = new UPPError(\n (chunk as Record<string, unknown>).error as string,\n 'PROVIDER_ERROR',\n 'ollama',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n const events = transformStreamChunk(chunk, state);\n for (const event of events) {\n yield event;\n }\n }\n\n // Build final response\n responseResolve(buildResponseFromState(state));\n } catch (error) {\n const err = toError(error);\n responseReject(err);\n throw err;\n }\n }\n\n return {\n [Symbol.asyncIterator]() {\n return generateEvents();\n },\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * @fileoverview Ollama Embeddings API Handler\n *\n * This module implements the embedding handler for Ollama's local embeddings API.\n * Supports various embedding models including nomic-embed-text, mxbai-embed-large,\n * qwen3-embedding, and others.\n *\n * @see {@link https://github.com/ollama/ollama/blob/main/docs/api.md#embeddings Ollama Embeddings API Reference}\n * @module providers/ollama/embed\n */\n\nimport type {\n EmbeddingHandler,\n BoundEmbeddingModel,\n EmbeddingRequest,\n EmbeddingResponse,\n EmbeddingProvider,\n} from '../../types/provider.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport { doFetch } from '../../http/fetch.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\n\n/** Default URL for Ollama's local API */\nconst OLLAMA_DEFAULT_URL = 'http://localhost:11434';\n\n/**\n * Ollama embedding parameters.\n * Passed through to the API.\n */\nexport interface OllamaEmbedParams {\n /** Truncates the end of each input to fit within context length (default: true) */\n truncate?: boolean;\n /** Controls how long the model stays loaded in memory (e.g., '5m', '1h') */\n keep_alive?: string;\n /** Additional model options */\n options?: Record<string, unknown>;\n}\n\n/**\n * Ollama embeddings API response structure.\n */\ninterface OllamaEmbeddingsResponse {\n model: string;\n embeddings: number[][];\n total_duration?: number;\n load_duration?: number;\n prompt_eval_count?: number;\n}\n\n/**\n * Creates an embedding handler for Ollama's local Embeddings API.\n *\n * @returns An embedding handler configured for Ollama\n *\n * @example\n * ```typescript\n * const handler = createEmbeddingHandler();\n * const model = handler.bind('nomic-embed-text');\n *\n * const response = await model.embed({\n * inputs: ['Hello world'],\n * config: { baseUrl: 'http://localhost:11434' }\n * });\n * ```\n */\nexport function createEmbeddingHandler(): EmbeddingHandler<OllamaEmbedParams> {\n let providerRef: EmbeddingProvider<OllamaEmbedParams> | null = null;\n\n return {\n supportedInputs: ['text'],\n\n _setProvider(provider: EmbeddingProvider<OllamaEmbedParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundEmbeddingModel<OllamaEmbedParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n 'INVALID_REQUEST',\n 'ollama',\n 'embedding'\n );\n }\n\n const model: BoundEmbeddingModel<OllamaEmbedParams> = {\n modelId,\n maxBatchSize: 512,\n maxInputLength: 8192,\n dimensions: 768, // Varies by model\n\n get provider(): EmbeddingProvider<OllamaEmbedParams> {\n return providerRef!;\n },\n\n async embed(request: EmbeddingRequest<OllamaEmbedParams>): Promise<EmbeddingResponse> {\n const baseUrl = request.config.baseUrl ?? OLLAMA_DEFAULT_URL;\n\n // Transform inputs to strings\n const inputTexts = request.inputs.map((input) => {\n if (typeof input === 'string') {\n return input;\n }\n if ('text' in input) {\n return input.text;\n }\n throw new UPPError(\n 'Ollama embeddings only support text input',\n 'INVALID_REQUEST',\n 'ollama',\n 'embedding'\n );\n });\n\n // Build request body\n const body: Record<string, unknown> = {\n model: modelId,\n input: inputTexts,\n };\n\n // Pass through Ollama-specific params\n if (request.params?.truncate !== undefined) {\n body.truncate = request.params.truncate;\n }\n if (request.params?.keep_alive !== undefined) {\n body.keep_alive = request.params.keep_alive;\n }\n if (request.params?.options !== undefined) {\n body.options = request.params.options;\n }\n\n const url = `${baseUrl}/api/embed`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Merge custom headers\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n }, request.config, 'ollama', 'embedding');\n\n const data = await parseJsonResponse<OllamaEmbeddingsResponse>(response, 'ollama', 'embedding');\n\n // Return EmbeddingResponse\n return {\n embeddings: data.embeddings.map((vec, index) => ({\n vector: vec,\n index,\n })),\n usage: {\n totalTokens: data.prompt_eval_count ?? 0,\n },\n metadata: {\n totalDuration: data.total_duration,\n loadDuration: data.load_duration,\n },\n };\n },\n };\n\n return model;\n },\n };\n}\n","import { createProvider } from '../../core/provider.ts';\nimport { createLLMHandler } from './llm.ts';\nimport { createEmbeddingHandler } from './embed.ts';\n\n/**\n * Ollama provider for local LLM inference.\n *\n * Ollama runs models locally on your machine, eliminating the need for API keys\n * and external network calls. This makes it ideal for development, testing,\n * and privacy-sensitive applications.\n *\n * **Supported Models:**\n * - Llama 3.x (Meta's latest open-weight models)\n * - Mistral / Mixtral (Mistral AI's efficient models)\n * - Gemma (Google's lightweight models)\n * - Qwen (Alibaba's multilingual models)\n * - DeepSeek (DeepSeek's code and reasoning models)\n * - Phi (Microsoft's small language models)\n * - CodeLlama (Code-specialized Llama variants)\n * - And many more from the Ollama model library\n *\n * **Prerequisites:**\n * 1. Install Ollama from https://ollama.ai\n * 2. Pull a model: `ollama pull llama3.2`\n * 3. Ensure Ollama is running (default: http://localhost:11434)\n *\n * **Note on Tool Calling:**\n * For tool/function calling, Ollama recommends using their OpenAI-compatible\n * API endpoint. Use the OpenAI provider with `baseUrl` pointed to Ollama instead.\n *\n * @example Basic usage with local model\n * ```typescript\n * import { llm } from 'provider-protocol';\n * import { ollama } from 'provider-protocol/ollama';\n *\n * const model = llm({ model: ollama('llama3.2') });\n * const turn = await model.generate('Hello!');\n * console.log(turn.response.text);\n * ```\n *\n * @example Custom Ollama server URL\n * ```typescript\n * import { llm } from 'provider-protocol';\n * import { ollama } from 'provider-protocol/ollama';\n *\n * const model = llm({\n * model: ollama('llama3.2'),\n * config: { baseUrl: 'http://my-ollama-server:11434' },\n * });\n * ```\n *\n * @example Streaming responses\n * ```typescript\n * const model = llm({ model: ollama('llama3.2') });\n * const stream = model.stream('Write a poem');\n *\n * for await (const event of stream) {\n * if (event.type === 'text_delta') {\n * process.stdout.write(event.delta.text);\n * }\n * }\n * ```\n *\n * @example Using model parameters\n * ```typescript\n * const model = llm({\n * model: ollama('llama3.2'),\n * params: {\n * temperature: 0.9,\n * top_p: 0.95,\n * num_predict: 500,\n * },\n * });\n * const result = await model.generate('Be creative!');\n * ```\n *\n * @see {@link OllamaLLMParams} for available model parameters\n */\nexport const ollama = createProvider({\n name: 'ollama',\n version: '1.0.0',\n handlers: {\n llm: createLLMHandler(),\n embedding: createEmbeddingHandler(),\n },\n});\n\nexport type { OllamaLLMParams, OllamaHeaders } from './types.ts';\nexport type { OllamaEmbedParams } from './embed.ts';\n"],"mappings":"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","names":["OLLAMA_DEFAULT_URL"]}
|
|
1
|
+
{"version":3,"sources":["../../src/providers/ollama/transform.ts","../../src/providers/ollama/llm.ts","../../src/providers/ollama/embed.ts","../../src/providers/ollama/index.ts"],"sourcesContent":["/**\n * @fileoverview Transformation utilities for Ollama provider.\n *\n * This module handles bidirectional transformation between the Unified Provider\n * Protocol (UPP) format and Ollama's native API format. It includes:\n *\n * - Request transformation (UPP to Ollama)\n * - Response transformation (Ollama to UPP)\n * - Stream chunk processing\n * - Message format conversion\n *\n * @module providers/ollama/transform\n */\n\nimport type { LLMRequest, LLMResponse } from '../../types/llm.ts';\nimport type { Message } from '../../types/messages.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport { StreamEventType } from '../../types/stream.ts';\nimport type { Tool, ToolCall } from '../../types/tool.ts';\nimport type { TokenUsage } from '../../types/turn.ts';\nimport type { ContentBlock, TextBlock, ImageBlock, AssistantContent } from '../../types/content.ts';\nimport {\n AssistantMessage,\n isUserMessage,\n isAssistantMessage,\n isToolResultMessage,\n} from '../../types/messages.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport type {\n OllamaLLMParams,\n OllamaRequest,\n OllamaMessage,\n OllamaTool,\n OllamaResponse,\n OllamaStreamChunk,\n OllamaToolCall,\n OllamaOptions,\n} from './types.ts';\n\n/**\n * Transforms a UPP LLM request into Ollama's native API format.\n *\n * This function handles the mapping between UPP's unified request structure\n * and Ollama's specific requirements, including:\n *\n * - Converting messages to Ollama's message format\n * - Mapping model parameters to Ollama's nested `options` structure\n * - Handling top-level parameters like `keep_alive` and `think`\n * - Converting tools to Ollama's function format\n * - Setting up structured output via the `format` field\n *\n * Parameters are spread to allow pass-through of any Ollama API fields,\n * enabling developers to use new API features without library updates.\n *\n * @typeParam TParams - The parameter type extending OllamaLLMParams\n * @param request - The UPP-format LLM request\n * @param modelId - The Ollama model identifier (e.g., 'llama3.2', 'mistral')\n * @returns The transformed Ollama API request body\n *\n * @example\n * ```typescript\n * const ollamaRequest = transformRequest(\n * {\n * messages: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],\n * config: {},\n * params: { temperature: 0.7 }\n * },\n * 'llama3.2'\n * );\n * ```\n */\nexport function transformRequest<TParams extends OllamaLLMParams>(\n request: LLMRequest<TParams>,\n modelId: string\n): OllamaRequest {\n const params = (request.params ?? {}) as OllamaLLMParams;\n\n // Extract top-level params vs options params\n const {\n keep_alive,\n think,\n logprobs,\n top_logprobs,\n ...optionsParams\n } = params;\n\n // Spread params to pass through all fields, then set required fields\n const ollamaRequest: OllamaRequest = {\n model: modelId,\n messages: transformMessages(request.messages, request.system),\n };\n\n // Add top-level params if provided\n if (keep_alive !== undefined) ollamaRequest.keep_alive = keep_alive;\n if (think !== undefined) ollamaRequest.think = think;\n if (logprobs !== undefined) ollamaRequest.logprobs = logprobs;\n if (top_logprobs !== undefined) ollamaRequest.top_logprobs = top_logprobs;\n\n // Spread remaining params into options to pass through all model parameters\n if (Object.keys(optionsParams).length > 0) {\n ollamaRequest.options = optionsParams as OllamaOptions;\n }\n\n // Tools come from request, not params\n if (request.tools && request.tools.length > 0) {\n ollamaRequest.tools = request.tools.map(transformTool);\n }\n\n // Structured output via format field\n if (request.structure) {\n ollamaRequest.format = request.structure as unknown as Record<string, unknown>;\n }\n\n return ollamaRequest;\n}\n\n/**\n * Normalizes system prompt to string.\n * Converts array format to concatenated string for providers that only support strings.\n */\nfunction normalizeSystem(system: string | unknown[] | undefined): string | undefined {\n if (system === undefined || system === null) return undefined;\n if (typeof system === 'string') return system;\n if (!Array.isArray(system)) {\n throw new UPPError(\n 'System prompt must be a string or an array of text blocks',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.LLM\n );\n }\n\n const texts: string[] = [];\n for (const block of system) {\n if (!block || typeof block !== 'object' || !('text' in block)) {\n throw new UPPError(\n 'System prompt array must contain objects with a text field',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.LLM\n );\n }\n const textValue = (block as { text?: unknown }).text;\n if (typeof textValue !== 'string') {\n throw new UPPError(\n 'System prompt text must be a string',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.LLM\n );\n }\n if (textValue.length > 0) {\n texts.push(textValue);\n }\n }\n\n return texts.length > 0 ? texts.join('\\n\\n') : undefined;\n}\n\n/**\n * Transforms UPP messages to Ollama's message format.\n *\n * Handles conversion of:\n * - User messages with text and image content\n * - Assistant messages with text and tool calls\n * - Tool result messages\n * - System prompts (prepended as first message)\n *\n * Image handling:\n * - Base64 images are passed directly\n * - Byte arrays are converted to base64\n * - URL images are converted to text placeholders (Ollama limitation)\n *\n * @param messages - Array of UPP messages to transform\n * @param system - Optional system prompt (string or array, normalized to string)\n * @returns Array of Ollama-formatted messages\n */\nfunction transformMessages(messages: Message[], system?: string | unknown[]): OllamaMessage[] {\n const ollamaMessages: OllamaMessage[] = [];\n const normalizedSystem = normalizeSystem(system);\n\n // System prompt as first message\n if (normalizedSystem) {\n ollamaMessages.push({\n role: 'system',\n content: normalizedSystem,\n });\n }\n\n for (const msg of messages) {\n if (isUserMessage(msg)) {\n const textContent: string[] = [];\n const images: string[] = [];\n\n for (const block of msg.content) {\n if (block.type === 'text') {\n textContent.push(block.text);\n } else if (block.type === 'image') {\n const imageBlock = block as ImageBlock;\n if (imageBlock.source.type === 'base64') {\n images.push(imageBlock.source.data);\n } else if (imageBlock.source.type === 'bytes') {\n // Convert bytes to base64\n const base64 = btoa(\n Array.from(imageBlock.source.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n images.push(base64);\n } else if (imageBlock.source.type === 'url') {\n // Ollama doesn't support URL images directly\n // Would need to fetch and convert, for now just add as text\n textContent.push(`[Image: ${imageBlock.source.url}]`);\n }\n }\n }\n\n const message: OllamaMessage = {\n role: 'user',\n content: textContent.join('\\n'),\n };\n\n if (images.length > 0) {\n message.images = images;\n }\n\n ollamaMessages.push(message);\n } else if (isAssistantMessage(msg)) {\n // Filter for text blocks only (exclude reasoning blocks from history)\n // Also strip any <think>...</think> tags that may be embedded in text\n // (required for proper multi-turn with Qwen 3, DeepSeek-R1, etc.)\n const textContent = msg.content\n .filter((block): block is TextBlock => block.type === 'text')\n .map((block) => block.text)\n .join('\\n')\n .replace(/<think>[\\s\\S]*?<\\/think>/g, '')\n .trim();\n\n const message: OllamaMessage = {\n role: 'assistant',\n content: textContent,\n };\n\n // Add tool calls if present\n if (msg.toolCalls && msg.toolCalls.length > 0) {\n message.tool_calls = msg.toolCalls.map((call) => ({\n function: {\n name: call.toolName,\n arguments: call.arguments,\n },\n }));\n }\n\n ollamaMessages.push(message);\n } else if (isToolResultMessage(msg)) {\n // Tool results are sent as 'tool' role messages\n for (const result of msg.results) {\n ollamaMessages.push({\n role: 'tool',\n tool_name: result.toolCallId, // In our UPP, toolCallId maps to tool name for Ollama\n content:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n });\n }\n }\n }\n\n return ollamaMessages;\n}\n\n/**\n * Transforms a UPP tool definition to Ollama's function format.\n *\n * Ollama uses the OpenAI-style function calling format with a\n * `type: 'function'` wrapper around the function definition.\n *\n * @param tool - The UPP tool definition\n * @returns The Ollama-formatted tool definition\n */\nfunction transformTool(tool: Tool): OllamaTool {\n return {\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: {\n type: 'object',\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n ...(tool.parameters.additionalProperties !== undefined\n ? { additionalProperties: tool.parameters.additionalProperties }\n : {}),\n },\n },\n };\n}\n\n/**\n * Transforms an Ollama API response to the UPP LLMResponse format.\n *\n * This function extracts and normalizes:\n * - Text content from the assistant message\n * - Tool calls with their arguments\n * - Token usage statistics (prompt + completion tokens)\n * - Stop reason mapping (stop -> end_turn, length -> max_tokens)\n * - Ollama-specific metadata (timings, model info, thinking content)\n *\n * For structured output requests, the response content is automatically\n * parsed as JSON and stored in the `data` field.\n *\n * @param data - The raw Ollama API response\n * @returns The normalized UPP LLM response\n */\nexport function transformResponse(data: OllamaResponse): LLMResponse {\n const content: AssistantContent[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n\n // Add reasoning/thinking content first (if present)\n if (data.message.thinking) {\n content.push({ type: 'reasoning', text: data.message.thinking });\n }\n\n // Add main content\n if (data.message.content) {\n content.push({ type: 'text', text: data.message.content });\n\n // Try to parse as JSON for structured output\n try {\n structuredData = JSON.parse(data.message.content);\n } catch {\n // Not valid JSON - that's fine, might not be structured output\n }\n }\n\n // Extract tool calls\n if (data.message.tool_calls) {\n for (const call of data.message.tool_calls) {\n toolCalls.push({\n toolCallId: call.function.name, // Ollama doesn't have separate IDs, use name\n toolName: call.function.name,\n arguments: call.function.arguments,\n });\n }\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n metadata: {\n ollama: {\n model: data.model,\n created_at: data.created_at,\n done_reason: data.done_reason,\n thinking: data.message.thinking,\n total_duration: data.total_duration,\n load_duration: data.load_duration,\n prompt_eval_duration: data.prompt_eval_duration,\n eval_duration: data.eval_duration,\n logprobs: data.logprobs,\n },\n },\n }\n );\n\n // Calculate token usage (Ollama doesn't support API-level prompt caching)\n const usage: TokenUsage = {\n inputTokens: data.prompt_eval_count ?? 0,\n outputTokens: data.eval_count ?? 0,\n totalTokens: (data.prompt_eval_count ?? 0) + (data.eval_count ?? 0),\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n };\n\n // Map done_reason to standard stop reason\n let stopReason = 'end_turn';\n if (data.done_reason === 'length') {\n stopReason = 'max_tokens';\n } else if (data.done_reason === 'stop') {\n stopReason = 'end_turn';\n } else if (toolCalls.length > 0) {\n stopReason = 'tool_use';\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n\n/**\n * Mutable state object for accumulating data during stream processing.\n *\n * As streaming chunks arrive, this state object accumulates content,\n * tool calls, and metadata. Once the stream completes (indicated by\n * `done: true`), this state is used to build the final LLMResponse.\n */\nexport interface StreamState {\n /** The model name from the stream. */\n model: string;\n /** Accumulated text content from all chunks. */\n content: string;\n /** Accumulated thinking/reasoning content (for models with think mode). */\n thinking: string;\n /** Tool calls extracted from the stream. */\n toolCalls: Array<{ name: string; args: Record<string, unknown> }>;\n /** The reason the generation stopped (stop, length, etc.). */\n doneReason: string | null;\n /** Number of tokens in the prompt evaluation. */\n promptEvalCount: number;\n /** Number of tokens generated in the response. */\n evalCount: number;\n /** Total generation duration in nanoseconds. */\n totalDuration: number;\n /** Whether we're still waiting for the first chunk. */\n isFirstChunk: boolean;\n /** ISO timestamp when the response was created. */\n createdAt: string;\n}\n\n/**\n * Creates an initial empty stream state for accumulating streaming responses.\n *\n * @returns A fresh StreamState object with default values\n */\nexport function createStreamState(): StreamState {\n return {\n model: '',\n content: '',\n thinking: '',\n toolCalls: [],\n doneReason: null,\n promptEvalCount: 0,\n evalCount: 0,\n totalDuration: 0,\n isFirstChunk: true,\n createdAt: '',\n };\n}\n\n/**\n * Transforms an Ollama stream chunk into UPP StreamEvents.\n *\n * Each Ollama chunk may produce zero or more UPP events:\n * - First chunk: `message_start` event\n * - Content chunks: `text_delta` events\n * - Thinking chunks: `reasoning_delta` events\n * - Tool call chunks: `tool_call_delta` events\n * - Final chunk (done=true): `message_stop` event\n *\n * The function also updates the provided state object with accumulated\n * content and metadata for building the final response.\n *\n * @param chunk - The raw Ollama stream chunk\n * @param state - Mutable state object to accumulate data\n * @returns Array of UPP stream events (may be empty)\n */\nexport function transformStreamChunk(\n chunk: OllamaStreamChunk,\n state: StreamState\n): StreamEvent[] {\n const events: StreamEvent[] = [];\n\n // First chunk - emit message start\n if (state.isFirstChunk) {\n state.model = chunk.model;\n state.createdAt = chunk.created_at;\n events.push({ type: StreamEventType.MessageStart, index: 0, delta: {} });\n state.isFirstChunk = false;\n }\n\n // Process message content\n if (chunk.message) {\n // Text content delta\n if (chunk.message.content) {\n state.content += chunk.message.content;\n events.push({\n type: StreamEventType.TextDelta,\n index: 0,\n delta: { text: chunk.message.content },\n });\n }\n\n // Thinking content delta\n if (chunk.message.thinking) {\n state.thinking += chunk.message.thinking;\n events.push({\n type: StreamEventType.ReasoningDelta,\n index: 0,\n delta: { text: chunk.message.thinking },\n });\n }\n\n // Tool calls (typically come in final chunk)\n if (chunk.message.tool_calls) {\n for (const call of chunk.message.tool_calls) {\n state.toolCalls.push({\n name: call.function.name,\n args: call.function.arguments,\n });\n events.push({\n type: StreamEventType.ToolCallDelta,\n index: state.toolCalls.length - 1,\n delta: {\n toolCallId: call.function.name,\n toolName: call.function.name,\n argumentsJson: JSON.stringify(call.function.arguments),\n },\n });\n }\n }\n }\n\n // Final chunk with metrics\n if (chunk.done) {\n state.doneReason = chunk.done_reason ?? null;\n state.promptEvalCount = chunk.prompt_eval_count ?? 0;\n state.evalCount = chunk.eval_count ?? 0;\n state.totalDuration = chunk.total_duration ?? 0;\n events.push({ type: StreamEventType.MessageStop, index: 0, delta: {} });\n }\n\n return events;\n}\n\n/**\n * Builds a complete LLMResponse from accumulated stream state.\n *\n * Called after the stream completes to construct the final response object\n * with all accumulated content, tool calls, usage statistics, and metadata.\n *\n * For structured output, attempts to parse the accumulated content as JSON\n * and stores it in the `data` field if successful.\n *\n * @param state - The accumulated stream state\n * @returns The complete UPP LLM response\n */\nexport function buildResponseFromState(state: StreamState): LLMResponse {\n const content: AssistantContent[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n\n // Add reasoning/thinking content first (if present)\n if (state.thinking) {\n content.push({ type: 'reasoning', text: state.thinking });\n }\n\n if (state.content) {\n content.push({ type: 'text', text: state.content });\n\n // Try to parse as JSON for structured output\n try {\n structuredData = JSON.parse(state.content);\n } catch {\n // Not valid JSON - that's fine\n }\n }\n\n for (const tc of state.toolCalls) {\n toolCalls.push({\n toolCallId: tc.name,\n toolName: tc.name,\n arguments: tc.args,\n });\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n metadata: {\n ollama: {\n model: state.model,\n created_at: state.createdAt,\n done_reason: state.doneReason,\n thinking: state.thinking || undefined,\n total_duration: state.totalDuration,\n },\n },\n }\n );\n\n // Ollama doesn't support API-level prompt caching\n const usage: TokenUsage = {\n inputTokens: state.promptEvalCount,\n outputTokens: state.evalCount,\n totalTokens: state.promptEvalCount + state.evalCount,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n };\n\n // Map done_reason to standard stop reason\n let stopReason = 'end_turn';\n if (state.doneReason === 'length') {\n stopReason = 'max_tokens';\n } else if (toolCalls.length > 0) {\n stopReason = 'tool_use';\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n","/**\n * @fileoverview Ollama LLM handler implementation.\n *\n * This module provides the core LLM functionality for the Ollama provider,\n * including both synchronous completion and streaming capabilities. It\n * communicates with Ollama's native `/api/chat` endpoint.\n *\n * @module providers/ollama/llm\n */\n\nimport type {\n LLMHandler,\n BoundLLMModel,\n LLMRequest,\n LLMResponse,\n LLMStreamResult,\n LLMCapabilities,\n} from '../../types/llm.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { toError } from '../../utils/error.ts';\nimport type { OllamaLLMParams, OllamaResponse, OllamaStreamChunk } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamChunk,\n createStreamState,\n buildResponseFromState,\n} from './transform.ts';\n\n/** Default Ollama server URL for local installations. */\nconst OLLAMA_DEFAULT_URL = 'http://localhost:11434';\n\n/**\n * Capability flags for the Ollama provider.\n *\n * **Important:** Tool calling is intentionally disabled. Ollama recommends\n * using their OpenAI-compatible API (`/v1/chat/completions`) for function\n * calling. To use tools with Ollama, configure the OpenAI provider with\n * `baseUrl` pointed to your Ollama instance.\n */\nconst OLLAMA_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: false,\n structuredOutput: true,\n imageInput: true,\n videoInput: false,\n audioInput: false,\n};\n\n/**\n * Parses Ollama's newline-delimited JSON (NDJSON) stream format.\n *\n * Ollama uses NDJSON where each line is a complete JSON object representing\n * a streaming chunk. This generator reads the stream incrementally, buffering\n * incomplete lines and yielding parsed chunks as they become available.\n *\n * @param body - The raw ReadableStream from the fetch response\n * @yields Parsed Ollama stream chunks\n */\nasync function* parseOllamaStream(\n body: ReadableStream<Uint8Array>\n): AsyncGenerator<OllamaStreamChunk, void, unknown> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete lines (Ollama uses newline-delimited JSON)\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? ''; // Keep incomplete line in buffer\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n try {\n const chunk = JSON.parse(trimmed) as OllamaStreamChunk;\n yield chunk;\n } catch (error) {\n throw new UPPError(\n 'Invalid JSON in Ollama stream',\n ErrorCode.InvalidResponse,\n 'ollama',\n ModalityType.LLM,\n undefined,\n toError(error)\n );\n }\n }\n }\n\n buffer += decoder.decode();\n // Process any remaining buffer\n if (buffer.trim()) {\n try {\n const chunk = JSON.parse(buffer.trim()) as OllamaStreamChunk;\n yield chunk;\n } catch (error) {\n throw new UPPError(\n 'Invalid JSON in Ollama stream',\n ErrorCode.InvalidResponse,\n 'ollama',\n ModalityType.LLM,\n undefined,\n toError(error)\n );\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Creates the Ollama LLM handler for chat completions.\n *\n * This factory function creates an LLM handler that communicates with\n * Ollama's `/api/chat` endpoint. The handler supports both synchronous\n * completions and streaming responses.\n *\n * The handler is designed to be used with `createProvider()` which injects\n * the provider reference after construction.\n *\n * @returns An LLM handler configured for Ollama\n *\n * @example\n * ```typescript\n * const handler = createLLMHandler();\n * const provider = createProvider({\n * name: 'ollama',\n * version: '1.0.0',\n * handlers: { llm: handler }\n * });\n * ```\n */\nexport function createLLMHandler(): LLMHandler<OllamaLLMParams> {\n let providerRef: LLMProvider<OllamaLLMParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<OllamaLLMParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<OllamaLLMParams> {\n // Use the injected provider reference (set by createProvider)\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.LLM\n );\n }\n\n const model: BoundLLMModel<OllamaLLMParams> = {\n modelId,\n capabilities: OLLAMA_CAPABILITIES,\n\n get provider(): LLMProvider<OllamaLLMParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<OllamaLLMParams>): Promise<LLMResponse> {\n // Ollama doesn't require an API key by default, but may use one for auth\n let apiKey: string | undefined;\n try {\n apiKey = await resolveApiKey(\n request.config,\n 'OLLAMA_API_KEY',\n 'ollama',\n 'llm'\n );\n } catch {\n // API key is optional for Ollama\n }\n\n const baseUrl = request.config.baseUrl ?? OLLAMA_DEFAULT_URL;\n const url = `${baseUrl}/api/chat`;\n const body = transformRequest(request, modelId);\n body.stream = false;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (apiKey) {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'ollama',\n 'llm'\n );\n\n const data = await parseJsonResponse<OllamaResponse>(response, 'ollama', 'llm');\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<OllamaLLMParams>): LLMStreamResult {\n const state = createStreamState();\n let responseResolve: (value: LLMResponse) => void;\n let responseReject: (error: Error) => void;\n\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n responseResolve = resolve;\n responseReject = reject;\n });\n\n async function* generateEvents(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n // Ollama doesn't require an API key by default\n let apiKey: string | undefined;\n try {\n apiKey = await resolveApiKey(\n request.config,\n 'OLLAMA_API_KEY',\n 'ollama',\n 'llm'\n );\n } catch {\n // API key is optional for Ollama\n }\n\n const baseUrl = request.config.baseUrl ?? OLLAMA_DEFAULT_URL;\n const url = `${baseUrl}/api/chat`;\n const body = transformRequest(request, modelId);\n body.stream = true;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (apiKey) {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doStreamFetch(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'ollama',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'ollama', 'llm');\n responseReject(error);\n throw error;\n }\n\n if (!response.body) {\n const error = new UPPError(\n 'No response body for streaming request',\n ErrorCode.ProviderError,\n 'ollama',\n ModalityType.LLM\n );\n responseReject(error);\n throw error;\n }\n\n // Parse Ollama's newline-delimited JSON stream\n for await (const chunk of parseOllamaStream(response.body)) {\n // Check for error in chunk\n if ('error' in chunk && typeof (chunk as Record<string, unknown>).error === 'string') {\n const error = new UPPError(\n (chunk as Record<string, unknown>).error as string,\n ErrorCode.ProviderError,\n 'ollama',\n ModalityType.LLM\n );\n responseReject(error);\n throw error;\n }\n\n const events = transformStreamChunk(chunk, state);\n for (const event of events) {\n yield event;\n }\n }\n\n // Build final response\n responseResolve(buildResponseFromState(state));\n } catch (error) {\n const err = toError(error);\n responseReject(err);\n throw err;\n }\n }\n\n return {\n [Symbol.asyncIterator]() {\n return generateEvents();\n },\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * @fileoverview Ollama Embeddings API Handler\n *\n * This module implements the embedding handler for Ollama's local embeddings API.\n * Supports various embedding models including nomic-embed-text, mxbai-embed-large,\n * qwen3-embedding, and others.\n *\n * @see {@link https://github.com/ollama/ollama/blob/main/docs/api.md#embeddings Ollama Embeddings API Reference}\n * @module providers/ollama/embed\n */\n\nimport type {\n EmbeddingHandler,\n BoundEmbeddingModel,\n EmbeddingRequest,\n EmbeddingResponse,\n EmbeddingProvider,\n} from '../../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { doFetch } from '../../http/fetch.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\n\n/** Default URL for Ollama's local API */\nconst OLLAMA_DEFAULT_URL = 'http://localhost:11434';\n\n/**\n * Ollama embedding parameters.\n * Passed through to the API.\n */\nexport interface OllamaEmbedParams {\n /** Truncates the end of each input to fit within context length (default: true) */\n truncate?: boolean;\n /** Controls how long the model stays loaded in memory (e.g., '5m', '1h') */\n keep_alive?: string;\n /** Additional model options */\n options?: Record<string, unknown>;\n}\n\n/**\n * Ollama embeddings API response structure.\n */\ninterface OllamaEmbeddingsResponse {\n model: string;\n embeddings: number[][];\n total_duration?: number;\n load_duration?: number;\n prompt_eval_count?: number;\n}\n\n/**\n * Creates an embedding handler for Ollama's local Embeddings API.\n *\n * @returns An embedding handler configured for Ollama\n *\n * @example\n * ```typescript\n * const handler = createEmbeddingHandler();\n * const model = handler.bind('nomic-embed-text');\n *\n * const response = await model.embed({\n * inputs: ['Hello world'],\n * config: { baseUrl: 'http://localhost:11434' }\n * });\n * ```\n */\nexport function createEmbeddingHandler(): EmbeddingHandler<OllamaEmbedParams> {\n let providerRef: EmbeddingProvider<OllamaEmbedParams> | null = null;\n\n return {\n supportedInputs: ['text'],\n\n _setProvider(provider: EmbeddingProvider<OllamaEmbedParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundEmbeddingModel<OllamaEmbedParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.Embedding\n );\n }\n\n const model: BoundEmbeddingModel<OllamaEmbedParams> = {\n modelId,\n maxBatchSize: 512,\n maxInputLength: 8192,\n dimensions: 768, // Varies by model\n\n get provider(): EmbeddingProvider<OllamaEmbedParams> {\n return providerRef!;\n },\n\n async embed(request: EmbeddingRequest<OllamaEmbedParams>): Promise<EmbeddingResponse> {\n const baseUrl = request.config.baseUrl ?? OLLAMA_DEFAULT_URL;\n\n // Transform inputs to strings\n const inputTexts = request.inputs.map((input) => {\n if (typeof input === 'string') {\n return input;\n }\n if ('text' in input) {\n return input.text;\n }\n throw new UPPError(\n 'Ollama embeddings only support text input',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.Embedding\n );\n });\n\n // Build request body\n const body: Record<string, unknown> = {\n model: modelId,\n input: inputTexts,\n };\n\n // Pass through Ollama-specific params\n if (request.params?.truncate !== undefined) {\n body.truncate = request.params.truncate;\n }\n if (request.params?.keep_alive !== undefined) {\n body.keep_alive = request.params.keep_alive;\n }\n if (request.params?.options !== undefined) {\n body.options = request.params.options;\n }\n\n const url = `${baseUrl}/api/embed`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Merge custom headers\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n }, request.config, 'ollama', 'embedding');\n\n const data = await parseJsonResponse<OllamaEmbeddingsResponse>(response, 'ollama', 'embedding');\n\n // Return EmbeddingResponse\n return {\n embeddings: data.embeddings.map((vec, index) => ({\n vector: vec,\n index,\n })),\n usage: {\n totalTokens: data.prompt_eval_count ?? 0,\n },\n metadata: {\n totalDuration: data.total_duration,\n loadDuration: data.load_duration,\n },\n };\n },\n };\n\n return model;\n },\n };\n}\n","import { createProvider } from '../../core/provider.ts';\nimport { createLLMHandler } from './llm.ts';\nimport { createEmbeddingHandler } from './embed.ts';\n\n/**\n * Ollama provider for local LLM inference.\n *\n * Ollama runs models locally on your machine, eliminating the need for API keys\n * and external network calls. This makes it ideal for development, testing,\n * and privacy-sensitive applications.\n *\n * **Supported Models:**\n * - Llama 3.x (Meta's latest open-weight models)\n * - Mistral / Mixtral (Mistral AI's efficient models)\n * - Gemma (Google's lightweight models)\n * - Qwen (Alibaba's multilingual models)\n * - DeepSeek (DeepSeek's code and reasoning models)\n * - Phi (Microsoft's small language models)\n * - CodeLlama (Code-specialized Llama variants)\n * - And many more from the Ollama model library\n *\n * **Prerequisites:**\n * 1. Install Ollama from https://ollama.ai\n * 2. Pull a model: `ollama pull llama3.2`\n * 3. Ensure Ollama is running (default: http://localhost:11434)\n *\n * **Note on Tool Calling:**\n * For tool/function calling, Ollama recommends using their OpenAI-compatible\n * API endpoint. Use the OpenAI provider with `baseUrl` pointed to Ollama instead.\n *\n * @example Basic usage with local model\n * ```typescript\n * import { llm } from 'provider-protocol';\n * import { ollama } from 'provider-protocol/ollama';\n *\n * const model = llm({ model: ollama('llama3.2') });\n * const turn = await model.generate('Hello!');\n * console.log(turn.response.text);\n * ```\n *\n * @example Custom Ollama server URL\n * ```typescript\n * import { llm } from 'provider-protocol';\n * import { ollama } from 'provider-protocol/ollama';\n *\n * const model = llm({\n * model: ollama('llama3.2'),\n * config: { baseUrl: 'http://my-ollama-server:11434' },\n * });\n * ```\n *\n * @example Streaming responses\n * ```typescript\n * import { llm, StreamEventType } from 'provider-protocol';\n * import { ollama } from 'provider-protocol/ollama';\n *\n * const model = llm({ model: ollama('llama3.2') });\n * const stream = model.stream('Write a poem');\n *\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text);\n * }\n * }\n * ```\n *\n * @example Using model parameters\n * ```typescript\n * const model = llm({\n * model: ollama('llama3.2'),\n * params: {\n * temperature: 0.9,\n * top_p: 0.95,\n * num_predict: 500,\n * },\n * });\n * const result = await model.generate('Be creative!');\n * ```\n *\n * @see {@link OllamaLLMParams} for available model parameters\n */\nexport const ollama = createProvider({\n name: 'ollama',\n version: '1.0.0',\n handlers: {\n llm: createLLMHandler(),\n embedding: createEmbeddingHandler(),\n },\n});\n\nexport type { OllamaLLMParams, OllamaHeaders } from './types.ts';\nexport type { OllamaEmbedParams } from './embed.ts';\n"],"mappings":"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","names":["OLLAMA_DEFAULT_URL"]}
|
package/dist/openai/index.d.ts
CHANGED