@jussmor/sdk-ai 0.2.0

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.
Files changed (111) hide show
  1. package/dist/conversation-kIkMQdYK.d.cts +105 -0
  2. package/dist/conversation-kIkMQdYK.d.ts +105 -0
  3. package/dist/conversation-store-CAyPuBjk.d.ts +10 -0
  4. package/dist/conversation-store-Cl42jpsA.d.cts +10 -0
  5. package/dist/index.cjs +1630 -0
  6. package/dist/index.cjs.map +1 -0
  7. package/dist/index.d.cts +251 -0
  8. package/dist/index.d.ts +251 -0
  9. package/dist/index.js +1536 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/memory-uBLqrQRY.d.cts +28 -0
  12. package/dist/memory-uBLqrQRY.d.ts +28 -0
  13. package/dist/providers/llm/anthropic.cjs +275 -0
  14. package/dist/providers/llm/anthropic.cjs.map +1 -0
  15. package/dist/providers/llm/anthropic.d.cts +22 -0
  16. package/dist/providers/llm/anthropic.d.ts +22 -0
  17. package/dist/providers/llm/anthropic.js +240 -0
  18. package/dist/providers/llm/anthropic.js.map +1 -0
  19. package/dist/providers/llm/ollama.cjs +195 -0
  20. package/dist/providers/llm/ollama.cjs.map +1 -0
  21. package/dist/providers/llm/ollama.d.cts +23 -0
  22. package/dist/providers/llm/ollama.d.ts +23 -0
  23. package/dist/providers/llm/ollama.js +170 -0
  24. package/dist/providers/llm/ollama.js.map +1 -0
  25. package/dist/providers/llm/openai.cjs +213 -0
  26. package/dist/providers/llm/openai.cjs.map +1 -0
  27. package/dist/providers/llm/openai.d.cts +22 -0
  28. package/dist/providers/llm/openai.d.ts +22 -0
  29. package/dist/providers/llm/openai.js +178 -0
  30. package/dist/providers/llm/openai.js.map +1 -0
  31. package/dist/providers/memory/filesystem.cjs +112 -0
  32. package/dist/providers/memory/filesystem.cjs.map +1 -0
  33. package/dist/providers/memory/filesystem.d.cts +17 -0
  34. package/dist/providers/memory/filesystem.d.ts +17 -0
  35. package/dist/providers/memory/filesystem.js +87 -0
  36. package/dist/providers/memory/filesystem.js.map +1 -0
  37. package/dist/providers/store/filesystem.cjs +87 -0
  38. package/dist/providers/store/filesystem.cjs.map +1 -0
  39. package/dist/providers/store/filesystem.d.cts +14 -0
  40. package/dist/providers/store/filesystem.d.ts +14 -0
  41. package/dist/providers/store/filesystem.js +62 -0
  42. package/dist/providers/store/filesystem.js.map +1 -0
  43. package/dist/providers/thread/memory.cjs +81 -0
  44. package/dist/providers/thread/memory.cjs.map +1 -0
  45. package/dist/providers/thread/memory.d.cts +14 -0
  46. package/dist/providers/thread/memory.d.ts +14 -0
  47. package/dist/providers/thread/memory.js +56 -0
  48. package/dist/providers/thread/memory.js.map +1 -0
  49. package/dist/providers/thread/sqlite.cjs +917 -0
  50. package/dist/providers/thread/sqlite.cjs.map +1 -0
  51. package/dist/providers/thread/sqlite.d.cts +17 -0
  52. package/dist/providers/thread/sqlite.d.ts +17 -0
  53. package/dist/providers/thread/sqlite.js +911 -0
  54. package/dist/providers/thread/sqlite.js.map +1 -0
  55. package/dist/providers/tokenizers/auto.cjs +136 -0
  56. package/dist/providers/tokenizers/auto.cjs.map +1 -0
  57. package/dist/providers/tokenizers/auto.d.cts +24 -0
  58. package/dist/providers/tokenizers/auto.d.ts +24 -0
  59. package/dist/providers/tokenizers/auto.js +107 -0
  60. package/dist/providers/tokenizers/auto.js.map +1 -0
  61. package/dist/streaming-B-P6Fw_k.d.cts +372 -0
  62. package/dist/streaming-BtD23BE0.d.ts +372 -0
  63. package/dist/thread-C2b9xRMJ.d.cts +30 -0
  64. package/dist/thread-C2b9xRMJ.d.ts +30 -0
  65. package/dist/tokenizer-BhG_RGUk.d.cts +13 -0
  66. package/dist/tokenizer-BhG_RGUk.d.ts +13 -0
  67. package/package.json +84 -0
  68. package/src/agent-loop.ts +311 -0
  69. package/src/agent-source.ts +12 -0
  70. package/src/artifact.ts +31 -0
  71. package/src/compaction.ts +75 -0
  72. package/src/context-budget.ts +65 -0
  73. package/src/conversation-store.ts +8 -0
  74. package/src/conversation.ts +42 -0
  75. package/src/dispatch.ts +207 -0
  76. package/src/engine.ts +53 -0
  77. package/src/execution-context.ts +31 -0
  78. package/src/index.ts +37 -0
  79. package/src/interrupt-store.ts +25 -0
  80. package/src/interrupt.ts +55 -0
  81. package/src/llm-router.ts +34 -0
  82. package/src/llm.ts +100 -0
  83. package/src/memory-selector.ts +38 -0
  84. package/src/memory.ts +34 -0
  85. package/src/mode.ts +81 -0
  86. package/src/permissions.ts +104 -0
  87. package/src/protocol.ts +1 -0
  88. package/src/providers/llm/anthropic.ts +298 -0
  89. package/src/providers/llm/ollama.ts +219 -0
  90. package/src/providers/llm/openai.ts +215 -0
  91. package/src/providers/memory/filesystem.ts +99 -0
  92. package/src/providers/store/filesystem.ts +64 -0
  93. package/src/providers/thread/memory.ts +67 -0
  94. package/src/providers/thread/sqlite.ts +147 -0
  95. package/src/providers/tokenizers/auto.ts +26 -0
  96. package/src/providers/tokenizers/byte.ts +27 -0
  97. package/src/providers/tokenizers/tiktoken.ts +91 -0
  98. package/src/reasoning.ts +7 -0
  99. package/src/rule-matcher.ts +32 -0
  100. package/src/runtime.ts +416 -0
  101. package/src/safety.ts +56 -0
  102. package/src/sandbox.ts +23 -0
  103. package/src/session-context.ts +33 -0
  104. package/src/skill-source.ts +21 -0
  105. package/src/streaming.ts +124 -0
  106. package/src/system-prompt.ts +71 -0
  107. package/src/system-reminder.ts +9 -0
  108. package/src/thread.ts +33 -0
  109. package/src/tokenizer.ts +31 -0
  110. package/src/tool.ts +175 -0
  111. package/src/tracing.ts +63 -0
@@ -0,0 +1,22 @@
1
+ import { b as ChatRequest, c as ChatResponse } from '../../conversation-kIkMQdYK.js';
2
+ import { G as StreamingLLMProvider, S as StreamEvent } from '../../streaming-BtD23BE0.js';
3
+ import '../../memory-uBLqrQRY.js';
4
+ import '../../thread-C2b9xRMJ.js';
5
+ import '../../tokenizer-BhG_RGUk.js';
6
+
7
+ interface AnthropicProviderOptions {
8
+ apiKey?: string;
9
+ baseURL?: string;
10
+ defaultModel?: string;
11
+ defaultMaxTokens?: number;
12
+ }
13
+ declare class AnthropicProvider implements StreamingLLMProvider {
14
+ private client;
15
+ private defaultModel;
16
+ private defaultMaxTokens;
17
+ constructor(opts?: AnthropicProviderOptions);
18
+ chat(req: ChatRequest, signal?: AbortSignal): Promise<ChatResponse>;
19
+ chatStream(req: ChatRequest, signal?: AbortSignal): AsyncGenerator<StreamEvent>;
20
+ }
21
+
22
+ export { AnthropicProvider, type AnthropicProviderOptions };
@@ -0,0 +1,240 @@
1
+ // src/providers/llm/anthropic.ts
2
+ import Anthropic from "@anthropic-ai/sdk";
3
+ function toAnthropicMessages(messages) {
4
+ const out = [];
5
+ for (const msg of messages) {
6
+ if (msg.role === "system") continue;
7
+ if (msg.role === "tool") {
8
+ const last = out[out.length - 1];
9
+ const toolResultBlock = {
10
+ type: "tool_result",
11
+ tool_use_id: msg.toolCallId ?? "",
12
+ content: msg.content
13
+ };
14
+ if (last?.role === "user" && Array.isArray(last.content)) {
15
+ last.content.push(toolResultBlock);
16
+ } else {
17
+ out.push({ role: "user", content: [toolResultBlock] });
18
+ }
19
+ continue;
20
+ }
21
+ if (msg.role === "assistant" && msg.toolCalls?.length) {
22
+ const content = [];
23
+ if (msg.content) {
24
+ content.push({ type: "text", text: msg.content });
25
+ }
26
+ for (const tc of msg.toolCalls) {
27
+ let input = {};
28
+ try {
29
+ input = JSON.parse(tc.arguments);
30
+ } catch {
31
+ }
32
+ content.push({
33
+ type: "tool_use",
34
+ id: tc.id,
35
+ name: tc.name,
36
+ input
37
+ });
38
+ }
39
+ out.push({ role: "assistant", content });
40
+ continue;
41
+ }
42
+ if (msg.role === "user" && (msg.images?.length || msg.documents?.length)) {
43
+ const content = [];
44
+ for (const img of msg.images ?? []) {
45
+ if (img.url) {
46
+ content.push({
47
+ type: "text",
48
+ text: `[Image URL: ${img.url}]`
49
+ });
50
+ } else if (img.source) {
51
+ content.push({
52
+ type: "image",
53
+ source: {
54
+ type: "base64",
55
+ media_type: img.mediaType ?? "image/jpeg",
56
+ data: img.source
57
+ }
58
+ });
59
+ }
60
+ }
61
+ if (msg.content) content.push({ type: "text", text: msg.content });
62
+ out.push({ role: "user", content });
63
+ continue;
64
+ }
65
+ out.push({
66
+ role: msg.role,
67
+ content: msg.content
68
+ });
69
+ }
70
+ return out;
71
+ }
72
+ function toAnthropicTools(tools) {
73
+ return tools.map((t) => ({
74
+ name: t.function.name,
75
+ description: t.function.description,
76
+ input_schema: t.function.parameters
77
+ }));
78
+ }
79
+ function extractSystemPrompt(messages) {
80
+ return messages.filter((m) => m.role === "system").map((m) => m.content).join("\n\n");
81
+ }
82
+ var AnthropicProvider = class {
83
+ client;
84
+ defaultModel;
85
+ defaultMaxTokens;
86
+ constructor(opts = {}) {
87
+ this.client = new Anthropic({
88
+ apiKey: opts.apiKey ?? process.env["ANTHROPIC_API_KEY"],
89
+ baseURL: opts.baseURL
90
+ });
91
+ this.defaultModel = opts.defaultModel ?? "claude-sonnet-4-6-20251001";
92
+ this.defaultMaxTokens = opts.defaultMaxTokens ?? 8096;
93
+ }
94
+ async chat(req, signal) {
95
+ const system = extractSystemPrompt(req.messages);
96
+ const messages = toAnthropicMessages(req.messages);
97
+ const tools = req.tools?.length ? toAnthropicTools(req.tools) : void 0;
98
+ const params = {
99
+ model: req.model ?? this.defaultModel,
100
+ max_tokens: req.maxTokens ?? this.defaultMaxTokens,
101
+ messages,
102
+ ...system ? { system } : {},
103
+ ...tools ? { tools } : {},
104
+ ...req.temperature != null ? { temperature: req.temperature } : {},
105
+ ...req.topP != null ? { top_p: req.topP } : {},
106
+ ...req.topK != null ? { top_k: req.topK } : {},
107
+ ...req.stop?.length ? { stop_sequences: req.stop } : {},
108
+ ...req.thinkingBudget ? {
109
+ thinking: {
110
+ type: "enabled",
111
+ budget_tokens: req.thinkingBudget
112
+ }
113
+ } : {}
114
+ };
115
+ const resp = await this.client.messages.create(params, {
116
+ signal
117
+ });
118
+ let content = "";
119
+ let thinkingContent = "";
120
+ const toolCalls = [];
121
+ for (const block of resp.content) {
122
+ if (block.type === "text") {
123
+ content += block.text;
124
+ } else if (block.type === "thinking") {
125
+ thinkingContent += block.thinking;
126
+ } else if (block.type === "tool_use") {
127
+ toolCalls.push({
128
+ id: block.id,
129
+ name: block.name,
130
+ arguments: JSON.stringify(block.input)
131
+ });
132
+ }
133
+ }
134
+ return {
135
+ content,
136
+ thinkingContent: thinkingContent || void 0,
137
+ toolCalls: toolCalls.length ? toolCalls : void 0,
138
+ finishReason: resp.stop_reason ?? "stop",
139
+ usage: {
140
+ promptTokens: resp.usage.input_tokens,
141
+ completionTokens: resp.usage.output_tokens,
142
+ totalTokens: resp.usage.input_tokens + resp.usage.output_tokens
143
+ },
144
+ model: resp.model
145
+ };
146
+ }
147
+ async *chatStream(req, signal) {
148
+ const system = extractSystemPrompt(req.messages);
149
+ const messages = toAnthropicMessages(req.messages);
150
+ const tools = req.tools?.length ? toAnthropicTools(req.tools) : void 0;
151
+ const params = {
152
+ model: req.model ?? this.defaultModel,
153
+ max_tokens: req.maxTokens ?? this.defaultMaxTokens,
154
+ messages,
155
+ stream: true,
156
+ ...system ? { system } : {},
157
+ ...tools ? { tools } : {},
158
+ ...req.temperature != null ? { temperature: req.temperature } : {},
159
+ ...req.topP != null ? { top_p: req.topP } : {},
160
+ ...req.topK != null ? { top_k: req.topK } : {},
161
+ ...req.stop?.length ? { stop_sequences: req.stop } : {},
162
+ ...req.thinkingBudget ? {
163
+ thinking: {
164
+ type: "enabled",
165
+ budget_tokens: req.thinkingBudget
166
+ }
167
+ } : {}
168
+ };
169
+ const stream = this.client.messages.stream(params, { signal });
170
+ let promptTokens = 0;
171
+ let completionTokens = 0;
172
+ const toolCallMap = /* @__PURE__ */ new Map();
173
+ for await (const chunk of stream) {
174
+ if (signal?.aborted) break;
175
+ if (chunk.type === "message_start") {
176
+ promptTokens = chunk.message.usage.input_tokens;
177
+ completionTokens = chunk.message.usage.output_tokens;
178
+ continue;
179
+ }
180
+ if (chunk.type === "message_delta") {
181
+ completionTokens = chunk.usage.output_tokens;
182
+ continue;
183
+ }
184
+ if (chunk.type === "content_block_start") {
185
+ if (chunk.content_block.type === "tool_use") {
186
+ toolCallMap.set(chunk.index, {
187
+ id: chunk.content_block.id,
188
+ name: chunk.content_block.name,
189
+ argsBuf: ""
190
+ });
191
+ }
192
+ continue;
193
+ }
194
+ if (chunk.type === "content_block_delta") {
195
+ if (chunk.delta.type === "text_delta") {
196
+ yield { type: "delta", delta: chunk.delta.text };
197
+ } else if (chunk.delta.type === "thinking_delta") {
198
+ yield { type: "thinking", thinking: chunk.delta.thinking };
199
+ } else if (chunk.delta.type === "input_json_delta") {
200
+ const tc = toolCallMap.get(chunk.index);
201
+ if (tc) tc.argsBuf += chunk.delta.partial_json;
202
+ }
203
+ continue;
204
+ }
205
+ if (chunk.type === "content_block_stop") {
206
+ const tc = toolCallMap.get(chunk.index);
207
+ if (tc) {
208
+ yield {
209
+ type: "tool_call",
210
+ toolCall: { id: tc.id, name: tc.name, arguments: tc.argsBuf }
211
+ };
212
+ toolCallMap.delete(chunk.index);
213
+ }
214
+ continue;
215
+ }
216
+ if (chunk.type === "message_stop") {
217
+ yield {
218
+ type: "done",
219
+ final: {
220
+ finalContent: "",
221
+ providerReasoning: "",
222
+ totalTurns: 1,
223
+ totalUsage: {
224
+ promptTokens,
225
+ completionTokens,
226
+ totalTokens: promptTokens + completionTokens
227
+ },
228
+ messages: [],
229
+ reasoningTrace: [],
230
+ stopReason: "complete"
231
+ }
232
+ };
233
+ }
234
+ }
235
+ }
236
+ };
237
+ export {
238
+ AnthropicProvider
239
+ };
240
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/providers/llm/anthropic.ts"],"sourcesContent":["import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n LLMProvider,\n ChatRequest,\n ChatResponse,\n ChatMessage,\n ToolDef,\n} from \"../../llm.js\";\nimport type { StreamingLLMProvider, StreamEvent } from \"../../streaming.js\";\n\nfunction toAnthropicMessages(\n messages: ChatMessage[],\n): Anthropic.MessageParam[] {\n const out: Anthropic.MessageParam[] = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue;\n\n if (msg.role === \"tool\") {\n const last = out[out.length - 1];\n const toolResultBlock: Anthropic.ToolResultBlockParam = {\n type: \"tool_result\",\n tool_use_id: msg.toolCallId ?? \"\",\n content: msg.content,\n };\n if (last?.role === \"user\" && Array.isArray(last.content)) {\n (last.content as Anthropic.ToolResultBlockParam[]).push(toolResultBlock);\n } else {\n out.push({ role: \"user\", content: [toolResultBlock] });\n }\n continue;\n }\n\n if (msg.role === \"assistant\" && msg.toolCalls?.length) {\n const content: Anthropic.ContentBlockParam[] = [];\n if (msg.content) {\n content.push({ type: \"text\", text: msg.content });\n }\n for (const tc of msg.toolCalls) {\n let input: Record<string, unknown> = {};\n try {\n input = JSON.parse(tc.arguments) as Record<string, unknown>;\n } catch {}\n content.push({\n type: \"tool_use\",\n id: tc.id,\n name: tc.name,\n input,\n });\n }\n out.push({ role: \"assistant\", content });\n continue;\n }\n\n if (msg.role === \"user\" && (msg.images?.length || msg.documents?.length)) {\n const content: Anthropic.ContentBlockParam[] = [];\n for (const img of msg.images ?? []) {\n if (img.url) {\n // Anthropic doesn't support URL images natively — fetch as base64 or skip\n content.push({\n type: \"text\",\n text: `[Image URL: ${img.url}]`,\n });\n } else if (img.source) {\n content.push({\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: (img.mediaType ?? \"image/jpeg\") as\n | \"image/jpeg\"\n | \"image/png\"\n | \"image/gif\"\n | \"image/webp\",\n data: img.source,\n },\n });\n }\n }\n if (msg.content) content.push({ type: \"text\", text: msg.content });\n out.push({ role: \"user\", content });\n continue;\n }\n\n out.push({\n role: msg.role as \"user\" | \"assistant\",\n content: msg.content,\n });\n }\n\n return out;\n}\n\nfunction toAnthropicTools(tools: ToolDef[]): Anthropic.Tool[] {\n return tools.map((t) => ({\n name: t.function.name,\n description: t.function.description,\n input_schema: t.function.parameters as Anthropic.Tool.InputSchema,\n }));\n}\n\nfunction extractSystemPrompt(messages: ChatMessage[]): string {\n return messages\n .filter((m) => m.role === \"system\")\n .map((m) => m.content)\n .join(\"\\n\\n\");\n}\n\nexport interface AnthropicProviderOptions {\n apiKey?: string;\n baseURL?: string;\n defaultModel?: string;\n defaultMaxTokens?: number;\n}\n\nexport class AnthropicProvider implements StreamingLLMProvider {\n private client: Anthropic;\n private defaultModel: string;\n private defaultMaxTokens: number;\n\n constructor(opts: AnthropicProviderOptions = {}) {\n this.client = new Anthropic({\n apiKey: opts.apiKey ?? process.env[\"ANTHROPIC_API_KEY\"],\n baseURL: opts.baseURL,\n });\n this.defaultModel = opts.defaultModel ?? \"claude-sonnet-4-6-20251001\";\n this.defaultMaxTokens = opts.defaultMaxTokens ?? 8096;\n }\n\n async chat(req: ChatRequest, signal?: AbortSignal): Promise<ChatResponse> {\n const system = extractSystemPrompt(req.messages);\n const messages = toAnthropicMessages(req.messages);\n const tools = req.tools?.length ? toAnthropicTools(req.tools) : undefined;\n\n const params: Anthropic.MessageCreateParamsNonStreaming = {\n model: req.model ?? this.defaultModel,\n max_tokens: req.maxTokens ?? this.defaultMaxTokens,\n messages,\n ...(system ? { system } : {}),\n ...(tools ? { tools } : {}),\n ...(req.temperature != null ? { temperature: req.temperature } : {}),\n ...(req.topP != null ? { top_p: req.topP } : {}),\n ...(req.topK != null ? { top_k: req.topK } : {}),\n ...(req.stop?.length ? { stop_sequences: req.stop } : {}),\n ...(req.thinkingBudget\n ? {\n thinking: {\n type: \"enabled\",\n budget_tokens: req.thinkingBudget,\n } as Anthropic.ThinkingConfigParam,\n }\n : {}),\n };\n\n const resp = await this.client.messages.create(params, {\n signal,\n });\n\n let content = \"\";\n let thinkingContent = \"\";\n const toolCalls: ChatResponse[\"toolCalls\"] = [];\n\n for (const block of resp.content) {\n if (block.type === \"text\") {\n content += block.text;\n } else if (block.type === \"thinking\") {\n thinkingContent += block.thinking;\n } else if (block.type === \"tool_use\") {\n toolCalls.push({\n id: block.id,\n name: block.name,\n arguments: JSON.stringify(block.input),\n });\n }\n }\n\n return {\n content,\n thinkingContent: thinkingContent || undefined,\n toolCalls: toolCalls.length ? toolCalls : undefined,\n finishReason: resp.stop_reason ?? \"stop\",\n usage: {\n promptTokens: resp.usage.input_tokens,\n completionTokens: resp.usage.output_tokens,\n totalTokens: resp.usage.input_tokens + resp.usage.output_tokens,\n },\n model: resp.model,\n };\n }\n\n async *chatStream(\n req: ChatRequest,\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n const system = extractSystemPrompt(req.messages);\n const messages = toAnthropicMessages(req.messages);\n const tools = req.tools?.length ? toAnthropicTools(req.tools) : undefined;\n\n const params: Anthropic.MessageCreateParamsStreaming = {\n model: req.model ?? this.defaultModel,\n max_tokens: req.maxTokens ?? this.defaultMaxTokens,\n messages,\n stream: true,\n ...(system ? { system } : {}),\n ...(tools ? { tools } : {}),\n ...(req.temperature != null ? { temperature: req.temperature } : {}),\n ...(req.topP != null ? { top_p: req.topP } : {}),\n ...(req.topK != null ? { top_k: req.topK } : {}),\n ...(req.stop?.length ? { stop_sequences: req.stop } : {}),\n ...(req.thinkingBudget\n ? {\n thinking: {\n type: \"enabled\",\n budget_tokens: req.thinkingBudget,\n } as Anthropic.ThinkingConfigParam,\n }\n : {}),\n };\n\n const stream = this.client.messages.stream(params, { signal });\n\n let promptTokens = 0;\n let completionTokens = 0;\n\n const toolCallMap = new Map<\n number,\n { id: string; name: string; argsBuf: string }\n >();\n\n for await (const chunk of stream) {\n if (signal?.aborted) break;\n\n if (chunk.type === \"message_start\") {\n promptTokens = chunk.message.usage.input_tokens;\n completionTokens = chunk.message.usage.output_tokens;\n continue;\n }\n\n if (chunk.type === \"message_delta\") {\n completionTokens = chunk.usage.output_tokens;\n continue;\n }\n\n if (chunk.type === \"content_block_start\") {\n if (chunk.content_block.type === \"tool_use\") {\n toolCallMap.set(chunk.index, {\n id: chunk.content_block.id,\n name: chunk.content_block.name,\n argsBuf: \"\",\n });\n }\n continue;\n }\n\n if (chunk.type === \"content_block_delta\") {\n if (chunk.delta.type === \"text_delta\") {\n yield { type: \"delta\", delta: chunk.delta.text };\n } else if (chunk.delta.type === \"thinking_delta\") {\n yield { type: \"thinking\", thinking: chunk.delta.thinking };\n } else if (chunk.delta.type === \"input_json_delta\") {\n const tc = toolCallMap.get(chunk.index);\n if (tc) tc.argsBuf += chunk.delta.partial_json;\n }\n continue;\n }\n\n if (chunk.type === \"content_block_stop\") {\n const tc = toolCallMap.get(chunk.index);\n if (tc) {\n yield {\n type: \"tool_call\",\n toolCall: { id: tc.id, name: tc.name, arguments: tc.argsBuf },\n };\n toolCallMap.delete(chunk.index);\n }\n continue;\n }\n\n if (chunk.type === \"message_stop\") {\n yield {\n type: \"done\",\n final: {\n finalContent: \"\",\n providerReasoning: \"\",\n totalTurns: 1,\n totalUsage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n messages: [],\n reasoningTrace: [],\n stopReason: \"complete\",\n },\n };\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,195 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/providers/llm/ollama.ts
21
+ var ollama_exports = {};
22
+ __export(ollama_exports, {
23
+ OllamaProvider: () => OllamaProvider
24
+ });
25
+ module.exports = __toCommonJS(ollama_exports);
26
+ function toOllamaMessages(messages) {
27
+ const out = [];
28
+ for (const msg of messages) {
29
+ if (msg.role === "system") {
30
+ out.push({ role: "system", content: msg.content });
31
+ continue;
32
+ }
33
+ if (msg.role === "tool") {
34
+ out.push({ role: "tool", content: msg.content });
35
+ continue;
36
+ }
37
+ const om = { role: msg.role, content: msg.content };
38
+ if (msg.images?.length) {
39
+ om.images = msg.images.filter((i) => i.source).map((i) => i.source);
40
+ }
41
+ if (msg.toolCalls?.length) {
42
+ om.tool_calls = msg.toolCalls.map((tc) => ({
43
+ function: {
44
+ name: tc.name,
45
+ arguments: JSON.parse(tc.arguments)
46
+ }
47
+ }));
48
+ }
49
+ out.push(om);
50
+ }
51
+ return out;
52
+ }
53
+ var OllamaProvider = class {
54
+ baseURL;
55
+ defaultModel;
56
+ nativeToolCalls;
57
+ temperature;
58
+ constructor(opts = {}) {
59
+ this.baseURL = (opts.baseURL ?? process.env["OLLAMA_BASE_URL"] ?? "http://localhost:11434").replace(/\/$/, "");
60
+ this.defaultModel = opts.defaultModel ?? "llama3.1";
61
+ this.nativeToolCalls = opts.nativeToolCalls ?? false;
62
+ this.temperature = opts.temperature;
63
+ }
64
+ async chat(req, signal) {
65
+ const body = {
66
+ model: req.model ?? this.defaultModel,
67
+ messages: toOllamaMessages(req.messages),
68
+ stream: false,
69
+ options: this.temperature != null ? { temperature: this.temperature } : void 0
70
+ };
71
+ if (this.nativeToolCalls && req.tools?.length) {
72
+ body["tools"] = req.tools.map((t) => ({
73
+ type: "function",
74
+ function: {
75
+ name: t.function.name,
76
+ description: t.function.description,
77
+ parameters: t.function.parameters
78
+ }
79
+ }));
80
+ }
81
+ const resp = await fetch(`${this.baseURL}/api/chat`, {
82
+ method: "POST",
83
+ headers: { "Content-Type": "application/json" },
84
+ body: JSON.stringify(body),
85
+ signal
86
+ });
87
+ if (!resp.ok) {
88
+ throw new Error(`Ollama error: ${resp.status} ${await resp.text()}`);
89
+ }
90
+ const data = await resp.json();
91
+ const toolCalls = [];
92
+ if (data.message.tool_calls?.length) {
93
+ for (let i = 0; i < data.message.tool_calls.length; i++) {
94
+ const tc = data.message.tool_calls[i];
95
+ toolCalls.push({
96
+ id: `ollama-${i}`,
97
+ name: tc.function.name,
98
+ arguments: JSON.stringify(tc.function.arguments)
99
+ });
100
+ }
101
+ }
102
+ const promptTokens = data.prompt_eval_count ?? 0;
103
+ const completionTokens = data.eval_count ?? 0;
104
+ return {
105
+ content: data.message.content,
106
+ toolCalls: toolCalls.length ? toolCalls : void 0,
107
+ finishReason: data.done_reason ?? "stop",
108
+ usage: {
109
+ promptTokens,
110
+ completionTokens,
111
+ totalTokens: promptTokens + completionTokens
112
+ },
113
+ model: data.model
114
+ };
115
+ }
116
+ async *chatStream(req, signal) {
117
+ const body = {
118
+ model: req.model ?? this.defaultModel,
119
+ messages: toOllamaMessages(req.messages),
120
+ stream: true,
121
+ options: this.temperature != null ? { temperature: this.temperature } : void 0
122
+ };
123
+ if (this.nativeToolCalls && req.tools?.length) {
124
+ body["tools"] = req.tools.map((t) => ({
125
+ type: "function",
126
+ function: {
127
+ name: t.function.name,
128
+ description: t.function.description,
129
+ parameters: t.function.parameters
130
+ }
131
+ }));
132
+ }
133
+ const resp = await fetch(`${this.baseURL}/api/chat`, {
134
+ method: "POST",
135
+ headers: { "Content-Type": "application/json" },
136
+ body: JSON.stringify(body),
137
+ signal
138
+ });
139
+ if (!resp.ok) {
140
+ throw new Error(`Ollama error: ${resp.status} ${await resp.text()}`);
141
+ }
142
+ const reader = resp.body?.getReader();
143
+ if (!reader) throw new Error("Ollama: no response body");
144
+ const decoder = new TextDecoder();
145
+ let buf = "";
146
+ let promptTokens = 0;
147
+ let completionTokens = 0;
148
+ let fullContent = "";
149
+ while (true) {
150
+ const { done, value } = await reader.read();
151
+ if (done) break;
152
+ if (signal?.aborted) {
153
+ reader.cancel();
154
+ break;
155
+ }
156
+ buf += decoder.decode(value, { stream: true });
157
+ const lines = buf.split("\n");
158
+ buf = lines.pop() ?? "";
159
+ for (const line of lines) {
160
+ const trimmed = line.trim();
161
+ if (!trimmed) continue;
162
+ const data = JSON.parse(trimmed);
163
+ if (data.message?.content) {
164
+ fullContent += data.message.content;
165
+ yield { type: "delta", delta: data.message.content };
166
+ }
167
+ if (data.done) {
168
+ promptTokens = data.prompt_eval_count ?? 0;
169
+ completionTokens = data.eval_count ?? 0;
170
+ yield {
171
+ type: "done",
172
+ final: {
173
+ finalContent: fullContent,
174
+ providerReasoning: "",
175
+ totalTurns: 1,
176
+ totalUsage: {
177
+ promptTokens,
178
+ completionTokens,
179
+ totalTokens: promptTokens + completionTokens
180
+ },
181
+ messages: [],
182
+ reasoningTrace: [],
183
+ stopReason: "complete"
184
+ }
185
+ };
186
+ }
187
+ }
188
+ }
189
+ }
190
+ };
191
+ // Annotate the CommonJS export names for ESM import in node:
192
+ 0 && (module.exports = {
193
+ OllamaProvider
194
+ });
195
+ //# sourceMappingURL=ollama.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/providers/llm/ollama.ts"],"sourcesContent":["import type {\n LLMProvider,\n ChatRequest,\n ChatResponse,\n ChatMessage,\n ToolCallEntry,\n} from \"../../llm.js\";\nimport type { StreamingLLMProvider, StreamEvent } from \"../../streaming.js\";\n\ninterface OllamaMessage {\n role: string;\n content: string;\n images?: string[];\n tool_calls?: Array<{\n function: { name: string; arguments: Record<string, unknown> };\n }>;\n}\n\ninterface OllamaChatResponse {\n model: string;\n message: OllamaMessage;\n done: boolean;\n done_reason?: string;\n prompt_eval_count?: number;\n eval_count?: number;\n}\n\nfunction toOllamaMessages(messages: ChatMessage[]): OllamaMessage[] {\n const out: OllamaMessage[] = [];\n for (const msg of messages) {\n if (msg.role === \"system\") {\n out.push({ role: \"system\", content: msg.content });\n continue;\n }\n if (msg.role === \"tool\") {\n out.push({ role: \"tool\", content: msg.content });\n continue;\n }\n const om: OllamaMessage = { role: msg.role, content: msg.content };\n if (msg.images?.length) {\n om.images = msg.images\n .filter((i) => i.source)\n .map((i) => i.source!);\n }\n if (msg.toolCalls?.length) {\n om.tool_calls = msg.toolCalls.map((tc) => ({\n function: {\n name: tc.name,\n arguments: JSON.parse(tc.arguments) as Record<string, unknown>,\n },\n }));\n }\n out.push(om);\n }\n return out;\n}\n\nexport interface OllamaProviderOptions {\n baseURL?: string;\n defaultModel?: string;\n nativeToolCalls?: boolean;\n temperature?: number;\n}\n\nexport class OllamaProvider implements StreamingLLMProvider {\n private baseURL: string;\n private defaultModel: string;\n private nativeToolCalls: boolean;\n private temperature?: number;\n\n constructor(opts: OllamaProviderOptions = {}) {\n this.baseURL =\n (opts.baseURL ?? process.env[\"OLLAMA_BASE_URL\"] ?? \"http://localhost:11434\").replace(/\\/$/, \"\");\n this.defaultModel = opts.defaultModel ?? \"llama3.1\";\n this.nativeToolCalls = opts.nativeToolCalls ?? false;\n this.temperature = opts.temperature;\n }\n\n async chat(req: ChatRequest, signal?: AbortSignal): Promise<ChatResponse> {\n const body: Record<string, unknown> = {\n model: req.model ?? this.defaultModel,\n messages: toOllamaMessages(req.messages),\n stream: false,\n options: this.temperature != null ? { temperature: this.temperature } : undefined,\n };\n\n if (this.nativeToolCalls && req.tools?.length) {\n body[\"tools\"] = req.tools.map((t) => ({\n type: \"function\",\n function: {\n name: t.function.name,\n description: t.function.description,\n parameters: t.function.parameters,\n },\n }));\n }\n\n const resp = await fetch(`${this.baseURL}/api/chat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!resp.ok) {\n throw new Error(`Ollama error: ${resp.status} ${await resp.text()}`);\n }\n\n const data = (await resp.json()) as OllamaChatResponse;\n const toolCalls: ToolCallEntry[] = [];\n\n if (data.message.tool_calls?.length) {\n for (let i = 0; i < data.message.tool_calls.length; i++) {\n const tc = data.message.tool_calls[i]!;\n toolCalls.push({\n id: `ollama-${i}`,\n name: tc.function.name,\n arguments: JSON.stringify(tc.function.arguments),\n });\n }\n }\n\n const promptTokens = data.prompt_eval_count ?? 0;\n const completionTokens = data.eval_count ?? 0;\n\n return {\n content: data.message.content,\n toolCalls: toolCalls.length ? toolCalls : undefined,\n finishReason: data.done_reason ?? \"stop\",\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n model: data.model,\n };\n }\n\n async *chatStream(\n req: ChatRequest,\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n const body: Record<string, unknown> = {\n model: req.model ?? this.defaultModel,\n messages: toOllamaMessages(req.messages),\n stream: true,\n options: this.temperature != null ? { temperature: this.temperature } : undefined,\n };\n\n if (this.nativeToolCalls && req.tools?.length) {\n body[\"tools\"] = req.tools.map((t) => ({\n type: \"function\",\n function: {\n name: t.function.name,\n description: t.function.description,\n parameters: t.function.parameters,\n },\n }));\n }\n\n const resp = await fetch(`${this.baseURL}/api/chat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!resp.ok) {\n throw new Error(`Ollama error: ${resp.status} ${await resp.text()}`);\n }\n\n const reader = resp.body?.getReader();\n if (!reader) throw new Error(\"Ollama: no response body\");\n\n const decoder = new TextDecoder();\n let buf = \"\";\n let promptTokens = 0;\n let completionTokens = 0;\n let fullContent = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (signal?.aborted) { reader.cancel(); break; }\n buf += decoder.decode(value, { stream: true });\n const lines = buf.split(\"\\n\");\n buf = lines.pop() ?? \"\";\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const data = JSON.parse(trimmed) as OllamaChatResponse;\n if (data.message?.content) {\n fullContent += data.message.content;\n yield { type: \"delta\", delta: data.message.content };\n }\n if (data.done) {\n promptTokens = data.prompt_eval_count ?? 0;\n completionTokens = data.eval_count ?? 0;\n yield {\n type: \"done\",\n final: {\n finalContent: fullContent,\n providerReasoning: \"\",\n totalTurns: 1,\n totalUsage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n messages: [],\n reasoningTrace: [],\n stopReason: \"complete\",\n },\n };\n }\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,23 @@
1
+ import { b as ChatRequest, c as ChatResponse } from '../../conversation-kIkMQdYK.cjs';
2
+ import { G as StreamingLLMProvider, S as StreamEvent } from '../../streaming-B-P6Fw_k.cjs';
3
+ import '../../memory-uBLqrQRY.cjs';
4
+ import '../../thread-C2b9xRMJ.cjs';
5
+ import '../../tokenizer-BhG_RGUk.cjs';
6
+
7
+ interface OllamaProviderOptions {
8
+ baseURL?: string;
9
+ defaultModel?: string;
10
+ nativeToolCalls?: boolean;
11
+ temperature?: number;
12
+ }
13
+ declare class OllamaProvider implements StreamingLLMProvider {
14
+ private baseURL;
15
+ private defaultModel;
16
+ private nativeToolCalls;
17
+ private temperature?;
18
+ constructor(opts?: OllamaProviderOptions);
19
+ chat(req: ChatRequest, signal?: AbortSignal): Promise<ChatResponse>;
20
+ chatStream(req: ChatRequest, signal?: AbortSignal): AsyncGenerator<StreamEvent>;
21
+ }
22
+
23
+ export { OllamaProvider, type OllamaProviderOptions };
@@ -0,0 +1,23 @@
1
+ import { b as ChatRequest, c as ChatResponse } from '../../conversation-kIkMQdYK.js';
2
+ import { G as StreamingLLMProvider, S as StreamEvent } from '../../streaming-BtD23BE0.js';
3
+ import '../../memory-uBLqrQRY.js';
4
+ import '../../thread-C2b9xRMJ.js';
5
+ import '../../tokenizer-BhG_RGUk.js';
6
+
7
+ interface OllamaProviderOptions {
8
+ baseURL?: string;
9
+ defaultModel?: string;
10
+ nativeToolCalls?: boolean;
11
+ temperature?: number;
12
+ }
13
+ declare class OllamaProvider implements StreamingLLMProvider {
14
+ private baseURL;
15
+ private defaultModel;
16
+ private nativeToolCalls;
17
+ private temperature?;
18
+ constructor(opts?: OllamaProviderOptions);
19
+ chat(req: ChatRequest, signal?: AbortSignal): Promise<ChatResponse>;
20
+ chatStream(req: ChatRequest, signal?: AbortSignal): AsyncGenerator<StreamEvent>;
21
+ }
22
+
23
+ export { OllamaProvider, type OllamaProviderOptions };