@agentionai/agents 0.13.0 → 1.0.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.
@@ -0,0 +1,440 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.OpenAICompatibleAgent = void 0;
7
+ const openai_1 = __importDefault(require("openai"));
8
+ const BaseAgent_1 = require("../BaseAgent");
9
+ const AgentEvent_1 = require("../AgentEvent");
10
+ const AgentError_1 = require("../errors/AgentError");
11
+ const transformers_1 = require("../../history/transformers");
12
+ const VizReporter_1 = require("../../viz/VizReporter");
13
+ const VizConfig_1 = require("../../viz/VizConfig");
14
+ /**
15
+ * Abstract base class for agents that talk to any OpenAI-compatible
16
+ * `/v1/chat/completions` endpoint (llama.cpp, vLLM, LM Studio, etc.).
17
+ *
18
+ * Subclasses must implement:
19
+ * - `getVendorName()` — human-readable name used in error messages (e.g. `"llama.cpp"`)
20
+ *
21
+ * Subclasses may override:
22
+ * - `buildExtraRequestParams()` — extra fields merged into the completions request
23
+ */
24
+ class OpenAICompatibleAgent extends BaseAgent_1.BaseAgent {
25
+ constructor(config, history) {
26
+ super(config, history);
27
+ this.currentToolCallCount = 0;
28
+ this.client = new openai_1.default({
29
+ apiKey: config.apiKey || "not-needed",
30
+ baseURL: config.baseURL,
31
+ });
32
+ this.config = {
33
+ model: config.model,
34
+ baseURL: config.baseURL,
35
+ maxTokens: config.maxTokens,
36
+ temperature: config.temperature,
37
+ topP: config.topP,
38
+ stopSequences: config.stopSequences,
39
+ seed: config.seed,
40
+ presencePenalty: config.presencePenalty,
41
+ frequencyPenalty: config.frequencyPenalty,
42
+ apiKey: config.apiKey,
43
+ };
44
+ this.addSystemMessage(this.getSystemMessage());
45
+ }
46
+ /** Extra fields to merge into the chat completions request. Override for vendor-specific params. */
47
+ buildExtraRequestParams() {
48
+ return {};
49
+ }
50
+ /**
51
+ * List the models available on the server via the `/v1/models` endpoint.
52
+ */
53
+ async listModels() {
54
+ try {
55
+ const page = await this.client.models.list();
56
+ return page.data;
57
+ }
58
+ catch (error) {
59
+ throw new AgentError_1.ExecutionError(`Failed to list ${this.getVendorName()} models: ${error instanceof Error ? error.message : "Unknown error"}`);
60
+ }
61
+ }
62
+ getToolDefinitions() {
63
+ return Array.from(this.tools.values()).map((tool) => {
64
+ const prompt = tool.getPrompt();
65
+ return {
66
+ type: "function",
67
+ function: {
68
+ name: prompt.name,
69
+ description: prompt.description,
70
+ parameters: prompt.input_schema,
71
+ },
72
+ };
73
+ });
74
+ }
75
+ async process(_input) {
76
+ return "";
77
+ }
78
+ async execute(input) {
79
+ this.emit(AgentEvent_1.AgentEvent.BEFORE_EXECUTE, input);
80
+ this.lastTokenUsage = undefined;
81
+ this.currentToolCallCount = 0;
82
+ const inputPreview = typeof input === "string" ? input : JSON.stringify(input);
83
+ if (VizConfig_1.vizConfig.isEnabled()) {
84
+ this.vizEventId = VizReporter_1.vizReporter.agentStart(this.id, this.name, this.config.model, this.vendor, inputPreview);
85
+ }
86
+ if (this.history.transient) {
87
+ this.history.clear();
88
+ this.addSystemMessage(this.getSystemMessage());
89
+ }
90
+ if (typeof input === "string") {
91
+ this.addTextToHistory("user", input);
92
+ }
93
+ else {
94
+ this.addMessageToHistory("user", input);
95
+ }
96
+ this.history.setSessionAnchor();
97
+ this.history.beginExecution();
98
+ try {
99
+ const response = await this.callProvider();
100
+ this.emit(AgentEvent_1.AgentEvent.AFTER_EXECUTE, response);
101
+ return await this.handleResponse(response);
102
+ }
103
+ catch (error) {
104
+ if (error instanceof openai_1.default.APIError) {
105
+ const apiError = new AgentError_1.ApiError(`${this.getVendorName()} API error: ${error.message}`, error.status, error);
106
+ this.emit(AgentEvent_1.AgentEvent.ERROR, apiError);
107
+ if (this.vizEventId) {
108
+ VizReporter_1.vizReporter.agentError(this.vizEventId, "ApiError", apiError.message, error.status === 429);
109
+ this.vizEventId = undefined;
110
+ }
111
+ throw apiError;
112
+ }
113
+ if (error instanceof AgentError_1.AgentError) {
114
+ this.emit(AgentEvent_1.AgentEvent.ERROR, error);
115
+ if (this.vizEventId) {
116
+ VizReporter_1.vizReporter.agentError(this.vizEventId, error.constructor.name, error.message, false);
117
+ this.vizEventId = undefined;
118
+ }
119
+ throw error;
120
+ }
121
+ const executionError = new AgentError_1.ExecutionError(`${this.getVendorName()} error: ${error instanceof Error ? error.message : "Unknown error"}`);
122
+ this.emit(AgentEvent_1.AgentEvent.ERROR, executionError);
123
+ if (this.vizEventId) {
124
+ VizReporter_1.vizReporter.agentError(this.vizEventId, "ExecutionError", executionError.message, false);
125
+ this.vizEventId = undefined;
126
+ }
127
+ throw executionError;
128
+ }
129
+ finally {
130
+ this.history.endExecution();
131
+ }
132
+ }
133
+ async callProvider() {
134
+ const messages = transformers_1.chatCompletionsTransformer.toProvider(this.history.getEntries());
135
+ const tools = this.tools.size > 0 ? this.getToolDefinitions() : undefined;
136
+ return this.client.chat.completions.create({
137
+ model: this.config.model,
138
+ messages,
139
+ tools,
140
+ stream: false,
141
+ max_tokens: this.config.maxTokens,
142
+ temperature: this.config.temperature,
143
+ top_p: this.config.topP,
144
+ stop: this.config.stopSequences,
145
+ seed: this.config.seed,
146
+ presence_penalty: this.config.presencePenalty,
147
+ frequency_penalty: this.config.frequencyPenalty,
148
+ ...this.buildExtraRequestParams(),
149
+ });
150
+ }
151
+ async handleResponse(response) {
152
+ const usage = this.parseUsage(response);
153
+ if (this.lastTokenUsage) {
154
+ this.lastTokenUsage.input_tokens += usage.input_tokens;
155
+ this.lastTokenUsage.output_tokens += usage.output_tokens;
156
+ this.lastTokenUsage.total_tokens += usage.total_tokens;
157
+ }
158
+ else {
159
+ this.lastTokenUsage = { ...usage };
160
+ }
161
+ const choice = response.choices[0];
162
+ const message = choice.message;
163
+ if (choice.finish_reason === "length") {
164
+ const error = new AgentError_1.MaxTokensExceededError("Response exceeded maximum token limit", this.config.maxTokens || 1024);
165
+ this.emit(AgentEvent_1.AgentEvent.MAX_TOKENS_EXCEEDED, error);
166
+ this.emit(AgentEvent_1.AgentEvent.ERROR, error);
167
+ if (this.vizEventId) {
168
+ VizReporter_1.vizReporter.agentError(this.vizEventId, "MaxTokensExceededError", error.message, false);
169
+ this.vizEventId = undefined;
170
+ }
171
+ throw error;
172
+ }
173
+ const hasToolCalls = message.tool_calls && message.tool_calls.length > 0;
174
+ if (!hasToolCalls) {
175
+ const textContent = message.content || "";
176
+ const entry = transformers_1.chatCompletionsTransformer.fromProviderMessage(message);
177
+ this.addToHistory(entry);
178
+ this.emit(AgentEvent_1.AgentEvent.DONE, message, usage);
179
+ if (this.vizEventId) {
180
+ VizReporter_1.vizReporter.agentComplete(this.vizEventId, {
181
+ input: this.lastTokenUsage?.input_tokens || 0,
182
+ output: this.lastTokenUsage?.output_tokens || 0,
183
+ total: this.lastTokenUsage?.total_tokens || 0,
184
+ }, "end_turn", this.currentToolCallCount > 0, this.currentToolCallCount, textContent);
185
+ this.vizEventId = undefined;
186
+ }
187
+ return textContent;
188
+ }
189
+ const toolCalls = message.tool_calls;
190
+ this.emit(AgentEvent_1.AgentEvent.TOOL_USE, toolCalls);
191
+ this.currentToolCallCount += toolCalls.length;
192
+ const assistantEntry = transformers_1.chatCompletionsTransformer.fromProviderMessage(message);
193
+ this.addToHistory(assistantEntry);
194
+ const toolResults = await this.handleToolCalls(toolCalls);
195
+ for (const result of toolResults) {
196
+ const resultEntry = transformers_1.chatCompletionsTransformer.toolResultEntry(result.toolCallId, result.content);
197
+ this.addToHistory(resultEntry);
198
+ }
199
+ try {
200
+ const newResponse = await this.callProvider();
201
+ this.emit(AgentEvent_1.AgentEvent.AFTER_EXECUTE, newResponse);
202
+ return this.handleResponse(newResponse);
203
+ }
204
+ catch (error) {
205
+ const executionError = new AgentError_1.ExecutionError(`${this.getVendorName()} error during tool response: ${error instanceof Error ? error.message : "Unknown error"}`);
206
+ this.emit(AgentEvent_1.AgentEvent.ERROR, executionError);
207
+ throw executionError;
208
+ }
209
+ }
210
+ async handleToolCalls(toolCalls) {
211
+ return Promise.all(toolCalls.map(async (toolCall) => {
212
+ const toolName = toolCall.type === "function" ? toolCall.function.name : "";
213
+ const tool = this.tools.get(toolName);
214
+ const toolCallId = toolCall.id;
215
+ if (toolCall.type !== "function" || !tool) {
216
+ const errorMessage = `Tool '${toolName}' not found`;
217
+ const error = new AgentError_1.ToolExecutionError(errorMessage, toolName, toolCall.type === "function"
218
+ ? toolCall.function.arguments
219
+ : undefined);
220
+ this.emit(AgentEvent_1.AgentEvent.TOOL_ERROR, error);
221
+ return { toolCallId, content: errorMessage };
222
+ }
223
+ try {
224
+ const args = JSON.parse(toolCall.function.arguments || "{}");
225
+ const result = await tool.execute(this.getId(), this.getName(), args, toolCallId, this.config.model, this.vendor);
226
+ return { toolCallId, content: JSON.stringify(result) };
227
+ }
228
+ catch (error) {
229
+ const errorMessage = `Error executing tool '${toolName}': ${error instanceof Error ? error.message : "Unknown error"}`;
230
+ if (this.debug) {
231
+ console.error(errorMessage);
232
+ }
233
+ const toolError = new AgentError_1.ToolExecutionError(errorMessage, toolName, toolCall.function.arguments);
234
+ this.emit(AgentEvent_1.AgentEvent.TOOL_ERROR, toolError);
235
+ return { toolCallId, content: errorMessage };
236
+ }
237
+ }));
238
+ }
239
+ /**
240
+ * Stream a response as an async generator of `StreamChunk` objects.
241
+ *
242
+ * Yields `{ type: "text" }` for visible output and `{ type: "reasoning" }` for
243
+ * internal reasoning tokens (models that expose `reasoning_content`, e.g. DeepSeek R1).
244
+ * Tool calls are executed transparently — the generator continues streaming after
245
+ * each tool-call round-trip.
246
+ *
247
+ * @example
248
+ * ```typescript
249
+ * for await (const chunk of agent.executeStream("Explain recursion")) {
250
+ * if (chunk.type === "text") process.stdout.write(chunk.content);
251
+ * }
252
+ * ```
253
+ */
254
+ async *executeStream(input) {
255
+ this.emit(AgentEvent_1.AgentEvent.BEFORE_EXECUTE, input);
256
+ this.lastTokenUsage = undefined;
257
+ this.currentToolCallCount = 0;
258
+ const inputPreview = typeof input === "string" ? input : JSON.stringify(input);
259
+ if (VizConfig_1.vizConfig.isEnabled()) {
260
+ this.vizEventId = VizReporter_1.vizReporter.agentStart(this.id, this.name, this.config.model, this.vendor, inputPreview);
261
+ }
262
+ if (this.history.transient) {
263
+ this.history.clear();
264
+ this.addSystemMessage(this.getSystemMessage());
265
+ }
266
+ if (typeof input === "string") {
267
+ this.addTextToHistory("user", input);
268
+ }
269
+ else {
270
+ this.addMessageToHistory("user", input);
271
+ }
272
+ this.history.setSessionAnchor();
273
+ this.history.beginExecution();
274
+ try {
275
+ yield* this.streamTurn();
276
+ }
277
+ catch (error) {
278
+ if (error instanceof openai_1.default.APIError) {
279
+ const apiError = new AgentError_1.ApiError(`${this.getVendorName()} API error: ${error.message}`, error.status, error);
280
+ this.emit(AgentEvent_1.AgentEvent.ERROR, apiError);
281
+ if (this.vizEventId) {
282
+ VizReporter_1.vizReporter.agentError(this.vizEventId, "ApiError", apiError.message, error.status === 429);
283
+ this.vizEventId = undefined;
284
+ }
285
+ throw apiError;
286
+ }
287
+ if (error instanceof AgentError_1.AgentError) {
288
+ this.emit(AgentEvent_1.AgentEvent.ERROR, error);
289
+ if (this.vizEventId) {
290
+ VizReporter_1.vizReporter.agentError(this.vizEventId, error.constructor.name, error.message, false);
291
+ this.vizEventId = undefined;
292
+ }
293
+ throw error;
294
+ }
295
+ const executionError = new AgentError_1.ExecutionError(`${this.getVendorName()} error: ${error instanceof Error ? error.message : "Unknown error"}`);
296
+ this.emit(AgentEvent_1.AgentEvent.ERROR, executionError);
297
+ if (this.vizEventId) {
298
+ VizReporter_1.vizReporter.agentError(this.vizEventId, "ExecutionError", executionError.message, false);
299
+ this.vizEventId = undefined;
300
+ }
301
+ throw executionError;
302
+ }
303
+ finally {
304
+ this.history.endExecution();
305
+ }
306
+ }
307
+ async *streamTurn() {
308
+ const messages = transformers_1.chatCompletionsTransformer.toProvider(this.history.getEntries());
309
+ const tools = this.tools.size > 0 ? this.getToolDefinitions() : undefined;
310
+ const stream = await this.client.chat.completions.create({
311
+ model: this.config.model,
312
+ messages,
313
+ tools,
314
+ stream: true,
315
+ stream_options: { include_usage: true },
316
+ max_tokens: this.config.maxTokens,
317
+ temperature: this.config.temperature,
318
+ top_p: this.config.topP,
319
+ stop: this.config.stopSequences,
320
+ seed: this.config.seed,
321
+ presence_penalty: this.config.presencePenalty,
322
+ frequency_penalty: this.config.frequencyPenalty,
323
+ ...this.buildExtraRequestParams(),
324
+ });
325
+ let textContent = "";
326
+ const toolCallAcc = new Map();
327
+ let finishReason = null;
328
+ for await (const chunk of stream) {
329
+ // Final chunk carrying usage (choices is empty)
330
+ if (chunk.choices.length === 0) {
331
+ if (chunk.usage)
332
+ this.accumulateStreamUsage(chunk.usage);
333
+ continue;
334
+ }
335
+ const choice = chunk.choices[0];
336
+ finishReason = choice.finish_reason ?? finishReason;
337
+ const delta = choice.delta;
338
+ if (delta.content) {
339
+ textContent += delta.content;
340
+ this.emit(AgentEvent_1.AgentEvent.CHUNK, delta.content);
341
+ yield { type: "text", content: delta.content };
342
+ }
343
+ // DeepSeek-style reasoning tokens (not in OpenAI SDK types — cast required)
344
+ const reasoningDelta = delta.reasoning_content;
345
+ if (reasoningDelta) {
346
+ this.emit(AgentEvent_1.AgentEvent.REASONING_CHUNK, reasoningDelta);
347
+ yield { type: "reasoning", content: reasoningDelta };
348
+ }
349
+ if (delta.tool_calls) {
350
+ for (const tc of delta.tool_calls) {
351
+ if (!toolCallAcc.has(tc.index)) {
352
+ toolCallAcc.set(tc.index, { id: "", name: "", arguments: "" });
353
+ }
354
+ const acc = toolCallAcc.get(tc.index);
355
+ if (tc.id)
356
+ acc.id = tc.id;
357
+ if (tc.function?.name)
358
+ acc.name += tc.function.name;
359
+ if (tc.function?.arguments)
360
+ acc.arguments += tc.function.arguments;
361
+ }
362
+ }
363
+ }
364
+ if (finishReason === "length") {
365
+ const error = new AgentError_1.MaxTokensExceededError("Response exceeded maximum token limit", this.config.maxTokens || 1024);
366
+ this.emit(AgentEvent_1.AgentEvent.MAX_TOKENS_EXCEEDED, error);
367
+ this.emit(AgentEvent_1.AgentEvent.ERROR, error);
368
+ if (this.vizEventId) {
369
+ VizReporter_1.vizReporter.agentError(this.vizEventId, "MaxTokensExceededError", error.message, false);
370
+ this.vizEventId = undefined;
371
+ }
372
+ throw error;
373
+ }
374
+ if (finishReason === "tool_calls" && toolCallAcc.size > 0) {
375
+ const toolCalls = Array.from(toolCallAcc.entries())
376
+ .sort(([a], [b]) => a - b)
377
+ .map(([, tc]) => ({
378
+ id: tc.id,
379
+ type: "function",
380
+ function: { name: tc.name, arguments: tc.arguments },
381
+ }));
382
+ this.emit(AgentEvent_1.AgentEvent.TOOL_USE, toolCalls);
383
+ this.currentToolCallCount += toolCalls.length;
384
+ const assistantEntry = transformers_1.chatCompletionsTransformer.fromProviderMessage({
385
+ role: "assistant",
386
+ content: textContent || null,
387
+ tool_calls: toolCalls,
388
+ });
389
+ this.addToHistory(assistantEntry);
390
+ const toolResults = await this.handleToolCalls(toolCalls);
391
+ for (const result of toolResults) {
392
+ this.addToHistory(transformers_1.chatCompletionsTransformer.toolResultEntry(result.toolCallId, result.content));
393
+ }
394
+ yield* this.streamTurn();
395
+ }
396
+ else {
397
+ const assistantEntry = transformers_1.chatCompletionsTransformer.fromProviderMessage({
398
+ role: "assistant",
399
+ content: textContent || null,
400
+ });
401
+ this.addToHistory(assistantEntry);
402
+ this.emit(AgentEvent_1.AgentEvent.DONE, { content: textContent }, this.lastTokenUsage);
403
+ if (this.vizEventId) {
404
+ VizReporter_1.vizReporter.agentComplete(this.vizEventId, {
405
+ input: this.lastTokenUsage?.input_tokens || 0,
406
+ output: this.lastTokenUsage?.output_tokens || 0,
407
+ total: this.lastTokenUsage?.total_tokens || 0,
408
+ }, "end_turn", this.currentToolCallCount > 0, this.currentToolCallCount, textContent);
409
+ this.vizEventId = undefined;
410
+ }
411
+ }
412
+ }
413
+ accumulateStreamUsage(usage) {
414
+ if (!usage)
415
+ return;
416
+ const u = {
417
+ input_tokens: usage.prompt_tokens ?? 0,
418
+ output_tokens: usage.completion_tokens ?? 0,
419
+ total_tokens: usage.total_tokens ?? 0,
420
+ };
421
+ if (this.lastTokenUsage) {
422
+ this.lastTokenUsage.input_tokens += u.input_tokens;
423
+ this.lastTokenUsage.output_tokens += u.output_tokens;
424
+ this.lastTokenUsage.total_tokens += u.total_tokens;
425
+ }
426
+ else {
427
+ this.lastTokenUsage = u;
428
+ }
429
+ }
430
+ parseUsage(response) {
431
+ const usage = response.usage;
432
+ return {
433
+ input_tokens: usage?.prompt_tokens ?? 0,
434
+ output_tokens: usage?.completion_tokens ?? 0,
435
+ total_tokens: usage?.total_tokens ?? 0,
436
+ };
437
+ }
438
+ }
439
+ exports.OpenAICompatibleAgent = OpenAICompatibleAgent;
440
+ //# sourceMappingURL=OpenAICompatibleAgent.js.map
@@ -3,8 +3,8 @@ import { HistoryEntry, MessageRole, MessageContent } from "./types";
3
3
  import type { ReduceOptions } from "./types";
4
4
  /** @internal — exposed for test teardown only */
5
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";
6
+ export type { HistoryEntry, MessageRole, MessageContent, ReduceOptions, ImageMimeType, ImageUrlContent, ImageBase64Content, ThinkingContent, } from "./types";
7
+ export { text, toolUse, toolResult, thinking, textMessage, imageUrl, imageBase64, isTextContent, isToolUseContent, isToolResultContent, isThinkingContent, isImageUrlContent, isImageBase64Content, isImageContent, } from "./types";
8
8
  /**
9
9
  * Metadata stored alongside each history entry.
10
10
  * Extended with summary tracking fields for the compression plugin.
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.History = exports.isImageContent = exports.isImageBase64Content = exports.isImageUrlContent = exports.isToolResultContent = exports.isToolUseContent = exports.isTextContent = exports.imageBase64 = exports.imageUrl = exports.textMessage = exports.toolResult = exports.toolUse = exports.text = void 0;
39
+ exports.History = exports.isImageContent = exports.isImageBase64Content = exports.isImageUrlContent = exports.isThinkingContent = exports.isToolResultContent = exports.isToolUseContent = exports.isTextContent = exports.imageBase64 = exports.imageUrl = exports.textMessage = exports.thinking = exports.toolResult = exports.toolUse = exports.text = void 0;
40
40
  exports.resetTokenxCache = resetTokenxCache;
41
41
  const events_1 = __importDefault(require("events"));
42
42
  const types_1 = require("./types");
@@ -70,12 +70,14 @@ var types_2 = require("./types");
70
70
  Object.defineProperty(exports, "text", { enumerable: true, get: function () { return types_2.text; } });
71
71
  Object.defineProperty(exports, "toolUse", { enumerable: true, get: function () { return types_2.toolUse; } });
72
72
  Object.defineProperty(exports, "toolResult", { enumerable: true, get: function () { return types_2.toolResult; } });
73
+ Object.defineProperty(exports, "thinking", { enumerable: true, get: function () { return types_2.thinking; } });
73
74
  Object.defineProperty(exports, "textMessage", { enumerable: true, get: function () { return types_2.textMessage; } });
74
75
  Object.defineProperty(exports, "imageUrl", { enumerable: true, get: function () { return types_2.imageUrl; } });
75
76
  Object.defineProperty(exports, "imageBase64", { enumerable: true, get: function () { return types_2.imageBase64; } });
76
77
  Object.defineProperty(exports, "isTextContent", { enumerable: true, get: function () { return types_2.isTextContent; } });
77
78
  Object.defineProperty(exports, "isToolUseContent", { enumerable: true, get: function () { return types_2.isToolUseContent; } });
78
79
  Object.defineProperty(exports, "isToolResultContent", { enumerable: true, get: function () { return types_2.isToolResultContent; } });
80
+ Object.defineProperty(exports, "isThinkingContent", { enumerable: true, get: function () { return types_2.isThinkingContent; } });
79
81
  Object.defineProperty(exports, "isImageUrlContent", { enumerable: true, get: function () { return types_2.isImageUrlContent; } });
80
82
  Object.defineProperty(exports, "isImageBase64Content", { enumerable: true, get: function () { return types_2.isImageBase64Content; } });
81
83
  Object.defineProperty(exports, "isImageContent", { enumerable: true, get: function () { return types_2.isImageContent; } });
@@ -1,5 +1,5 @@
1
1
  export { History, resetTokenxCache, type EntryMetadata, type ReducibleEntry, type HistoryPlugin, } from "./History";
2
2
  export { RedisHistory } from "./RedisHistory";
3
- export type { HistoryEntry, MessageRole, MessageContent, TextContent, ToolUseContent, ToolResultContent, ProviderMeta, ReduceOptions, } from "./types";
4
- export { text, toolUse, toolResult, textMessage, isTextContent, isToolUseContent, isToolResultContent, } from "./types";
3
+ export type { HistoryEntry, MessageRole, MessageContent, TextContent, ToolUseContent, ToolResultContent, ThinkingContent, ProviderMeta, ReduceOptions, } from "./types";
4
+ export { text, toolUse, toolResult, thinking, textMessage, isTextContent, isToolUseContent, isToolResultContent, isThinkingContent, } from "./types";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isToolResultContent = exports.isToolUseContent = exports.isTextContent = exports.textMessage = exports.toolResult = exports.toolUse = exports.text = exports.RedisHistory = exports.resetTokenxCache = exports.History = void 0;
3
+ exports.isThinkingContent = exports.isToolResultContent = exports.isToolUseContent = exports.isTextContent = exports.textMessage = exports.thinking = exports.toolResult = exports.toolUse = exports.text = exports.RedisHistory = exports.resetTokenxCache = exports.History = void 0;
4
4
  var History_1 = require("./History");
5
5
  Object.defineProperty(exports, "History", { enumerable: true, get: function () { return History_1.History; } });
6
6
  Object.defineProperty(exports, "resetTokenxCache", { enumerable: true, get: function () { return History_1.resetTokenxCache; } });
@@ -10,8 +10,10 @@ var types_1 = require("./types");
10
10
  Object.defineProperty(exports, "text", { enumerable: true, get: function () { return types_1.text; } });
11
11
  Object.defineProperty(exports, "toolUse", { enumerable: true, get: function () { return types_1.toolUse; } });
12
12
  Object.defineProperty(exports, "toolResult", { enumerable: true, get: function () { return types_1.toolResult; } });
13
+ Object.defineProperty(exports, "thinking", { enumerable: true, get: function () { return types_1.thinking; } });
13
14
  Object.defineProperty(exports, "textMessage", { enumerable: true, get: function () { return types_1.textMessage; } });
14
15
  Object.defineProperty(exports, "isTextContent", { enumerable: true, get: function () { return types_1.isTextContent; } });
15
16
  Object.defineProperty(exports, "isToolUseContent", { enumerable: true, get: function () { return types_1.isToolUseContent; } });
16
17
  Object.defineProperty(exports, "isToolResultContent", { enumerable: true, get: function () { return types_1.isToolResultContent; } });
18
+ Object.defineProperty(exports, "isThinkingContent", { enumerable: true, get: function () { return types_1.isThinkingContent; } });
17
19
  //# sourceMappingURL=index.js.map
@@ -40,6 +40,19 @@ exports.anthropicTransformer = {
40
40
  is_error: block.is_error,
41
41
  };
42
42
  }
43
+ if ((0, types_1.isThinkingContent)(block)) {
44
+ if (block.redactedData !== undefined) {
45
+ return {
46
+ type: "redacted_thinking",
47
+ data: block.redactedData,
48
+ };
49
+ }
50
+ return {
51
+ type: "thinking",
52
+ thinking: block.thinking,
53
+ signature: block.signature ?? "",
54
+ };
55
+ }
43
56
  if ((0, types_1.isImageUrlContent)(block)) {
44
57
  return {
45
58
  type: "image",
@@ -72,7 +85,13 @@ exports.anthropicTransformer = {
72
85
  if (block.type === "tool_use") {
73
86
  return (0, types_1.toolUse)(block.id, block.name, block.input);
74
87
  }
75
- // Handle thinking blocks or other types as text
88
+ if (block.type === "thinking") {
89
+ return (0, types_1.thinking)(block.thinking, block.signature);
90
+ }
91
+ if (block.type === "redacted_thinking") {
92
+ return (0, types_1.thinking)("", undefined, block.data);
93
+ }
94
+ // Unknown / unsupported block — preserve a textual representation
76
95
  return (0, types_1.text)(JSON.stringify(block));
77
96
  });
78
97
  return {
@@ -29,6 +29,20 @@ export type ToolResultContent = {
29
29
  content: string;
30
30
  is_error?: boolean;
31
31
  };
32
+ /**
33
+ * Extended-thinking / reasoning block produced by the assistant (Anthropic).
34
+ *
35
+ * These must be preserved verbatim — including `signature` — and echoed back on
36
+ * the following request when the assistant used a tool, or the provider rejects
37
+ * the turn. `redactedData` is set instead of `thinking` for redacted blocks,
38
+ * whose payload is opaque and must be returned unchanged.
39
+ */
40
+ export type ThinkingContent = {
41
+ type: "thinking";
42
+ thinking: string;
43
+ signature?: string;
44
+ redactedData?: string;
45
+ };
32
46
  /**
33
47
  * Supported image MIME types across all providers
34
48
  */
@@ -56,7 +70,7 @@ export type ImageBase64Content = {
56
70
  /**
57
71
  * Union of all content types
58
72
  */
59
- export type MessageContent = TextContent | ToolUseContent | ToolResultContent | ImageUrlContent | ImageBase64Content;
73
+ export type MessageContent = TextContent | ToolUseContent | ToolResultContent | ThinkingContent | ImageUrlContent | ImageBase64Content;
60
74
  /**
61
75
  * Anthropic-specific metadata
62
76
  */
@@ -149,6 +163,7 @@ export type HistoryEntry = {
149
163
  export declare function isTextContent(content: MessageContent): content is TextContent;
150
164
  export declare function isToolUseContent(content: MessageContent): content is ToolUseContent;
151
165
  export declare function isToolResultContent(content: MessageContent): content is ToolResultContent;
166
+ export declare function isThinkingContent(content: MessageContent): content is ThinkingContent;
152
167
  export declare function isImageUrlContent(content: MessageContent): content is ImageUrlContent;
153
168
  export declare function isImageBase64Content(content: MessageContent): content is ImageBase64Content;
154
169
  export declare function isImageContent(content: MessageContent): content is ImageUrlContent | ImageBase64Content;
@@ -160,6 +175,10 @@ export declare function text(value: string): TextContent;
160
175
  * Create a tool use content block
161
176
  */
162
177
  export declare function toolUse(id: string, name: string, input: Record<string, unknown>): ToolUseContent;
178
+ /**
179
+ * Create a thinking content block. Pass `redactedData` for redacted thinking.
180
+ */
181
+ export declare function thinking(thinkingText: string, signature?: string, redactedData?: string): ThinkingContent;
163
182
  /**
164
183
  * Create a tool result content block
165
184
  */
@@ -9,11 +9,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.isTextContent = isTextContent;
10
10
  exports.isToolUseContent = isToolUseContent;
11
11
  exports.isToolResultContent = isToolResultContent;
12
+ exports.isThinkingContent = isThinkingContent;
12
13
  exports.isImageUrlContent = isImageUrlContent;
13
14
  exports.isImageBase64Content = isImageBase64Content;
14
15
  exports.isImageContent = isImageContent;
15
16
  exports.text = text;
16
17
  exports.toolUse = toolUse;
18
+ exports.thinking = thinking;
17
19
  exports.toolResult = toolResult;
18
20
  exports.textMessage = textMessage;
19
21
  exports.imageUrl = imageUrl;
@@ -30,6 +32,9 @@ function isToolUseContent(content) {
30
32
  function isToolResultContent(content) {
31
33
  return content.type === "tool_result";
32
34
  }
35
+ function isThinkingContent(content) {
36
+ return content.type === "thinking";
37
+ }
33
38
  function isImageUrlContent(content) {
34
39
  return content.type === "image_url";
35
40
  }
@@ -54,6 +59,12 @@ function text(value) {
54
59
  function toolUse(id, name, input) {
55
60
  return { type: "tool_use", id, name, input };
56
61
  }
62
+ /**
63
+ * Create a thinking content block. Pass `redactedData` for redacted thinking.
64
+ */
65
+ function thinking(thinkingText, signature, redactedData) {
66
+ return { type: "thinking", thinking: thinkingText, signature, redactedData };
67
+ }
57
68
  /**
58
69
  * Create a tool result content block
59
70
  */
package/dist/index.d.ts CHANGED
@@ -5,6 +5,8 @@ export { MistralAgent } from "./agents/mistral/MistralAgent";
5
5
  export { GeminiAgent } from "./agents/google/GeminiAgent";
6
6
  export { OllamaAgent } from "./agents/ollama/OllamaAgent";
7
7
  export { LlamaCppAgent } from "./agents/llamacpp/LlamaCppAgent";
8
+ export { OpenAICompatibleAgent } from "./agents/openai-compatible/OpenAICompatibleAgent";
9
+ export type { OpenAICompatibleConfig, StreamChunk } from "./agents/openai-compatible/OpenAICompatibleAgent";
8
10
  export * from "./agents/model-types";
9
11
  export * from "./agents/AgentConfig";
10
12
  export * from "./agents/AgentEvent";
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.chatCompletionsTransformer = exports.ollamaTransformer = exports.geminiTransformer = exports.mistralTransformer = exports.openAiTransformer = exports.anthropicTransformer = exports.LlamaCppAgent = exports.OllamaAgent = exports.GeminiAgent = exports.MistralAgent = exports.OpenAiAgent = void 0;
25
+ exports.chatCompletionsTransformer = exports.ollamaTransformer = exports.geminiTransformer = exports.mistralTransformer = exports.openAiTransformer = exports.anthropicTransformer = exports.OpenAICompatibleAgent = exports.LlamaCppAgent = 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);
@@ -36,6 +36,8 @@ var OllamaAgent_1 = require("./agents/ollama/OllamaAgent");
36
36
  Object.defineProperty(exports, "OllamaAgent", { enumerable: true, get: function () { return OllamaAgent_1.OllamaAgent; } });
37
37
  var LlamaCppAgent_1 = require("./agents/llamacpp/LlamaCppAgent");
38
38
  Object.defineProperty(exports, "LlamaCppAgent", { enumerable: true, get: function () { return LlamaCppAgent_1.LlamaCppAgent; } });
39
+ var OpenAICompatibleAgent_1 = require("./agents/openai-compatible/OpenAICompatibleAgent");
40
+ Object.defineProperty(exports, "OpenAICompatibleAgent", { enumerable: true, get: function () { return OpenAICompatibleAgent_1.OpenAICompatibleAgent; } });
39
41
  __exportStar(require("./agents/model-types"), exports);
40
42
  __exportStar(require("./agents/AgentConfig"), exports);
41
43
  __exportStar(require("./agents/AgentEvent"), exports);
@@ -187,7 +187,7 @@ class IngestionPipeline {
187
187
  await this.store.addEmbeddedDocuments(embeddedDocs);
188
188
  result.chunksStored += embeddedDocs.length;
189
189
  }
190
- catch (error) {
190
+ catch {
191
191
  // Try storing one by one to identify problematic chunks
192
192
  for (let i = 0; i < embeddedDocs.length; i++) {
193
193
  try {