@agentionai/agents 0.12.0-beta → 0.13.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 (46) hide show
  1. package/README.md +63 -7
  2. package/dist/agents/Agent.d.ts +15 -3
  3. package/dist/agents/Agent.js +8 -0
  4. package/dist/agents/AgentConfig.d.ts +38 -2
  5. package/dist/agents/anthropic/ClaudeAgent.d.ts +19 -1
  6. package/dist/agents/anthropic/ClaudeAgent.js +27 -8
  7. package/dist/agents/llamacpp/LlamaCppAgent.d.ts +60 -0
  8. package/dist/agents/llamacpp/LlamaCppAgent.js +262 -0
  9. package/dist/agents/model-types.d.ts +14 -1
  10. package/dist/agents/ollama/OllamaAgent.d.ts +91 -0
  11. package/dist/agents/ollama/OllamaAgent.js +317 -0
  12. package/dist/chunkers/index.d.ts +0 -1
  13. package/dist/chunkers/index.js +1 -3
  14. package/dist/core.d.ts +1 -0
  15. package/dist/core.js +1 -0
  16. package/dist/history/transformers.d.ts +100 -0
  17. package/dist/history/transformers.js +195 -1
  18. package/dist/history/types.d.ts +15 -1
  19. package/dist/index.d.ts +4 -1
  20. package/dist/index.js +8 -1
  21. package/dist/ingestion/IngestionPipeline.d.ts +1 -73
  22. package/dist/ingestion/IngestionPipeline.js +1 -110
  23. package/dist/llamacpp.d.ts +4 -0
  24. package/dist/llamacpp.js +24 -0
  25. package/dist/ollama.d.ts +4 -0
  26. package/dist/ollama.js +24 -0
  27. package/dist/tools/BuiltInTool.d.ts +72 -0
  28. package/dist/tools/BuiltInTool.js +53 -0
  29. package/dist/viz/types.d.ts +1 -1
  30. package/package.json +10 -42
  31. package/dist/chunkers/ElementChunker.d.ts +0 -100
  32. package/dist/chunkers/ElementChunker.js +0 -242
  33. package/dist/parsers/DocumentParser.d.ts +0 -36
  34. package/dist/parsers/DocumentParser.js +0 -35
  35. package/dist/parsers/LlamaIndexParser.d.ts +0 -58
  36. package/dist/parsers/LlamaIndexParser.js +0 -71
  37. package/dist/parsers/OllamaOCRParser.d.ts +0 -98
  38. package/dist/parsers/OllamaOCRParser.js +0 -203
  39. package/dist/parsers/UnstructuredAPIParser.d.ts +0 -57
  40. package/dist/parsers/UnstructuredAPIParser.js +0 -131
  41. package/dist/parsers/UnstructuredLocalParser.d.ts +0 -42
  42. package/dist/parsers/UnstructuredLocalParser.js +0 -118
  43. package/dist/parsers/index.d.ts +0 -3
  44. package/dist/parsers/index.js +0 -6
  45. package/dist/parsers/types.d.ts +0 -50
  46. package/dist/parsers/types.js +0 -3
@@ -0,0 +1,317 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.OllamaAgent = void 0;
37
+ const BaseAgent_1 = require("../BaseAgent");
38
+ const AgentEvent_1 = require("../AgentEvent");
39
+ const AgentError_1 = require("../errors/AgentError");
40
+ const transformers_1 = require("../../history/transformers");
41
+ const VizReporter_1 = require("../../viz/VizReporter");
42
+ const VizConfig_1 = require("../../viz/VizConfig");
43
+ /**
44
+ * Agent for locally-hosted Ollama models.
45
+ *
46
+ * Requires the `ollama` package as a peer dependency and Ollama running locally.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const agent = new OllamaAgent({
51
+ * id: "1",
52
+ * name: "Assistant",
53
+ * description: "A helpful assistant",
54
+ * model: "llama3.2",
55
+ * });
56
+ *
57
+ * const response = await agent.execute("Hello!");
58
+ * ```
59
+ *
60
+ * @example With tools
61
+ * ```typescript
62
+ * const agent = new OllamaAgent({
63
+ * id: "1",
64
+ * name: "Assistant",
65
+ * description: "A helpful assistant",
66
+ * model: "qwen2.5", // Qwen models have strong tool-use support
67
+ * tools: [myTool],
68
+ * });
69
+ * ```
70
+ */
71
+ class OllamaAgent extends BaseAgent_1.BaseAgent {
72
+ constructor(config, history) {
73
+ super({ ...config, vendor: "ollama" }, history);
74
+ /** Count of tool calls in current execution */
75
+ this.currentToolCallCount = 0;
76
+ /** Cached Ollama client instance */
77
+ this._client = null;
78
+ const vendorConfig = config.vendorConfig?.ollama || {};
79
+ const host = config.host ?? vendorConfig.host;
80
+ this.config = {
81
+ model: config.model || "llama3.2",
82
+ host,
83
+ maxTokens: config.maxTokens,
84
+ temperature: config.temperature,
85
+ topP: config.topP,
86
+ topK: config.topK,
87
+ stopSequences: config.stopSequences,
88
+ seed: config.seed,
89
+ think: config.think,
90
+ };
91
+ this.addSystemMessage(this.getSystemMessage());
92
+ }
93
+ async getClient() {
94
+ if (!this._client) {
95
+ const pkg = "ollama";
96
+ try {
97
+ const mod = (await Promise.resolve(`${pkg}`).then(s => __importStar(require(s))));
98
+ const OllamaClass = mod.Ollama ?? mod.default?.Ollama;
99
+ if (!OllamaClass) {
100
+ throw new Error("Could not find Ollama class in ollama package");
101
+ }
102
+ this._client = new OllamaClass({ host: this.config.host });
103
+ }
104
+ catch (err) {
105
+ throw new AgentError_1.ExecutionError(`Failed to load 'ollama' package. Install it with: npm install ollama\n${err instanceof Error ? err.message : String(err)}`);
106
+ }
107
+ }
108
+ return this._client;
109
+ }
110
+ /**
111
+ * List the models currently available on the Ollama server.
112
+ */
113
+ async listModels() {
114
+ try {
115
+ const client = await this.getClient();
116
+ const response = await client.list();
117
+ return response.models;
118
+ }
119
+ catch (error) {
120
+ throw new AgentError_1.ExecutionError(`Failed to list Ollama models: ${error instanceof Error ? error.message : "Unknown error"}`);
121
+ }
122
+ }
123
+ getToolDefinitions() {
124
+ return Array.from(this.tools.values()).map((tool) => ({
125
+ type: "function",
126
+ function: {
127
+ name: tool.getPrompt().name,
128
+ description: tool.getPrompt().description,
129
+ parameters: tool.getPrompt().input_schema,
130
+ },
131
+ }));
132
+ }
133
+ async process(_input) {
134
+ return "";
135
+ }
136
+ async execute(input) {
137
+ this.emit(AgentEvent_1.AgentEvent.BEFORE_EXECUTE, input);
138
+ this.lastTokenUsage = undefined;
139
+ this.currentToolCallCount = 0;
140
+ const inputPreview = typeof input === "string" ? input : JSON.stringify(input);
141
+ if (VizConfig_1.vizConfig.isEnabled()) {
142
+ this.vizEventId = VizReporter_1.vizReporter.agentStart(this.id, this.name, this.config.model, "ollama", inputPreview);
143
+ }
144
+ if (this.history.transient) {
145
+ this.history.clear();
146
+ this.addSystemMessage(this.getSystemMessage());
147
+ }
148
+ if (typeof input === "string") {
149
+ this.addTextToHistory("user", input);
150
+ }
151
+ else {
152
+ this.addMessageToHistory("user", input);
153
+ }
154
+ this.history.setSessionAnchor();
155
+ this.history.beginExecution();
156
+ try {
157
+ await this.getClient(); // ensure client is cached before handleResponse loop
158
+ const response = await this.callOllama();
159
+ this.emit(AgentEvent_1.AgentEvent.AFTER_EXECUTE, response);
160
+ return await this.handleResponse(response);
161
+ }
162
+ catch (error) {
163
+ if (error instanceof AgentError_1.ExecutionError || error instanceof AgentError_1.ApiError) {
164
+ this.emit(AgentEvent_1.AgentEvent.ERROR, error);
165
+ if (this.vizEventId) {
166
+ VizReporter_1.vizReporter.agentError(this.vizEventId, error.constructor.name, error.message, false);
167
+ this.vizEventId = undefined;
168
+ }
169
+ throw error;
170
+ }
171
+ const executionError = new AgentError_1.ExecutionError(`Ollama error: ${error instanceof Error ? error.message : "Unknown error"}`);
172
+ this.emit(AgentEvent_1.AgentEvent.ERROR, executionError);
173
+ if (this.vizEventId) {
174
+ VizReporter_1.vizReporter.agentError(this.vizEventId, "ExecutionError", executionError.message, false);
175
+ this.vizEventId = undefined;
176
+ }
177
+ throw executionError;
178
+ }
179
+ finally {
180
+ this.history.endExecution();
181
+ }
182
+ }
183
+ buildOptions() {
184
+ const opts = {};
185
+ if (this.config.temperature !== undefined)
186
+ opts.temperature = this.config.temperature;
187
+ if (this.config.topP !== undefined)
188
+ opts.top_p = this.config.topP;
189
+ if (this.config.topK !== undefined)
190
+ opts.top_k = this.config.topK;
191
+ if (this.config.seed !== undefined)
192
+ opts.seed = this.config.seed;
193
+ if (this.config.maxTokens !== undefined)
194
+ opts.num_predict = this.config.maxTokens;
195
+ if (this.config.stopSequences?.length)
196
+ opts.stop = this.config.stopSequences;
197
+ if (this.config.think)
198
+ opts.think = this.config.think;
199
+ return opts;
200
+ }
201
+ async callOllama() {
202
+ const client = await this.getClient();
203
+ const messages = transformers_1.ollamaTransformer.toProvider(this.history.getEntries());
204
+ const tools = this.tools.size > 0 ? this.getToolDefinitions() : undefined;
205
+ const options = this.buildOptions();
206
+ return client.chat({
207
+ model: this.config.model,
208
+ messages,
209
+ tools,
210
+ stream: false,
211
+ think: this.config.think,
212
+ options: Object.keys(options).length > 0 ? options : undefined,
213
+ });
214
+ }
215
+ async handleResponse(response) {
216
+ const ollamaResponse = response;
217
+ const usage = this.parseUsage(ollamaResponse);
218
+ if (this.lastTokenUsage) {
219
+ this.lastTokenUsage.input_tokens += usage.input_tokens;
220
+ this.lastTokenUsage.output_tokens += usage.output_tokens;
221
+ this.lastTokenUsage.total_tokens += usage.total_tokens;
222
+ }
223
+ else {
224
+ this.lastTokenUsage = { ...usage };
225
+ }
226
+ if (ollamaResponse.done_reason === "length") {
227
+ const error = new AgentError_1.MaxTokensExceededError("Response exceeded maximum token limit", this.config.maxTokens || 2048);
228
+ this.emit(AgentEvent_1.AgentEvent.MAX_TOKENS_EXCEEDED, error);
229
+ this.emit(AgentEvent_1.AgentEvent.ERROR, error);
230
+ if (this.vizEventId) {
231
+ VizReporter_1.vizReporter.agentError(this.vizEventId, "MaxTokensExceededError", error.message, false);
232
+ this.vizEventId = undefined;
233
+ }
234
+ throw error;
235
+ }
236
+ const message = ollamaResponse.message;
237
+ const hasToolCalls = message.tool_calls && message.tool_calls.length > 0;
238
+ if (!hasToolCalls) {
239
+ const textContent = message.content || "";
240
+ const entry = transformers_1.ollamaTransformer.fromProviderMessage(message, []);
241
+ this.addToHistory(entry);
242
+ this.emit(AgentEvent_1.AgentEvent.DONE, message, usage);
243
+ if (this.vizEventId) {
244
+ VizReporter_1.vizReporter.agentComplete(this.vizEventId, {
245
+ input: this.lastTokenUsage?.input_tokens || 0,
246
+ output: this.lastTokenUsage?.output_tokens || 0,
247
+ total: this.lastTokenUsage?.total_tokens || 0,
248
+ }, "end_turn", this.currentToolCallCount > 0, this.currentToolCallCount, textContent);
249
+ this.vizEventId = undefined;
250
+ }
251
+ return textContent;
252
+ }
253
+ // Tool calls detected
254
+ const toolCalls = message.tool_calls;
255
+ this.emit(AgentEvent_1.AgentEvent.TOOL_USE, toolCalls);
256
+ this.currentToolCallCount += toolCalls.length;
257
+ // Generate IDs — Ollama doesn't provide tool call IDs
258
+ const generatedIds = toolCalls.map((_, i) => `ollama_${Date.now()}_${i}`);
259
+ const assistantEntry = transformers_1.ollamaTransformer.fromProviderMessage(message, generatedIds);
260
+ this.addToHistory(assistantEntry);
261
+ const toolResults = await this.handleToolCalls(toolCalls, generatedIds);
262
+ for (const result of toolResults) {
263
+ const resultEntry = transformers_1.ollamaTransformer.toolResultEntry(result.toolCallId, result.content);
264
+ this.addToHistory(resultEntry);
265
+ }
266
+ // Continue conversation with tool results
267
+ try {
268
+ const newResponse = await this.callOllama();
269
+ this.emit(AgentEvent_1.AgentEvent.AFTER_EXECUTE, newResponse);
270
+ return this.handleResponse(newResponse);
271
+ }
272
+ catch (error) {
273
+ const executionError = new AgentError_1.ExecutionError(`Ollama error during tool response: ${error instanceof Error ? error.message : "Unknown error"}`);
274
+ this.emit(AgentEvent_1.AgentEvent.ERROR, executionError);
275
+ throw executionError;
276
+ }
277
+ }
278
+ async handleToolCalls(toolCalls, generatedIds) {
279
+ return Promise.all(toolCalls.map(async (toolCall, idx) => {
280
+ const toolName = toolCall.function.name;
281
+ const tool = this.tools.get(toolName);
282
+ const toolCallId = generatedIds[idx];
283
+ if (!tool) {
284
+ const errorMessage = `Tool '${toolName}' not found`;
285
+ const error = new AgentError_1.ToolExecutionError(errorMessage, toolName, toolCall.function.arguments);
286
+ this.emit(AgentEvent_1.AgentEvent.TOOL_ERROR, error);
287
+ return { toolCallId, content: errorMessage };
288
+ }
289
+ try {
290
+ const args = typeof toolCall.function.arguments === "string"
291
+ ? JSON.parse(toolCall.function.arguments)
292
+ : toolCall.function.arguments;
293
+ const result = await tool.execute(this.getId(), this.getName(), args, toolCallId, this.config.model, "ollama");
294
+ return { toolCallId, content: JSON.stringify(result) };
295
+ }
296
+ catch (error) {
297
+ const errorMessage = `Error executing tool '${toolName}': ${error instanceof Error ? error.message : "Unknown error"}`;
298
+ if (this.debug) {
299
+ console.error(errorMessage);
300
+ }
301
+ const toolError = new AgentError_1.ToolExecutionError(errorMessage, toolName, toolCall.function.arguments);
302
+ this.emit(AgentEvent_1.AgentEvent.TOOL_ERROR, toolError);
303
+ return { toolCallId, content: errorMessage };
304
+ }
305
+ }));
306
+ }
307
+ parseUsage(input) {
308
+ const response = input;
309
+ return {
310
+ input_tokens: response.prompt_eval_count ?? 0,
311
+ output_tokens: response.eval_count ?? 0,
312
+ total_tokens: (response.prompt_eval_count ?? 0) + (response.eval_count ?? 0),
313
+ };
314
+ }
315
+ }
316
+ exports.OllamaAgent = OllamaAgent;
317
+ //# sourceMappingURL=OllamaAgent.js.map
@@ -3,5 +3,4 @@ export { Chunker } from "./Chunker";
3
3
  export { TextChunker } from "./TextChunker";
4
4
  export { RecursiveChunker } from "./RecursiveChunker";
5
5
  export { TokenChunker } from "./TokenChunker";
6
- export { ElementChunker, type ElementChunkerConfig } from "./ElementChunker";
7
6
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ElementChunker = exports.TokenChunker = exports.RecursiveChunker = exports.TextChunker = exports.Chunker = void 0;
3
+ exports.TokenChunker = exports.RecursiveChunker = exports.TextChunker = exports.Chunker = void 0;
4
4
  // Base class
5
5
  var Chunker_1 = require("./Chunker");
6
6
  Object.defineProperty(exports, "Chunker", { enumerable: true, get: function () { return Chunker_1.Chunker; } });
@@ -11,6 +11,4 @@ var RecursiveChunker_1 = require("./RecursiveChunker");
11
11
  Object.defineProperty(exports, "RecursiveChunker", { enumerable: true, get: function () { return RecursiveChunker_1.RecursiveChunker; } });
12
12
  var TokenChunker_1 = require("./TokenChunker");
13
13
  Object.defineProperty(exports, "TokenChunker", { enumerable: true, get: function () { return TokenChunker_1.TokenChunker; } });
14
- var ElementChunker_1 = require("./ElementChunker");
15
- Object.defineProperty(exports, "ElementChunker", { enumerable: true, get: function () { return ElementChunker_1.ElementChunker; } });
16
14
  //# sourceMappingURL=index.js.map
package/dist/core.d.ts CHANGED
@@ -7,6 +7,7 @@ export * from "./history/History";
7
7
  export * from "./history/types";
8
8
  export * from "./graph/AgentGraph";
9
9
  export * from "./tools/Tool";
10
+ export * from "./tools/BuiltInTool";
10
11
  export * from "./mcp";
11
12
  export * from "./viz";
12
13
  export * from "./embeddings";
package/dist/core.js CHANGED
@@ -29,6 +29,7 @@ __exportStar(require("./history/types"), exports);
29
29
  __exportStar(require("./graph/AgentGraph"), exports);
30
30
  // Tools
31
31
  __exportStar(require("./tools/Tool"), exports);
32
+ __exportStar(require("./tools/BuiltInTool"), exports);
32
33
  // MCP (Model Context Protocol)
33
34
  __exportStar(require("./mcp"), exports);
34
35
  // Visualization
@@ -98,5 +98,105 @@ export declare const geminiTransformer: {
98
98
  */
99
99
  getSystemMessage(entries: HistoryEntry[]): string | undefined;
100
100
  };
101
+ type OllamaMessage = {
102
+ role: "user" | "assistant" | "system" | "tool";
103
+ content: string;
104
+ tool_calls?: Array<{
105
+ function: {
106
+ name: string;
107
+ arguments: Record<string, unknown>;
108
+ };
109
+ }>;
110
+ };
111
+ type OllamaResponseMessage = {
112
+ role: string;
113
+ content: string;
114
+ tool_calls?: Array<{
115
+ function: {
116
+ name: string;
117
+ arguments: Record<string, unknown> | string;
118
+ };
119
+ }>;
120
+ };
121
+ export declare const ollamaTransformer: {
122
+ /**
123
+ * Convert normalized entries to Ollama message format.
124
+ * Tool results become role:"tool" messages; tool calls are embedded in assistant messages.
125
+ */
126
+ toProvider(entries: HistoryEntry[]): OllamaMessage[];
127
+ /**
128
+ * Convert Ollama response message to normalized HistoryEntry.
129
+ * generatedIds must supply one ID per tool call (Ollama doesn't return IDs).
130
+ */
131
+ fromProviderMessage(message: OllamaResponseMessage, generatedIds: string[]): HistoryEntry;
132
+ /**
133
+ * Create a normalized tool result entry for Ollama
134
+ */
135
+ toolResultEntry(tool_call_id: string, output: string): HistoryEntry;
136
+ };
137
+ /**
138
+ * Convert normalized entries to/from the OpenAI Chat Completions message format
139
+ * (`/v1/chat/completions`). Used by `LlamaCppAgent` and any other agent that
140
+ * targets an OpenAI-compatible chat-completions endpoint.
141
+ */
142
+ export declare const chatCompletionsTransformer: {
143
+ /**
144
+ * Convert normalized entries to Chat Completions message format.
145
+ * Tool results become role:"tool" messages; tool calls are embedded in assistant messages.
146
+ */
147
+ toProvider(entries: HistoryEntry[]): ChatCompletionMessage[];
148
+ /**
149
+ * Convert a Chat Completions response message to a normalized HistoryEntry.
150
+ */
151
+ fromProviderMessage(message: ChatCompletionResponseMessage): HistoryEntry;
152
+ /**
153
+ * Create a normalized tool result entry for a Chat Completions tool call
154
+ */
155
+ toolResultEntry(tool_call_id: string, output: string): HistoryEntry;
156
+ };
157
+ type ChatCompletionToolCallParam = {
158
+ id: string;
159
+ type: "function";
160
+ function: {
161
+ name: string;
162
+ arguments: string;
163
+ };
164
+ };
165
+ type ChatCompletionContentPart = {
166
+ type: "text";
167
+ text: string;
168
+ } | {
169
+ type: "image_url";
170
+ image_url: {
171
+ url: string;
172
+ detail?: "auto" | "low" | "high";
173
+ };
174
+ };
175
+ type ChatCompletionMessage = {
176
+ role: "system";
177
+ content: string;
178
+ } | {
179
+ role: "user";
180
+ content: string | ChatCompletionContentPart[];
181
+ } | {
182
+ role: "assistant";
183
+ content: string | null;
184
+ tool_calls?: ChatCompletionToolCallParam[];
185
+ } | {
186
+ role: "tool";
187
+ tool_call_id: string;
188
+ content: string;
189
+ };
190
+ type ChatCompletionResponseMessage = {
191
+ role: string;
192
+ content: string | null;
193
+ tool_calls?: Array<{
194
+ id: string;
195
+ function?: {
196
+ name: string;
197
+ arguments: string;
198
+ };
199
+ }>;
200
+ };
101
201
  export {};
102
202
  //# sourceMappingURL=transformers.d.ts.map
@@ -5,7 +5,7 @@
5
5
  * Transform between normalized HistoryEntry format and provider-specific formats.
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.geminiTransformer = exports.mistralTransformer = exports.openAiTransformer = exports.anthropicTransformer = void 0;
8
+ exports.chatCompletionsTransformer = exports.ollamaTransformer = exports.geminiTransformer = exports.mistralTransformer = exports.openAiTransformer = exports.anthropicTransformer = void 0;
9
9
  const types_1 = require("./types");
10
10
  // =============================================================================
11
11
  // Anthropic Transformer
@@ -499,4 +499,198 @@ exports.geminiTransformer = {
499
499
  .join("\n");
500
500
  },
501
501
  };
502
+ exports.ollamaTransformer = {
503
+ /**
504
+ * Convert normalized entries to Ollama message format.
505
+ * Tool results become role:"tool" messages; tool calls are embedded in assistant messages.
506
+ */
507
+ toProvider(entries) {
508
+ const messages = [];
509
+ for (const entry of entries) {
510
+ const textBlocks = entry.content.filter(types_1.isTextContent);
511
+ const toolUseBlocks = entry.content.filter(types_1.isToolUseContent);
512
+ const toolResultBlocks = entry.content.filter(types_1.isToolResultContent);
513
+ if (entry.role === "system") {
514
+ messages.push({ role: "system", content: textBlocks.map((c) => c.text).join("\n") });
515
+ continue;
516
+ }
517
+ if (entry.role === "assistant") {
518
+ const msg = {
519
+ role: "assistant",
520
+ content: textBlocks.map((c) => c.text).join("\n"),
521
+ };
522
+ if (toolUseBlocks.length > 0) {
523
+ msg.tool_calls = toolUseBlocks.map((block) => ({
524
+ function: {
525
+ name: block.name,
526
+ arguments: block.input,
527
+ },
528
+ }));
529
+ }
530
+ messages.push(msg);
531
+ continue;
532
+ }
533
+ // User role — could be text or tool results
534
+ if (toolResultBlocks.length > 0) {
535
+ for (const result of toolResultBlocks) {
536
+ messages.push({ role: "tool", content: result.content });
537
+ }
538
+ }
539
+ else if (textBlocks.length > 0) {
540
+ messages.push({ role: "user", content: textBlocks.map((c) => c.text).join("\n") });
541
+ }
542
+ }
543
+ return messages;
544
+ },
545
+ /**
546
+ * Convert Ollama response message to normalized HistoryEntry.
547
+ * generatedIds must supply one ID per tool call (Ollama doesn't return IDs).
548
+ */
549
+ fromProviderMessage(message, generatedIds) {
550
+ const content = [];
551
+ if (typeof message.content === "string" && message.content) {
552
+ content.push((0, types_1.text)(message.content));
553
+ }
554
+ if (message.tool_calls) {
555
+ message.tool_calls.forEach((call, idx) => {
556
+ const args = typeof call.function.arguments === "string"
557
+ ? JSON.parse(call.function.arguments)
558
+ : call.function.arguments;
559
+ content.push((0, types_1.toolUse)(generatedIds[idx] ?? `ollama_tool_${idx}`, call.function.name, args));
560
+ });
561
+ }
562
+ return {
563
+ role: "assistant",
564
+ content,
565
+ meta: { provider: "ollama" },
566
+ };
567
+ },
568
+ /**
569
+ * Create a normalized tool result entry for Ollama
570
+ */
571
+ toolResultEntry(tool_call_id, output) {
572
+ return {
573
+ role: "user",
574
+ content: [(0, types_1.toolResult)(tool_call_id, output)],
575
+ meta: { provider: "ollama", tool_call_id },
576
+ };
577
+ },
578
+ };
579
+ // =============================================================================
580
+ // Chat Completions Transformer (OpenAI-compatible servers, e.g. llama.cpp)
581
+ // =============================================================================
582
+ /**
583
+ * Convert normalized entries to/from the OpenAI Chat Completions message format
584
+ * (`/v1/chat/completions`). Used by `LlamaCppAgent` and any other agent that
585
+ * targets an OpenAI-compatible chat-completions endpoint.
586
+ */
587
+ exports.chatCompletionsTransformer = {
588
+ /**
589
+ * Convert normalized entries to Chat Completions message format.
590
+ * Tool results become role:"tool" messages; tool calls are embedded in assistant messages.
591
+ */
592
+ toProvider(entries) {
593
+ const messages = [];
594
+ for (const entry of entries) {
595
+ const textBlocks = entry.content.filter(types_1.isTextContent);
596
+ const toolUseBlocks = entry.content.filter(types_1.isToolUseContent);
597
+ const toolResultBlocks = entry.content.filter(types_1.isToolResultContent);
598
+ const imageUrlBlocks = entry.content.filter(types_1.isImageUrlContent);
599
+ const imageBase64Blocks = entry.content.filter(types_1.isImageBase64Content);
600
+ const hasImages = imageUrlBlocks.length > 0 || imageBase64Blocks.length > 0;
601
+ if (entry.role === "system") {
602
+ messages.push({ role: "system", content: textBlocks.map((c) => c.text).join("\n") });
603
+ continue;
604
+ }
605
+ if (entry.role === "assistant") {
606
+ const msg = {
607
+ role: "assistant",
608
+ content: textBlocks.map((c) => c.text).join("\n") || null,
609
+ };
610
+ if (toolUseBlocks.length > 0) {
611
+ msg.tool_calls = toolUseBlocks.map((block) => ({
612
+ id: block.id,
613
+ type: "function",
614
+ function: {
615
+ name: block.name,
616
+ arguments: JSON.stringify(block.input),
617
+ },
618
+ }));
619
+ }
620
+ messages.push(msg);
621
+ continue;
622
+ }
623
+ // User role — could be text, images, or tool results
624
+ if (toolResultBlocks.length > 0) {
625
+ for (const result of toolResultBlocks) {
626
+ messages.push({
627
+ role: "tool",
628
+ tool_call_id: result.tool_use_id,
629
+ content: result.content,
630
+ });
631
+ }
632
+ }
633
+ else if (hasImages) {
634
+ const parts = [];
635
+ for (const block of entry.content) {
636
+ if ((0, types_1.isTextContent)(block)) {
637
+ parts.push({ type: "text", text: block.text });
638
+ }
639
+ else if ((0, types_1.isImageUrlContent)(block)) {
640
+ parts.push({
641
+ type: "image_url",
642
+ image_url: {
643
+ url: block.url,
644
+ ...(block.detail ? { detail: block.detail } : {}),
645
+ },
646
+ });
647
+ }
648
+ else if ((0, types_1.isImageBase64Content)(block)) {
649
+ parts.push({
650
+ type: "image_url",
651
+ image_url: { url: `data:${block.mimeType};base64,${block.data}` },
652
+ });
653
+ }
654
+ }
655
+ messages.push({ role: "user", content: parts });
656
+ }
657
+ else if (textBlocks.length > 0) {
658
+ messages.push({ role: "user", content: textBlocks.map((c) => c.text).join("\n") });
659
+ }
660
+ }
661
+ return messages;
662
+ },
663
+ /**
664
+ * Convert a Chat Completions response message to a normalized HistoryEntry.
665
+ */
666
+ fromProviderMessage(message) {
667
+ const content = [];
668
+ if (typeof message.content === "string" && message.content) {
669
+ content.push((0, types_1.text)(message.content));
670
+ }
671
+ if (message.tool_calls) {
672
+ message.tool_calls.forEach((call) => {
673
+ if (!call.function)
674
+ return;
675
+ const args = JSON.parse(call.function.arguments || "{}");
676
+ content.push((0, types_1.toolUse)(call.id, call.function.name, args));
677
+ });
678
+ }
679
+ return {
680
+ role: "assistant",
681
+ content,
682
+ meta: { provider: "llamacpp" },
683
+ };
684
+ },
685
+ /**
686
+ * Create a normalized tool result entry for a Chat Completions tool call
687
+ */
688
+ toolResultEntry(tool_call_id, output) {
689
+ return {
690
+ role: "user",
691
+ content: [(0, types_1.toolResult)(tool_call_id, output)],
692
+ meta: { provider: "llamacpp", tool_call_id },
693
+ };
694
+ },
695
+ };
502
696
  //# sourceMappingURL=transformers.js.map