agentblit 0.1.4 → 0.1.6
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 +26 -2
- package/dist/index.cjs +105 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -4
- package/dist/index.d.ts +28 -4
- package/dist/index.js +105 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -45,6 +45,28 @@ for await (const chunk of agent.run("What is 200 + 30? Use tools if needed.")) {
|
|
|
45
45
|
process.stdout.write("\n");
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
## Multimodal Input (OpenAI Content Parts)
|
|
49
|
+
|
|
50
|
+
`agent.run(...)` accepts:
|
|
51
|
+
- a plain string (existing behavior), or
|
|
52
|
+
- OpenAI-style content parts (`text`, `image_url`, `file`), or
|
|
53
|
+
- an object with a `content` field containing either of the above.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
const input = [
|
|
57
|
+
{ type: "text", text: "What do you see in this image?" },
|
|
58
|
+
{
|
|
59
|
+
type: "image_url",
|
|
60
|
+
image_url: { url: "https://example.com/sample.png", detail: "auto" },
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
for await (const chunk of agent.run(input)) {
|
|
65
|
+
// Output stream stays text chunks.
|
|
66
|
+
process.stdout.write(chunk);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
48
70
|
---
|
|
49
71
|
|
|
50
72
|
## 1) Agent Initialization Configs
|
|
@@ -72,10 +94,11 @@ process.stdout.write("\n");
|
|
|
72
94
|
## 2) All SDK Features
|
|
73
95
|
|
|
74
96
|
- Vendor routing for `openai`, `anthropic`, `gemini`, and `openrouter`
|
|
75
|
-
- Remote AgentBlit tools (`/api/tools/list`, `/api/tools/call`)
|
|
97
|
+
- Remote AgentBlit tools (`/api/1.0/tools/list`, `/api/1.0/tools/call`)
|
|
76
98
|
- Local tools via `tool(...)` and `customTools` / `registerTool(...)`
|
|
77
99
|
- Approval-gated tools (`needs_approval`) via callback or terminal prompt
|
|
78
|
-
-
|
|
100
|
+
- OpenAI-native multimodal inputs (`text`, `image_url`, `file`)
|
|
101
|
+
- Streaming text responses with `for await (const chunk of agent.run(...))`
|
|
79
102
|
- Multi-round tool calling in one `run()`
|
|
80
103
|
- Memory summarization using `maxHistory`
|
|
81
104
|
- Default system guidance to use tools and available long-term memory tools (`retrieveRelevantMemory`, `updateMemory`) when needed
|
|
@@ -119,3 +142,4 @@ const agent = new Agent({
|
|
|
119
142
|
|
|
120
143
|
- [`examples/basic-agent.ts`](examples/basic-agent.ts) - interactive terminal chat with remote tools.
|
|
121
144
|
- [`examples/custom-tools.ts`](examples/custom-tools.ts) - local TypeScript tools + AgentBlit tools.
|
|
145
|
+
- [`examples/multimodal-input.ts`](examples/multimodal-input.ts) - OpenAI-style multimodal input with text stream output.
|
package/dist/index.cjs
CHANGED
|
@@ -213,7 +213,7 @@ var ToolRegistry = class {
|
|
|
213
213
|
});
|
|
214
214
|
}
|
|
215
215
|
async refreshRemote() {
|
|
216
|
-
const url = `${this.baseUrl}/api/tools/list`;
|
|
216
|
+
const url = `${this.baseUrl}/api/1.0/tools/list`;
|
|
217
217
|
const response = await fetch(url, {
|
|
218
218
|
method: "GET",
|
|
219
219
|
headers: { "X-API-Key": this.apiKey },
|
|
@@ -225,24 +225,25 @@ var ToolRegistry = class {
|
|
|
225
225
|
);
|
|
226
226
|
}
|
|
227
227
|
const data = await response.json();
|
|
228
|
-
if (!data.ok) {
|
|
229
|
-
throw new Error("tools/list returned ok=false");
|
|
230
|
-
}
|
|
231
228
|
this.remote.clear();
|
|
232
229
|
for (const toolItem of data.tools ?? []) {
|
|
233
|
-
const
|
|
230
|
+
const type = String(toolItem.type ?? "");
|
|
231
|
+
if (type !== "function") {
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
const fn = toolItem.function ?? {};
|
|
235
|
+
const name = String(fn.name ?? "");
|
|
234
236
|
if (!name) {
|
|
235
237
|
continue;
|
|
236
238
|
}
|
|
237
239
|
this.remote.set(name, {
|
|
238
240
|
name,
|
|
239
|
-
description: String(
|
|
240
|
-
inputSchema:
|
|
241
|
+
description: String(fn.description ?? ""),
|
|
242
|
+
inputSchema: fn.parameters ?? {
|
|
241
243
|
type: "object",
|
|
242
244
|
properties: {}
|
|
243
245
|
},
|
|
244
|
-
permissionMode: String(toolItem.
|
|
245
|
-
outputSchema: toolItem.outputSchema
|
|
246
|
+
permissionMode: String(toolItem.permission_mode ?? "always_allow") === "needs_approval" ? "needs_approval" : "always_allow"
|
|
246
247
|
});
|
|
247
248
|
}
|
|
248
249
|
}
|
|
@@ -317,7 +318,10 @@ var ToolRegistry = class {
|
|
|
317
318
|
}
|
|
318
319
|
]
|
|
319
320
|
};
|
|
320
|
-
|
|
321
|
+
if (!toolCallId.trim()) {
|
|
322
|
+
return jsonDumpsSafe({ error: "Missing tool_call_id" });
|
|
323
|
+
}
|
|
324
|
+
const url = `${this.baseUrl}/api/1.0/tools/call`;
|
|
321
325
|
const response = await fetch(url, {
|
|
322
326
|
method: "POST",
|
|
323
327
|
headers: {
|
|
@@ -333,26 +337,17 @@ var ToolRegistry = class {
|
|
|
333
337
|
);
|
|
334
338
|
}
|
|
335
339
|
const data = await response.json();
|
|
336
|
-
if (!data.ok) {
|
|
337
|
-
return jsonDumpsSafe({ error: data });
|
|
338
|
-
}
|
|
339
340
|
const result = (data.results ?? []).find((item) => item.tool_call_id === toolCallId);
|
|
340
341
|
if (!result) {
|
|
341
342
|
return jsonDumpsSafe({ error: "No result for tool_call_id" });
|
|
342
343
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
return jsonDumpsSafe({ error: "Missing tool result payload" });
|
|
344
|
+
if (typeof result.error !== "undefined") {
|
|
345
|
+
return jsonDumpsSafe({ error: result.error });
|
|
346
346
|
}
|
|
347
|
-
if (
|
|
348
|
-
|
|
349
|
-
return jsonDumpsSafe({ error: text2 || "Tool error" });
|
|
347
|
+
if (typeof result.result !== "undefined") {
|
|
348
|
+
return jsonDumpsSafe(result.result);
|
|
350
349
|
}
|
|
351
|
-
|
|
352
|
-
return jsonDumpsSafe(toolResult.structuredContent);
|
|
353
|
-
}
|
|
354
|
-
const text = (toolResult.content ?? []).map((part) => part.text ?? "").join("");
|
|
355
|
-
return jsonDumpsSafe({ result: text });
|
|
350
|
+
return jsonDumpsSafe({ error: "Missing result or error for tool_call_id" });
|
|
356
351
|
}
|
|
357
352
|
};
|
|
358
353
|
|
|
@@ -406,9 +401,88 @@ function formatMessagesForSummary(messages) {
|
|
|
406
401
|
if (message.role === "assistant" && message.tool_calls) {
|
|
407
402
|
return `[${index}] assistant (tool_calls): ${jsonDumpsSafe(message.tool_calls)}`;
|
|
408
403
|
}
|
|
409
|
-
return `[${index}] ${message.role}: ${message.content
|
|
404
|
+
return `[${index}] ${message.role}: ${serializeContentForSummary(message.content)}`;
|
|
410
405
|
}).join("\n");
|
|
411
406
|
}
|
|
407
|
+
function serializeContentForSummary(content) {
|
|
408
|
+
if (content === null || content === void 0) {
|
|
409
|
+
return "";
|
|
410
|
+
}
|
|
411
|
+
if (typeof content === "string") {
|
|
412
|
+
return content;
|
|
413
|
+
}
|
|
414
|
+
const parts = [];
|
|
415
|
+
for (const part of content) {
|
|
416
|
+
if (part.type === "text") {
|
|
417
|
+
parts.push(part.text);
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
if (part.type === "image_url") {
|
|
421
|
+
parts.push(`[image: ${part.image_url.url}]`);
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
if (part.type === "file") {
|
|
425
|
+
parts.push(`[file: ${part.file.file_id ?? part.file.filename ?? "inline_data"}]`);
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
parts.push("[unsupported_content_part]");
|
|
429
|
+
}
|
|
430
|
+
return parts.join(" ").trim();
|
|
431
|
+
}
|
|
432
|
+
function isObject(value) {
|
|
433
|
+
return typeof value === "object" && value !== null;
|
|
434
|
+
}
|
|
435
|
+
function validateInputContentParts(parts) {
|
|
436
|
+
for (const part of parts) {
|
|
437
|
+
if (part.type === "text") {
|
|
438
|
+
if (typeof part.text !== "string") {
|
|
439
|
+
throw new Error("Text content part must include a string 'text' field.");
|
|
440
|
+
}
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
if (part.type === "image_url") {
|
|
444
|
+
if (!part.image_url || typeof part.image_url.url !== "string") {
|
|
445
|
+
throw new Error(
|
|
446
|
+
"Image content part must include image_url.url as a string."
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
continue;
|
|
450
|
+
}
|
|
451
|
+
if (part.type === "file") {
|
|
452
|
+
const file = part.file;
|
|
453
|
+
if (!file || !file.file_id && !file.file_data) {
|
|
454
|
+
throw new Error(
|
|
455
|
+
"File content part must include at least one of file.file_id or file.file_data."
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
throw new Error(
|
|
461
|
+
"Unsupported content part type. Supported types: text, image_url, file."
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
return parts;
|
|
465
|
+
}
|
|
466
|
+
function normalizeRunInput(userInput) {
|
|
467
|
+
if (typeof userInput === "string") {
|
|
468
|
+
return userInput;
|
|
469
|
+
}
|
|
470
|
+
if (Array.isArray(userInput)) {
|
|
471
|
+
return validateInputContentParts(userInput);
|
|
472
|
+
}
|
|
473
|
+
if (isObject(userInput)) {
|
|
474
|
+
const { content } = userInput;
|
|
475
|
+
if (typeof content === "string") {
|
|
476
|
+
return content;
|
|
477
|
+
}
|
|
478
|
+
if (Array.isArray(content)) {
|
|
479
|
+
return validateInputContentParts(content);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
throw new Error(
|
|
483
|
+
"run input must be a string, an array of OpenAI content parts, or an object with a content field."
|
|
484
|
+
);
|
|
485
|
+
}
|
|
412
486
|
var Agent = class {
|
|
413
487
|
vendor;
|
|
414
488
|
model;
|
|
@@ -573,11 +647,12 @@ var Agent = class {
|
|
|
573
647
|
});
|
|
574
648
|
return response.choices[0]?.message?.content?.trim() ?? "";
|
|
575
649
|
}
|
|
576
|
-
async *run(
|
|
650
|
+
async *run(userInput) {
|
|
577
651
|
const events = [...this.pendingCustomEvents];
|
|
578
652
|
this.pendingCustomEvents.length = 0;
|
|
579
653
|
try {
|
|
580
|
-
|
|
654
|
+
const userContent = normalizeRunInput(userInput);
|
|
655
|
+
this.memory.append({ role: "user", content: userContent });
|
|
581
656
|
await this.tools.refreshRemote();
|
|
582
657
|
const openaiTools = this.tools.toOpenAITools();
|
|
583
658
|
const toolsSignature = jsonDumpsSafe(openaiTools);
|
|
@@ -597,7 +672,7 @@ var Agent = class {
|
|
|
597
672
|
events.push(
|
|
598
673
|
this.makeEvent({
|
|
599
674
|
eventType: "user_prompt",
|
|
600
|
-
data: { request: { message:
|
|
675
|
+
data: { request: { message: userContent }, response: null }
|
|
601
676
|
})
|
|
602
677
|
);
|
|
603
678
|
let finishedNormally = false;
|
|
@@ -753,9 +828,9 @@ var Agent = class {
|
|
|
753
828
|
* Runs the agent to completion and returns the full assistant text (concatenated stream chunks).
|
|
754
829
|
* Same behavior as iterating {@link Agent.run}; use when you do not need incremental output.
|
|
755
830
|
*/
|
|
756
|
-
async runSync(
|
|
831
|
+
async runSync(userInput) {
|
|
757
832
|
let text = "";
|
|
758
|
-
for await (const chunk of this.run(
|
|
833
|
+
for await (const chunk of this.run(userInput)) {
|
|
759
834
|
text += chunk;
|
|
760
835
|
}
|
|
761
836
|
return text;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/agent.ts","../src/memory.ts","../src/utils.ts","../src/tools.ts"],"sourcesContent":["export { Agent } from \"./agent.js\";\nexport { ChatMemory } from \"./memory.js\";\nexport { tool, ToolRegistry } from \"./tools.js\";\nexport type {\n AgentConfig,\n AgentOptions,\n ApprovalCallback,\n ChatMessage,\n JSONSchema,\n OpenAIToolCall,\n SummarizeFn,\n ToolDefinition,\n ToolHandler,\n ToolOptions,\n ToolPermissionMode,\n} from \"./types.js\";\n","import OpenAI from \"openai\";\nimport { randomUUID } from \"node:crypto\";\nimport { ChatMemory } from \"./memory.js\";\nimport {\n AgentConfig,\n AgentOptions,\n ChatMessage,\n OpenAIToolCall,\n ToolHandler,\n} from \"./types.js\";\nimport { ToolRegistry } from \"./tools.js\";\nimport { DebugLogger, jsonDumpsSafe, nowIsoTimestamp, randomId } from \"./utils.js\";\n\nconst VENDOR_BASE_URLS: Record<string, string> = {\n openai: \"https://api.openai.com/v1\",\n anthropic: \"https://api.anthropic.com/v1\",\n gemini: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n openrouter: \"https://openrouter.ai/api/v1\",\n};\n\nconst DEFAULT_TOOL_USAGE_INSTRUCTION =\n \"Use tools when they help answer accurately.\";\n\nfunction resolveVendorAndModel(modelInput: string): { vendor: string; model: string } {\n const model = modelInput.trim();\n if (!model || !model.includes(\"/\")) {\n throw new Error(\n \"model must be in the format 'vendor/model', for example 'openai/gpt-4o-mini'.\",\n );\n }\n const [vendorRaw, ...rest] = model.split(\"/\");\n const vendor = (vendorRaw ?? \"\").trim().toLowerCase();\n const providerModel = rest.join(\"/\").trim();\n if (!vendor || !providerModel) {\n throw new Error(\n \"model must be in the format 'vendor/model', for example 'openai/gpt-4o-mini'.\",\n );\n }\n return { vendor, model: providerModel };\n}\n\nfunction resolveLlmUrl(vendor: string): string {\n const url = VENDOR_BASE_URLS[vendor];\n if (!url) {\n const supported = Object.keys(VENDOR_BASE_URLS).sort().join(\", \");\n throw new Error(`Unsupported model vendor '${vendor}'. Supported vendors: ${supported}.`);\n }\n return url;\n}\n\nfunction composeSystemPrompt(systemPrompt: string): string {\n const userPrompt = systemPrompt.trim();\n if (userPrompt.toLowerCase().includes(DEFAULT_TOOL_USAGE_INSTRUCTION.toLowerCase())) {\n return userPrompt;\n }\n if (!userPrompt) {\n return DEFAULT_TOOL_USAGE_INSTRUCTION;\n }\n return `${userPrompt}\\n\\n${DEFAULT_TOOL_USAGE_INSTRUCTION}`;\n}\n\nfunction formatMessagesForSummary(messages: ChatMessage[]): string {\n return messages\n .map((message, index) => {\n if (message.role === \"assistant\" && message.tool_calls) {\n return `[${index}] assistant (tool_calls): ${jsonDumpsSafe(message.tool_calls)}`;\n }\n return `[${index}] ${message.role}: ${message.content ?? \"\"}`;\n })\n .join(\"\\n\");\n}\n\ninterface EventPayload {\n id: string;\n session_id: string;\n agent_id: string;\n timestamp: string;\n type: string;\n data: unknown;\n tokens: number;\n latency_ms: number;\n}\n\nexport class Agent {\n readonly vendor: string;\n readonly model: string;\n readonly llmUrl: string;\n readonly agentId: string;\n readonly sessionId: string;\n readonly config: AgentConfig;\n readonly memory: ChatMemory;\n\n private readonly client: OpenAI;\n private readonly tools: ToolRegistry;\n private readonly systemPrompt: string;\n private readonly timeout: number;\n private readonly debug: DebugLogger;\n private readonly approvalCallback?: AgentOptions[\"approvalCallback\"];\n private readonly maxToolRounds: number;\n private readonly eventBaseUrl: string;\n private readonly eventApiKey: string;\n private readonly pendingCustomEvents: EventPayload[] = [];\n private agentInitSent = false;\n private toolsSignature?: string;\n\n constructor(options: AgentOptions) {\n const agentblitApiKey = options.agentblitApiKey.trim();\n if (!agentblitApiKey) {\n throw new Error(\"agentblitApiKey is required\");\n }\n const maxHistory = options.maxHistory ?? 5;\n if (maxHistory < 1) {\n throw new Error(\"maxHistory must be at least 1\");\n }\n const maxToolRounds = options.maxToolRounds ?? 25;\n if (maxToolRounds < 1) {\n throw new Error(\"maxToolRounds must be at least 1\");\n }\n\n const { vendor, model } = resolveVendorAndModel(options.model);\n const llmUrl = resolveLlmUrl(vendor);\n const timeoutSeconds = options.timeout ?? 30;\n const timeoutMs = timeoutSeconds * 1000;\n const agentblitUrl = (options.agentblitUrl ?? \"https://console.agentblit.com\").replace(/\\/$/, \"\");\n const systemPrompt = composeSystemPrompt(options.systemPrompt ?? options.system_prompt ?? \"\");\n\n this.vendor = vendor;\n this.model = model;\n this.llmUrl = llmUrl;\n this.systemPrompt = systemPrompt;\n this.timeout = timeoutMs;\n this.approvalCallback = options.approvalCallback;\n this.maxToolRounds = maxToolRounds;\n this.agentId = options.agentId?.trim() || randomUUID();\n this.sessionId = randomUUID();\n this.eventBaseUrl = agentblitUrl;\n this.eventApiKey = agentblitApiKey;\n this.debug = new DebugLogger(Boolean(options.debug));\n\n this.client = new OpenAI({\n apiKey: options.apiKey,\n baseURL: llmUrl,\n timeout: timeoutMs,\n });\n this.tools = new ToolRegistry({\n baseUrl: agentblitUrl,\n apiKey: agentblitApiKey,\n timeout: timeoutMs,\n });\n for (const customTool of options.customTools ?? []) {\n this.registerTool(customTool);\n }\n this.memory = new ChatMemory({\n maxHistory,\n summarizeFn: (older) => this.summarizeOlderMessages(older),\n });\n this.config = Object.freeze({\n model: this.model,\n vendor: this.vendor,\n llmUrl: this.llmUrl,\n agentblitUrl: this.eventBaseUrl,\n systemPrompt: this.systemPrompt,\n maxHistory,\n debug: Boolean(options.debug),\n timeout: timeoutSeconds,\n agentId: this.agentId,\n sessionId: this.sessionId,\n });\n }\n\n registerTool(fn: ToolHandler): void {\n this.tools.register(fn);\n }\n\n track(eventType: string, properties: Record<string, unknown>): void {\n this.pendingCustomEvents.push(this.makeEvent({ eventType, data: properties }));\n }\n\n private makeEvent(input: {\n eventType: string;\n data: unknown;\n tokens?: number;\n latencyMs?: number;\n }): EventPayload {\n return {\n id: randomId(\"evt\"),\n session_id: this.sessionId,\n agent_id: this.agentId,\n timestamp: nowIsoTimestamp(),\n type: input.eventType,\n data: input.data,\n tokens: Math.max(0, Math.trunc(input.tokens ?? 0)),\n latency_ms: Math.max(0, Math.trunc(input.latencyMs ?? 0)),\n };\n }\n\n private async flushEvents(events: EventPayload[]): Promise<void> {\n if (events.length === 0) {\n return;\n }\n const url = `${this.eventBaseUrl}/api/events/batch`;\n this.debug.log(\"Event batch send start url=%s count=%s\", url, events.length);\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-API-Key\": this.eventApiKey,\n \"Content-Type\": \"application/json\",\n },\n body: jsonDumpsSafe({ events }),\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!response.ok) {\n const body = (await response.text()).slice(0, 1000);\n this.debug.log(\n \"Failed to send events batch status=%s body=%s\",\n response.status,\n body,\n );\n return;\n }\n this.debug.log(\"Event batch send success status=%s count=%s\", response.status, events.length);\n } catch (error) {\n this.debug.log(\"Failed to send events batch: %s\", String(error));\n }\n }\n\n private extractLlmEventMessages(messages: ChatMessage[]): ChatMessage[] {\n if (messages.length === 0) {\n return [];\n }\n const summaryMessage = messages.find(\n (message) =>\n message.role === \"system\" &&\n typeof message.content === \"string\" &&\n message.content.startsWith(\"Summary of earlier conversation:\"),\n );\n const lastMessage = messages[messages.length - 1];\n if (!lastMessage) {\n return [];\n }\n if (!summaryMessage) {\n return [lastMessage];\n }\n if (summaryMessage === lastMessage) {\n return [summaryMessage];\n }\n return [summaryMessage, lastMessage];\n }\n\n private async summarizeOlderMessages(older: ChatMessage[]): Promise<string> {\n const text = formatMessagesForSummary(older);\n this.debug.log(\"Summarizing %s older messages\", older.length);\n const response = await this.client.chat.completions.create({\n model: this.model,\n messages: [\n {\n role: \"system\",\n content:\n \"Summarize the conversation excerpt below for use as memory. Preserve key facts, decisions, and tool outcomes. Be concise.\",\n },\n { role: \"user\", content: text },\n ],\n temperature: 0.2,\n });\n return response.choices[0]?.message?.content?.trim() ?? \"\";\n }\n\n async *run(userMessage: string): AsyncGenerator<string> {\n const events: EventPayload[] = [...this.pendingCustomEvents];\n this.pendingCustomEvents.length = 0;\n try {\n this.memory.append({ role: \"user\", content: userMessage });\n await this.tools.refreshRemote();\n const openaiTools = this.tools.toOpenAITools();\n const toolsSignature = jsonDumpsSafe(openaiTools);\n if (!this.agentInitSent) {\n events.push(\n this.makeEvent({\n eventType: \"agent_init\",\n data: { system_prompt: this.systemPrompt, tools: openaiTools },\n }),\n );\n this.agentInitSent = true;\n this.toolsSignature = toolsSignature;\n } else if (toolsSignature !== this.toolsSignature) {\n events.push(this.makeEvent({ eventType: \"tools_updated\", data: { tools: openaiTools } }));\n this.toolsSignature = toolsSignature;\n }\n events.push(\n this.makeEvent({\n eventType: \"user_prompt\",\n data: { request: { message: userMessage }, response: null },\n }),\n );\n\n let finishedNormally = false;\n for (let round = 0; round < this.maxToolRounds; round += 1) {\n const messages = await this.memory.buildMessagesForLLM(this.systemPrompt);\n this.debug.logLLMRequest(this.model, messages.length, openaiTools.length);\n const llmRequest = {\n model: this.model,\n messages: messages as any,\n stream: true as const,\n ...(openaiTools.length > 0 ? { tools: openaiTools } : {}),\n ...(this.vendor === \"openai\" || this.vendor === \"openrouter\"\n ? { stream_options: { include_usage: true } }\n : {}),\n };\n\n const llmEventRequestData = {\n model: this.model,\n messages: this.extractLlmEventMessages(messages) as any,\n stream: true,\n };\n\n const startedAt = Date.now();\n const stream = (await this.client.chat.completions.create(\n llmRequest as any,\n )) as unknown as AsyncIterable<any>;\n\n const contentParts: string[] = [];\n const toolCallsMap = new Map<\n number,\n { id: string; name: string; arguments: string }\n >();\n let finishReason: string | null = null;\n let llmTotalTokens = 0;\n\n for await (const chunk of stream) {\n if (chunk.usage?.total_tokens) {\n llmTotalTokens = chunk.usage.total_tokens;\n }\n const choice = chunk.choices?.[0];\n if (!choice) {\n continue;\n }\n if (choice.finish_reason) {\n finishReason = choice.finish_reason;\n }\n const delta = choice.delta;\n if (!delta) {\n continue;\n }\n if (delta.content) {\n contentParts.push(delta.content);\n yield delta.content;\n }\n for (const toolCall of delta.tool_calls ?? []) {\n const index = toolCall.index ?? 0;\n const existing = toolCallsMap.get(index) ?? { id: \"\", name: \"\", arguments: \"\" };\n if (toolCall.id) {\n existing.id = toolCall.id;\n }\n if (toolCall.function?.name) {\n existing.name = toolCall.function.name;\n }\n if (toolCall.function?.arguments) {\n existing.arguments += toolCall.function.arguments;\n }\n toolCallsMap.set(index, existing);\n }\n }\n\n const assistantContent = contentParts.join(\"\") || null;\n const llmLatencyMs = Date.now() - startedAt;\n const toolCalls = [...toolCallsMap.entries()]\n .sort(([a], [b]) => a - b)\n .map(([, call]): OpenAIToolCall => ({\n id: call.id,\n type: \"function\",\n function: {\n name: call.name,\n arguments: call.arguments || \"{}\",\n },\n }));\n\n events.push(\n this.makeEvent({\n eventType: \"llm_call\",\n data: {\n request: llmEventRequestData,\n response: {\n finish_reason: finishReason,\n content: assistantContent,\n tool_calls: toolCalls,\n },\n },\n tokens: llmTotalTokens,\n latencyMs: llmLatencyMs,\n }),\n );\n\n if (finishReason === \"tool_calls\" || toolCalls.length > 0) {\n this.debug.logToolCalls(toolCalls);\n this.memory.append({\n role: \"assistant\",\n content: assistantContent,\n tool_calls: toolCalls,\n });\n\n for (const toolCall of toolCalls) {\n const toolStartedAt = Date.now();\n const result = await this.tools.execute(\n toolCall.id,\n toolCall.function.name,\n toolCall.function.arguments,\n this.approvalCallback,\n );\n const toolLatencyMs = Date.now() - toolStartedAt;\n this.debug.logToolResult(toolCall.id, true, result);\n let parsedResponse: unknown;\n try {\n parsedResponse = JSON.parse(result);\n } catch {\n parsedResponse = { raw: result };\n }\n events.push(\n this.makeEvent({\n eventType: \"tool_call\",\n data: {\n request: toolCall,\n response: parsedResponse,\n },\n latencyMs: toolLatencyMs,\n }),\n );\n this.memory.append({\n role: \"tool\",\n tool_call_id: toolCall.id,\n content: result,\n });\n }\n continue;\n }\n\n this.memory.append({\n role: \"assistant\",\n content: assistantContent ?? \"\",\n });\n finishedNormally = true;\n break;\n }\n\n if (!finishedNormally) {\n throw new Error(\n `Exceeded maxToolRounds (${this.maxToolRounds}); increase maxToolRounds or simplify the task.`,\n );\n }\n } catch (error) {\n events.push(\n this.makeEvent({\n eventType: \"agent_loop_error\",\n data: { error: error instanceof Error ? error.message : String(error) },\n }),\n );\n throw error;\n } finally {\n this.debug.log(\"Queueing event flush count=%s\", events.length);\n await this.flushEvents(events);\n }\n }\n\n /**\n * Runs the agent to completion and returns the full assistant text (concatenated stream chunks).\n * Same behavior as iterating {@link Agent.run}; use when you do not need incremental output.\n */\n async runSync(userMessage: string): Promise<string> {\n let text = \"\";\n for await (const chunk of this.run(userMessage)) {\n text += chunk;\n }\n return text;\n }\n}\n","import { ChatMessage, SummarizeFn } from \"./types.js\";\n\nexport class ChatMemory {\n private readonly messagesStore: ChatMessage[] = [];\n private readonly maxHistory: number;\n private readonly summarizeFn?: SummarizeFn;\n\n constructor(options?: { maxHistory?: number; summarizeFn?: SummarizeFn }) {\n const maxHistory = options?.maxHistory ?? 5;\n if (maxHistory < 1) {\n throw new Error(\"maxHistory must be at least 1\");\n }\n this.maxHistory = maxHistory;\n this.summarizeFn = options?.summarizeFn;\n }\n\n get messages(): ChatMessage[] {\n return [...this.messagesStore];\n }\n\n append(message: ChatMessage): void {\n this.messagesStore.push(message);\n }\n\n extend(messages: ChatMessage[]): void {\n this.messagesStore.push(...messages);\n }\n\n clear(): void {\n this.messagesStore.length = 0;\n }\n\n async buildMessagesForLLM(systemPrompt: string): Promise<ChatMessage[]> {\n const out: ChatMessage[] = [{ role: \"system\", content: systemPrompt }];\n if (this.messagesStore.length <= this.maxHistory) {\n out.push(...this.messagesStore);\n return out;\n }\n\n const older = this.messagesStore.slice(0, -this.maxHistory);\n const recent = this.messagesStore.slice(-this.maxHistory);\n let summaryText: string;\n if (!this.summarizeFn) {\n summaryText = `[Earlier conversation truncated: ${older.length} message(s) not shown. Provide summarizeFn on Agent to compress older context with the LLM.]`;\n } else {\n summaryText = await this.summarizeFn(older);\n }\n out.push({\n role: \"system\",\n content: `Summary of earlier conversation:\\n${summaryText}`,\n });\n out.push(...recent);\n return out;\n }\n}\n","import process from \"node:process\";\nimport { randomUUID } from \"node:crypto\";\nimport { ToolHandler, ToolOptions } from \"./types.js\";\n\nconst LOGGER_PREFIX = \"[agentblit]\";\n\nexport class DebugLogger {\n constructor(private readonly enabled: boolean) {}\n\n log(message: string, ...args: unknown[]): void {\n if (!this.enabled) {\n return;\n }\n console.debug(`${LOGGER_PREFIX} ${message}`, ...args);\n }\n\n logLLMRequest(model: string, messageCount: number, toolCount: number): void {\n this.log(\"LLM request model=%s messages=%s tools=%s\", model, messageCount, toolCount);\n }\n\n logToolCalls(calls: unknown[]): void {\n this.log(\"Tool calls: %s\", jsonDumpsSafe(calls));\n }\n\n logToolResult(toolCallId: string, ok: boolean, preview: string): void {\n this.log(\"Tool result id=%s ok=%s preview=%s\", toolCallId, ok, preview.slice(0, 500));\n }\n}\n\nexport function jsonDumpsSafe(obj: unknown): string {\n return JSON.stringify(obj, (_key, value) => {\n if (value instanceof Error) {\n return {\n name: value.name,\n message: value.message,\n stack: value.stack,\n };\n }\n return value;\n });\n}\n\nfunction extractParamNames(fn: ToolHandler): string[] {\n const source = fn.toString();\n const match = source.match(/\\(([^)]*)\\)/);\n if (!match) {\n return [];\n }\n const rawParams = match[1] ?? \"\";\n return rawParams\n .split(\",\")\n .map((segment) => segment.trim())\n .filter(Boolean)\n .map((segment) => segment.replace(/=[\\s\\S]*$/, \"\").trim())\n .map((segment) => segment.replace(/^\\.{3}/, \"\"))\n .filter((segment) => segment !== \"this\");\n}\n\nexport function functionToToolSchema(fn: ToolHandler, explicitSchema?: Record<string, unknown>): Record<string, unknown> {\n if (explicitSchema) {\n return explicitSchema;\n }\n const properties = Object.fromEntries(\n extractParamNames(fn).map((name) => [name, { type: \"string\" }]),\n );\n const required = Object.keys(properties);\n return {\n type: \"object\",\n properties,\n ...(required.length > 0 ? { required } : {}),\n };\n}\n\nexport const TOOL_META = Symbol.for(\"agentblit.tool.meta\");\n\nexport interface ToolMetadata extends Required<Pick<ToolOptions, \"name\" | \"description\" | \"permissionMode\">> {\n inputSchema?: Record<string, unknown>;\n}\n\nexport function setToolMetadata(fn: ToolHandler, options: ToolOptions): ToolHandler {\n const metadata: ToolMetadata = {\n name: options.name ?? fn.name,\n description: options.description ?? \"\",\n permissionMode: options.permissionMode ?? \"always_allow\",\n inputSchema: options.inputSchema,\n };\n (fn as ToolHandler & { [TOOL_META]?: ToolMetadata })[TOOL_META] = metadata;\n return fn;\n}\n\nexport function getToolMetadata(fn: ToolHandler): ToolMetadata | undefined {\n return (fn as ToolHandler & { [TOOL_META]?: ToolMetadata })[TOOL_META];\n}\n\nexport function nowIsoTimestamp(): string {\n return new Date().toISOString();\n}\n\nexport function randomId(prefix: string): string {\n return `${prefix}_${randomUUID().replace(/-/g, \"\")}`;\n}\n\nexport function readStdinLine(promptText: string): Promise<string> {\n return new Promise((resolve) => {\n process.stdout.write(promptText);\n process.stdin.resume();\n process.stdin.once(\"data\", (chunk) => {\n resolve(String(chunk).trim());\n });\n });\n}\n","import {\n ApprovalCallback,\n OpenAIToolCall,\n ToolDefinition,\n ToolHandler,\n ToolOptions,\n} from \"./types.js\";\nimport {\n functionToToolSchema,\n getToolMetadata,\n jsonDumpsSafe,\n readStdinLine,\n setToolMetadata,\n} from \"./utils.js\";\n\ninterface ToolsListResponse {\n ok: boolean;\n tools?: Array<Record<string, unknown>>;\n}\n\nexport function tool(options: ToolOptions): <T extends ToolHandler>(fn: T) => T;\nexport function tool<T extends ToolHandler>(fn: T, options?: ToolOptions): T;\nexport function tool<T extends ToolHandler>(arg1: ToolOptions | T, arg2?: ToolOptions) {\n if (typeof arg1 === \"function\") {\n return setToolMetadata(arg1, arg2 ?? {}) as T;\n }\n return (fn: T): T => setToolMetadata(fn, arg1) as T;\n}\n\nexport class ToolRegistry {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeout: number;\n private readonly remote = new Map<string, ToolDefinition>();\n private readonly custom = new Map<string, ToolDefinition>();\n\n constructor(options: { baseUrl: string; apiKey: string; timeout?: number }) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.apiKey = options.apiKey;\n this.timeout = options.timeout ?? 30000;\n }\n\n register(fn: ToolHandler): void {\n const metadata = getToolMetadata(fn);\n const name = metadata?.name ?? fn.name;\n const description = metadata?.description ?? \"\";\n const permissionMode = metadata?.permissionMode ?? \"always_allow\";\n const inputSchema = functionToToolSchema(fn, metadata?.inputSchema);\n this.custom.set(name, {\n name,\n description,\n inputSchema,\n permissionMode,\n handler: fn,\n });\n }\n\n async refreshRemote(): Promise<void> {\n const url = `${this.baseUrl}/api/tools/list`;\n const response = await fetch(url, {\n method: \"GET\",\n headers: { \"X-API-Key\": this.apiKey },\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!response.ok) {\n throw new Error(\n `AgentBlit request failed for GET '${url}': ${response.status} ${response.statusText}`,\n );\n }\n\n const data = (await response.json()) as ToolsListResponse;\n if (!data.ok) {\n throw new Error(\"tools/list returned ok=false\");\n }\n\n this.remote.clear();\n for (const toolItem of data.tools ?? []) {\n const name = String(toolItem.name ?? \"\");\n if (!name) {\n continue;\n }\n this.remote.set(name, {\n name,\n description: String(toolItem.description ?? \"\"),\n inputSchema: (toolItem.inputSchema as Record<string, unknown>) ?? {\n type: \"object\",\n properties: {},\n },\n permissionMode:\n String(toolItem.permissionMode ?? \"always_allow\") === \"needs_approval\"\n ? \"needs_approval\"\n : \"always_allow\",\n outputSchema: toolItem.outputSchema as Record<string, unknown> | undefined,\n });\n }\n }\n\n private merged(): Map<string, ToolDefinition> {\n const merged = new Map(this.remote);\n for (const [name, def] of this.custom.entries()) {\n merged.set(name, def);\n }\n return merged;\n }\n\n getDefinition(name: string): ToolDefinition | undefined {\n return this.merged().get(name);\n }\n\n toOpenAITools(): Array<Record<string, unknown>> {\n return [...this.merged().values()].map((definition) => ({\n type: \"function\",\n function: {\n name: definition.name,\n description: definition.description,\n parameters: definition.inputSchema,\n },\n }));\n }\n\n private async ensureApproval(\n definition: ToolDefinition,\n toolName: string,\n args: Record<string, unknown>,\n approvalCallback?: ApprovalCallback,\n ): Promise<boolean> {\n if (definition.permissionMode !== \"needs_approval\") {\n return true;\n }\n if (approvalCallback) {\n return approvalCallback(toolName, args);\n }\n const answer = await readStdinLine(\n `Approve tool \"${toolName}\" with args ${jsonDumpsSafe(args)}? [y/N]: `,\n );\n return [\"y\", \"yes\"].includes(answer.toLowerCase());\n }\n\n async execute(\n toolCallId: string,\n toolName: string,\n argumentsJson: string,\n approvalCallback?: ApprovalCallback,\n ): Promise<string> {\n const definition = this.getDefinition(toolName);\n if (!definition) {\n return jsonDumpsSafe({ error: `Unknown tool: ${toolName}` });\n }\n let args: Record<string, unknown>;\n try {\n args = argumentsJson ? (JSON.parse(argumentsJson) as Record<string, unknown>) : {};\n } catch (error) {\n return jsonDumpsSafe({ error: `Invalid JSON arguments: ${String(error)}` });\n }\n\n if (!(await this.ensureApproval(definition, toolName, args, approvalCallback))) {\n return jsonDumpsSafe({ error: \"User denied approval for this tool call.\" });\n }\n\n if (definition.handler) {\n try {\n let result: unknown;\n try {\n result = await definition.handler(...Object.values(args));\n } catch {\n result = await definition.handler(args);\n }\n return jsonDumpsSafe(result);\n } catch (error) {\n return jsonDumpsSafe({ error: error instanceof Error ? error.message : String(error) });\n }\n }\n\n const payload = {\n tool_calls: [\n {\n id: toolCallId,\n type: \"function\",\n function: {\n name: toolName,\n arguments: jsonDumpsSafe(args),\n },\n },\n ] satisfies OpenAIToolCall[],\n };\n const url = `${this.baseUrl}/api/tools/call`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-API-Key\": this.apiKey,\n \"Content-Type\": \"application/json\",\n },\n body: jsonDumpsSafe(payload),\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!response.ok) {\n throw new Error(\n `AgentBlit request failed for POST '${url}': ${response.status} ${response.statusText}`,\n );\n }\n const data = (await response.json()) as {\n ok?: boolean;\n results?: Array<{\n tool_call_id?: string;\n result?: {\n isError?: boolean;\n content?: Array<{ text?: string }>;\n structuredContent?: unknown;\n };\n }>;\n };\n if (!data.ok) {\n return jsonDumpsSafe({ error: data });\n }\n const result = (data.results ?? []).find((item) => item.tool_call_id === toolCallId);\n if (!result) {\n return jsonDumpsSafe({ error: \"No result for tool_call_id\" });\n }\n const toolResult = result.result;\n if (!toolResult) {\n return jsonDumpsSafe({ error: \"Missing tool result payload\" });\n }\n if (toolResult.isError) {\n const text = (toolResult.content ?? []).map((part) => part.text ?? \"\").join(\"\");\n return jsonDumpsSafe({ error: text || \"Tool error\" });\n }\n if (typeof toolResult.structuredContent !== \"undefined\") {\n return jsonDumpsSafe(toolResult.structuredContent);\n }\n const text = (toolResult.content ?? []).map((part) => part.text ?? \"\").join(\"\");\n return jsonDumpsSafe({ result: text });\n }\n}\n"],"mappings":"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","names":["import_node_crypto","process","result","text","OpenAI"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/agent.ts","../src/memory.ts","../src/utils.ts","../src/tools.ts"],"sourcesContent":["export { Agent } from \"./agent.js\";\nexport { ChatMemory } from \"./memory.js\";\nexport { tool, ToolRegistry } from \"./tools.js\";\nexport type {\n AgentConfig,\n AgentRunInput,\n AgentOptions,\n ApprovalCallback,\n ChatMessage,\n ChatMessageContent,\n JSONSchema,\n OpenAIFileContentPart,\n OpenAIImageUrlContentPart,\n OpenAIInputContentPart,\n OpenAITextContentPart,\n OpenAIToolCall,\n SummarizeFn,\n ToolDefinition,\n ToolHandler,\n ToolOptions,\n ToolPermissionMode,\n} from \"./types.js\";\n","import OpenAI from \"openai\";\nimport { randomUUID } from \"node:crypto\";\nimport { ChatMemory } from \"./memory.js\";\nimport {\n AgentRunInput,\n AgentConfig,\n AgentOptions,\n ChatMessage,\n ChatMessageContent,\n OpenAIInputContentPart,\n OpenAIToolCall,\n ToolHandler,\n} from \"./types.js\";\nimport { ToolRegistry } from \"./tools.js\";\nimport { DebugLogger, jsonDumpsSafe, nowIsoTimestamp, randomId } from \"./utils.js\";\n\nconst VENDOR_BASE_URLS: Record<string, string> = {\n openai: \"https://api.openai.com/v1\",\n anthropic: \"https://api.anthropic.com/v1\",\n gemini: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n openrouter: \"https://openrouter.ai/api/v1\",\n};\n\nconst DEFAULT_TOOL_USAGE_INSTRUCTION =\n \"Use tools when they help answer accurately.\";\n\nfunction resolveVendorAndModel(modelInput: string): { vendor: string; model: string } {\n const model = modelInput.trim();\n if (!model || !model.includes(\"/\")) {\n throw new Error(\n \"model must be in the format 'vendor/model', for example 'openai/gpt-4o-mini'.\",\n );\n }\n const [vendorRaw, ...rest] = model.split(\"/\");\n const vendor = (vendorRaw ?? \"\").trim().toLowerCase();\n const providerModel = rest.join(\"/\").trim();\n if (!vendor || !providerModel) {\n throw new Error(\n \"model must be in the format 'vendor/model', for example 'openai/gpt-4o-mini'.\",\n );\n }\n return { vendor, model: providerModel };\n}\n\nfunction resolveLlmUrl(vendor: string): string {\n const url = VENDOR_BASE_URLS[vendor];\n if (!url) {\n const supported = Object.keys(VENDOR_BASE_URLS).sort().join(\", \");\n throw new Error(`Unsupported model vendor '${vendor}'. Supported vendors: ${supported}.`);\n }\n return url;\n}\n\nfunction composeSystemPrompt(systemPrompt: string): string {\n const userPrompt = systemPrompt.trim();\n if (userPrompt.toLowerCase().includes(DEFAULT_TOOL_USAGE_INSTRUCTION.toLowerCase())) {\n return userPrompt;\n }\n if (!userPrompt) {\n return DEFAULT_TOOL_USAGE_INSTRUCTION;\n }\n return `${userPrompt}\\n\\n${DEFAULT_TOOL_USAGE_INSTRUCTION}`;\n}\n\nfunction formatMessagesForSummary(messages: ChatMessage[]): string {\n return messages\n .map((message, index) => {\n if (message.role === \"assistant\" && message.tool_calls) {\n return `[${index}] assistant (tool_calls): ${jsonDumpsSafe(message.tool_calls)}`;\n }\n return `[${index}] ${message.role}: ${serializeContentForSummary(message.content)}`;\n })\n .join(\"\\n\");\n}\n\nfunction serializeContentForSummary(content: ChatMessageContent | undefined): string {\n if (content === null || content === undefined) {\n return \"\";\n }\n if (typeof content === \"string\") {\n return content;\n }\n const parts: string[] = [];\n for (const part of content) {\n if (part.type === \"text\") {\n parts.push(part.text);\n continue;\n }\n if (part.type === \"image_url\") {\n parts.push(`[image: ${part.image_url.url}]`);\n continue;\n }\n if (part.type === \"file\") {\n parts.push(`[file: ${part.file.file_id ?? part.file.filename ?? \"inline_data\"}]`);\n continue;\n }\n parts.push(\"[unsupported_content_part]\");\n }\n return parts.join(\" \").trim();\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction validateInputContentParts(parts: OpenAIInputContentPart[]): OpenAIInputContentPart[] {\n for (const part of parts) {\n if (part.type === \"text\") {\n if (typeof part.text !== \"string\") {\n throw new Error(\"Text content part must include a string 'text' field.\");\n }\n continue;\n }\n if (part.type === \"image_url\") {\n if (!part.image_url || typeof part.image_url.url !== \"string\") {\n throw new Error(\n \"Image content part must include image_url.url as a string.\",\n );\n }\n continue;\n }\n if (part.type === \"file\") {\n const file = part.file;\n if (!file || (!file.file_id && !file.file_data)) {\n throw new Error(\n \"File content part must include at least one of file.file_id or file.file_data.\",\n );\n }\n continue;\n }\n throw new Error(\n \"Unsupported content part type. Supported types: text, image_url, file.\",\n );\n }\n return parts;\n}\n\nfunction normalizeRunInput(userInput: AgentRunInput): ChatMessageContent {\n if (typeof userInput === \"string\") {\n return userInput;\n }\n if (Array.isArray(userInput)) {\n return validateInputContentParts(userInput);\n }\n if (isObject(userInput)) {\n const { content } = userInput;\n if (typeof content === \"string\") {\n return content;\n }\n if (Array.isArray(content)) {\n return validateInputContentParts(content as OpenAIInputContentPart[]);\n }\n }\n throw new Error(\n \"run input must be a string, an array of OpenAI content parts, or an object with a content field.\",\n );\n}\n\ninterface EventPayload {\n id: string;\n session_id: string;\n agent_id: string;\n timestamp: string;\n type: string;\n data: unknown;\n tokens: number;\n latency_ms: number;\n}\n\nexport class Agent {\n readonly vendor: string;\n readonly model: string;\n readonly llmUrl: string;\n readonly agentId: string;\n readonly sessionId: string;\n readonly config: AgentConfig;\n readonly memory: ChatMemory;\n\n private readonly client: OpenAI;\n private readonly tools: ToolRegistry;\n private readonly systemPrompt: string;\n private readonly timeout: number;\n private readonly debug: DebugLogger;\n private readonly approvalCallback?: AgentOptions[\"approvalCallback\"];\n private readonly maxToolRounds: number;\n private readonly eventBaseUrl: string;\n private readonly eventApiKey: string;\n private readonly pendingCustomEvents: EventPayload[] = [];\n private agentInitSent = false;\n private toolsSignature?: string;\n\n constructor(options: AgentOptions) {\n const agentblitApiKey = options.agentblitApiKey.trim();\n if (!agentblitApiKey) {\n throw new Error(\"agentblitApiKey is required\");\n }\n const maxHistory = options.maxHistory ?? 5;\n if (maxHistory < 1) {\n throw new Error(\"maxHistory must be at least 1\");\n }\n const maxToolRounds = options.maxToolRounds ?? 25;\n if (maxToolRounds < 1) {\n throw new Error(\"maxToolRounds must be at least 1\");\n }\n\n const { vendor, model } = resolveVendorAndModel(options.model);\n const llmUrl = resolveLlmUrl(vendor);\n const timeoutSeconds = options.timeout ?? 30;\n const timeoutMs = timeoutSeconds * 1000;\n const agentblitUrl = (options.agentblitUrl ?? \"https://console.agentblit.com\").replace(/\\/$/, \"\");\n const systemPrompt = composeSystemPrompt(options.systemPrompt ?? options.system_prompt ?? \"\");\n\n this.vendor = vendor;\n this.model = model;\n this.llmUrl = llmUrl;\n this.systemPrompt = systemPrompt;\n this.timeout = timeoutMs;\n this.approvalCallback = options.approvalCallback;\n this.maxToolRounds = maxToolRounds;\n this.agentId = options.agentId?.trim() || randomUUID();\n this.sessionId = randomUUID();\n this.eventBaseUrl = agentblitUrl;\n this.eventApiKey = agentblitApiKey;\n this.debug = new DebugLogger(Boolean(options.debug));\n\n this.client = new OpenAI({\n apiKey: options.apiKey,\n baseURL: llmUrl,\n timeout: timeoutMs,\n });\n this.tools = new ToolRegistry({\n baseUrl: agentblitUrl,\n apiKey: agentblitApiKey,\n timeout: timeoutMs,\n });\n for (const customTool of options.customTools ?? []) {\n this.registerTool(customTool);\n }\n this.memory = new ChatMemory({\n maxHistory,\n summarizeFn: (older) => this.summarizeOlderMessages(older),\n });\n this.config = Object.freeze({\n model: this.model,\n vendor: this.vendor,\n llmUrl: this.llmUrl,\n agentblitUrl: this.eventBaseUrl,\n systemPrompt: this.systemPrompt,\n maxHistory,\n debug: Boolean(options.debug),\n timeout: timeoutSeconds,\n agentId: this.agentId,\n sessionId: this.sessionId,\n });\n }\n\n registerTool(fn: ToolHandler): void {\n this.tools.register(fn);\n }\n\n track(eventType: string, properties: Record<string, unknown>): void {\n this.pendingCustomEvents.push(this.makeEvent({ eventType, data: properties }));\n }\n\n private makeEvent(input: {\n eventType: string;\n data: unknown;\n tokens?: number;\n latencyMs?: number;\n }): EventPayload {\n return {\n id: randomId(\"evt\"),\n session_id: this.sessionId,\n agent_id: this.agentId,\n timestamp: nowIsoTimestamp(),\n type: input.eventType,\n data: input.data,\n tokens: Math.max(0, Math.trunc(input.tokens ?? 0)),\n latency_ms: Math.max(0, Math.trunc(input.latencyMs ?? 0)),\n };\n }\n\n private async flushEvents(events: EventPayload[]): Promise<void> {\n if (events.length === 0) {\n return;\n }\n const url = `${this.eventBaseUrl}/api/events/batch`;\n this.debug.log(\"Event batch send start url=%s count=%s\", url, events.length);\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-API-Key\": this.eventApiKey,\n \"Content-Type\": \"application/json\",\n },\n body: jsonDumpsSafe({ events }),\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!response.ok) {\n const body = (await response.text()).slice(0, 1000);\n this.debug.log(\n \"Failed to send events batch status=%s body=%s\",\n response.status,\n body,\n );\n return;\n }\n this.debug.log(\"Event batch send success status=%s count=%s\", response.status, events.length);\n } catch (error) {\n this.debug.log(\"Failed to send events batch: %s\", String(error));\n }\n }\n\n private extractLlmEventMessages(messages: ChatMessage[]): ChatMessage[] {\n if (messages.length === 0) {\n return [];\n }\n const summaryMessage = messages.find(\n (message) =>\n message.role === \"system\" &&\n typeof message.content === \"string\" &&\n message.content.startsWith(\"Summary of earlier conversation:\"),\n );\n const lastMessage = messages[messages.length - 1];\n if (!lastMessage) {\n return [];\n }\n if (!summaryMessage) {\n return [lastMessage];\n }\n if (summaryMessage === lastMessage) {\n return [summaryMessage];\n }\n return [summaryMessage, lastMessage];\n }\n\n private async summarizeOlderMessages(older: ChatMessage[]): Promise<string> {\n const text = formatMessagesForSummary(older);\n this.debug.log(\"Summarizing %s older messages\", older.length);\n const response = await this.client.chat.completions.create({\n model: this.model,\n messages: [\n {\n role: \"system\",\n content:\n \"Summarize the conversation excerpt below for use as memory. Preserve key facts, decisions, and tool outcomes. Be concise.\",\n },\n { role: \"user\", content: text },\n ],\n temperature: 0.2,\n });\n return response.choices[0]?.message?.content?.trim() ?? \"\";\n }\n\n async *run(userInput: AgentRunInput): AsyncGenerator<string> {\n const events: EventPayload[] = [...this.pendingCustomEvents];\n this.pendingCustomEvents.length = 0;\n try {\n const userContent = normalizeRunInput(userInput);\n this.memory.append({ role: \"user\", content: userContent });\n await this.tools.refreshRemote();\n const openaiTools = this.tools.toOpenAITools();\n const toolsSignature = jsonDumpsSafe(openaiTools);\n if (!this.agentInitSent) {\n events.push(\n this.makeEvent({\n eventType: \"agent_init\",\n data: { system_prompt: this.systemPrompt, tools: openaiTools },\n }),\n );\n this.agentInitSent = true;\n this.toolsSignature = toolsSignature;\n } else if (toolsSignature !== this.toolsSignature) {\n events.push(this.makeEvent({ eventType: \"tools_updated\", data: { tools: openaiTools } }));\n this.toolsSignature = toolsSignature;\n }\n events.push(\n this.makeEvent({\n eventType: \"user_prompt\",\n data: { request: { message: userContent }, response: null },\n }),\n );\n\n let finishedNormally = false;\n for (let round = 0; round < this.maxToolRounds; round += 1) {\n const messages = await this.memory.buildMessagesForLLM(this.systemPrompt);\n this.debug.logLLMRequest(this.model, messages.length, openaiTools.length);\n const llmRequest = {\n model: this.model,\n messages: messages as any,\n stream: true as const,\n ...(openaiTools.length > 0 ? { tools: openaiTools } : {}),\n ...(this.vendor === \"openai\" || this.vendor === \"openrouter\"\n ? { stream_options: { include_usage: true } }\n : {}),\n };\n\n const llmEventRequestData = {\n model: this.model,\n messages: this.extractLlmEventMessages(messages) as any,\n stream: true,\n };\n\n const startedAt = Date.now();\n const stream = (await this.client.chat.completions.create(\n llmRequest as any,\n )) as unknown as AsyncIterable<any>;\n\n const contentParts: string[] = [];\n const toolCallsMap = new Map<\n number,\n { id: string; name: string; arguments: string }\n >();\n let finishReason: string | null = null;\n let llmTotalTokens = 0;\n\n for await (const chunk of stream) {\n if (chunk.usage?.total_tokens) {\n llmTotalTokens = chunk.usage.total_tokens;\n }\n const choice = chunk.choices?.[0];\n if (!choice) {\n continue;\n }\n if (choice.finish_reason) {\n finishReason = choice.finish_reason;\n }\n const delta = choice.delta;\n if (!delta) {\n continue;\n }\n if (delta.content) {\n contentParts.push(delta.content);\n yield delta.content;\n }\n for (const toolCall of delta.tool_calls ?? []) {\n const index = toolCall.index ?? 0;\n const existing = toolCallsMap.get(index) ?? { id: \"\", name: \"\", arguments: \"\" };\n if (toolCall.id) {\n existing.id = toolCall.id;\n }\n if (toolCall.function?.name) {\n existing.name = toolCall.function.name;\n }\n if (toolCall.function?.arguments) {\n existing.arguments += toolCall.function.arguments;\n }\n toolCallsMap.set(index, existing);\n }\n }\n\n const assistantContent = contentParts.join(\"\") || null;\n const llmLatencyMs = Date.now() - startedAt;\n const toolCalls = [...toolCallsMap.entries()]\n .sort(([a], [b]) => a - b)\n .map(([, call]): OpenAIToolCall => ({\n id: call.id,\n type: \"function\",\n function: {\n name: call.name,\n arguments: call.arguments || \"{}\",\n },\n }));\n\n events.push(\n this.makeEvent({\n eventType: \"llm_call\",\n data: {\n request: llmEventRequestData,\n response: {\n finish_reason: finishReason,\n content: assistantContent,\n tool_calls: toolCalls,\n },\n },\n tokens: llmTotalTokens,\n latencyMs: llmLatencyMs,\n }),\n );\n\n if (finishReason === \"tool_calls\" || toolCalls.length > 0) {\n this.debug.logToolCalls(toolCalls);\n this.memory.append({\n role: \"assistant\",\n content: assistantContent,\n tool_calls: toolCalls,\n });\n\n for (const toolCall of toolCalls) {\n const toolStartedAt = Date.now();\n const result = await this.tools.execute(\n toolCall.id,\n toolCall.function.name,\n toolCall.function.arguments,\n this.approvalCallback,\n );\n const toolLatencyMs = Date.now() - toolStartedAt;\n this.debug.logToolResult(toolCall.id, true, result);\n let parsedResponse: unknown;\n try {\n parsedResponse = JSON.parse(result);\n } catch {\n parsedResponse = { raw: result };\n }\n events.push(\n this.makeEvent({\n eventType: \"tool_call\",\n data: {\n request: toolCall,\n response: parsedResponse,\n },\n latencyMs: toolLatencyMs,\n }),\n );\n this.memory.append({\n role: \"tool\",\n tool_call_id: toolCall.id,\n content: result,\n });\n }\n continue;\n }\n\n this.memory.append({\n role: \"assistant\",\n content: assistantContent ?? \"\",\n });\n finishedNormally = true;\n break;\n }\n\n if (!finishedNormally) {\n throw new Error(\n `Exceeded maxToolRounds (${this.maxToolRounds}); increase maxToolRounds or simplify the task.`,\n );\n }\n } catch (error) {\n events.push(\n this.makeEvent({\n eventType: \"agent_loop_error\",\n data: { error: error instanceof Error ? error.message : String(error) },\n }),\n );\n throw error;\n } finally {\n this.debug.log(\"Queueing event flush count=%s\", events.length);\n await this.flushEvents(events);\n }\n }\n\n /**\n * Runs the agent to completion and returns the full assistant text (concatenated stream chunks).\n * Same behavior as iterating {@link Agent.run}; use when you do not need incremental output.\n */\n async runSync(userInput: AgentRunInput): Promise<string> {\n let text = \"\";\n for await (const chunk of this.run(userInput)) {\n text += chunk;\n }\n return text;\n }\n}\n","import { ChatMessage, SummarizeFn } from \"./types.js\";\n\nexport class ChatMemory {\n private readonly messagesStore: ChatMessage[] = [];\n private readonly maxHistory: number;\n private readonly summarizeFn?: SummarizeFn;\n\n constructor(options?: { maxHistory?: number; summarizeFn?: SummarizeFn }) {\n const maxHistory = options?.maxHistory ?? 5;\n if (maxHistory < 1) {\n throw new Error(\"maxHistory must be at least 1\");\n }\n this.maxHistory = maxHistory;\n this.summarizeFn = options?.summarizeFn;\n }\n\n get messages(): ChatMessage[] {\n return [...this.messagesStore];\n }\n\n append(message: ChatMessage): void {\n this.messagesStore.push(message);\n }\n\n extend(messages: ChatMessage[]): void {\n this.messagesStore.push(...messages);\n }\n\n clear(): void {\n this.messagesStore.length = 0;\n }\n\n async buildMessagesForLLM(systemPrompt: string): Promise<ChatMessage[]> {\n const out: ChatMessage[] = [{ role: \"system\", content: systemPrompt }];\n if (this.messagesStore.length <= this.maxHistory) {\n out.push(...this.messagesStore);\n return out;\n }\n\n const older = this.messagesStore.slice(0, -this.maxHistory);\n const recent = this.messagesStore.slice(-this.maxHistory);\n let summaryText: string;\n if (!this.summarizeFn) {\n summaryText = `[Earlier conversation truncated: ${older.length} message(s) not shown. Provide summarizeFn on Agent to compress older context with the LLM.]`;\n } else {\n summaryText = await this.summarizeFn(older);\n }\n out.push({\n role: \"system\",\n content: `Summary of earlier conversation:\\n${summaryText}`,\n });\n out.push(...recent);\n return out;\n }\n}\n","import process from \"node:process\";\nimport { randomUUID } from \"node:crypto\";\nimport { ToolHandler, ToolOptions } from \"./types.js\";\n\nconst LOGGER_PREFIX = \"[agentblit]\";\n\nexport class DebugLogger {\n constructor(private readonly enabled: boolean) {}\n\n log(message: string, ...args: unknown[]): void {\n if (!this.enabled) {\n return;\n }\n console.debug(`${LOGGER_PREFIX} ${message}`, ...args);\n }\n\n logLLMRequest(model: string, messageCount: number, toolCount: number): void {\n this.log(\"LLM request model=%s messages=%s tools=%s\", model, messageCount, toolCount);\n }\n\n logToolCalls(calls: unknown[]): void {\n this.log(\"Tool calls: %s\", jsonDumpsSafe(calls));\n }\n\n logToolResult(toolCallId: string, ok: boolean, preview: string): void {\n this.log(\"Tool result id=%s ok=%s preview=%s\", toolCallId, ok, preview.slice(0, 500));\n }\n}\n\nexport function jsonDumpsSafe(obj: unknown): string {\n return JSON.stringify(obj, (_key, value) => {\n if (value instanceof Error) {\n return {\n name: value.name,\n message: value.message,\n stack: value.stack,\n };\n }\n return value;\n });\n}\n\nfunction extractParamNames(fn: ToolHandler): string[] {\n const source = fn.toString();\n const match = source.match(/\\(([^)]*)\\)/);\n if (!match) {\n return [];\n }\n const rawParams = match[1] ?? \"\";\n return rawParams\n .split(\",\")\n .map((segment) => segment.trim())\n .filter(Boolean)\n .map((segment) => segment.replace(/=[\\s\\S]*$/, \"\").trim())\n .map((segment) => segment.replace(/^\\.{3}/, \"\"))\n .filter((segment) => segment !== \"this\");\n}\n\nexport function functionToToolSchema(fn: ToolHandler, explicitSchema?: Record<string, unknown>): Record<string, unknown> {\n if (explicitSchema) {\n return explicitSchema;\n }\n const properties = Object.fromEntries(\n extractParamNames(fn).map((name) => [name, { type: \"string\" }]),\n );\n const required = Object.keys(properties);\n return {\n type: \"object\",\n properties,\n ...(required.length > 0 ? { required } : {}),\n };\n}\n\nexport const TOOL_META = Symbol.for(\"agentblit.tool.meta\");\n\nexport interface ToolMetadata extends Required<Pick<ToolOptions, \"name\" | \"description\" | \"permissionMode\">> {\n inputSchema?: Record<string, unknown>;\n}\n\nexport function setToolMetadata(fn: ToolHandler, options: ToolOptions): ToolHandler {\n const metadata: ToolMetadata = {\n name: options.name ?? fn.name,\n description: options.description ?? \"\",\n permissionMode: options.permissionMode ?? \"always_allow\",\n inputSchema: options.inputSchema,\n };\n (fn as ToolHandler & { [TOOL_META]?: ToolMetadata })[TOOL_META] = metadata;\n return fn;\n}\n\nexport function getToolMetadata(fn: ToolHandler): ToolMetadata | undefined {\n return (fn as ToolHandler & { [TOOL_META]?: ToolMetadata })[TOOL_META];\n}\n\nexport function nowIsoTimestamp(): string {\n return new Date().toISOString();\n}\n\nexport function randomId(prefix: string): string {\n return `${prefix}_${randomUUID().replace(/-/g, \"\")}`;\n}\n\nexport function readStdinLine(promptText: string): Promise<string> {\n return new Promise((resolve) => {\n process.stdout.write(promptText);\n process.stdin.resume();\n process.stdin.once(\"data\", (chunk) => {\n resolve(String(chunk).trim());\n });\n });\n}\n","import {\n ApprovalCallback,\n OpenAIToolCall,\n ToolDefinition,\n ToolHandler,\n ToolOptions,\n} from \"./types.js\";\nimport {\n functionToToolSchema,\n getToolMetadata,\n jsonDumpsSafe,\n readStdinLine,\n setToolMetadata,\n} from \"./utils.js\";\n\ninterface ToolsListResponse {\n tools?: Array<Record<string, unknown>>;\n}\n\nexport function tool(options: ToolOptions): <T extends ToolHandler>(fn: T) => T;\nexport function tool<T extends ToolHandler>(fn: T, options?: ToolOptions): T;\nexport function tool<T extends ToolHandler>(arg1: ToolOptions | T, arg2?: ToolOptions) {\n if (typeof arg1 === \"function\") {\n return setToolMetadata(arg1, arg2 ?? {}) as T;\n }\n return (fn: T): T => setToolMetadata(fn, arg1) as T;\n}\n\nexport class ToolRegistry {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeout: number;\n private readonly remote = new Map<string, ToolDefinition>();\n private readonly custom = new Map<string, ToolDefinition>();\n\n constructor(options: { baseUrl: string; apiKey: string; timeout?: number }) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.apiKey = options.apiKey;\n this.timeout = options.timeout ?? 30000;\n }\n\n register(fn: ToolHandler): void {\n const metadata = getToolMetadata(fn);\n const name = metadata?.name ?? fn.name;\n const description = metadata?.description ?? \"\";\n const permissionMode = metadata?.permissionMode ?? \"always_allow\";\n const inputSchema = functionToToolSchema(fn, metadata?.inputSchema);\n this.custom.set(name, {\n name,\n description,\n inputSchema,\n permissionMode,\n handler: fn,\n });\n }\n\n async refreshRemote(): Promise<void> {\n const url = `${this.baseUrl}/api/1.0/tools/list`;\n const response = await fetch(url, {\n method: \"GET\",\n headers: { \"X-API-Key\": this.apiKey },\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!response.ok) {\n throw new Error(\n `AgentBlit request failed for GET '${url}': ${response.status} ${response.statusText}`,\n );\n }\n\n const data = (await response.json()) as ToolsListResponse;\n\n this.remote.clear();\n for (const toolItem of data.tools ?? []) {\n const type = String(toolItem.type ?? \"\");\n if (type !== \"function\") {\n continue;\n }\n const fn = (toolItem.function as Record<string, unknown> | undefined) ?? {};\n const name = String(fn.name ?? \"\");\n if (!name) {\n continue;\n }\n this.remote.set(name, {\n name,\n description: String(fn.description ?? \"\"),\n inputSchema: (fn.parameters as Record<string, unknown>) ?? {\n type: \"object\",\n properties: {},\n },\n permissionMode:\n String(toolItem.permission_mode ?? \"always_allow\") === \"needs_approval\"\n ? \"needs_approval\"\n : \"always_allow\",\n });\n }\n }\n\n private merged(): Map<string, ToolDefinition> {\n const merged = new Map(this.remote);\n for (const [name, def] of this.custom.entries()) {\n merged.set(name, def);\n }\n return merged;\n }\n\n getDefinition(name: string): ToolDefinition | undefined {\n return this.merged().get(name);\n }\n\n toOpenAITools(): Array<Record<string, unknown>> {\n return [...this.merged().values()].map((definition) => ({\n type: \"function\",\n function: {\n name: definition.name,\n description: definition.description,\n parameters: definition.inputSchema,\n },\n }));\n }\n\n private async ensureApproval(\n definition: ToolDefinition,\n toolName: string,\n args: Record<string, unknown>,\n approvalCallback?: ApprovalCallback,\n ): Promise<boolean> {\n if (definition.permissionMode !== \"needs_approval\") {\n return true;\n }\n if (approvalCallback) {\n return approvalCallback(toolName, args);\n }\n const answer = await readStdinLine(\n `Approve tool \"${toolName}\" with args ${jsonDumpsSafe(args)}? [y/N]: `,\n );\n return [\"y\", \"yes\"].includes(answer.toLowerCase());\n }\n\n async execute(\n toolCallId: string,\n toolName: string,\n argumentsJson: string,\n approvalCallback?: ApprovalCallback,\n ): Promise<string> {\n const definition = this.getDefinition(toolName);\n if (!definition) {\n return jsonDumpsSafe({ error: `Unknown tool: ${toolName}` });\n }\n let args: Record<string, unknown>;\n try {\n args = argumentsJson ? (JSON.parse(argumentsJson) as Record<string, unknown>) : {};\n } catch (error) {\n return jsonDumpsSafe({ error: `Invalid JSON arguments: ${String(error)}` });\n }\n\n if (!(await this.ensureApproval(definition, toolName, args, approvalCallback))) {\n return jsonDumpsSafe({ error: \"User denied approval for this tool call.\" });\n }\n\n if (definition.handler) {\n try {\n let result: unknown;\n try {\n result = await definition.handler(...Object.values(args));\n } catch {\n result = await definition.handler(args);\n }\n return jsonDumpsSafe(result);\n } catch (error) {\n return jsonDumpsSafe({ error: error instanceof Error ? error.message : String(error) });\n }\n }\n\n const payload = {\n tool_calls: [\n {\n id: toolCallId,\n type: \"function\",\n function: {\n name: toolName,\n arguments: jsonDumpsSafe(args),\n },\n },\n ] satisfies OpenAIToolCall[],\n };\n if (!toolCallId.trim()) {\n return jsonDumpsSafe({ error: \"Missing tool_call_id\" });\n }\n const url = `${this.baseUrl}/api/1.0/tools/call`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-API-Key\": this.apiKey,\n \"Content-Type\": \"application/json\",\n },\n body: jsonDumpsSafe(payload),\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!response.ok) {\n throw new Error(\n `AgentBlit request failed for POST '${url}': ${response.status} ${response.statusText}`,\n );\n }\n const data = (await response.json()) as {\n results?: Array<{\n tool_call_id?: string;\n result?: unknown;\n error?: unknown;\n }>;\n };\n const result = (data.results ?? []).find((item) => item.tool_call_id === toolCallId);\n if (!result) {\n return jsonDumpsSafe({ error: \"No result for tool_call_id\" });\n }\n if (typeof result.error !== \"undefined\") {\n return jsonDumpsSafe({ error: result.error });\n }\n if (typeof result.result !== \"undefined\") {\n return jsonDumpsSafe(result.result);\n }\n return jsonDumpsSafe({ error: \"Missing result or error for tool_call_id\" });\n }\n}\n"],"mappings":"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","names":["import_node_crypto","process","result","OpenAI"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -23,12 +23,36 @@ interface AgentConfig {
|
|
|
23
23
|
}
|
|
24
24
|
type ApprovalCallback = (toolName: string, args: Record<string, unknown>) => Promise<boolean>;
|
|
25
25
|
type SummarizeFn = (messages: ChatMessage[]) => Promise<string>;
|
|
26
|
+
interface OpenAITextContentPart {
|
|
27
|
+
type: "text";
|
|
28
|
+
text: string;
|
|
29
|
+
}
|
|
30
|
+
interface OpenAIImageUrlContentPart {
|
|
31
|
+
type: "image_url";
|
|
32
|
+
image_url: {
|
|
33
|
+
url: string;
|
|
34
|
+
detail?: "auto" | "low" | "high" | string;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
interface OpenAIFileContentPart {
|
|
38
|
+
type: "file";
|
|
39
|
+
file: {
|
|
40
|
+
file_id?: string;
|
|
41
|
+
file_data?: string;
|
|
42
|
+
filename?: string;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
type OpenAIInputContentPart = OpenAITextContentPart | OpenAIImageUrlContentPart | OpenAIFileContentPart;
|
|
46
|
+
type ChatMessageContent = string | OpenAIInputContentPart[] | null;
|
|
26
47
|
interface ChatMessage {
|
|
27
48
|
role: "system" | "user" | "assistant" | "tool";
|
|
28
|
-
content?:
|
|
49
|
+
content?: ChatMessageContent;
|
|
29
50
|
tool_call_id?: string;
|
|
30
51
|
tool_calls?: OpenAIToolCall[];
|
|
31
52
|
}
|
|
53
|
+
type AgentRunInput = string | OpenAIInputContentPart[] | {
|
|
54
|
+
content: string | OpenAIInputContentPart[];
|
|
55
|
+
};
|
|
32
56
|
interface OpenAIToolCall {
|
|
33
57
|
id: string;
|
|
34
58
|
type: "function";
|
|
@@ -101,12 +125,12 @@ declare class Agent {
|
|
|
101
125
|
private flushEvents;
|
|
102
126
|
private extractLlmEventMessages;
|
|
103
127
|
private summarizeOlderMessages;
|
|
104
|
-
run(
|
|
128
|
+
run(userInput: AgentRunInput): AsyncGenerator<string>;
|
|
105
129
|
/**
|
|
106
130
|
* Runs the agent to completion and returns the full assistant text (concatenated stream chunks).
|
|
107
131
|
* Same behavior as iterating {@link Agent.run}; use when you do not need incremental output.
|
|
108
132
|
*/
|
|
109
|
-
runSync(
|
|
133
|
+
runSync(userInput: AgentRunInput): Promise<string>;
|
|
110
134
|
}
|
|
111
135
|
|
|
112
136
|
declare function tool(options: ToolOptions): <T extends ToolHandler>(fn: T) => T;
|
|
@@ -131,4 +155,4 @@ declare class ToolRegistry {
|
|
|
131
155
|
execute(toolCallId: string, toolName: string, argumentsJson: string, approvalCallback?: ApprovalCallback): Promise<string>;
|
|
132
156
|
}
|
|
133
157
|
|
|
134
|
-
export { Agent, type AgentConfig, type AgentOptions, type ApprovalCallback, ChatMemory, type ChatMessage, type JSONSchema, type OpenAIToolCall, type SummarizeFn, type ToolDefinition, type ToolHandler, type ToolOptions, type ToolPermissionMode, ToolRegistry, tool };
|
|
158
|
+
export { Agent, type AgentConfig, type AgentOptions, type AgentRunInput, type ApprovalCallback, ChatMemory, type ChatMessage, type ChatMessageContent, type JSONSchema, type OpenAIFileContentPart, type OpenAIImageUrlContentPart, type OpenAIInputContentPart, type OpenAITextContentPart, type OpenAIToolCall, type SummarizeFn, type ToolDefinition, type ToolHandler, type ToolOptions, type ToolPermissionMode, ToolRegistry, tool };
|
package/dist/index.d.ts
CHANGED
|
@@ -23,12 +23,36 @@ interface AgentConfig {
|
|
|
23
23
|
}
|
|
24
24
|
type ApprovalCallback = (toolName: string, args: Record<string, unknown>) => Promise<boolean>;
|
|
25
25
|
type SummarizeFn = (messages: ChatMessage[]) => Promise<string>;
|
|
26
|
+
interface OpenAITextContentPart {
|
|
27
|
+
type: "text";
|
|
28
|
+
text: string;
|
|
29
|
+
}
|
|
30
|
+
interface OpenAIImageUrlContentPart {
|
|
31
|
+
type: "image_url";
|
|
32
|
+
image_url: {
|
|
33
|
+
url: string;
|
|
34
|
+
detail?: "auto" | "low" | "high" | string;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
interface OpenAIFileContentPart {
|
|
38
|
+
type: "file";
|
|
39
|
+
file: {
|
|
40
|
+
file_id?: string;
|
|
41
|
+
file_data?: string;
|
|
42
|
+
filename?: string;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
type OpenAIInputContentPart = OpenAITextContentPart | OpenAIImageUrlContentPart | OpenAIFileContentPart;
|
|
46
|
+
type ChatMessageContent = string | OpenAIInputContentPart[] | null;
|
|
26
47
|
interface ChatMessage {
|
|
27
48
|
role: "system" | "user" | "assistant" | "tool";
|
|
28
|
-
content?:
|
|
49
|
+
content?: ChatMessageContent;
|
|
29
50
|
tool_call_id?: string;
|
|
30
51
|
tool_calls?: OpenAIToolCall[];
|
|
31
52
|
}
|
|
53
|
+
type AgentRunInput = string | OpenAIInputContentPart[] | {
|
|
54
|
+
content: string | OpenAIInputContentPart[];
|
|
55
|
+
};
|
|
32
56
|
interface OpenAIToolCall {
|
|
33
57
|
id: string;
|
|
34
58
|
type: "function";
|
|
@@ -101,12 +125,12 @@ declare class Agent {
|
|
|
101
125
|
private flushEvents;
|
|
102
126
|
private extractLlmEventMessages;
|
|
103
127
|
private summarizeOlderMessages;
|
|
104
|
-
run(
|
|
128
|
+
run(userInput: AgentRunInput): AsyncGenerator<string>;
|
|
105
129
|
/**
|
|
106
130
|
* Runs the agent to completion and returns the full assistant text (concatenated stream chunks).
|
|
107
131
|
* Same behavior as iterating {@link Agent.run}; use when you do not need incremental output.
|
|
108
132
|
*/
|
|
109
|
-
runSync(
|
|
133
|
+
runSync(userInput: AgentRunInput): Promise<string>;
|
|
110
134
|
}
|
|
111
135
|
|
|
112
136
|
declare function tool(options: ToolOptions): <T extends ToolHandler>(fn: T) => T;
|
|
@@ -131,4 +155,4 @@ declare class ToolRegistry {
|
|
|
131
155
|
execute(toolCallId: string, toolName: string, argumentsJson: string, approvalCallback?: ApprovalCallback): Promise<string>;
|
|
132
156
|
}
|
|
133
157
|
|
|
134
|
-
export { Agent, type AgentConfig, type AgentOptions, type ApprovalCallback, ChatMemory, type ChatMessage, type JSONSchema, type OpenAIToolCall, type SummarizeFn, type ToolDefinition, type ToolHandler, type ToolOptions, type ToolPermissionMode, ToolRegistry, tool };
|
|
158
|
+
export { Agent, type AgentConfig, type AgentOptions, type AgentRunInput, type ApprovalCallback, ChatMemory, type ChatMessage, type ChatMessageContent, type JSONSchema, type OpenAIFileContentPart, type OpenAIImageUrlContentPart, type OpenAIInputContentPart, type OpenAITextContentPart, type OpenAIToolCall, type SummarizeFn, type ToolDefinition, type ToolHandler, type ToolOptions, type ToolPermissionMode, ToolRegistry, tool };
|
package/dist/index.js
CHANGED
|
@@ -174,7 +174,7 @@ var ToolRegistry = class {
|
|
|
174
174
|
});
|
|
175
175
|
}
|
|
176
176
|
async refreshRemote() {
|
|
177
|
-
const url = `${this.baseUrl}/api/tools/list`;
|
|
177
|
+
const url = `${this.baseUrl}/api/1.0/tools/list`;
|
|
178
178
|
const response = await fetch(url, {
|
|
179
179
|
method: "GET",
|
|
180
180
|
headers: { "X-API-Key": this.apiKey },
|
|
@@ -186,24 +186,25 @@ var ToolRegistry = class {
|
|
|
186
186
|
);
|
|
187
187
|
}
|
|
188
188
|
const data = await response.json();
|
|
189
|
-
if (!data.ok) {
|
|
190
|
-
throw new Error("tools/list returned ok=false");
|
|
191
|
-
}
|
|
192
189
|
this.remote.clear();
|
|
193
190
|
for (const toolItem of data.tools ?? []) {
|
|
194
|
-
const
|
|
191
|
+
const type = String(toolItem.type ?? "");
|
|
192
|
+
if (type !== "function") {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
const fn = toolItem.function ?? {};
|
|
196
|
+
const name = String(fn.name ?? "");
|
|
195
197
|
if (!name) {
|
|
196
198
|
continue;
|
|
197
199
|
}
|
|
198
200
|
this.remote.set(name, {
|
|
199
201
|
name,
|
|
200
|
-
description: String(
|
|
201
|
-
inputSchema:
|
|
202
|
+
description: String(fn.description ?? ""),
|
|
203
|
+
inputSchema: fn.parameters ?? {
|
|
202
204
|
type: "object",
|
|
203
205
|
properties: {}
|
|
204
206
|
},
|
|
205
|
-
permissionMode: String(toolItem.
|
|
206
|
-
outputSchema: toolItem.outputSchema
|
|
207
|
+
permissionMode: String(toolItem.permission_mode ?? "always_allow") === "needs_approval" ? "needs_approval" : "always_allow"
|
|
207
208
|
});
|
|
208
209
|
}
|
|
209
210
|
}
|
|
@@ -278,7 +279,10 @@ var ToolRegistry = class {
|
|
|
278
279
|
}
|
|
279
280
|
]
|
|
280
281
|
};
|
|
281
|
-
|
|
282
|
+
if (!toolCallId.trim()) {
|
|
283
|
+
return jsonDumpsSafe({ error: "Missing tool_call_id" });
|
|
284
|
+
}
|
|
285
|
+
const url = `${this.baseUrl}/api/1.0/tools/call`;
|
|
282
286
|
const response = await fetch(url, {
|
|
283
287
|
method: "POST",
|
|
284
288
|
headers: {
|
|
@@ -294,26 +298,17 @@ var ToolRegistry = class {
|
|
|
294
298
|
);
|
|
295
299
|
}
|
|
296
300
|
const data = await response.json();
|
|
297
|
-
if (!data.ok) {
|
|
298
|
-
return jsonDumpsSafe({ error: data });
|
|
299
|
-
}
|
|
300
301
|
const result = (data.results ?? []).find((item) => item.tool_call_id === toolCallId);
|
|
301
302
|
if (!result) {
|
|
302
303
|
return jsonDumpsSafe({ error: "No result for tool_call_id" });
|
|
303
304
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
return jsonDumpsSafe({ error: "Missing tool result payload" });
|
|
305
|
+
if (typeof result.error !== "undefined") {
|
|
306
|
+
return jsonDumpsSafe({ error: result.error });
|
|
307
307
|
}
|
|
308
|
-
if (
|
|
309
|
-
|
|
310
|
-
return jsonDumpsSafe({ error: text2 || "Tool error" });
|
|
308
|
+
if (typeof result.result !== "undefined") {
|
|
309
|
+
return jsonDumpsSafe(result.result);
|
|
311
310
|
}
|
|
312
|
-
|
|
313
|
-
return jsonDumpsSafe(toolResult.structuredContent);
|
|
314
|
-
}
|
|
315
|
-
const text = (toolResult.content ?? []).map((part) => part.text ?? "").join("");
|
|
316
|
-
return jsonDumpsSafe({ result: text });
|
|
311
|
+
return jsonDumpsSafe({ error: "Missing result or error for tool_call_id" });
|
|
317
312
|
}
|
|
318
313
|
};
|
|
319
314
|
|
|
@@ -367,9 +362,88 @@ function formatMessagesForSummary(messages) {
|
|
|
367
362
|
if (message.role === "assistant" && message.tool_calls) {
|
|
368
363
|
return `[${index}] assistant (tool_calls): ${jsonDumpsSafe(message.tool_calls)}`;
|
|
369
364
|
}
|
|
370
|
-
return `[${index}] ${message.role}: ${message.content
|
|
365
|
+
return `[${index}] ${message.role}: ${serializeContentForSummary(message.content)}`;
|
|
371
366
|
}).join("\n");
|
|
372
367
|
}
|
|
368
|
+
function serializeContentForSummary(content) {
|
|
369
|
+
if (content === null || content === void 0) {
|
|
370
|
+
return "";
|
|
371
|
+
}
|
|
372
|
+
if (typeof content === "string") {
|
|
373
|
+
return content;
|
|
374
|
+
}
|
|
375
|
+
const parts = [];
|
|
376
|
+
for (const part of content) {
|
|
377
|
+
if (part.type === "text") {
|
|
378
|
+
parts.push(part.text);
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
if (part.type === "image_url") {
|
|
382
|
+
parts.push(`[image: ${part.image_url.url}]`);
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
if (part.type === "file") {
|
|
386
|
+
parts.push(`[file: ${part.file.file_id ?? part.file.filename ?? "inline_data"}]`);
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
parts.push("[unsupported_content_part]");
|
|
390
|
+
}
|
|
391
|
+
return parts.join(" ").trim();
|
|
392
|
+
}
|
|
393
|
+
function isObject(value) {
|
|
394
|
+
return typeof value === "object" && value !== null;
|
|
395
|
+
}
|
|
396
|
+
function validateInputContentParts(parts) {
|
|
397
|
+
for (const part of parts) {
|
|
398
|
+
if (part.type === "text") {
|
|
399
|
+
if (typeof part.text !== "string") {
|
|
400
|
+
throw new Error("Text content part must include a string 'text' field.");
|
|
401
|
+
}
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
if (part.type === "image_url") {
|
|
405
|
+
if (!part.image_url || typeof part.image_url.url !== "string") {
|
|
406
|
+
throw new Error(
|
|
407
|
+
"Image content part must include image_url.url as a string."
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
if (part.type === "file") {
|
|
413
|
+
const file = part.file;
|
|
414
|
+
if (!file || !file.file_id && !file.file_data) {
|
|
415
|
+
throw new Error(
|
|
416
|
+
"File content part must include at least one of file.file_id or file.file_data."
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
throw new Error(
|
|
422
|
+
"Unsupported content part type. Supported types: text, image_url, file."
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
return parts;
|
|
426
|
+
}
|
|
427
|
+
function normalizeRunInput(userInput) {
|
|
428
|
+
if (typeof userInput === "string") {
|
|
429
|
+
return userInput;
|
|
430
|
+
}
|
|
431
|
+
if (Array.isArray(userInput)) {
|
|
432
|
+
return validateInputContentParts(userInput);
|
|
433
|
+
}
|
|
434
|
+
if (isObject(userInput)) {
|
|
435
|
+
const { content } = userInput;
|
|
436
|
+
if (typeof content === "string") {
|
|
437
|
+
return content;
|
|
438
|
+
}
|
|
439
|
+
if (Array.isArray(content)) {
|
|
440
|
+
return validateInputContentParts(content);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
throw new Error(
|
|
444
|
+
"run input must be a string, an array of OpenAI content parts, or an object with a content field."
|
|
445
|
+
);
|
|
446
|
+
}
|
|
373
447
|
var Agent = class {
|
|
374
448
|
vendor;
|
|
375
449
|
model;
|
|
@@ -534,11 +608,12 @@ var Agent = class {
|
|
|
534
608
|
});
|
|
535
609
|
return response.choices[0]?.message?.content?.trim() ?? "";
|
|
536
610
|
}
|
|
537
|
-
async *run(
|
|
611
|
+
async *run(userInput) {
|
|
538
612
|
const events = [...this.pendingCustomEvents];
|
|
539
613
|
this.pendingCustomEvents.length = 0;
|
|
540
614
|
try {
|
|
541
|
-
|
|
615
|
+
const userContent = normalizeRunInput(userInput);
|
|
616
|
+
this.memory.append({ role: "user", content: userContent });
|
|
542
617
|
await this.tools.refreshRemote();
|
|
543
618
|
const openaiTools = this.tools.toOpenAITools();
|
|
544
619
|
const toolsSignature = jsonDumpsSafe(openaiTools);
|
|
@@ -558,7 +633,7 @@ var Agent = class {
|
|
|
558
633
|
events.push(
|
|
559
634
|
this.makeEvent({
|
|
560
635
|
eventType: "user_prompt",
|
|
561
|
-
data: { request: { message:
|
|
636
|
+
data: { request: { message: userContent }, response: null }
|
|
562
637
|
})
|
|
563
638
|
);
|
|
564
639
|
let finishedNormally = false;
|
|
@@ -714,9 +789,9 @@ var Agent = class {
|
|
|
714
789
|
* Runs the agent to completion and returns the full assistant text (concatenated stream chunks).
|
|
715
790
|
* Same behavior as iterating {@link Agent.run}; use when you do not need incremental output.
|
|
716
791
|
*/
|
|
717
|
-
async runSync(
|
|
792
|
+
async runSync(userInput) {
|
|
718
793
|
let text = "";
|
|
719
|
-
for await (const chunk of this.run(
|
|
794
|
+
for await (const chunk of this.run(userInput)) {
|
|
720
795
|
text += chunk;
|
|
721
796
|
}
|
|
722
797
|
return text;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/agent.ts","../src/memory.ts","../src/utils.ts","../src/tools.ts"],"sourcesContent":["import OpenAI from \"openai\";\nimport { randomUUID } from \"node:crypto\";\nimport { ChatMemory } from \"./memory.js\";\nimport {\n AgentConfig,\n AgentOptions,\n ChatMessage,\n OpenAIToolCall,\n ToolHandler,\n} from \"./types.js\";\nimport { ToolRegistry } from \"./tools.js\";\nimport { DebugLogger, jsonDumpsSafe, nowIsoTimestamp, randomId } from \"./utils.js\";\n\nconst VENDOR_BASE_URLS: Record<string, string> = {\n openai: \"https://api.openai.com/v1\",\n anthropic: \"https://api.anthropic.com/v1\",\n gemini: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n openrouter: \"https://openrouter.ai/api/v1\",\n};\n\nconst DEFAULT_TOOL_USAGE_INSTRUCTION =\n \"Use tools when they help answer accurately.\";\n\nfunction resolveVendorAndModel(modelInput: string): { vendor: string; model: string } {\n const model = modelInput.trim();\n if (!model || !model.includes(\"/\")) {\n throw new Error(\n \"model must be in the format 'vendor/model', for example 'openai/gpt-4o-mini'.\",\n );\n }\n const [vendorRaw, ...rest] = model.split(\"/\");\n const vendor = (vendorRaw ?? \"\").trim().toLowerCase();\n const providerModel = rest.join(\"/\").trim();\n if (!vendor || !providerModel) {\n throw new Error(\n \"model must be in the format 'vendor/model', for example 'openai/gpt-4o-mini'.\",\n );\n }\n return { vendor, model: providerModel };\n}\n\nfunction resolveLlmUrl(vendor: string): string {\n const url = VENDOR_BASE_URLS[vendor];\n if (!url) {\n const supported = Object.keys(VENDOR_BASE_URLS).sort().join(\", \");\n throw new Error(`Unsupported model vendor '${vendor}'. Supported vendors: ${supported}.`);\n }\n return url;\n}\n\nfunction composeSystemPrompt(systemPrompt: string): string {\n const userPrompt = systemPrompt.trim();\n if (userPrompt.toLowerCase().includes(DEFAULT_TOOL_USAGE_INSTRUCTION.toLowerCase())) {\n return userPrompt;\n }\n if (!userPrompt) {\n return DEFAULT_TOOL_USAGE_INSTRUCTION;\n }\n return `${userPrompt}\\n\\n${DEFAULT_TOOL_USAGE_INSTRUCTION}`;\n}\n\nfunction formatMessagesForSummary(messages: ChatMessage[]): string {\n return messages\n .map((message, index) => {\n if (message.role === \"assistant\" && message.tool_calls) {\n return `[${index}] assistant (tool_calls): ${jsonDumpsSafe(message.tool_calls)}`;\n }\n return `[${index}] ${message.role}: ${message.content ?? \"\"}`;\n })\n .join(\"\\n\");\n}\n\ninterface EventPayload {\n id: string;\n session_id: string;\n agent_id: string;\n timestamp: string;\n type: string;\n data: unknown;\n tokens: number;\n latency_ms: number;\n}\n\nexport class Agent {\n readonly vendor: string;\n readonly model: string;\n readonly llmUrl: string;\n readonly agentId: string;\n readonly sessionId: string;\n readonly config: AgentConfig;\n readonly memory: ChatMemory;\n\n private readonly client: OpenAI;\n private readonly tools: ToolRegistry;\n private readonly systemPrompt: string;\n private readonly timeout: number;\n private readonly debug: DebugLogger;\n private readonly approvalCallback?: AgentOptions[\"approvalCallback\"];\n private readonly maxToolRounds: number;\n private readonly eventBaseUrl: string;\n private readonly eventApiKey: string;\n private readonly pendingCustomEvents: EventPayload[] = [];\n private agentInitSent = false;\n private toolsSignature?: string;\n\n constructor(options: AgentOptions) {\n const agentblitApiKey = options.agentblitApiKey.trim();\n if (!agentblitApiKey) {\n throw new Error(\"agentblitApiKey is required\");\n }\n const maxHistory = options.maxHistory ?? 5;\n if (maxHistory < 1) {\n throw new Error(\"maxHistory must be at least 1\");\n }\n const maxToolRounds = options.maxToolRounds ?? 25;\n if (maxToolRounds < 1) {\n throw new Error(\"maxToolRounds must be at least 1\");\n }\n\n const { vendor, model } = resolveVendorAndModel(options.model);\n const llmUrl = resolveLlmUrl(vendor);\n const timeoutSeconds = options.timeout ?? 30;\n const timeoutMs = timeoutSeconds * 1000;\n const agentblitUrl = (options.agentblitUrl ?? \"https://console.agentblit.com\").replace(/\\/$/, \"\");\n const systemPrompt = composeSystemPrompt(options.systemPrompt ?? options.system_prompt ?? \"\");\n\n this.vendor = vendor;\n this.model = model;\n this.llmUrl = llmUrl;\n this.systemPrompt = systemPrompt;\n this.timeout = timeoutMs;\n this.approvalCallback = options.approvalCallback;\n this.maxToolRounds = maxToolRounds;\n this.agentId = options.agentId?.trim() || randomUUID();\n this.sessionId = randomUUID();\n this.eventBaseUrl = agentblitUrl;\n this.eventApiKey = agentblitApiKey;\n this.debug = new DebugLogger(Boolean(options.debug));\n\n this.client = new OpenAI({\n apiKey: options.apiKey,\n baseURL: llmUrl,\n timeout: timeoutMs,\n });\n this.tools = new ToolRegistry({\n baseUrl: agentblitUrl,\n apiKey: agentblitApiKey,\n timeout: timeoutMs,\n });\n for (const customTool of options.customTools ?? []) {\n this.registerTool(customTool);\n }\n this.memory = new ChatMemory({\n maxHistory,\n summarizeFn: (older) => this.summarizeOlderMessages(older),\n });\n this.config = Object.freeze({\n model: this.model,\n vendor: this.vendor,\n llmUrl: this.llmUrl,\n agentblitUrl: this.eventBaseUrl,\n systemPrompt: this.systemPrompt,\n maxHistory,\n debug: Boolean(options.debug),\n timeout: timeoutSeconds,\n agentId: this.agentId,\n sessionId: this.sessionId,\n });\n }\n\n registerTool(fn: ToolHandler): void {\n this.tools.register(fn);\n }\n\n track(eventType: string, properties: Record<string, unknown>): void {\n this.pendingCustomEvents.push(this.makeEvent({ eventType, data: properties }));\n }\n\n private makeEvent(input: {\n eventType: string;\n data: unknown;\n tokens?: number;\n latencyMs?: number;\n }): EventPayload {\n return {\n id: randomId(\"evt\"),\n session_id: this.sessionId,\n agent_id: this.agentId,\n timestamp: nowIsoTimestamp(),\n type: input.eventType,\n data: input.data,\n tokens: Math.max(0, Math.trunc(input.tokens ?? 0)),\n latency_ms: Math.max(0, Math.trunc(input.latencyMs ?? 0)),\n };\n }\n\n private async flushEvents(events: EventPayload[]): Promise<void> {\n if (events.length === 0) {\n return;\n }\n const url = `${this.eventBaseUrl}/api/events/batch`;\n this.debug.log(\"Event batch send start url=%s count=%s\", url, events.length);\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-API-Key\": this.eventApiKey,\n \"Content-Type\": \"application/json\",\n },\n body: jsonDumpsSafe({ events }),\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!response.ok) {\n const body = (await response.text()).slice(0, 1000);\n this.debug.log(\n \"Failed to send events batch status=%s body=%s\",\n response.status,\n body,\n );\n return;\n }\n this.debug.log(\"Event batch send success status=%s count=%s\", response.status, events.length);\n } catch (error) {\n this.debug.log(\"Failed to send events batch: %s\", String(error));\n }\n }\n\n private extractLlmEventMessages(messages: ChatMessage[]): ChatMessage[] {\n if (messages.length === 0) {\n return [];\n }\n const summaryMessage = messages.find(\n (message) =>\n message.role === \"system\" &&\n typeof message.content === \"string\" &&\n message.content.startsWith(\"Summary of earlier conversation:\"),\n );\n const lastMessage = messages[messages.length - 1];\n if (!lastMessage) {\n return [];\n }\n if (!summaryMessage) {\n return [lastMessage];\n }\n if (summaryMessage === lastMessage) {\n return [summaryMessage];\n }\n return [summaryMessage, lastMessage];\n }\n\n private async summarizeOlderMessages(older: ChatMessage[]): Promise<string> {\n const text = formatMessagesForSummary(older);\n this.debug.log(\"Summarizing %s older messages\", older.length);\n const response = await this.client.chat.completions.create({\n model: this.model,\n messages: [\n {\n role: \"system\",\n content:\n \"Summarize the conversation excerpt below for use as memory. Preserve key facts, decisions, and tool outcomes. Be concise.\",\n },\n { role: \"user\", content: text },\n ],\n temperature: 0.2,\n });\n return response.choices[0]?.message?.content?.trim() ?? \"\";\n }\n\n async *run(userMessage: string): AsyncGenerator<string> {\n const events: EventPayload[] = [...this.pendingCustomEvents];\n this.pendingCustomEvents.length = 0;\n try {\n this.memory.append({ role: \"user\", content: userMessage });\n await this.tools.refreshRemote();\n const openaiTools = this.tools.toOpenAITools();\n const toolsSignature = jsonDumpsSafe(openaiTools);\n if (!this.agentInitSent) {\n events.push(\n this.makeEvent({\n eventType: \"agent_init\",\n data: { system_prompt: this.systemPrompt, tools: openaiTools },\n }),\n );\n this.agentInitSent = true;\n this.toolsSignature = toolsSignature;\n } else if (toolsSignature !== this.toolsSignature) {\n events.push(this.makeEvent({ eventType: \"tools_updated\", data: { tools: openaiTools } }));\n this.toolsSignature = toolsSignature;\n }\n events.push(\n this.makeEvent({\n eventType: \"user_prompt\",\n data: { request: { message: userMessage }, response: null },\n }),\n );\n\n let finishedNormally = false;\n for (let round = 0; round < this.maxToolRounds; round += 1) {\n const messages = await this.memory.buildMessagesForLLM(this.systemPrompt);\n this.debug.logLLMRequest(this.model, messages.length, openaiTools.length);\n const llmRequest = {\n model: this.model,\n messages: messages as any,\n stream: true as const,\n ...(openaiTools.length > 0 ? { tools: openaiTools } : {}),\n ...(this.vendor === \"openai\" || this.vendor === \"openrouter\"\n ? { stream_options: { include_usage: true } }\n : {}),\n };\n\n const llmEventRequestData = {\n model: this.model,\n messages: this.extractLlmEventMessages(messages) as any,\n stream: true,\n };\n\n const startedAt = Date.now();\n const stream = (await this.client.chat.completions.create(\n llmRequest as any,\n )) as unknown as AsyncIterable<any>;\n\n const contentParts: string[] = [];\n const toolCallsMap = new Map<\n number,\n { id: string; name: string; arguments: string }\n >();\n let finishReason: string | null = null;\n let llmTotalTokens = 0;\n\n for await (const chunk of stream) {\n if (chunk.usage?.total_tokens) {\n llmTotalTokens = chunk.usage.total_tokens;\n }\n const choice = chunk.choices?.[0];\n if (!choice) {\n continue;\n }\n if (choice.finish_reason) {\n finishReason = choice.finish_reason;\n }\n const delta = choice.delta;\n if (!delta) {\n continue;\n }\n if (delta.content) {\n contentParts.push(delta.content);\n yield delta.content;\n }\n for (const toolCall of delta.tool_calls ?? []) {\n const index = toolCall.index ?? 0;\n const existing = toolCallsMap.get(index) ?? { id: \"\", name: \"\", arguments: \"\" };\n if (toolCall.id) {\n existing.id = toolCall.id;\n }\n if (toolCall.function?.name) {\n existing.name = toolCall.function.name;\n }\n if (toolCall.function?.arguments) {\n existing.arguments += toolCall.function.arguments;\n }\n toolCallsMap.set(index, existing);\n }\n }\n\n const assistantContent = contentParts.join(\"\") || null;\n const llmLatencyMs = Date.now() - startedAt;\n const toolCalls = [...toolCallsMap.entries()]\n .sort(([a], [b]) => a - b)\n .map(([, call]): OpenAIToolCall => ({\n id: call.id,\n type: \"function\",\n function: {\n name: call.name,\n arguments: call.arguments || \"{}\",\n },\n }));\n\n events.push(\n this.makeEvent({\n eventType: \"llm_call\",\n data: {\n request: llmEventRequestData,\n response: {\n finish_reason: finishReason,\n content: assistantContent,\n tool_calls: toolCalls,\n },\n },\n tokens: llmTotalTokens,\n latencyMs: llmLatencyMs,\n }),\n );\n\n if (finishReason === \"tool_calls\" || toolCalls.length > 0) {\n this.debug.logToolCalls(toolCalls);\n this.memory.append({\n role: \"assistant\",\n content: assistantContent,\n tool_calls: toolCalls,\n });\n\n for (const toolCall of toolCalls) {\n const toolStartedAt = Date.now();\n const result = await this.tools.execute(\n toolCall.id,\n toolCall.function.name,\n toolCall.function.arguments,\n this.approvalCallback,\n );\n const toolLatencyMs = Date.now() - toolStartedAt;\n this.debug.logToolResult(toolCall.id, true, result);\n let parsedResponse: unknown;\n try {\n parsedResponse = JSON.parse(result);\n } catch {\n parsedResponse = { raw: result };\n }\n events.push(\n this.makeEvent({\n eventType: \"tool_call\",\n data: {\n request: toolCall,\n response: parsedResponse,\n },\n latencyMs: toolLatencyMs,\n }),\n );\n this.memory.append({\n role: \"tool\",\n tool_call_id: toolCall.id,\n content: result,\n });\n }\n continue;\n }\n\n this.memory.append({\n role: \"assistant\",\n content: assistantContent ?? \"\",\n });\n finishedNormally = true;\n break;\n }\n\n if (!finishedNormally) {\n throw new Error(\n `Exceeded maxToolRounds (${this.maxToolRounds}); increase maxToolRounds or simplify the task.`,\n );\n }\n } catch (error) {\n events.push(\n this.makeEvent({\n eventType: \"agent_loop_error\",\n data: { error: error instanceof Error ? error.message : String(error) },\n }),\n );\n throw error;\n } finally {\n this.debug.log(\"Queueing event flush count=%s\", events.length);\n await this.flushEvents(events);\n }\n }\n\n /**\n * Runs the agent to completion and returns the full assistant text (concatenated stream chunks).\n * Same behavior as iterating {@link Agent.run}; use when you do not need incremental output.\n */\n async runSync(userMessage: string): Promise<string> {\n let text = \"\";\n for await (const chunk of this.run(userMessage)) {\n text += chunk;\n }\n return text;\n }\n}\n","import { ChatMessage, SummarizeFn } from \"./types.js\";\n\nexport class ChatMemory {\n private readonly messagesStore: ChatMessage[] = [];\n private readonly maxHistory: number;\n private readonly summarizeFn?: SummarizeFn;\n\n constructor(options?: { maxHistory?: number; summarizeFn?: SummarizeFn }) {\n const maxHistory = options?.maxHistory ?? 5;\n if (maxHistory < 1) {\n throw new Error(\"maxHistory must be at least 1\");\n }\n this.maxHistory = maxHistory;\n this.summarizeFn = options?.summarizeFn;\n }\n\n get messages(): ChatMessage[] {\n return [...this.messagesStore];\n }\n\n append(message: ChatMessage): void {\n this.messagesStore.push(message);\n }\n\n extend(messages: ChatMessage[]): void {\n this.messagesStore.push(...messages);\n }\n\n clear(): void {\n this.messagesStore.length = 0;\n }\n\n async buildMessagesForLLM(systemPrompt: string): Promise<ChatMessage[]> {\n const out: ChatMessage[] = [{ role: \"system\", content: systemPrompt }];\n if (this.messagesStore.length <= this.maxHistory) {\n out.push(...this.messagesStore);\n return out;\n }\n\n const older = this.messagesStore.slice(0, -this.maxHistory);\n const recent = this.messagesStore.slice(-this.maxHistory);\n let summaryText: string;\n if (!this.summarizeFn) {\n summaryText = `[Earlier conversation truncated: ${older.length} message(s) not shown. Provide summarizeFn on Agent to compress older context with the LLM.]`;\n } else {\n summaryText = await this.summarizeFn(older);\n }\n out.push({\n role: \"system\",\n content: `Summary of earlier conversation:\\n${summaryText}`,\n });\n out.push(...recent);\n return out;\n }\n}\n","import process from \"node:process\";\nimport { randomUUID } from \"node:crypto\";\nimport { ToolHandler, ToolOptions } from \"./types.js\";\n\nconst LOGGER_PREFIX = \"[agentblit]\";\n\nexport class DebugLogger {\n constructor(private readonly enabled: boolean) {}\n\n log(message: string, ...args: unknown[]): void {\n if (!this.enabled) {\n return;\n }\n console.debug(`${LOGGER_PREFIX} ${message}`, ...args);\n }\n\n logLLMRequest(model: string, messageCount: number, toolCount: number): void {\n this.log(\"LLM request model=%s messages=%s tools=%s\", model, messageCount, toolCount);\n }\n\n logToolCalls(calls: unknown[]): void {\n this.log(\"Tool calls: %s\", jsonDumpsSafe(calls));\n }\n\n logToolResult(toolCallId: string, ok: boolean, preview: string): void {\n this.log(\"Tool result id=%s ok=%s preview=%s\", toolCallId, ok, preview.slice(0, 500));\n }\n}\n\nexport function jsonDumpsSafe(obj: unknown): string {\n return JSON.stringify(obj, (_key, value) => {\n if (value instanceof Error) {\n return {\n name: value.name,\n message: value.message,\n stack: value.stack,\n };\n }\n return value;\n });\n}\n\nfunction extractParamNames(fn: ToolHandler): string[] {\n const source = fn.toString();\n const match = source.match(/\\(([^)]*)\\)/);\n if (!match) {\n return [];\n }\n const rawParams = match[1] ?? \"\";\n return rawParams\n .split(\",\")\n .map((segment) => segment.trim())\n .filter(Boolean)\n .map((segment) => segment.replace(/=[\\s\\S]*$/, \"\").trim())\n .map((segment) => segment.replace(/^\\.{3}/, \"\"))\n .filter((segment) => segment !== \"this\");\n}\n\nexport function functionToToolSchema(fn: ToolHandler, explicitSchema?: Record<string, unknown>): Record<string, unknown> {\n if (explicitSchema) {\n return explicitSchema;\n }\n const properties = Object.fromEntries(\n extractParamNames(fn).map((name) => [name, { type: \"string\" }]),\n );\n const required = Object.keys(properties);\n return {\n type: \"object\",\n properties,\n ...(required.length > 0 ? { required } : {}),\n };\n}\n\nexport const TOOL_META = Symbol.for(\"agentblit.tool.meta\");\n\nexport interface ToolMetadata extends Required<Pick<ToolOptions, \"name\" | \"description\" | \"permissionMode\">> {\n inputSchema?: Record<string, unknown>;\n}\n\nexport function setToolMetadata(fn: ToolHandler, options: ToolOptions): ToolHandler {\n const metadata: ToolMetadata = {\n name: options.name ?? fn.name,\n description: options.description ?? \"\",\n permissionMode: options.permissionMode ?? \"always_allow\",\n inputSchema: options.inputSchema,\n };\n (fn as ToolHandler & { [TOOL_META]?: ToolMetadata })[TOOL_META] = metadata;\n return fn;\n}\n\nexport function getToolMetadata(fn: ToolHandler): ToolMetadata | undefined {\n return (fn as ToolHandler & { [TOOL_META]?: ToolMetadata })[TOOL_META];\n}\n\nexport function nowIsoTimestamp(): string {\n return new Date().toISOString();\n}\n\nexport function randomId(prefix: string): string {\n return `${prefix}_${randomUUID().replace(/-/g, \"\")}`;\n}\n\nexport function readStdinLine(promptText: string): Promise<string> {\n return new Promise((resolve) => {\n process.stdout.write(promptText);\n process.stdin.resume();\n process.stdin.once(\"data\", (chunk) => {\n resolve(String(chunk).trim());\n });\n });\n}\n","import {\n ApprovalCallback,\n OpenAIToolCall,\n ToolDefinition,\n ToolHandler,\n ToolOptions,\n} from \"./types.js\";\nimport {\n functionToToolSchema,\n getToolMetadata,\n jsonDumpsSafe,\n readStdinLine,\n setToolMetadata,\n} from \"./utils.js\";\n\ninterface ToolsListResponse {\n ok: boolean;\n tools?: Array<Record<string, unknown>>;\n}\n\nexport function tool(options: ToolOptions): <T extends ToolHandler>(fn: T) => T;\nexport function tool<T extends ToolHandler>(fn: T, options?: ToolOptions): T;\nexport function tool<T extends ToolHandler>(arg1: ToolOptions | T, arg2?: ToolOptions) {\n if (typeof arg1 === \"function\") {\n return setToolMetadata(arg1, arg2 ?? {}) as T;\n }\n return (fn: T): T => setToolMetadata(fn, arg1) as T;\n}\n\nexport class ToolRegistry {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeout: number;\n private readonly remote = new Map<string, ToolDefinition>();\n private readonly custom = new Map<string, ToolDefinition>();\n\n constructor(options: { baseUrl: string; apiKey: string; timeout?: number }) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.apiKey = options.apiKey;\n this.timeout = options.timeout ?? 30000;\n }\n\n register(fn: ToolHandler): void {\n const metadata = getToolMetadata(fn);\n const name = metadata?.name ?? fn.name;\n const description = metadata?.description ?? \"\";\n const permissionMode = metadata?.permissionMode ?? \"always_allow\";\n const inputSchema = functionToToolSchema(fn, metadata?.inputSchema);\n this.custom.set(name, {\n name,\n description,\n inputSchema,\n permissionMode,\n handler: fn,\n });\n }\n\n async refreshRemote(): Promise<void> {\n const url = `${this.baseUrl}/api/tools/list`;\n const response = await fetch(url, {\n method: \"GET\",\n headers: { \"X-API-Key\": this.apiKey },\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!response.ok) {\n throw new Error(\n `AgentBlit request failed for GET '${url}': ${response.status} ${response.statusText}`,\n );\n }\n\n const data = (await response.json()) as ToolsListResponse;\n if (!data.ok) {\n throw new Error(\"tools/list returned ok=false\");\n }\n\n this.remote.clear();\n for (const toolItem of data.tools ?? []) {\n const name = String(toolItem.name ?? \"\");\n if (!name) {\n continue;\n }\n this.remote.set(name, {\n name,\n description: String(toolItem.description ?? \"\"),\n inputSchema: (toolItem.inputSchema as Record<string, unknown>) ?? {\n type: \"object\",\n properties: {},\n },\n permissionMode:\n String(toolItem.permissionMode ?? \"always_allow\") === \"needs_approval\"\n ? \"needs_approval\"\n : \"always_allow\",\n outputSchema: toolItem.outputSchema as Record<string, unknown> | undefined,\n });\n }\n }\n\n private merged(): Map<string, ToolDefinition> {\n const merged = new Map(this.remote);\n for (const [name, def] of this.custom.entries()) {\n merged.set(name, def);\n }\n return merged;\n }\n\n getDefinition(name: string): ToolDefinition | undefined {\n return this.merged().get(name);\n }\n\n toOpenAITools(): Array<Record<string, unknown>> {\n return [...this.merged().values()].map((definition) => ({\n type: \"function\",\n function: {\n name: definition.name,\n description: definition.description,\n parameters: definition.inputSchema,\n },\n }));\n }\n\n private async ensureApproval(\n definition: ToolDefinition,\n toolName: string,\n args: Record<string, unknown>,\n approvalCallback?: ApprovalCallback,\n ): Promise<boolean> {\n if (definition.permissionMode !== \"needs_approval\") {\n return true;\n }\n if (approvalCallback) {\n return approvalCallback(toolName, args);\n }\n const answer = await readStdinLine(\n `Approve tool \"${toolName}\" with args ${jsonDumpsSafe(args)}? [y/N]: `,\n );\n return [\"y\", \"yes\"].includes(answer.toLowerCase());\n }\n\n async execute(\n toolCallId: string,\n toolName: string,\n argumentsJson: string,\n approvalCallback?: ApprovalCallback,\n ): Promise<string> {\n const definition = this.getDefinition(toolName);\n if (!definition) {\n return jsonDumpsSafe({ error: `Unknown tool: ${toolName}` });\n }\n let args: Record<string, unknown>;\n try {\n args = argumentsJson ? (JSON.parse(argumentsJson) as Record<string, unknown>) : {};\n } catch (error) {\n return jsonDumpsSafe({ error: `Invalid JSON arguments: ${String(error)}` });\n }\n\n if (!(await this.ensureApproval(definition, toolName, args, approvalCallback))) {\n return jsonDumpsSafe({ error: \"User denied approval for this tool call.\" });\n }\n\n if (definition.handler) {\n try {\n let result: unknown;\n try {\n result = await definition.handler(...Object.values(args));\n } catch {\n result = await definition.handler(args);\n }\n return jsonDumpsSafe(result);\n } catch (error) {\n return jsonDumpsSafe({ error: error instanceof Error ? error.message : String(error) });\n }\n }\n\n const payload = {\n tool_calls: [\n {\n id: toolCallId,\n type: \"function\",\n function: {\n name: toolName,\n arguments: jsonDumpsSafe(args),\n },\n },\n ] satisfies OpenAIToolCall[],\n };\n const url = `${this.baseUrl}/api/tools/call`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-API-Key\": this.apiKey,\n \"Content-Type\": \"application/json\",\n },\n body: jsonDumpsSafe(payload),\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!response.ok) {\n throw new Error(\n `AgentBlit request failed for POST '${url}': ${response.status} ${response.statusText}`,\n );\n }\n const data = (await response.json()) as {\n ok?: boolean;\n results?: Array<{\n tool_call_id?: string;\n result?: {\n isError?: boolean;\n content?: Array<{ text?: string }>;\n structuredContent?: unknown;\n };\n }>;\n };\n if (!data.ok) {\n return jsonDumpsSafe({ error: data });\n }\n const result = (data.results ?? []).find((item) => item.tool_call_id === toolCallId);\n if (!result) {\n return jsonDumpsSafe({ error: \"No result for tool_call_id\" });\n }\n const toolResult = result.result;\n if (!toolResult) {\n return jsonDumpsSafe({ error: \"Missing tool result payload\" });\n }\n if (toolResult.isError) {\n const text = (toolResult.content ?? []).map((part) => part.text ?? \"\").join(\"\");\n return jsonDumpsSafe({ error: text || \"Tool error\" });\n }\n if (typeof toolResult.structuredContent !== \"undefined\") {\n return jsonDumpsSafe(toolResult.structuredContent);\n }\n const text = (toolResult.content ?? []).map((part) => part.text ?? \"\").join(\"\");\n return jsonDumpsSafe({ result: text });\n }\n}\n"],"mappings":"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","names":["randomUUID","result","text","randomUUID"]}
|
|
1
|
+
{"version":3,"sources":["../src/agent.ts","../src/memory.ts","../src/utils.ts","../src/tools.ts"],"sourcesContent":["import OpenAI from \"openai\";\nimport { randomUUID } from \"node:crypto\";\nimport { ChatMemory } from \"./memory.js\";\nimport {\n AgentRunInput,\n AgentConfig,\n AgentOptions,\n ChatMessage,\n ChatMessageContent,\n OpenAIInputContentPart,\n OpenAIToolCall,\n ToolHandler,\n} from \"./types.js\";\nimport { ToolRegistry } from \"./tools.js\";\nimport { DebugLogger, jsonDumpsSafe, nowIsoTimestamp, randomId } from \"./utils.js\";\n\nconst VENDOR_BASE_URLS: Record<string, string> = {\n openai: \"https://api.openai.com/v1\",\n anthropic: \"https://api.anthropic.com/v1\",\n gemini: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n openrouter: \"https://openrouter.ai/api/v1\",\n};\n\nconst DEFAULT_TOOL_USAGE_INSTRUCTION =\n \"Use tools when they help answer accurately.\";\n\nfunction resolveVendorAndModel(modelInput: string): { vendor: string; model: string } {\n const model = modelInput.trim();\n if (!model || !model.includes(\"/\")) {\n throw new Error(\n \"model must be in the format 'vendor/model', for example 'openai/gpt-4o-mini'.\",\n );\n }\n const [vendorRaw, ...rest] = model.split(\"/\");\n const vendor = (vendorRaw ?? \"\").trim().toLowerCase();\n const providerModel = rest.join(\"/\").trim();\n if (!vendor || !providerModel) {\n throw new Error(\n \"model must be in the format 'vendor/model', for example 'openai/gpt-4o-mini'.\",\n );\n }\n return { vendor, model: providerModel };\n}\n\nfunction resolveLlmUrl(vendor: string): string {\n const url = VENDOR_BASE_URLS[vendor];\n if (!url) {\n const supported = Object.keys(VENDOR_BASE_URLS).sort().join(\", \");\n throw new Error(`Unsupported model vendor '${vendor}'. Supported vendors: ${supported}.`);\n }\n return url;\n}\n\nfunction composeSystemPrompt(systemPrompt: string): string {\n const userPrompt = systemPrompt.trim();\n if (userPrompt.toLowerCase().includes(DEFAULT_TOOL_USAGE_INSTRUCTION.toLowerCase())) {\n return userPrompt;\n }\n if (!userPrompt) {\n return DEFAULT_TOOL_USAGE_INSTRUCTION;\n }\n return `${userPrompt}\\n\\n${DEFAULT_TOOL_USAGE_INSTRUCTION}`;\n}\n\nfunction formatMessagesForSummary(messages: ChatMessage[]): string {\n return messages\n .map((message, index) => {\n if (message.role === \"assistant\" && message.tool_calls) {\n return `[${index}] assistant (tool_calls): ${jsonDumpsSafe(message.tool_calls)}`;\n }\n return `[${index}] ${message.role}: ${serializeContentForSummary(message.content)}`;\n })\n .join(\"\\n\");\n}\n\nfunction serializeContentForSummary(content: ChatMessageContent | undefined): string {\n if (content === null || content === undefined) {\n return \"\";\n }\n if (typeof content === \"string\") {\n return content;\n }\n const parts: string[] = [];\n for (const part of content) {\n if (part.type === \"text\") {\n parts.push(part.text);\n continue;\n }\n if (part.type === \"image_url\") {\n parts.push(`[image: ${part.image_url.url}]`);\n continue;\n }\n if (part.type === \"file\") {\n parts.push(`[file: ${part.file.file_id ?? part.file.filename ?? \"inline_data\"}]`);\n continue;\n }\n parts.push(\"[unsupported_content_part]\");\n }\n return parts.join(\" \").trim();\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction validateInputContentParts(parts: OpenAIInputContentPart[]): OpenAIInputContentPart[] {\n for (const part of parts) {\n if (part.type === \"text\") {\n if (typeof part.text !== \"string\") {\n throw new Error(\"Text content part must include a string 'text' field.\");\n }\n continue;\n }\n if (part.type === \"image_url\") {\n if (!part.image_url || typeof part.image_url.url !== \"string\") {\n throw new Error(\n \"Image content part must include image_url.url as a string.\",\n );\n }\n continue;\n }\n if (part.type === \"file\") {\n const file = part.file;\n if (!file || (!file.file_id && !file.file_data)) {\n throw new Error(\n \"File content part must include at least one of file.file_id or file.file_data.\",\n );\n }\n continue;\n }\n throw new Error(\n \"Unsupported content part type. Supported types: text, image_url, file.\",\n );\n }\n return parts;\n}\n\nfunction normalizeRunInput(userInput: AgentRunInput): ChatMessageContent {\n if (typeof userInput === \"string\") {\n return userInput;\n }\n if (Array.isArray(userInput)) {\n return validateInputContentParts(userInput);\n }\n if (isObject(userInput)) {\n const { content } = userInput;\n if (typeof content === \"string\") {\n return content;\n }\n if (Array.isArray(content)) {\n return validateInputContentParts(content as OpenAIInputContentPart[]);\n }\n }\n throw new Error(\n \"run input must be a string, an array of OpenAI content parts, or an object with a content field.\",\n );\n}\n\ninterface EventPayload {\n id: string;\n session_id: string;\n agent_id: string;\n timestamp: string;\n type: string;\n data: unknown;\n tokens: number;\n latency_ms: number;\n}\n\nexport class Agent {\n readonly vendor: string;\n readonly model: string;\n readonly llmUrl: string;\n readonly agentId: string;\n readonly sessionId: string;\n readonly config: AgentConfig;\n readonly memory: ChatMemory;\n\n private readonly client: OpenAI;\n private readonly tools: ToolRegistry;\n private readonly systemPrompt: string;\n private readonly timeout: number;\n private readonly debug: DebugLogger;\n private readonly approvalCallback?: AgentOptions[\"approvalCallback\"];\n private readonly maxToolRounds: number;\n private readonly eventBaseUrl: string;\n private readonly eventApiKey: string;\n private readonly pendingCustomEvents: EventPayload[] = [];\n private agentInitSent = false;\n private toolsSignature?: string;\n\n constructor(options: AgentOptions) {\n const agentblitApiKey = options.agentblitApiKey.trim();\n if (!agentblitApiKey) {\n throw new Error(\"agentblitApiKey is required\");\n }\n const maxHistory = options.maxHistory ?? 5;\n if (maxHistory < 1) {\n throw new Error(\"maxHistory must be at least 1\");\n }\n const maxToolRounds = options.maxToolRounds ?? 25;\n if (maxToolRounds < 1) {\n throw new Error(\"maxToolRounds must be at least 1\");\n }\n\n const { vendor, model } = resolveVendorAndModel(options.model);\n const llmUrl = resolveLlmUrl(vendor);\n const timeoutSeconds = options.timeout ?? 30;\n const timeoutMs = timeoutSeconds * 1000;\n const agentblitUrl = (options.agentblitUrl ?? \"https://console.agentblit.com\").replace(/\\/$/, \"\");\n const systemPrompt = composeSystemPrompt(options.systemPrompt ?? options.system_prompt ?? \"\");\n\n this.vendor = vendor;\n this.model = model;\n this.llmUrl = llmUrl;\n this.systemPrompt = systemPrompt;\n this.timeout = timeoutMs;\n this.approvalCallback = options.approvalCallback;\n this.maxToolRounds = maxToolRounds;\n this.agentId = options.agentId?.trim() || randomUUID();\n this.sessionId = randomUUID();\n this.eventBaseUrl = agentblitUrl;\n this.eventApiKey = agentblitApiKey;\n this.debug = new DebugLogger(Boolean(options.debug));\n\n this.client = new OpenAI({\n apiKey: options.apiKey,\n baseURL: llmUrl,\n timeout: timeoutMs,\n });\n this.tools = new ToolRegistry({\n baseUrl: agentblitUrl,\n apiKey: agentblitApiKey,\n timeout: timeoutMs,\n });\n for (const customTool of options.customTools ?? []) {\n this.registerTool(customTool);\n }\n this.memory = new ChatMemory({\n maxHistory,\n summarizeFn: (older) => this.summarizeOlderMessages(older),\n });\n this.config = Object.freeze({\n model: this.model,\n vendor: this.vendor,\n llmUrl: this.llmUrl,\n agentblitUrl: this.eventBaseUrl,\n systemPrompt: this.systemPrompt,\n maxHistory,\n debug: Boolean(options.debug),\n timeout: timeoutSeconds,\n agentId: this.agentId,\n sessionId: this.sessionId,\n });\n }\n\n registerTool(fn: ToolHandler): void {\n this.tools.register(fn);\n }\n\n track(eventType: string, properties: Record<string, unknown>): void {\n this.pendingCustomEvents.push(this.makeEvent({ eventType, data: properties }));\n }\n\n private makeEvent(input: {\n eventType: string;\n data: unknown;\n tokens?: number;\n latencyMs?: number;\n }): EventPayload {\n return {\n id: randomId(\"evt\"),\n session_id: this.sessionId,\n agent_id: this.agentId,\n timestamp: nowIsoTimestamp(),\n type: input.eventType,\n data: input.data,\n tokens: Math.max(0, Math.trunc(input.tokens ?? 0)),\n latency_ms: Math.max(0, Math.trunc(input.latencyMs ?? 0)),\n };\n }\n\n private async flushEvents(events: EventPayload[]): Promise<void> {\n if (events.length === 0) {\n return;\n }\n const url = `${this.eventBaseUrl}/api/events/batch`;\n this.debug.log(\"Event batch send start url=%s count=%s\", url, events.length);\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-API-Key\": this.eventApiKey,\n \"Content-Type\": \"application/json\",\n },\n body: jsonDumpsSafe({ events }),\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!response.ok) {\n const body = (await response.text()).slice(0, 1000);\n this.debug.log(\n \"Failed to send events batch status=%s body=%s\",\n response.status,\n body,\n );\n return;\n }\n this.debug.log(\"Event batch send success status=%s count=%s\", response.status, events.length);\n } catch (error) {\n this.debug.log(\"Failed to send events batch: %s\", String(error));\n }\n }\n\n private extractLlmEventMessages(messages: ChatMessage[]): ChatMessage[] {\n if (messages.length === 0) {\n return [];\n }\n const summaryMessage = messages.find(\n (message) =>\n message.role === \"system\" &&\n typeof message.content === \"string\" &&\n message.content.startsWith(\"Summary of earlier conversation:\"),\n );\n const lastMessage = messages[messages.length - 1];\n if (!lastMessage) {\n return [];\n }\n if (!summaryMessage) {\n return [lastMessage];\n }\n if (summaryMessage === lastMessage) {\n return [summaryMessage];\n }\n return [summaryMessage, lastMessage];\n }\n\n private async summarizeOlderMessages(older: ChatMessage[]): Promise<string> {\n const text = formatMessagesForSummary(older);\n this.debug.log(\"Summarizing %s older messages\", older.length);\n const response = await this.client.chat.completions.create({\n model: this.model,\n messages: [\n {\n role: \"system\",\n content:\n \"Summarize the conversation excerpt below for use as memory. Preserve key facts, decisions, and tool outcomes. Be concise.\",\n },\n { role: \"user\", content: text },\n ],\n temperature: 0.2,\n });\n return response.choices[0]?.message?.content?.trim() ?? \"\";\n }\n\n async *run(userInput: AgentRunInput): AsyncGenerator<string> {\n const events: EventPayload[] = [...this.pendingCustomEvents];\n this.pendingCustomEvents.length = 0;\n try {\n const userContent = normalizeRunInput(userInput);\n this.memory.append({ role: \"user\", content: userContent });\n await this.tools.refreshRemote();\n const openaiTools = this.tools.toOpenAITools();\n const toolsSignature = jsonDumpsSafe(openaiTools);\n if (!this.agentInitSent) {\n events.push(\n this.makeEvent({\n eventType: \"agent_init\",\n data: { system_prompt: this.systemPrompt, tools: openaiTools },\n }),\n );\n this.agentInitSent = true;\n this.toolsSignature = toolsSignature;\n } else if (toolsSignature !== this.toolsSignature) {\n events.push(this.makeEvent({ eventType: \"tools_updated\", data: { tools: openaiTools } }));\n this.toolsSignature = toolsSignature;\n }\n events.push(\n this.makeEvent({\n eventType: \"user_prompt\",\n data: { request: { message: userContent }, response: null },\n }),\n );\n\n let finishedNormally = false;\n for (let round = 0; round < this.maxToolRounds; round += 1) {\n const messages = await this.memory.buildMessagesForLLM(this.systemPrompt);\n this.debug.logLLMRequest(this.model, messages.length, openaiTools.length);\n const llmRequest = {\n model: this.model,\n messages: messages as any,\n stream: true as const,\n ...(openaiTools.length > 0 ? { tools: openaiTools } : {}),\n ...(this.vendor === \"openai\" || this.vendor === \"openrouter\"\n ? { stream_options: { include_usage: true } }\n : {}),\n };\n\n const llmEventRequestData = {\n model: this.model,\n messages: this.extractLlmEventMessages(messages) as any,\n stream: true,\n };\n\n const startedAt = Date.now();\n const stream = (await this.client.chat.completions.create(\n llmRequest as any,\n )) as unknown as AsyncIterable<any>;\n\n const contentParts: string[] = [];\n const toolCallsMap = new Map<\n number,\n { id: string; name: string; arguments: string }\n >();\n let finishReason: string | null = null;\n let llmTotalTokens = 0;\n\n for await (const chunk of stream) {\n if (chunk.usage?.total_tokens) {\n llmTotalTokens = chunk.usage.total_tokens;\n }\n const choice = chunk.choices?.[0];\n if (!choice) {\n continue;\n }\n if (choice.finish_reason) {\n finishReason = choice.finish_reason;\n }\n const delta = choice.delta;\n if (!delta) {\n continue;\n }\n if (delta.content) {\n contentParts.push(delta.content);\n yield delta.content;\n }\n for (const toolCall of delta.tool_calls ?? []) {\n const index = toolCall.index ?? 0;\n const existing = toolCallsMap.get(index) ?? { id: \"\", name: \"\", arguments: \"\" };\n if (toolCall.id) {\n existing.id = toolCall.id;\n }\n if (toolCall.function?.name) {\n existing.name = toolCall.function.name;\n }\n if (toolCall.function?.arguments) {\n existing.arguments += toolCall.function.arguments;\n }\n toolCallsMap.set(index, existing);\n }\n }\n\n const assistantContent = contentParts.join(\"\") || null;\n const llmLatencyMs = Date.now() - startedAt;\n const toolCalls = [...toolCallsMap.entries()]\n .sort(([a], [b]) => a - b)\n .map(([, call]): OpenAIToolCall => ({\n id: call.id,\n type: \"function\",\n function: {\n name: call.name,\n arguments: call.arguments || \"{}\",\n },\n }));\n\n events.push(\n this.makeEvent({\n eventType: \"llm_call\",\n data: {\n request: llmEventRequestData,\n response: {\n finish_reason: finishReason,\n content: assistantContent,\n tool_calls: toolCalls,\n },\n },\n tokens: llmTotalTokens,\n latencyMs: llmLatencyMs,\n }),\n );\n\n if (finishReason === \"tool_calls\" || toolCalls.length > 0) {\n this.debug.logToolCalls(toolCalls);\n this.memory.append({\n role: \"assistant\",\n content: assistantContent,\n tool_calls: toolCalls,\n });\n\n for (const toolCall of toolCalls) {\n const toolStartedAt = Date.now();\n const result = await this.tools.execute(\n toolCall.id,\n toolCall.function.name,\n toolCall.function.arguments,\n this.approvalCallback,\n );\n const toolLatencyMs = Date.now() - toolStartedAt;\n this.debug.logToolResult(toolCall.id, true, result);\n let parsedResponse: unknown;\n try {\n parsedResponse = JSON.parse(result);\n } catch {\n parsedResponse = { raw: result };\n }\n events.push(\n this.makeEvent({\n eventType: \"tool_call\",\n data: {\n request: toolCall,\n response: parsedResponse,\n },\n latencyMs: toolLatencyMs,\n }),\n );\n this.memory.append({\n role: \"tool\",\n tool_call_id: toolCall.id,\n content: result,\n });\n }\n continue;\n }\n\n this.memory.append({\n role: \"assistant\",\n content: assistantContent ?? \"\",\n });\n finishedNormally = true;\n break;\n }\n\n if (!finishedNormally) {\n throw new Error(\n `Exceeded maxToolRounds (${this.maxToolRounds}); increase maxToolRounds or simplify the task.`,\n );\n }\n } catch (error) {\n events.push(\n this.makeEvent({\n eventType: \"agent_loop_error\",\n data: { error: error instanceof Error ? error.message : String(error) },\n }),\n );\n throw error;\n } finally {\n this.debug.log(\"Queueing event flush count=%s\", events.length);\n await this.flushEvents(events);\n }\n }\n\n /**\n * Runs the agent to completion and returns the full assistant text (concatenated stream chunks).\n * Same behavior as iterating {@link Agent.run}; use when you do not need incremental output.\n */\n async runSync(userInput: AgentRunInput): Promise<string> {\n let text = \"\";\n for await (const chunk of this.run(userInput)) {\n text += chunk;\n }\n return text;\n }\n}\n","import { ChatMessage, SummarizeFn } from \"./types.js\";\n\nexport class ChatMemory {\n private readonly messagesStore: ChatMessage[] = [];\n private readonly maxHistory: number;\n private readonly summarizeFn?: SummarizeFn;\n\n constructor(options?: { maxHistory?: number; summarizeFn?: SummarizeFn }) {\n const maxHistory = options?.maxHistory ?? 5;\n if (maxHistory < 1) {\n throw new Error(\"maxHistory must be at least 1\");\n }\n this.maxHistory = maxHistory;\n this.summarizeFn = options?.summarizeFn;\n }\n\n get messages(): ChatMessage[] {\n return [...this.messagesStore];\n }\n\n append(message: ChatMessage): void {\n this.messagesStore.push(message);\n }\n\n extend(messages: ChatMessage[]): void {\n this.messagesStore.push(...messages);\n }\n\n clear(): void {\n this.messagesStore.length = 0;\n }\n\n async buildMessagesForLLM(systemPrompt: string): Promise<ChatMessage[]> {\n const out: ChatMessage[] = [{ role: \"system\", content: systemPrompt }];\n if (this.messagesStore.length <= this.maxHistory) {\n out.push(...this.messagesStore);\n return out;\n }\n\n const older = this.messagesStore.slice(0, -this.maxHistory);\n const recent = this.messagesStore.slice(-this.maxHistory);\n let summaryText: string;\n if (!this.summarizeFn) {\n summaryText = `[Earlier conversation truncated: ${older.length} message(s) not shown. Provide summarizeFn on Agent to compress older context with the LLM.]`;\n } else {\n summaryText = await this.summarizeFn(older);\n }\n out.push({\n role: \"system\",\n content: `Summary of earlier conversation:\\n${summaryText}`,\n });\n out.push(...recent);\n return out;\n }\n}\n","import process from \"node:process\";\nimport { randomUUID } from \"node:crypto\";\nimport { ToolHandler, ToolOptions } from \"./types.js\";\n\nconst LOGGER_PREFIX = \"[agentblit]\";\n\nexport class DebugLogger {\n constructor(private readonly enabled: boolean) {}\n\n log(message: string, ...args: unknown[]): void {\n if (!this.enabled) {\n return;\n }\n console.debug(`${LOGGER_PREFIX} ${message}`, ...args);\n }\n\n logLLMRequest(model: string, messageCount: number, toolCount: number): void {\n this.log(\"LLM request model=%s messages=%s tools=%s\", model, messageCount, toolCount);\n }\n\n logToolCalls(calls: unknown[]): void {\n this.log(\"Tool calls: %s\", jsonDumpsSafe(calls));\n }\n\n logToolResult(toolCallId: string, ok: boolean, preview: string): void {\n this.log(\"Tool result id=%s ok=%s preview=%s\", toolCallId, ok, preview.slice(0, 500));\n }\n}\n\nexport function jsonDumpsSafe(obj: unknown): string {\n return JSON.stringify(obj, (_key, value) => {\n if (value instanceof Error) {\n return {\n name: value.name,\n message: value.message,\n stack: value.stack,\n };\n }\n return value;\n });\n}\n\nfunction extractParamNames(fn: ToolHandler): string[] {\n const source = fn.toString();\n const match = source.match(/\\(([^)]*)\\)/);\n if (!match) {\n return [];\n }\n const rawParams = match[1] ?? \"\";\n return rawParams\n .split(\",\")\n .map((segment) => segment.trim())\n .filter(Boolean)\n .map((segment) => segment.replace(/=[\\s\\S]*$/, \"\").trim())\n .map((segment) => segment.replace(/^\\.{3}/, \"\"))\n .filter((segment) => segment !== \"this\");\n}\n\nexport function functionToToolSchema(fn: ToolHandler, explicitSchema?: Record<string, unknown>): Record<string, unknown> {\n if (explicitSchema) {\n return explicitSchema;\n }\n const properties = Object.fromEntries(\n extractParamNames(fn).map((name) => [name, { type: \"string\" }]),\n );\n const required = Object.keys(properties);\n return {\n type: \"object\",\n properties,\n ...(required.length > 0 ? { required } : {}),\n };\n}\n\nexport const TOOL_META = Symbol.for(\"agentblit.tool.meta\");\n\nexport interface ToolMetadata extends Required<Pick<ToolOptions, \"name\" | \"description\" | \"permissionMode\">> {\n inputSchema?: Record<string, unknown>;\n}\n\nexport function setToolMetadata(fn: ToolHandler, options: ToolOptions): ToolHandler {\n const metadata: ToolMetadata = {\n name: options.name ?? fn.name,\n description: options.description ?? \"\",\n permissionMode: options.permissionMode ?? \"always_allow\",\n inputSchema: options.inputSchema,\n };\n (fn as ToolHandler & { [TOOL_META]?: ToolMetadata })[TOOL_META] = metadata;\n return fn;\n}\n\nexport function getToolMetadata(fn: ToolHandler): ToolMetadata | undefined {\n return (fn as ToolHandler & { [TOOL_META]?: ToolMetadata })[TOOL_META];\n}\n\nexport function nowIsoTimestamp(): string {\n return new Date().toISOString();\n}\n\nexport function randomId(prefix: string): string {\n return `${prefix}_${randomUUID().replace(/-/g, \"\")}`;\n}\n\nexport function readStdinLine(promptText: string): Promise<string> {\n return new Promise((resolve) => {\n process.stdout.write(promptText);\n process.stdin.resume();\n process.stdin.once(\"data\", (chunk) => {\n resolve(String(chunk).trim());\n });\n });\n}\n","import {\n ApprovalCallback,\n OpenAIToolCall,\n ToolDefinition,\n ToolHandler,\n ToolOptions,\n} from \"./types.js\";\nimport {\n functionToToolSchema,\n getToolMetadata,\n jsonDumpsSafe,\n readStdinLine,\n setToolMetadata,\n} from \"./utils.js\";\n\ninterface ToolsListResponse {\n tools?: Array<Record<string, unknown>>;\n}\n\nexport function tool(options: ToolOptions): <T extends ToolHandler>(fn: T) => T;\nexport function tool<T extends ToolHandler>(fn: T, options?: ToolOptions): T;\nexport function tool<T extends ToolHandler>(arg1: ToolOptions | T, arg2?: ToolOptions) {\n if (typeof arg1 === \"function\") {\n return setToolMetadata(arg1, arg2 ?? {}) as T;\n }\n return (fn: T): T => setToolMetadata(fn, arg1) as T;\n}\n\nexport class ToolRegistry {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeout: number;\n private readonly remote = new Map<string, ToolDefinition>();\n private readonly custom = new Map<string, ToolDefinition>();\n\n constructor(options: { baseUrl: string; apiKey: string; timeout?: number }) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.apiKey = options.apiKey;\n this.timeout = options.timeout ?? 30000;\n }\n\n register(fn: ToolHandler): void {\n const metadata = getToolMetadata(fn);\n const name = metadata?.name ?? fn.name;\n const description = metadata?.description ?? \"\";\n const permissionMode = metadata?.permissionMode ?? \"always_allow\";\n const inputSchema = functionToToolSchema(fn, metadata?.inputSchema);\n this.custom.set(name, {\n name,\n description,\n inputSchema,\n permissionMode,\n handler: fn,\n });\n }\n\n async refreshRemote(): Promise<void> {\n const url = `${this.baseUrl}/api/1.0/tools/list`;\n const response = await fetch(url, {\n method: \"GET\",\n headers: { \"X-API-Key\": this.apiKey },\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!response.ok) {\n throw new Error(\n `AgentBlit request failed for GET '${url}': ${response.status} ${response.statusText}`,\n );\n }\n\n const data = (await response.json()) as ToolsListResponse;\n\n this.remote.clear();\n for (const toolItem of data.tools ?? []) {\n const type = String(toolItem.type ?? \"\");\n if (type !== \"function\") {\n continue;\n }\n const fn = (toolItem.function as Record<string, unknown> | undefined) ?? {};\n const name = String(fn.name ?? \"\");\n if (!name) {\n continue;\n }\n this.remote.set(name, {\n name,\n description: String(fn.description ?? \"\"),\n inputSchema: (fn.parameters as Record<string, unknown>) ?? {\n type: \"object\",\n properties: {},\n },\n permissionMode:\n String(toolItem.permission_mode ?? \"always_allow\") === \"needs_approval\"\n ? \"needs_approval\"\n : \"always_allow\",\n });\n }\n }\n\n private merged(): Map<string, ToolDefinition> {\n const merged = new Map(this.remote);\n for (const [name, def] of this.custom.entries()) {\n merged.set(name, def);\n }\n return merged;\n }\n\n getDefinition(name: string): ToolDefinition | undefined {\n return this.merged().get(name);\n }\n\n toOpenAITools(): Array<Record<string, unknown>> {\n return [...this.merged().values()].map((definition) => ({\n type: \"function\",\n function: {\n name: definition.name,\n description: definition.description,\n parameters: definition.inputSchema,\n },\n }));\n }\n\n private async ensureApproval(\n definition: ToolDefinition,\n toolName: string,\n args: Record<string, unknown>,\n approvalCallback?: ApprovalCallback,\n ): Promise<boolean> {\n if (definition.permissionMode !== \"needs_approval\") {\n return true;\n }\n if (approvalCallback) {\n return approvalCallback(toolName, args);\n }\n const answer = await readStdinLine(\n `Approve tool \"${toolName}\" with args ${jsonDumpsSafe(args)}? [y/N]: `,\n );\n return [\"y\", \"yes\"].includes(answer.toLowerCase());\n }\n\n async execute(\n toolCallId: string,\n toolName: string,\n argumentsJson: string,\n approvalCallback?: ApprovalCallback,\n ): Promise<string> {\n const definition = this.getDefinition(toolName);\n if (!definition) {\n return jsonDumpsSafe({ error: `Unknown tool: ${toolName}` });\n }\n let args: Record<string, unknown>;\n try {\n args = argumentsJson ? (JSON.parse(argumentsJson) as Record<string, unknown>) : {};\n } catch (error) {\n return jsonDumpsSafe({ error: `Invalid JSON arguments: ${String(error)}` });\n }\n\n if (!(await this.ensureApproval(definition, toolName, args, approvalCallback))) {\n return jsonDumpsSafe({ error: \"User denied approval for this tool call.\" });\n }\n\n if (definition.handler) {\n try {\n let result: unknown;\n try {\n result = await definition.handler(...Object.values(args));\n } catch {\n result = await definition.handler(args);\n }\n return jsonDumpsSafe(result);\n } catch (error) {\n return jsonDumpsSafe({ error: error instanceof Error ? error.message : String(error) });\n }\n }\n\n const payload = {\n tool_calls: [\n {\n id: toolCallId,\n type: \"function\",\n function: {\n name: toolName,\n arguments: jsonDumpsSafe(args),\n },\n },\n ] satisfies OpenAIToolCall[],\n };\n if (!toolCallId.trim()) {\n return jsonDumpsSafe({ error: \"Missing tool_call_id\" });\n }\n const url = `${this.baseUrl}/api/1.0/tools/call`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-API-Key\": this.apiKey,\n \"Content-Type\": \"application/json\",\n },\n body: jsonDumpsSafe(payload),\n signal: AbortSignal.timeout(this.timeout),\n });\n if (!response.ok) {\n throw new Error(\n `AgentBlit request failed for POST '${url}': ${response.status} ${response.statusText}`,\n );\n }\n const data = (await response.json()) as {\n results?: Array<{\n tool_call_id?: string;\n result?: unknown;\n error?: unknown;\n }>;\n };\n const result = (data.results ?? []).find((item) => item.tool_call_id === toolCallId);\n if (!result) {\n return jsonDumpsSafe({ error: \"No result for tool_call_id\" });\n }\n if (typeof result.error !== \"undefined\") {\n return jsonDumpsSafe({ error: result.error });\n }\n if (typeof result.result !== \"undefined\") {\n return jsonDumpsSafe(result.result);\n }\n return jsonDumpsSafe({ error: \"Missing result or error for tool_call_id\" });\n }\n}\n"],"mappings":"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","names":["randomUUID","result","randomUUID"]}
|