@agentionai/agents 0.11.1 → 0.12.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.
- package/dist/agents/Agent.d.ts +9 -3
- package/dist/agents/Agent.js +4 -0
- package/dist/agents/AgentConfig.d.ts +12 -2
- package/dist/agents/model-types.d.ts +6 -0
- package/dist/agents/ollama/OllamaAgent.d.ts +69 -0
- package/dist/agents/ollama/OllamaAgent.js +304 -0
- package/dist/history/transformers.d.ts +36 -0
- package/dist/history/transformers.js +78 -1
- package/dist/history/types.d.ts +8 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -1
- package/dist/ollama.d.ts +4 -0
- package/dist/ollama.js +24 -0
- package/dist/viz/VizReporter.js +0 -1
- package/dist/viz/types.d.ts +1 -1
- package/package.json +9 -1
package/dist/agents/Agent.d.ts
CHANGED
|
@@ -4,7 +4,8 @@ import { BaseAgentConfig } from "./BaseAgent";
|
|
|
4
4
|
import { OpenAiAgent } from "./openai/OpenAiAgent";
|
|
5
5
|
import { GeminiAgent } from "./google/GeminiAgent";
|
|
6
6
|
import { MistralAgent } from "./mistral/MistralAgent";
|
|
7
|
-
import {
|
|
7
|
+
import { OllamaAgent } from "./ollama/OllamaAgent";
|
|
8
|
+
import { ClaudeModel, OpenAIModel, GeminiModel, MistralModel, OllamaModel } from "./model-types";
|
|
8
9
|
type ClaudeAgentConfig = Omit<BaseAgentConfig, "vendor" | "model"> & {
|
|
9
10
|
vendor: "anthropic";
|
|
10
11
|
model?: ClaudeModel;
|
|
@@ -21,9 +22,14 @@ type MistralAgentConfig = Omit<BaseAgentConfig, "vendor" | "model"> & {
|
|
|
21
22
|
vendor: "mistral";
|
|
22
23
|
model?: MistralModel;
|
|
23
24
|
};
|
|
24
|
-
type
|
|
25
|
+
type OllamaAgentConfig = Omit<BaseAgentConfig, "vendor" | "model"> & {
|
|
26
|
+
vendor: "ollama";
|
|
27
|
+
model?: OllamaModel;
|
|
28
|
+
host?: string;
|
|
29
|
+
};
|
|
30
|
+
type AgentConfig = ClaudeAgentConfig | OpenAIAgentConfig | GeminiAgentConfig | MistralAgentConfig | OllamaAgentConfig;
|
|
25
31
|
export declare class Agent {
|
|
26
|
-
static create(config: AgentConfig, history?: History): ClaudeAgent | GeminiAgent | OpenAiAgent | MistralAgent;
|
|
32
|
+
static create(config: AgentConfig, history?: History): ClaudeAgent | GeminiAgent | OpenAiAgent | MistralAgent | OllamaAgent;
|
|
27
33
|
}
|
|
28
34
|
export {};
|
|
29
35
|
//# sourceMappingURL=Agent.d.ts.map
|
package/dist/agents/Agent.js
CHANGED
|
@@ -5,6 +5,7 @@ const ClaudeAgent_1 = require("./anthropic/ClaudeAgent");
|
|
|
5
5
|
const OpenAiAgent_1 = require("./openai/OpenAiAgent");
|
|
6
6
|
const GeminiAgent_1 = require("./google/GeminiAgent");
|
|
7
7
|
const MistralAgent_1 = require("./mistral/MistralAgent");
|
|
8
|
+
const OllamaAgent_1 = require("./ollama/OllamaAgent");
|
|
8
9
|
class Agent {
|
|
9
10
|
static create(config, history) {
|
|
10
11
|
if (config.vendor === "anthropic") {
|
|
@@ -19,6 +20,9 @@ class Agent {
|
|
|
19
20
|
else if (config.vendor === "mistral") {
|
|
20
21
|
return new MistralAgent_1.MistralAgent(config, history);
|
|
21
22
|
}
|
|
23
|
+
else if (config.vendor === "ollama") {
|
|
24
|
+
return new OllamaAgent_1.OllamaAgent(config, history);
|
|
25
|
+
}
|
|
22
26
|
else {
|
|
23
27
|
throw new Error("No vendor defined");
|
|
24
28
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Tool } from "../tools/Tool";
|
|
2
2
|
import { BaseAgent } from "./BaseAgent";
|
|
3
3
|
/** Supported LLM vendors */
|
|
4
|
-
export type AgentVendor = "openai" | "anthropic" | "mistral" | "gemini";
|
|
4
|
+
export type AgentVendor = "openai" | "anthropic" | "mistral" | "gemini" | "ollama";
|
|
5
5
|
/**
|
|
6
6
|
* Common configuration shared by all agents
|
|
7
7
|
*/
|
|
@@ -86,6 +86,13 @@ export interface GeminiSpecificConfig {
|
|
|
86
86
|
responseMimeType?: string;
|
|
87
87
|
responseSchema?: any;
|
|
88
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Vendor-specific configuration for Ollama (local)
|
|
91
|
+
*/
|
|
92
|
+
export interface OllamaSpecificConfig {
|
|
93
|
+
/** Ollama server URL (default: http://localhost:11434) */
|
|
94
|
+
host?: string;
|
|
95
|
+
}
|
|
89
96
|
/**
|
|
90
97
|
* Generic vendor-specific configuration container
|
|
91
98
|
* This allows any vendor to add custom config without modifying base types
|
|
@@ -95,6 +102,7 @@ export interface VendorSpecificConfig {
|
|
|
95
102
|
openai?: OpenAISpecificConfig;
|
|
96
103
|
mistral?: MistralSpecificConfig;
|
|
97
104
|
gemini?: GeminiSpecificConfig;
|
|
105
|
+
ollama?: OllamaSpecificConfig;
|
|
98
106
|
}
|
|
99
107
|
/**
|
|
100
108
|
* Complete agent configuration with vendor-specific extensions
|
|
@@ -134,10 +142,12 @@ export type TypedAgentConfig<V extends AgentVendor> = CommonAgentConfig & {
|
|
|
134
142
|
mistral?: MistralSpecificConfig;
|
|
135
143
|
} : V extends "gemini" ? {
|
|
136
144
|
gemini?: GeminiSpecificConfig;
|
|
145
|
+
} : V extends "ollama" ? {
|
|
146
|
+
ollama?: OllamaSpecificConfig;
|
|
137
147
|
} : never;
|
|
138
148
|
};
|
|
139
149
|
/**
|
|
140
150
|
* Helper type to extract vendor-specific config for a given vendor
|
|
141
151
|
*/
|
|
142
|
-
export type VendorConfigFor<V extends AgentVendor> = V extends "anthropic" ? ClaudeSpecificConfig : V extends "openai" ? OpenAISpecificConfig : V extends "mistral" ? MistralSpecificConfig : V extends "gemini" ? GeminiSpecificConfig : never;
|
|
152
|
+
export type VendorConfigFor<V extends AgentVendor> = V extends "anthropic" ? ClaudeSpecificConfig : V extends "openai" ? OpenAISpecificConfig : V extends "mistral" ? MistralSpecificConfig : V extends "gemini" ? GeminiSpecificConfig : V extends "ollama" ? OllamaSpecificConfig : never;
|
|
143
153
|
//# sourceMappingURL=AgentConfig.d.ts.map
|
|
@@ -21,6 +21,12 @@ export type GeminiModel = "gemini-flash-latest" | "gemini-flash-lite-latest" | "
|
|
|
21
21
|
* @see https://docs.mistral.ai/getting-started/models/
|
|
22
22
|
*/
|
|
23
23
|
export type MistralModel = "mistral-large-latest" | "mistral-small-latest" | "ministral-8b-latest" | "ministral-8b-2410" | "ministral-3b-latest" | "ministral-3b-2410" | "codestral-latest" | "codestral-2405" | "mistral-embed" | "mistral-moderation-latest" | "mistral-moderation-2411" | (string & {});
|
|
24
|
+
/**
|
|
25
|
+
* Popular Ollama models (locally hosted).
|
|
26
|
+
* You can also provide any custom string for models you have pulled.
|
|
27
|
+
* @see https://ollama.com/library
|
|
28
|
+
*/
|
|
29
|
+
export type OllamaModel = "llama3.2" | "llama3.2:1b" | "llama3.1" | "llama3.1:70b" | "llama3" | "mistral" | "mistral-nemo" | "mixtral" | "qwen2.5" | "qwen2.5:7b" | "qwen2.5:72b" | "qwen2.5-coder" | "gemma2" | "gemma2:27b" | "phi3" | "phi4" | "deepseek-r1" | "deepseek-r1:7b" | "deepseek-r1:14b" | "deepseek-r1:70b" | "codellama" | (string & {});
|
|
24
30
|
/**
|
|
25
31
|
* Supported OpenAI models.
|
|
26
32
|
* You can also provide any custom string for newer models not yet listed.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { BaseAgent, BaseAgentConfig, TokenUsage } from "../BaseAgent";
|
|
2
|
+
import { History, MessageContent } from "../../history/History";
|
|
3
|
+
import { OllamaModel } from "../model-types";
|
|
4
|
+
type AgentConfig = BaseAgentConfig & {
|
|
5
|
+
/** Ollama server URL (default: http://localhost:11434) */
|
|
6
|
+
host?: string;
|
|
7
|
+
model?: OllamaModel;
|
|
8
|
+
maxTokens?: number;
|
|
9
|
+
think?: boolean;
|
|
10
|
+
};
|
|
11
|
+
type OllamaToolDefinition = {
|
|
12
|
+
type: "function";
|
|
13
|
+
function: {
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
parameters: object;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Agent for locally-hosted Ollama models.
|
|
21
|
+
*
|
|
22
|
+
* Requires the `ollama` package as a peer dependency and Ollama running locally.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const agent = new OllamaAgent({
|
|
27
|
+
* id: "1",
|
|
28
|
+
* name: "Assistant",
|
|
29
|
+
* description: "A helpful assistant",
|
|
30
|
+
* model: "llama3.2",
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* const response = await agent.execute("Hello!");
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @example With tools
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const agent = new OllamaAgent({
|
|
39
|
+
* id: "1",
|
|
40
|
+
* name: "Assistant",
|
|
41
|
+
* description: "A helpful assistant",
|
|
42
|
+
* model: "qwen2.5", // Qwen models have strong tool-use support
|
|
43
|
+
* tools: [myTool],
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare class OllamaAgent extends BaseAgent {
|
|
48
|
+
protected config: Partial<AgentConfig>;
|
|
49
|
+
/** Token usage from the last execution (for metrics tracking) */
|
|
50
|
+
lastTokenUsage?: TokenUsage;
|
|
51
|
+
/** Current visualization event ID */
|
|
52
|
+
private vizEventId?;
|
|
53
|
+
/** Count of tool calls in current execution */
|
|
54
|
+
private currentToolCallCount;
|
|
55
|
+
/** Cached Ollama client instance */
|
|
56
|
+
private _client;
|
|
57
|
+
constructor(config: Omit<AgentConfig, "vendor">, history?: History);
|
|
58
|
+
private getClient;
|
|
59
|
+
protected getToolDefinitions(): OllamaToolDefinition[];
|
|
60
|
+
protected process(_input: string): Promise<string>;
|
|
61
|
+
execute(input: string | MessageContent[]): Promise<string>;
|
|
62
|
+
private buildOptions;
|
|
63
|
+
private callOllama;
|
|
64
|
+
protected handleResponse(response: unknown): Promise<string>;
|
|
65
|
+
private handleToolCalls;
|
|
66
|
+
protected parseUsage(input: unknown): TokenUsage;
|
|
67
|
+
}
|
|
68
|
+
export {};
|
|
69
|
+
//# sourceMappingURL=OllamaAgent.d.ts.map
|
|
@@ -0,0 +1,304 @@
|
|
|
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
|
+
getToolDefinitions() {
|
|
111
|
+
return Array.from(this.tools.values()).map((tool) => ({
|
|
112
|
+
type: "function",
|
|
113
|
+
function: {
|
|
114
|
+
name: tool.getPrompt().name,
|
|
115
|
+
description: tool.getPrompt().description,
|
|
116
|
+
parameters: tool.getPrompt().input_schema,
|
|
117
|
+
},
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
async process(_input) {
|
|
121
|
+
return "";
|
|
122
|
+
}
|
|
123
|
+
async execute(input) {
|
|
124
|
+
this.emit(AgentEvent_1.AgentEvent.BEFORE_EXECUTE, input);
|
|
125
|
+
this.lastTokenUsage = undefined;
|
|
126
|
+
this.currentToolCallCount = 0;
|
|
127
|
+
const inputPreview = typeof input === "string" ? input : JSON.stringify(input);
|
|
128
|
+
if (VizConfig_1.vizConfig.isEnabled()) {
|
|
129
|
+
this.vizEventId = VizReporter_1.vizReporter.agentStart(this.id, this.name, this.config.model, "ollama", inputPreview);
|
|
130
|
+
}
|
|
131
|
+
if (this.history.transient) {
|
|
132
|
+
this.history.clear();
|
|
133
|
+
this.addSystemMessage(this.getSystemMessage());
|
|
134
|
+
}
|
|
135
|
+
if (typeof input === "string") {
|
|
136
|
+
this.addTextToHistory("user", input);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
this.addMessageToHistory("user", input);
|
|
140
|
+
}
|
|
141
|
+
this.history.setSessionAnchor();
|
|
142
|
+
this.history.beginExecution();
|
|
143
|
+
try {
|
|
144
|
+
await this.getClient(); // ensure client is cached before handleResponse loop
|
|
145
|
+
const response = await this.callOllama();
|
|
146
|
+
this.emit(AgentEvent_1.AgentEvent.AFTER_EXECUTE, response);
|
|
147
|
+
return await this.handleResponse(response);
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
if (error instanceof AgentError_1.ExecutionError || error instanceof AgentError_1.ApiError) {
|
|
151
|
+
this.emit(AgentEvent_1.AgentEvent.ERROR, error);
|
|
152
|
+
if (this.vizEventId) {
|
|
153
|
+
VizReporter_1.vizReporter.agentError(this.vizEventId, error.constructor.name, error.message, false);
|
|
154
|
+
this.vizEventId = undefined;
|
|
155
|
+
}
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
const executionError = new AgentError_1.ExecutionError(`Ollama error: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
159
|
+
this.emit(AgentEvent_1.AgentEvent.ERROR, executionError);
|
|
160
|
+
if (this.vizEventId) {
|
|
161
|
+
VizReporter_1.vizReporter.agentError(this.vizEventId, "ExecutionError", executionError.message, false);
|
|
162
|
+
this.vizEventId = undefined;
|
|
163
|
+
}
|
|
164
|
+
throw executionError;
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
this.history.endExecution();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
buildOptions() {
|
|
171
|
+
const opts = {};
|
|
172
|
+
if (this.config.temperature !== undefined)
|
|
173
|
+
opts.temperature = this.config.temperature;
|
|
174
|
+
if (this.config.topP !== undefined)
|
|
175
|
+
opts.top_p = this.config.topP;
|
|
176
|
+
if (this.config.topK !== undefined)
|
|
177
|
+
opts.top_k = this.config.topK;
|
|
178
|
+
if (this.config.seed !== undefined)
|
|
179
|
+
opts.seed = this.config.seed;
|
|
180
|
+
if (this.config.maxTokens !== undefined)
|
|
181
|
+
opts.num_predict = this.config.maxTokens;
|
|
182
|
+
if (this.config.stopSequences?.length)
|
|
183
|
+
opts.stop = this.config.stopSequences;
|
|
184
|
+
if (this.config.think)
|
|
185
|
+
opts.think = this.config.think;
|
|
186
|
+
return opts;
|
|
187
|
+
}
|
|
188
|
+
async callOllama() {
|
|
189
|
+
const client = await this.getClient();
|
|
190
|
+
const messages = transformers_1.ollamaTransformer.toProvider(this.history.getEntries());
|
|
191
|
+
const tools = this.tools.size > 0 ? this.getToolDefinitions() : undefined;
|
|
192
|
+
const options = this.buildOptions();
|
|
193
|
+
return client.chat({
|
|
194
|
+
model: this.config.model,
|
|
195
|
+
messages,
|
|
196
|
+
tools,
|
|
197
|
+
stream: false,
|
|
198
|
+
think: this.config.think,
|
|
199
|
+
options: Object.keys(options).length > 0 ? options : undefined,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
async handleResponse(response) {
|
|
203
|
+
const ollamaResponse = response;
|
|
204
|
+
const usage = this.parseUsage(ollamaResponse);
|
|
205
|
+
if (this.lastTokenUsage) {
|
|
206
|
+
this.lastTokenUsage.input_tokens += usage.input_tokens;
|
|
207
|
+
this.lastTokenUsage.output_tokens += usage.output_tokens;
|
|
208
|
+
this.lastTokenUsage.total_tokens += usage.total_tokens;
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
this.lastTokenUsage = { ...usage };
|
|
212
|
+
}
|
|
213
|
+
if (ollamaResponse.done_reason === "length") {
|
|
214
|
+
const error = new AgentError_1.MaxTokensExceededError("Response exceeded maximum token limit", this.config.maxTokens || 2048);
|
|
215
|
+
this.emit(AgentEvent_1.AgentEvent.MAX_TOKENS_EXCEEDED, error);
|
|
216
|
+
this.emit(AgentEvent_1.AgentEvent.ERROR, error);
|
|
217
|
+
if (this.vizEventId) {
|
|
218
|
+
VizReporter_1.vizReporter.agentError(this.vizEventId, "MaxTokensExceededError", error.message, false);
|
|
219
|
+
this.vizEventId = undefined;
|
|
220
|
+
}
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
223
|
+
const message = ollamaResponse.message;
|
|
224
|
+
const hasToolCalls = message.tool_calls && message.tool_calls.length > 0;
|
|
225
|
+
if (!hasToolCalls) {
|
|
226
|
+
const textContent = message.content || "";
|
|
227
|
+
const entry = transformers_1.ollamaTransformer.fromProviderMessage(message, []);
|
|
228
|
+
this.addToHistory(entry);
|
|
229
|
+
this.emit(AgentEvent_1.AgentEvent.DONE, message, usage);
|
|
230
|
+
if (this.vizEventId) {
|
|
231
|
+
VizReporter_1.vizReporter.agentComplete(this.vizEventId, {
|
|
232
|
+
input: this.lastTokenUsage?.input_tokens || 0,
|
|
233
|
+
output: this.lastTokenUsage?.output_tokens || 0,
|
|
234
|
+
total: this.lastTokenUsage?.total_tokens || 0,
|
|
235
|
+
}, "end_turn", this.currentToolCallCount > 0, this.currentToolCallCount, textContent);
|
|
236
|
+
this.vizEventId = undefined;
|
|
237
|
+
}
|
|
238
|
+
return textContent;
|
|
239
|
+
}
|
|
240
|
+
// Tool calls detected
|
|
241
|
+
const toolCalls = message.tool_calls;
|
|
242
|
+
this.emit(AgentEvent_1.AgentEvent.TOOL_USE, toolCalls);
|
|
243
|
+
this.currentToolCallCount += toolCalls.length;
|
|
244
|
+
// Generate IDs — Ollama doesn't provide tool call IDs
|
|
245
|
+
const generatedIds = toolCalls.map((_, i) => `ollama_${Date.now()}_${i}`);
|
|
246
|
+
const assistantEntry = transformers_1.ollamaTransformer.fromProviderMessage(message, generatedIds);
|
|
247
|
+
this.addToHistory(assistantEntry);
|
|
248
|
+
const toolResults = await this.handleToolCalls(toolCalls, generatedIds);
|
|
249
|
+
for (const result of toolResults) {
|
|
250
|
+
const resultEntry = transformers_1.ollamaTransformer.toolResultEntry(result.toolCallId, result.content);
|
|
251
|
+
this.addToHistory(resultEntry);
|
|
252
|
+
}
|
|
253
|
+
// Continue conversation with tool results
|
|
254
|
+
try {
|
|
255
|
+
const newResponse = await this.callOllama();
|
|
256
|
+
this.emit(AgentEvent_1.AgentEvent.AFTER_EXECUTE, newResponse);
|
|
257
|
+
return this.handleResponse(newResponse);
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
const executionError = new AgentError_1.ExecutionError(`Ollama error during tool response: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
261
|
+
this.emit(AgentEvent_1.AgentEvent.ERROR, executionError);
|
|
262
|
+
throw executionError;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
async handleToolCalls(toolCalls, generatedIds) {
|
|
266
|
+
return Promise.all(toolCalls.map(async (toolCall, idx) => {
|
|
267
|
+
const toolName = toolCall.function.name;
|
|
268
|
+
const tool = this.tools.get(toolName);
|
|
269
|
+
const toolCallId = generatedIds[idx];
|
|
270
|
+
if (!tool) {
|
|
271
|
+
const errorMessage = `Tool '${toolName}' not found`;
|
|
272
|
+
const error = new AgentError_1.ToolExecutionError(errorMessage, toolName, toolCall.function.arguments);
|
|
273
|
+
this.emit(AgentEvent_1.AgentEvent.TOOL_ERROR, error);
|
|
274
|
+
return { toolCallId, content: errorMessage };
|
|
275
|
+
}
|
|
276
|
+
try {
|
|
277
|
+
const args = typeof toolCall.function.arguments === "string"
|
|
278
|
+
? JSON.parse(toolCall.function.arguments)
|
|
279
|
+
: toolCall.function.arguments;
|
|
280
|
+
const result = await tool.execute(this.getId(), this.getName(), args, toolCallId, this.config.model, "ollama");
|
|
281
|
+
return { toolCallId, content: JSON.stringify(result) };
|
|
282
|
+
}
|
|
283
|
+
catch (error) {
|
|
284
|
+
const errorMessage = `Error executing tool '${toolName}': ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
285
|
+
if (this.debug) {
|
|
286
|
+
console.error(errorMessage);
|
|
287
|
+
}
|
|
288
|
+
const toolError = new AgentError_1.ToolExecutionError(errorMessage, toolName, toolCall.function.arguments);
|
|
289
|
+
this.emit(AgentEvent_1.AgentEvent.TOOL_ERROR, toolError);
|
|
290
|
+
return { toolCallId, content: errorMessage };
|
|
291
|
+
}
|
|
292
|
+
}));
|
|
293
|
+
}
|
|
294
|
+
parseUsage(input) {
|
|
295
|
+
const response = input;
|
|
296
|
+
return {
|
|
297
|
+
input_tokens: response.prompt_eval_count ?? 0,
|
|
298
|
+
output_tokens: response.eval_count ?? 0,
|
|
299
|
+
total_tokens: (response.prompt_eval_count ?? 0) + (response.eval_count ?? 0),
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
exports.OllamaAgent = OllamaAgent;
|
|
304
|
+
//# sourceMappingURL=OllamaAgent.js.map
|
|
@@ -98,5 +98,41 @@ 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
|
+
};
|
|
101
137
|
export {};
|
|
102
138
|
//# 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.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,81 @@ 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
|
+
};
|
|
502
579
|
//# sourceMappingURL=transformers.js.map
|
package/dist/history/types.d.ts
CHANGED
|
@@ -87,10 +87,17 @@ export type MistralMeta = {
|
|
|
87
87
|
export type GeminiMeta = {
|
|
88
88
|
provider: "gemini";
|
|
89
89
|
};
|
|
90
|
+
/**
|
|
91
|
+
* Ollama-specific metadata
|
|
92
|
+
*/
|
|
93
|
+
export type OllamaMeta = {
|
|
94
|
+
provider: "ollama";
|
|
95
|
+
tool_call_id?: string;
|
|
96
|
+
};
|
|
90
97
|
/**
|
|
91
98
|
* Union of all provider metadata types
|
|
92
99
|
*/
|
|
93
|
-
export type ProviderMeta = AnthropicMeta | OpenAiMeta | MistralMeta | GeminiMeta;
|
|
100
|
+
export type ProviderMeta = AnthropicMeta | OpenAiMeta | MistralMeta | GeminiMeta | OllamaMeta;
|
|
94
101
|
/**
|
|
95
102
|
* Valid roles for history entries
|
|
96
103
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -3,13 +3,14 @@ export * from "./agents/anthropic/ClaudeAgent";
|
|
|
3
3
|
export { OpenAiAgent } from "./agents/openai/OpenAiAgent";
|
|
4
4
|
export { MistralAgent } from "./agents/mistral/MistralAgent";
|
|
5
5
|
export { GeminiAgent } from "./agents/google/GeminiAgent";
|
|
6
|
+
export { OllamaAgent } from "./agents/ollama/OllamaAgent";
|
|
6
7
|
export * from "./agents/model-types";
|
|
7
8
|
export * from "./agents/AgentConfig";
|
|
8
9
|
export * from "./agents/AgentEvent";
|
|
9
10
|
export * from "./agents/errors/AgentError";
|
|
10
11
|
export * from "./history/History";
|
|
11
12
|
export * from "./history/types";
|
|
12
|
-
export { anthropicTransformer, openAiTransformer, mistralTransformer, geminiTransformer, } from "./history/transformers";
|
|
13
|
+
export { anthropicTransformer, openAiTransformer, mistralTransformer, geminiTransformer, ollamaTransformer, } from "./history/transformers";
|
|
13
14
|
export * from "./graph/AgentGraph";
|
|
14
15
|
export * from "./tools/Tool";
|
|
15
16
|
export * from "./mcp";
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
22
22
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
23
23
|
};
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.geminiTransformer = exports.mistralTransformer = exports.openAiTransformer = exports.anthropicTransformer = exports.GeminiAgent = exports.MistralAgent = exports.OpenAiAgent = void 0;
|
|
25
|
+
exports.ollamaTransformer = exports.geminiTransformer = exports.mistralTransformer = exports.openAiTransformer = exports.anthropicTransformer = exports.OllamaAgent = exports.GeminiAgent = exports.MistralAgent = exports.OpenAiAgent = void 0;
|
|
26
26
|
// Agents
|
|
27
27
|
__exportStar(require("./agents/BaseAgent"), exports);
|
|
28
28
|
__exportStar(require("./agents/anthropic/ClaudeAgent"), exports);
|
|
@@ -32,6 +32,8 @@ var MistralAgent_1 = require("./agents/mistral/MistralAgent");
|
|
|
32
32
|
Object.defineProperty(exports, "MistralAgent", { enumerable: true, get: function () { return MistralAgent_1.MistralAgent; } });
|
|
33
33
|
var GeminiAgent_1 = require("./agents/google/GeminiAgent");
|
|
34
34
|
Object.defineProperty(exports, "GeminiAgent", { enumerable: true, get: function () { return GeminiAgent_1.GeminiAgent; } });
|
|
35
|
+
var OllamaAgent_1 = require("./agents/ollama/OllamaAgent");
|
|
36
|
+
Object.defineProperty(exports, "OllamaAgent", { enumerable: true, get: function () { return OllamaAgent_1.OllamaAgent; } });
|
|
35
37
|
__exportStar(require("./agents/model-types"), exports);
|
|
36
38
|
__exportStar(require("./agents/AgentConfig"), exports);
|
|
37
39
|
__exportStar(require("./agents/AgentEvent"), exports);
|
|
@@ -44,6 +46,7 @@ Object.defineProperty(exports, "anthropicTransformer", { enumerable: true, get:
|
|
|
44
46
|
Object.defineProperty(exports, "openAiTransformer", { enumerable: true, get: function () { return transformers_1.openAiTransformer; } });
|
|
45
47
|
Object.defineProperty(exports, "mistralTransformer", { enumerable: true, get: function () { return transformers_1.mistralTransformer; } });
|
|
46
48
|
Object.defineProperty(exports, "geminiTransformer", { enumerable: true, get: function () { return transformers_1.geminiTransformer; } });
|
|
49
|
+
Object.defineProperty(exports, "ollamaTransformer", { enumerable: true, get: function () { return transformers_1.ollamaTransformer; } });
|
|
47
50
|
// Graph
|
|
48
51
|
__exportStar(require("./graph/AgentGraph"), exports);
|
|
49
52
|
// Tools
|
package/dist/ollama.d.ts
ADDED
package/dist/ollama.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.ollamaTransformer = exports.OllamaAgent = void 0;
|
|
18
|
+
// Ollama Agent Entry Point
|
|
19
|
+
__exportStar(require("./core"), exports);
|
|
20
|
+
var OllamaAgent_1 = require("./agents/ollama/OllamaAgent");
|
|
21
|
+
Object.defineProperty(exports, "OllamaAgent", { enumerable: true, get: function () { return OllamaAgent_1.OllamaAgent; } });
|
|
22
|
+
var transformers_1 = require("./history/transformers");
|
|
23
|
+
Object.defineProperty(exports, "ollamaTransformer", { enumerable: true, get: function () { return transformers_1.ollamaTransformer; } });
|
|
24
|
+
//# sourceMappingURL=ollama.js.map
|
package/dist/viz/VizReporter.js
CHANGED
package/dist/viz/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Visualization event types and interfaces for agent monitoring.
|
|
3
3
|
* These types define the contract between agention-lib and @agention/viz.
|
|
4
4
|
*/
|
|
5
|
-
export type VizVendor = "anthropic" | "openai" | "mistral" | "gemini";
|
|
5
|
+
export type VizVendor = "anthropic" | "openai" | "mistral" | "gemini" | "ollama";
|
|
6
6
|
export type VizEventType = "session.start" | "session.end" | "pipeline.start" | "pipeline.end" | "executor.start" | "executor.end" | "agent.start" | "agent.complete" | "agent.error" | "tool.start" | "tool.complete" | "tool.error" | "message.user" | "message.assistant";
|
|
7
7
|
export type VizExecutorType = "sequential" | "parallel" | "map" | "voting" | "router";
|
|
8
8
|
export type VizStopReason = "end_turn" | "tool_use" | "max_tokens" | "stop_sequence" | "error";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentionai/agents",
|
|
3
3
|
"author": "Laurent Zuijdwijk",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.12.0",
|
|
5
5
|
"description": "Agent Library",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
"types": "./dist/gemini.d.ts",
|
|
31
31
|
"default": "./dist/gemini.js"
|
|
32
32
|
},
|
|
33
|
+
"./ollama": {
|
|
34
|
+
"types": "./dist/ollama.d.ts",
|
|
35
|
+
"default": "./dist/ollama.js"
|
|
36
|
+
},
|
|
33
37
|
"./embeddings": {
|
|
34
38
|
"types": "./dist/embeddings/index.d.ts",
|
|
35
39
|
"default": "./dist/embeddings/index.js"
|
|
@@ -140,6 +144,7 @@
|
|
|
140
144
|
"@mistralai/mistralai": "^1.13.0",
|
|
141
145
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
142
146
|
"apache-arrow": "^18.0.0",
|
|
147
|
+
"ollama": "^0.5.18",
|
|
143
148
|
"openai": "^6.16.0",
|
|
144
149
|
"voyageai": "^0.0.3"
|
|
145
150
|
},
|
|
@@ -170,6 +175,9 @@
|
|
|
170
175
|
},
|
|
171
176
|
"@opensearch-project/opensearch": {
|
|
172
177
|
"optional": true
|
|
178
|
+
},
|
|
179
|
+
"ollama": {
|
|
180
|
+
"optional": true
|
|
173
181
|
}
|
|
174
182
|
},
|
|
175
183
|
"dependencies": {
|