@agentionai/agents 0.8.1 → 0.10.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/README.md +44 -0
- package/dist/agents/AgentConfig.d.ts +6 -0
- package/dist/agents/BaseAgent.d.ts +3 -3
- package/dist/agents/BaseAgent.js +8 -4
- package/dist/agents/anthropic/ClaudeAgent.d.ts +2 -2
- package/dist/agents/anthropic/ClaudeAgent.js +31 -4
- package/dist/agents/google/GeminiAgent.d.ts +2 -2
- package/dist/agents/google/GeminiAgent.js +10 -4
- package/dist/agents/mistral/MistralAgent.d.ts +2 -2
- package/dist/agents/mistral/MistralAgent.js +10 -4
- package/dist/agents/openai/OpenAiAgent.d.ts +2 -2
- package/dist/agents/openai/OpenAiAgent.js +10 -4
- package/dist/history/History.d.ts +144 -9
- package/dist/history/History.js +242 -5
- package/dist/history/index.d.ts +5 -0
- package/dist/history/index.js +17 -0
- package/dist/history/plugins/compressionPlugin.d.ts +54 -0
- package/dist/history/plugins/compressionPlugin.js +143 -0
- package/dist/history/plugins/index.d.ts +3 -0
- package/dist/history/plugins/index.js +8 -0
- package/dist/history/plugins/toolResultMaskingPlugin.d.ts +66 -0
- package/dist/history/plugins/toolResultMaskingPlugin.js +141 -0
- package/dist/history/transformers.js +101 -14
- package/dist/history/types.d.ts +51 -1
- package/dist/history/types.js +26 -0
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -73,6 +73,7 @@ import { ClaudeAgent, OpenAiAgent } from '@agentionai/agents';
|
|
|
73
73
|
|
|
74
74
|
- **Multi-Provider, No Lock-in** - Claude, OpenAI, Gemini, Mistral—same interface. Switch models with one line.
|
|
75
75
|
- **Composable, Not Magical** - Agents are objects. Pipelines are arrays. No hidden state, no surprises.
|
|
76
|
+
- **Multimodal / Vision** - Send images alongside text with a unified `MessageContent[]` API across all providers.
|
|
76
77
|
- **Full Observability** - Per-call token counts, execution timing, pipeline structure visualization.
|
|
77
78
|
- **TypeScript-Native** - Strict typing, interfaces, and generics from the ground up.
|
|
78
79
|
- **RAG Ready** - LanceDB vector store, token-aware chunking, ingestion pipeline out of the box.
|
|
@@ -175,6 +176,43 @@ const researcher = new ClaudeAgent({
|
|
|
175
176
|
const result = await researcher.execute('Latest developments in quantum computing');
|
|
176
177
|
```
|
|
177
178
|
|
|
179
|
+
### Multimodal / Vision
|
|
180
|
+
|
|
181
|
+
Send images alongside text using `imageUrl()` or `imageBase64()`. The same `MessageContent[]` interface works across all providers:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { ClaudeAgent } from '@agentionai/agents/claude';
|
|
185
|
+
import { imageUrl, imageBase64 } from '@agentionai/agents/core';
|
|
186
|
+
import * as fs from 'fs';
|
|
187
|
+
|
|
188
|
+
const agent = new ClaudeAgent({
|
|
189
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
190
|
+
model: 'claude-opus-4-6',
|
|
191
|
+
name: 'VisionAgent',
|
|
192
|
+
description: 'You analyze images.',
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Remote image by URL
|
|
196
|
+
const response = await agent.execute([
|
|
197
|
+
imageUrl('https://example.com/chart.png'),
|
|
198
|
+
{ type: 'text', text: 'Summarize this chart in one sentence.' },
|
|
199
|
+
]);
|
|
200
|
+
|
|
201
|
+
// Local image as base64
|
|
202
|
+
const data = fs.readFileSync('./photo.jpg').toString('base64');
|
|
203
|
+
const response2 = await agent.execute([
|
|
204
|
+
imageBase64(data, 'image/jpeg'),
|
|
205
|
+
{ type: 'text', text: 'What plant is this?' },
|
|
206
|
+
]);
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
| Provider | URL | Base64 |
|
|
210
|
+
|----------|:---:|:------:|
|
|
211
|
+
| Claude | ✅ | ✅ |
|
|
212
|
+
| OpenAI | ✅ | ✅ |
|
|
213
|
+
| Gemini | ✅ | ✅ |
|
|
214
|
+
| Mistral | ✅ | ❌ |
|
|
215
|
+
|
|
178
216
|
## Core Concepts
|
|
179
217
|
|
|
180
218
|
### Agents
|
|
@@ -187,6 +225,11 @@ JSON Schema + handler pattern. Unique capability: wrap any agent as a tool for d
|
|
|
187
225
|
|
|
188
226
|
[Learn more →](https://docs.agention.ai/guide/tools)
|
|
189
227
|
|
|
228
|
+
### Multimodal / Vision
|
|
229
|
+
Unified `MessageContent[]` interface for images across all providers. URL and base64 images, mix text and images freely in a single call.
|
|
230
|
+
|
|
231
|
+
[Learn more →](https://docs.agention.ai/guide/multimodal)
|
|
232
|
+
|
|
190
233
|
### History
|
|
191
234
|
Provider-agnostic, persistent (Redis, file, custom), shareable across agents of different providers.
|
|
192
235
|
|
|
@@ -213,6 +256,7 @@ Per-call and per-node token counts, duration metrics, full execution visibility.
|
|
|
213
256
|
- **[Quick Start](https://docs.agention.ai/guide/quickstart)** - Build a weather assistant in 5 minutes
|
|
214
257
|
- **[Agents](https://docs.agention.ai/guide/agents)** - Agent configuration and providers
|
|
215
258
|
- **[Tools](https://docs.agention.ai/guide/tools)** - Adding capabilities and agent delegation
|
|
259
|
+
- **[Multimodal / Vision](https://docs.agention.ai/guide/multimodal)** - Sending images across all providers
|
|
216
260
|
- **[Graph Pipelines](https://docs.agention.ai/guide/graph-pipelines)** - Multi-agent workflows
|
|
217
261
|
- **[Vector Stores](https://docs.agention.ai/guide/vector-stores)** - RAG and semantic search
|
|
218
262
|
- **[Examples](https://docs.agention.ai/guide/examples)** - Real-world implementations
|
|
@@ -18,6 +18,12 @@ export interface CommonAgentConfig {
|
|
|
18
18
|
debug?: boolean;
|
|
19
19
|
/** Maximum number of messages to retain in conversation history */
|
|
20
20
|
maxHistoryLength?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Maximum estimated tokens to retain in conversation history.
|
|
23
|
+
* When exceeded, oldest non-system entries are dropped.
|
|
24
|
+
* Takes precedence over maxHistoryLength for context-window-aware trimming.
|
|
25
|
+
*/
|
|
26
|
+
maxHistoryTokens?: number;
|
|
21
27
|
/** Model identifier (e.g., "claude-3-5-sonnet-20241022", "gpt-4") */
|
|
22
28
|
model?: string;
|
|
23
29
|
/** Array of tools the agent can use during execution */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import EventEmitter from "events";
|
|
2
2
|
import { Tool } from "../tools/Tool";
|
|
3
|
-
import { History, HistoryEntry, MessageRole, MessageContent } from "../history/History";
|
|
3
|
+
import { History, HistoryEntry, MessageRole, MessageContent, ImageMimeType } from "../history/History";
|
|
4
4
|
import { AgentVendor, CommonAgentConfig, VendorSpecificConfig } from "./AgentConfig";
|
|
5
|
-
export type { HistoryEntry, MessageRole, MessageContent };
|
|
5
|
+
export type { HistoryEntry, MessageRole, MessageContent, ImageMimeType };
|
|
6
6
|
export type { AgentVendor };
|
|
7
7
|
/**
|
|
8
8
|
* Agent config as used across all agents
|
|
@@ -22,13 +22,13 @@ export type TokenUsage = {
|
|
|
22
22
|
* Handles the BaseConfig
|
|
23
23
|
*/
|
|
24
24
|
export declare abstract class BaseAgent<TInput = unknown, TOutput = unknown> extends EventEmitter {
|
|
25
|
-
protected history: History;
|
|
26
25
|
protected id: string;
|
|
27
26
|
protected debug: boolean;
|
|
28
27
|
protected name: string;
|
|
29
28
|
protected description: string;
|
|
30
29
|
protected tools: Map<string, Tool<unknown>>;
|
|
31
30
|
protected maxHistoryLength: number;
|
|
31
|
+
protected history: History;
|
|
32
32
|
/** The vendor/provider for this agent (anthropic, openai, mistral, gemini) */
|
|
33
33
|
protected vendor: AgentVendor;
|
|
34
34
|
/** The model identifier for this agent */
|
package/dist/agents/BaseAgent.js
CHANGED
|
@@ -21,9 +21,8 @@ class BaseAgent extends events_1.default {
|
|
|
21
21
|
* prompts, then supply a History object.
|
|
22
22
|
*
|
|
23
23
|
*/
|
|
24
|
-
constructor(config, history
|
|
24
|
+
constructor(config, history) {
|
|
25
25
|
super();
|
|
26
|
-
this.history = history;
|
|
27
26
|
this.debug = true;
|
|
28
27
|
this.id = config.id;
|
|
29
28
|
this.debug = config.debug || false;
|
|
@@ -31,6 +30,12 @@ class BaseAgent extends events_1.default {
|
|
|
31
30
|
this.description = config.description;
|
|
32
31
|
this.vendor = config.vendor;
|
|
33
32
|
this.model = config.model || "unknown";
|
|
33
|
+
this.maxHistoryLength = config.maxHistoryLength || 100;
|
|
34
|
+
this.history = history ?? new History_1.History([], {
|
|
35
|
+
transient: true,
|
|
36
|
+
maxLength: config.maxHistoryLength,
|
|
37
|
+
maxTokens: config.maxHistoryTokens,
|
|
38
|
+
});
|
|
34
39
|
if (config.agents) {
|
|
35
40
|
const agentTools = config.agents.map((agent) => {
|
|
36
41
|
return Tool_1.Tool.fromAgent(agent, `You can use this agent ${agent.getName()} to execute tasks`);
|
|
@@ -40,7 +45,6 @@ class BaseAgent extends events_1.default {
|
|
|
40
45
|
: agentTools;
|
|
41
46
|
}
|
|
42
47
|
this.tools = new Map((config.tools || []).map((tool) => [tool.name, tool]));
|
|
43
|
-
this.maxHistoryLength = config.maxHistoryLength || 100;
|
|
44
48
|
}
|
|
45
49
|
getToolDefinitions() {
|
|
46
50
|
return Array.from(this.tools.values()).map((tool) => tool.getPrompt());
|
|
@@ -108,7 +112,7 @@ class BaseAgent extends events_1.default {
|
|
|
108
112
|
return this.model;
|
|
109
113
|
}
|
|
110
114
|
getHistoryEntries() {
|
|
111
|
-
return this.history.
|
|
115
|
+
return this.history.getEntries();
|
|
112
116
|
}
|
|
113
117
|
getTools() {
|
|
114
118
|
return [...this.tools.values()];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Message, Usage } from "@anthropic-ai/sdk/resources";
|
|
2
2
|
import { type ToolDefinition } from "../../tools/Tool";
|
|
3
3
|
import { BaseAgent, BaseAgentConfig, TokenUsage } from "../BaseAgent";
|
|
4
|
-
import { History } from "../../history/History";
|
|
4
|
+
import { History, MessageContent } from "../../history/History";
|
|
5
5
|
import { ClaudeModel } from "../model-types";
|
|
6
6
|
type AgentConfig = BaseAgentConfig & {
|
|
7
7
|
apiKey: string;
|
|
@@ -37,7 +37,7 @@ export declare class ClaudeAgent extends BaseAgent {
|
|
|
37
37
|
constructor(config: Omit<AgentConfig, "vendor">, history?: History);
|
|
38
38
|
protected getToolDefinitions(): ToolDefinition[];
|
|
39
39
|
protected process(_input: string): Promise<string>;
|
|
40
|
-
execute(input: string): Promise<string>;
|
|
40
|
+
execute(input: string | MessageContent[]): Promise<string>;
|
|
41
41
|
protected handleResponse(response: Message): Promise<string>;
|
|
42
42
|
private handleToolUse;
|
|
43
43
|
protected parseUsage(input: Usage): TokenUsage;
|
|
@@ -64,18 +64,25 @@ class ClaudeAgent extends BaseAgent_1.BaseAgent {
|
|
|
64
64
|
// Reset token usage for this execution
|
|
65
65
|
this.lastTokenUsage = undefined;
|
|
66
66
|
this.currentToolCallCount = 0;
|
|
67
|
+
// Normalise input to a display string for viz reporting
|
|
68
|
+
const inputPreview = typeof input === "string" ? input : JSON.stringify(input);
|
|
67
69
|
// Start visualization reporting
|
|
68
70
|
if (VizConfig_1.vizConfig.isEnabled()) {
|
|
69
|
-
this.vizEventId = VizReporter_1.vizReporter.agentStart(this.id, this.name, this.config.model, "anthropic",
|
|
71
|
+
this.vizEventId = VizReporter_1.vizReporter.agentStart(this.id, this.name, this.config.model, "anthropic", inputPreview);
|
|
70
72
|
}
|
|
71
73
|
if (this.history.transient) {
|
|
72
74
|
this.history.clear();
|
|
73
75
|
// Re-add system message after clear
|
|
74
76
|
this.addSystemMessage(this.getSystemMessage());
|
|
75
77
|
}
|
|
76
|
-
|
|
78
|
+
if (typeof input === "string") {
|
|
79
|
+
this.addTextToHistory("user", input);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
this.addMessageToHistory("user", input);
|
|
83
|
+
}
|
|
77
84
|
try {
|
|
78
|
-
const messages = transformers_1.anthropicTransformer.toProvider(this.history.
|
|
85
|
+
const messages = transformers_1.anthropicTransformer.toProvider(this.history.getEntries());
|
|
79
86
|
const systemMessage = this.history.getSystemMessage();
|
|
80
87
|
const response = await this.client.messages.create({
|
|
81
88
|
model: this.config.model,
|
|
@@ -177,9 +184,10 @@ class ClaudeAgent extends BaseAgent_1.BaseAgent {
|
|
|
177
184
|
this.addMessageToHistory("user", toolResults);
|
|
178
185
|
// Continue conversation with tool results
|
|
179
186
|
try {
|
|
180
|
-
const messages = transformers_1.anthropicTransformer.toProvider(this.history.
|
|
187
|
+
const messages = transformers_1.anthropicTransformer.toProvider(this.history.getEntries());
|
|
181
188
|
const newResponse = await this.client.messages.create({
|
|
182
189
|
model: this.config.model,
|
|
190
|
+
system: this.history.getSystemMessage(),
|
|
183
191
|
max_tokens: this.config.maxTokens,
|
|
184
192
|
messages,
|
|
185
193
|
tools: this.getToolDefinitions(),
|
|
@@ -224,6 +232,12 @@ class ClaudeAgent extends BaseAgent_1.BaseAgent {
|
|
|
224
232
|
}
|
|
225
233
|
// Track tool call count for viz reporting
|
|
226
234
|
this.currentToolCallCount += toolUseBlocks.length;
|
|
235
|
+
const agentSource = {
|
|
236
|
+
agentId: this.getId(),
|
|
237
|
+
agentName: this.getName(),
|
|
238
|
+
model: this.config.model,
|
|
239
|
+
vendor: "anthropic",
|
|
240
|
+
};
|
|
227
241
|
const results = await Promise.all(toolUseBlocks.map(async (block) => {
|
|
228
242
|
const tool = this.tools.get(block.name);
|
|
229
243
|
if (!tool) {
|
|
@@ -232,10 +246,20 @@ class ClaudeAgent extends BaseAgent_1.BaseAgent {
|
|
|
232
246
|
if (this.debug) {
|
|
233
247
|
console.error(error);
|
|
234
248
|
}
|
|
249
|
+
if (VizConfig_1.vizConfig.isEnabled()) {
|
|
250
|
+
const vizEventId = VizReporter_1.vizReporter.toolStart(block.name, block.id, block.input, agentSource);
|
|
251
|
+
VizReporter_1.vizReporter.toolError(vizEventId, block.name, block.id, errorMessage);
|
|
252
|
+
}
|
|
235
253
|
return (0, History_1.toolResult)(block.id, errorMessage, true);
|
|
236
254
|
}
|
|
255
|
+
const vizEventId = VizConfig_1.vizConfig.isEnabled()
|
|
256
|
+
? VizReporter_1.vizReporter.toolStart(block.name, block.id, block.input, agentSource)
|
|
257
|
+
: undefined;
|
|
237
258
|
try {
|
|
238
259
|
const result = await tool.execute(this.getId(), this.getName(), block.input, block.id, this.config.model, "anthropic");
|
|
260
|
+
if (vizEventId) {
|
|
261
|
+
VizReporter_1.vizReporter.toolComplete(vizEventId, block.name, block.id, true, result);
|
|
262
|
+
}
|
|
239
263
|
return (0, History_1.toolResult)(block.id, JSON.stringify(result));
|
|
240
264
|
}
|
|
241
265
|
catch (error) {
|
|
@@ -245,6 +269,9 @@ class ClaudeAgent extends BaseAgent_1.BaseAgent {
|
|
|
245
269
|
}
|
|
246
270
|
const toolError = new AgentError_1.ToolExecutionError(errorMessage, block.name, block.input);
|
|
247
271
|
this.emit(AgentEvent_1.AgentEvent.TOOL_ERROR, toolError);
|
|
272
|
+
if (vizEventId) {
|
|
273
|
+
VizReporter_1.vizReporter.toolError(vizEventId, block.name, block.id, errorMessage);
|
|
274
|
+
}
|
|
248
275
|
return (0, History_1.toolResult)(block.id, errorMessage, true);
|
|
249
276
|
}
|
|
250
277
|
}));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FunctionDeclarationsTool, GenerateContentResult, Schema } from "@google/generative-ai";
|
|
2
2
|
import { BaseAgent, BaseAgentConfig, TokenUsage } from "../BaseAgent";
|
|
3
|
-
import { History } from "../../history/History";
|
|
3
|
+
import { History, MessageContent } from "../../history/History";
|
|
4
4
|
import { GeminiModel } from "../model-types";
|
|
5
5
|
type AgentConfig = BaseAgentConfig & {
|
|
6
6
|
apiKey: string;
|
|
@@ -50,7 +50,7 @@ export declare class GeminiAgent extends BaseAgent {
|
|
|
50
50
|
*/
|
|
51
51
|
private mapJsonSchemaTypeToGemini;
|
|
52
52
|
protected process(_input: string): Promise<string>;
|
|
53
|
-
execute(input: string): Promise<string>;
|
|
53
|
+
execute(input: string | MessageContent[]): Promise<string>;
|
|
54
54
|
protected handleResponse(response: GenerateContentResult): Promise<string>;
|
|
55
55
|
private handleFunctionCalls;
|
|
56
56
|
protected parseUsage(input: {
|
|
@@ -165,18 +165,24 @@ class GeminiAgent extends BaseAgent_1.BaseAgent {
|
|
|
165
165
|
// Reset token usage for this execution
|
|
166
166
|
this.lastTokenUsage = undefined;
|
|
167
167
|
this.currentToolCallCount = 0;
|
|
168
|
+
const inputPreview = typeof input === "string" ? input : JSON.stringify(input);
|
|
168
169
|
// Start visualization reporting
|
|
169
170
|
if (VizConfig_1.vizConfig.isEnabled()) {
|
|
170
|
-
this.vizEventId = VizReporter_1.vizReporter.agentStart(this.id, this.name, this.config.model, "gemini",
|
|
171
|
+
this.vizEventId = VizReporter_1.vizReporter.agentStart(this.id, this.name, this.config.model, "gemini", inputPreview);
|
|
171
172
|
}
|
|
172
173
|
if (this.history.transient) {
|
|
173
174
|
this.history.clear();
|
|
174
175
|
// Re-add system message after clear
|
|
175
176
|
this.addSystemMessage(this.getSystemMessage());
|
|
176
177
|
}
|
|
177
|
-
|
|
178
|
+
if (typeof input === "string") {
|
|
179
|
+
this.addTextToHistory("user", input);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
this.addMessageToHistory("user", input);
|
|
183
|
+
}
|
|
178
184
|
try {
|
|
179
|
-
const contents = transformers_1.geminiTransformer.toProvider(this.history.
|
|
185
|
+
const contents = transformers_1.geminiTransformer.toProvider(this.history.getEntries());
|
|
180
186
|
const systemMessage = this.history.getSystemMessage();
|
|
181
187
|
const tools = this.getToolDefinitionsForGemini();
|
|
182
188
|
const response = await this.generativeModel.generateContent({
|
|
@@ -290,7 +296,7 @@ class GeminiAgent extends BaseAgent_1.BaseAgent {
|
|
|
290
296
|
}
|
|
291
297
|
// Continue conversation
|
|
292
298
|
try {
|
|
293
|
-
const newContents = transformers_1.geminiTransformer.toProvider(this.history.
|
|
299
|
+
const newContents = transformers_1.geminiTransformer.toProvider(this.history.getEntries());
|
|
294
300
|
const systemMessage = this.history.getSystemMessage();
|
|
295
301
|
const tools = this.getToolDefinitionsForGemini();
|
|
296
302
|
const newResponse = await this.generativeModel.generateContent({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseAgent, BaseAgentConfig, TokenUsage } from "../BaseAgent";
|
|
2
|
-
import { History } from "../../history/History";
|
|
2
|
+
import { History, MessageContent } from "../../history/History";
|
|
3
3
|
import { ChatCompletionResponse, Tool, UsageInfo } from "@mistralai/mistralai/models/components";
|
|
4
4
|
import { MistralModel } from "../model-types";
|
|
5
5
|
type AgentConfig = BaseAgentConfig & {
|
|
@@ -38,7 +38,7 @@ export declare class MistralAgent extends BaseAgent {
|
|
|
38
38
|
constructor(config: Omit<AgentConfig, "vendor">, history?: History);
|
|
39
39
|
protected getToolDefinitions(): Tool[];
|
|
40
40
|
protected process(_input: string): Promise<string>;
|
|
41
|
-
execute(input: string): Promise<string>;
|
|
41
|
+
execute(input: string | MessageContent[]): Promise<string>;
|
|
42
42
|
protected handleResponse(response: ChatCompletionResponse): Promise<string>;
|
|
43
43
|
private handleToolCalls;
|
|
44
44
|
protected parseUsage(input: UsageInfo): TokenUsage;
|
|
@@ -75,18 +75,24 @@ class MistralAgent extends BaseAgent_1.BaseAgent {
|
|
|
75
75
|
// Reset token usage for this execution
|
|
76
76
|
this.lastTokenUsage = undefined;
|
|
77
77
|
this.currentToolCallCount = 0;
|
|
78
|
+
const inputPreview = typeof input === "string" ? input : JSON.stringify(input);
|
|
78
79
|
// Start visualization reporting
|
|
79
80
|
if (VizConfig_1.vizConfig.isEnabled()) {
|
|
80
|
-
this.vizEventId = VizReporter_1.vizReporter.agentStart(this.id, this.name, this.config.model, "mistral",
|
|
81
|
+
this.vizEventId = VizReporter_1.vizReporter.agentStart(this.id, this.name, this.config.model, "mistral", inputPreview);
|
|
81
82
|
}
|
|
82
83
|
if (this.history.transient) {
|
|
83
84
|
this.history.clear();
|
|
84
85
|
// Re-add system message after clear
|
|
85
86
|
this.addSystemMessage(this.getSystemMessage());
|
|
86
87
|
}
|
|
87
|
-
|
|
88
|
+
if (typeof input === "string") {
|
|
89
|
+
this.addTextToHistory("user", input);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
this.addMessageToHistory("user", input);
|
|
93
|
+
}
|
|
88
94
|
try {
|
|
89
|
-
const messages = transformers_1.mistralTransformer.toProvider(this.history.
|
|
95
|
+
const messages = transformers_1.mistralTransformer.toProvider(this.history.getEntries());
|
|
90
96
|
const response = await this.client.chat.complete({
|
|
91
97
|
model: this.config.model,
|
|
92
98
|
messages: messages,
|
|
@@ -202,7 +208,7 @@ class MistralAgent extends BaseAgent_1.BaseAgent {
|
|
|
202
208
|
await (0, promises_1.setTimeout)(this.config.rateLimitDelay || 1500);
|
|
203
209
|
// Continue conversation
|
|
204
210
|
try {
|
|
205
|
-
const messages = transformers_1.mistralTransformer.toProvider(this.history.
|
|
211
|
+
const messages = transformers_1.mistralTransformer.toProvider(this.history.getEntries());
|
|
206
212
|
const newResponse = await this.client.chat.complete({
|
|
207
213
|
model: this.config.model,
|
|
208
214
|
messages: messages,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseAgent, BaseAgentConfig, TokenUsage } from "../BaseAgent";
|
|
2
|
-
import { History } from "../../history/History";
|
|
2
|
+
import { History, MessageContent } from "../../history/History";
|
|
3
3
|
import { Tool, Response, ResponseUsage } from "openai/resources/responses/responses";
|
|
4
4
|
import { OpenAIModel } from "../model-types";
|
|
5
5
|
type AgentConfig = BaseAgentConfig & {
|
|
@@ -39,7 +39,7 @@ export declare class OpenAiAgent extends BaseAgent {
|
|
|
39
39
|
constructor(config: Omit<AgentConfig, "vendor">, history?: History);
|
|
40
40
|
protected getToolDefinitions(): Tool[];
|
|
41
41
|
protected process(_input: string): Promise<string>;
|
|
42
|
-
execute(input: string): Promise<string>;
|
|
42
|
+
execute(input: string | MessageContent[]): Promise<string>;
|
|
43
43
|
protected handleResponse(response: Response): Promise<string>;
|
|
44
44
|
private handleToolUse;
|
|
45
45
|
protected parseUsage(input: ResponseUsage): TokenUsage;
|
|
@@ -86,18 +86,24 @@ class OpenAiAgent extends BaseAgent_1.BaseAgent {
|
|
|
86
86
|
// Reset token usage for this execution
|
|
87
87
|
this.lastTokenUsage = undefined;
|
|
88
88
|
this.currentToolCallCount = 0;
|
|
89
|
+
const inputPreview = typeof input === "string" ? input : JSON.stringify(input);
|
|
89
90
|
// Start visualization reporting
|
|
90
91
|
if (VizConfig_1.vizConfig.isEnabled()) {
|
|
91
|
-
this.vizEventId = VizReporter_1.vizReporter.agentStart(this.id, this.name, this.config.model, "openai",
|
|
92
|
+
this.vizEventId = VizReporter_1.vizReporter.agentStart(this.id, this.name, this.config.model, "openai", inputPreview);
|
|
92
93
|
}
|
|
93
94
|
if (this.history.transient) {
|
|
94
95
|
this.history.clear();
|
|
95
96
|
// Re-add system message after clear
|
|
96
97
|
this.addSystemMessage(this.getSystemMessage());
|
|
97
98
|
}
|
|
98
|
-
|
|
99
|
+
if (typeof input === "string") {
|
|
100
|
+
this.addTextToHistory("user", input);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
this.addMessageToHistory("user", input);
|
|
104
|
+
}
|
|
99
105
|
try {
|
|
100
|
-
const inputMessages = transformers_1.openAiTransformer.toProvider(this.history.
|
|
106
|
+
const inputMessages = transformers_1.openAiTransformer.toProvider(this.history.getEntries());
|
|
101
107
|
const response = await this.client.responses.create({
|
|
102
108
|
model: this.config.model,
|
|
103
109
|
max_output_tokens: this.config.maxTokens,
|
|
@@ -216,7 +222,7 @@ class OpenAiAgent extends BaseAgent_1.BaseAgent {
|
|
|
216
222
|
}
|
|
217
223
|
// Continue conversation
|
|
218
224
|
try {
|
|
219
|
-
const inputMessages = transformers_1.openAiTransformer.toProvider(this.history.
|
|
225
|
+
const inputMessages = transformers_1.openAiTransformer.toProvider(this.history.getEntries());
|
|
220
226
|
const newResponse = await this.client.responses.create({
|
|
221
227
|
model: this.config.model,
|
|
222
228
|
max_output_tokens: this.config.maxTokens,
|
|
@@ -1,22 +1,80 @@
|
|
|
1
1
|
import EventEmitter from "events";
|
|
2
2
|
import { HistoryEntry, MessageRole, MessageContent } from "./types";
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import type { ReduceOptions } from "./types";
|
|
4
|
+
/** @internal — exposed for test teardown only */
|
|
5
|
+
export declare function resetTokenxCache(): void;
|
|
6
|
+
export type { HistoryEntry, MessageRole, MessageContent, ReduceOptions, ImageMimeType, ImageUrlContent, ImageBase64Content, } from "./types";
|
|
7
|
+
export { text, toolUse, toolResult, textMessage, imageUrl, imageBase64, isTextContent, isToolUseContent, isToolResultContent, isImageUrlContent, isImageBase64Content, isImageContent, } from "./types";
|
|
5
8
|
/**
|
|
6
|
-
*
|
|
9
|
+
* Metadata stored alongside each history entry.
|
|
10
|
+
* Extended with summary tracking fields for the compression plugin.
|
|
7
11
|
*/
|
|
8
|
-
type
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
export type EntryMetadata = {
|
|
13
|
+
date: string;
|
|
14
|
+
contentLength: number;
|
|
15
|
+
estimatedTokens: number;
|
|
16
|
+
/**
|
|
17
|
+
* True when this entry was produced by a compression plugin as a rolling
|
|
18
|
+
* summary of earlier turns. Used so subsequent compressions can include
|
|
19
|
+
* the existing summary as prior context rather than treating it as a
|
|
20
|
+
* regular conversation turn.
|
|
21
|
+
*/
|
|
22
|
+
isSummary?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* ISO date range covered by a summary entry.
|
|
25
|
+
* Only present when isSummary is true.
|
|
26
|
+
*/
|
|
27
|
+
coversRange?: {
|
|
28
|
+
from: string;
|
|
29
|
+
to: string;
|
|
12
30
|
};
|
|
13
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* A history entry with its internal metadata attached.
|
|
34
|
+
* Passed to plugin reduce() and transform() hooks.
|
|
35
|
+
*/
|
|
36
|
+
export type ReducibleEntry = HistoryEntry & {
|
|
37
|
+
__metadata: EntryMetadata;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* A history plugin. Register with `history.use(plugin)`.
|
|
41
|
+
*
|
|
42
|
+
* Hooks:
|
|
43
|
+
* - `onRegistered` — called once immediately when the plugin is registered
|
|
44
|
+
* - `afterAdd` — called fire-and-forget after every addEntry(); errors are
|
|
45
|
+
* routed to the `onPluginError` option / `"pluginError"` event, never thrown
|
|
46
|
+
* - `reduce` — called by history.reduce(); receives and returns the full
|
|
47
|
+
* entry array; plugins are piped in registration order
|
|
48
|
+
* - `transform` — pure read-time rewrite; called by history.getEntries();
|
|
49
|
+
* sync, cheap, must not mutate stored entries; applied in registration order
|
|
50
|
+
*/
|
|
51
|
+
export type HistoryPlugin = {
|
|
52
|
+
onRegistered?: (history: History) => void;
|
|
53
|
+
afterAdd?: (history: History) => void | Promise<void>;
|
|
54
|
+
reduce?: (entries: ReducibleEntry[], options: ReduceOptions) => Promise<ReducibleEntry[]>;
|
|
55
|
+
transform?: (entries: ReducibleEntry[]) => ReducibleEntry[];
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Internal entry with metadata
|
|
59
|
+
*/
|
|
60
|
+
type EntryWithMetadata = ReducibleEntry;
|
|
14
61
|
/**
|
|
15
62
|
* History configuration options
|
|
16
63
|
*/
|
|
17
64
|
type HistoryOptions = {
|
|
18
65
|
maxLength?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Maximum estimated tokens to retain in history. When exceeded, oldest
|
|
68
|
+
* non-system entries are dropped via the addEntry() safety net.
|
|
69
|
+
* The system message is always preserved.
|
|
70
|
+
*/
|
|
71
|
+
maxTokens?: number;
|
|
19
72
|
transient?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Called when a plugin's afterAdd hook throws. If not provided, the error
|
|
75
|
+
* is re-emitted as a "pluginError" event on the History instance.
|
|
76
|
+
*/
|
|
77
|
+
onPluginError?: (error: Error, plugin: HistoryPlugin, hook: "afterAdd") => void;
|
|
20
78
|
};
|
|
21
79
|
/**
|
|
22
80
|
* Manages conversation history in a provider-agnostic format.
|
|
@@ -27,6 +85,10 @@ type HistoryOptions = {
|
|
|
27
85
|
* History can be shared between agents of different providers, enabling
|
|
28
86
|
* cross-provider conversations and handoffs.
|
|
29
87
|
*
|
|
88
|
+
* Plugins can be registered with `history.use(plugin)` to add read-time
|
|
89
|
+
* transforms (e.g., tool result masking) or async reduce strategies
|
|
90
|
+
* (e.g., rolling LLM summarization).
|
|
91
|
+
*
|
|
30
92
|
* @example Basic usage
|
|
31
93
|
* ```typescript
|
|
32
94
|
* const history = new History();
|
|
@@ -34,6 +96,19 @@ type HistoryOptions = {
|
|
|
34
96
|
* history.addText("assistant", "Hi there!");
|
|
35
97
|
* ```
|
|
36
98
|
*
|
|
99
|
+
* @example With tool result masking plugin
|
|
100
|
+
* ```typescript
|
|
101
|
+
* import { toolResultMaskingPlugin } from "agention-lib/history/plugins";
|
|
102
|
+
*
|
|
103
|
+
* const maskingPlugin = toolResultMaskingPlugin({ keepRecentResults: 2 });
|
|
104
|
+
* const history = new History().use(maskingPlugin);
|
|
105
|
+
*
|
|
106
|
+
* const agent = new ClaudeAgent(
|
|
107
|
+
* { tools: [maskingPlugin.retrieveTool, ...otherTools] },
|
|
108
|
+
* history
|
|
109
|
+
* );
|
|
110
|
+
* ```
|
|
111
|
+
*
|
|
37
112
|
* @example Sharing between agents
|
|
38
113
|
* ```typescript
|
|
39
114
|
* const history = new History();
|
|
@@ -46,7 +121,22 @@ export declare class History extends EventEmitter {
|
|
|
46
121
|
protected _entries: EntryWithMetadata[];
|
|
47
122
|
private options;
|
|
48
123
|
transient: boolean;
|
|
124
|
+
private _plugins;
|
|
125
|
+
private _reducing;
|
|
49
126
|
constructor(entries?: HistoryEntry[], options?: HistoryOptions);
|
|
127
|
+
/**
|
|
128
|
+
* Register a plugin with this history instance.
|
|
129
|
+
* Calls plugin.onRegistered(this) immediately after registration.
|
|
130
|
+
* Returns `this` for chaining.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* history
|
|
135
|
+
* .use(compressionPlugin(summaryAgent))
|
|
136
|
+
* .use(toolResultMaskingPlugin({ keepRecentResults: 2 }));
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
use(plugin: HistoryPlugin): this;
|
|
50
140
|
/**
|
|
51
141
|
* Add a complete history entry
|
|
52
142
|
*/
|
|
@@ -64,9 +154,27 @@ export declare class History extends EventEmitter {
|
|
|
64
154
|
*/
|
|
65
155
|
addSystem(content: string): void;
|
|
66
156
|
/**
|
|
67
|
-
* Get
|
|
157
|
+
* Get entries as agents should see them — with all registered transform
|
|
158
|
+
* plugins applied in registration order.
|
|
159
|
+
*
|
|
160
|
+
* Use this when building API requests. The raw `entries` getter is
|
|
161
|
+
* reserved for serialization, cloning, and other internal purposes.
|
|
162
|
+
*/
|
|
163
|
+
getEntries(): HistoryEntry[];
|
|
164
|
+
/**
|
|
165
|
+
* Get all entries without transform plugins applied (raw storage).
|
|
166
|
+
* Use for serialization, cloning, and debugging.
|
|
68
167
|
*/
|
|
69
168
|
get entries(): HistoryEntry[];
|
|
169
|
+
/**
|
|
170
|
+
* Get the full content of a tool result by its tool_use_id.
|
|
171
|
+
* Always reads from raw stored entries — never affected by transform plugins.
|
|
172
|
+
*
|
|
173
|
+
* For RedisHistory: call await load() before using this method.
|
|
174
|
+
*
|
|
175
|
+
* @returns The full result string, or undefined if not found.
|
|
176
|
+
*/
|
|
177
|
+
getToolResult(tool_use_id: string): string | undefined;
|
|
70
178
|
/**
|
|
71
179
|
* Get the number of entries
|
|
72
180
|
*/
|
|
@@ -75,6 +183,11 @@ export declare class History extends EventEmitter {
|
|
|
75
183
|
* Get total content size in characters
|
|
76
184
|
*/
|
|
77
185
|
get size(): number;
|
|
186
|
+
/**
|
|
187
|
+
* Get total estimated token count across all entries.
|
|
188
|
+
* Uses a rough approximation of 1 token ≈ 4 characters.
|
|
189
|
+
*/
|
|
190
|
+
get totalEstimatedTokens(): number;
|
|
78
191
|
/**
|
|
79
192
|
* Get the last entry
|
|
80
193
|
*/
|
|
@@ -84,9 +197,25 @@ export declare class History extends EventEmitter {
|
|
|
84
197
|
*/
|
|
85
198
|
getSystemMessage(): string | undefined;
|
|
86
199
|
/**
|
|
87
|
-
* Get entries without system messages
|
|
200
|
+
* Get entries without system messages, with transform plugins applied.
|
|
88
201
|
*/
|
|
89
202
|
getMessagesWithoutSystem(): HistoryEntry[];
|
|
203
|
+
/**
|
|
204
|
+
* Asynchronously compact history using registered reduce plugins.
|
|
205
|
+
*
|
|
206
|
+
* Plugins are called in registration order, each receiving and returning
|
|
207
|
+
* the full entry array. If no plugin has a `reduce` hook, this is a no-op —
|
|
208
|
+
* the addEntry() safety net (FIFO drop via maxTokens) runs independently.
|
|
209
|
+
*
|
|
210
|
+
* Re-entrant calls during an in-progress reduce() return immediately.
|
|
211
|
+
*
|
|
212
|
+
* @example Rolling summarization
|
|
213
|
+
* ```typescript
|
|
214
|
+
* history.use(compressionPlugin(summaryAgent));
|
|
215
|
+
* await history.reduce({ maxTokens: 4000 });
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
reduce(options?: ReduceOptions): Promise<void>;
|
|
90
219
|
/**
|
|
91
220
|
* Clear all history entries
|
|
92
221
|
*/
|
|
@@ -103,5 +232,11 @@ export declare class History extends EventEmitter {
|
|
|
103
232
|
* Create a copy of this history
|
|
104
233
|
*/
|
|
105
234
|
clone(options?: HistoryOptions): History;
|
|
235
|
+
/**
|
|
236
|
+
* Drop oldest non-system entries until totalEstimatedTokens fits within budget.
|
|
237
|
+
* Called synchronously from addEntry() as a safety net.
|
|
238
|
+
* The system message is always preserved.
|
|
239
|
+
*/
|
|
240
|
+
private trimToTokenBudget;
|
|
106
241
|
}
|
|
107
242
|
//# sourceMappingURL=History.d.ts.map
|