@theokit/agents 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bridge.d.ts +52 -13
- package/dist/bridge.js +9 -4
- package/dist/chunk-7QVYU63E.js +7 -0
- package/dist/chunk-7QVYU63E.js.map +1 -0
- package/dist/{chunk-SWPOX3LR.js → chunk-NC5EE7HN.js} +279 -311
- package/dist/chunk-NC5EE7HN.js.map +1 -0
- package/dist/{chunk-3LCIXX3T.js → chunk-O4UG4RXE.js} +19 -7
- package/dist/chunk-O4UG4RXE.js.map +1 -0
- package/dist/{chunk-QNPXMBSH.js → chunk-VKHDADMG.js} +23 -7
- package/dist/chunk-VKHDADMG.js.map +1 -0
- package/dist/decorators.d.ts +3 -3
- package/dist/decorators.js +3 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +10 -5
- package/dist/{mcp-DmtwLSF-.d.ts → mcp-yyfC5u7t.d.ts} +2 -2
- package/dist/testing.d.ts +47 -0
- package/dist/testing.js +73 -0
- package/dist/testing.js.map +1 -0
- package/package.json +9 -3
- package/dist/chunk-3LCIXX3T.js.map +0 -1
- package/dist/chunk-QNPXMBSH.js.map +0 -1
- package/dist/chunk-SWPOX3LR.js.map +0 -1
|
@@ -2,12 +2,12 @@ import {
|
|
|
2
2
|
AGENT_CONFIG,
|
|
3
3
|
AGENT_MAIN_LOOP,
|
|
4
4
|
Audit,
|
|
5
|
+
Budget,
|
|
5
6
|
RequiresApproval,
|
|
6
7
|
TOOLBOX_CONFIG,
|
|
7
8
|
TOOL_CONFIG,
|
|
8
9
|
TOOL_METHODS,
|
|
9
10
|
Trace,
|
|
10
|
-
__name,
|
|
11
11
|
getAgentConfig,
|
|
12
12
|
getGatewayConfig,
|
|
13
13
|
getMcpConfig,
|
|
@@ -16,7 +16,10 @@ import {
|
|
|
16
16
|
getMixins,
|
|
17
17
|
getSkillsConfig,
|
|
18
18
|
getSubAgents
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-O4UG4RXE.js";
|
|
20
|
+
import {
|
|
21
|
+
__name
|
|
22
|
+
} from "./chunk-7QVYU63E.js";
|
|
20
23
|
|
|
21
24
|
// src/bridge/agent-execution-context.ts
|
|
22
25
|
function createAgentExecutionContext(base, agent, run, toolCall) {
|
|
@@ -39,11 +42,16 @@ __name(isAgentContext, "isAgentContext");
|
|
|
39
42
|
|
|
40
43
|
// src/bridge/walk-agent-metadata.ts
|
|
41
44
|
import "reflect-metadata";
|
|
42
|
-
import { Reflector } from "@theokit/http
|
|
43
|
-
var reflectorInstance = new Reflector();
|
|
45
|
+
import { Reflector } from "@theokit/http";
|
|
44
46
|
var USE_GUARDS = /* @__PURE__ */ Symbol.for("theokit:http-decorators:use-guards");
|
|
45
47
|
var USE_INTERCEPTORS = /* @__PURE__ */ Symbol.for("theokit:http-decorators:use-interceptors");
|
|
46
48
|
var USE_FILTERS = /* @__PURE__ */ Symbol.for("theokit:http-decorators:use-filters");
|
|
49
|
+
var AgentWarningCode = {
|
|
50
|
+
INTERCEPTOR_METADATA_ONLY: "THEO_AGENT_INTERCEPTOR_METADATA_ONLY",
|
|
51
|
+
FILTER_METADATA_ONLY: "THEO_AGENT_FILTER_METADATA_ONLY",
|
|
52
|
+
BUDGET_TOP_LEVEL_METADATA_ONLY: "THEO_AGENT_BUDGET_TOP_LEVEL_METADATA_ONLY"
|
|
53
|
+
};
|
|
54
|
+
var reflectorInstance = new Reflector();
|
|
47
55
|
function walkToolbox(ToolboxClass) {
|
|
48
56
|
const config = getMeta(TOOLBOX_CONFIG, ToolboxClass) ?? {};
|
|
49
57
|
const methods = getMeta(TOOL_METHODS, ToolboxClass) ?? [];
|
|
@@ -96,7 +104,17 @@ function walkAgentMetadata(AgentClass, toolboxClasses = []) {
|
|
|
96
104
|
}
|
|
97
105
|
const guards = getMeta(USE_GUARDS, AgentClass) ?? [];
|
|
98
106
|
const interceptors = getMeta(USE_INTERCEPTORS, AgentClass) ?? [];
|
|
107
|
+
if (interceptors.length > 0) {
|
|
108
|
+
console.warn(`[${AgentWarningCode.INTERCEPTOR_METADATA_ONLY}] Agent ${AgentClass.name}: @UseInterceptors is metadata-only on agents and will not execute. Agent pipeline shares guards with HTTP but uses a distinct execution model. Interceptors are reserved for future agent-specific lifecycle hooks.`);
|
|
109
|
+
}
|
|
99
110
|
const filters = getMeta(USE_FILTERS, AgentClass) ?? [];
|
|
111
|
+
if (filters.length > 0) {
|
|
112
|
+
console.warn(`[${AgentWarningCode.FILTER_METADATA_ONLY}] Agent ${AgentClass.name}: @UseFilters is metadata-only on agents and will not catch agent runtime errors. Agent errors flow through SSE error events, not HTTP exception filters. Filters are reserved for future agent-specific error handling.`);
|
|
113
|
+
}
|
|
114
|
+
const agentBudget = reflectorInstance.get(Budget, AgentClass);
|
|
115
|
+
if (agentBudget) {
|
|
116
|
+
console.warn(`[${AgentWarningCode.BUDGET_TOP_LEVEL_METADATA_ONLY}] Agent ${AgentClass.name}: @Budget on top-level agents is metadata-only in this version. Budget enforcement currently applies to delegate() calls only. Top-level run enforcement will be wired through SDK cost tracking in a future release.`);
|
|
117
|
+
}
|
|
100
118
|
const toolboxes = toolboxClasses.map(walkToolbox);
|
|
101
119
|
const gateway = getGatewayConfig(AgentClass);
|
|
102
120
|
const subAgentClasses = getSubAgents(AgentClass);
|
|
@@ -299,7 +317,8 @@ function generateAgentRoutes(ctx) {
|
|
|
299
317
|
}
|
|
300
318
|
});
|
|
301
319
|
}
|
|
302
|
-
const
|
|
320
|
+
const rawSessionId = body?.sessionId;
|
|
321
|
+
const sessionId = typeof rawSessionId === "string" ? rawSessionId : `session-${Date.now()}`;
|
|
303
322
|
return streamAgentResponse(createRun(message, sessionId));
|
|
304
323
|
}, "handler")
|
|
305
324
|
});
|
|
@@ -337,281 +356,197 @@ function generateAgentRoutes(ctx) {
|
|
|
337
356
|
}
|
|
338
357
|
__name(generateAgentRoutes, "generateAgentRoutes");
|
|
339
358
|
|
|
340
|
-
// src/bridge/
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
359
|
+
// src/bridge/event-translator.ts
|
|
360
|
+
function asString(value, fallback) {
|
|
361
|
+
if (typeof value === "string") return value;
|
|
362
|
+
return fallback;
|
|
363
|
+
}
|
|
364
|
+
__name(asString, "asString");
|
|
365
|
+
function translateSystemEvent(msg, runId) {
|
|
366
|
+
return [
|
|
367
|
+
{
|
|
368
|
+
type: "run_started",
|
|
369
|
+
runId,
|
|
370
|
+
agentName: asString(msg.agent_id, "agent"),
|
|
371
|
+
model: asString(msg.model, "unknown")
|
|
372
|
+
}
|
|
373
|
+
];
|
|
374
|
+
}
|
|
375
|
+
__name(translateSystemEvent, "translateSystemEvent");
|
|
376
|
+
function translateAssistantEvent(msg) {
|
|
377
|
+
const events = [];
|
|
378
|
+
const content = msg.content;
|
|
379
|
+
if (!Array.isArray(content)) return events;
|
|
380
|
+
for (const block of content) {
|
|
381
|
+
const b = block;
|
|
382
|
+
if (b.type === "text" && b.text) {
|
|
383
|
+
events.push({
|
|
384
|
+
type: "text_delta",
|
|
385
|
+
content: b.text
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
if (b.type === "tool_use") {
|
|
389
|
+
events.push({
|
|
390
|
+
type: "tool_call",
|
|
391
|
+
callId: b.id ?? `tc-${Date.now()}`,
|
|
392
|
+
toolName: b.name ?? "unknown",
|
|
393
|
+
input: b.input ?? {}
|
|
394
|
+
});
|
|
395
|
+
}
|
|
349
396
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
toolMap.set(s, t);
|
|
365
|
-
return {
|
|
366
|
-
type: "function",
|
|
367
|
-
function: {
|
|
368
|
-
name: s,
|
|
369
|
-
description: t.description,
|
|
370
|
-
parameters: convertZodToJsonSchema(t.inputSchema)
|
|
397
|
+
return events;
|
|
398
|
+
}
|
|
399
|
+
__name(translateAssistantEvent, "translateAssistantEvent");
|
|
400
|
+
function translateToolCallEvent(msg) {
|
|
401
|
+
const status = msg.status;
|
|
402
|
+
if (status === "completed") {
|
|
403
|
+
return [
|
|
404
|
+
{
|
|
405
|
+
type: "tool_result",
|
|
406
|
+
callId: asString(msg.id, `tc-${Date.now()}`),
|
|
407
|
+
toolName: asString(msg.name, "unknown"),
|
|
408
|
+
output: asString(msg.result, ""),
|
|
409
|
+
durationMs: 0,
|
|
410
|
+
isError: false
|
|
371
411
|
}
|
|
372
|
-
|
|
373
|
-
}
|
|
374
|
-
|
|
412
|
+
];
|
|
413
|
+
}
|
|
414
|
+
if (status === "error") {
|
|
415
|
+
return [
|
|
416
|
+
{
|
|
417
|
+
type: "tool_result",
|
|
418
|
+
callId: asString(msg.id, `tc-${Date.now()}`),
|
|
419
|
+
toolName: asString(msg.name, "unknown"),
|
|
420
|
+
output: asString(msg.error, "Tool failed"),
|
|
421
|
+
durationMs: 0,
|
|
422
|
+
isError: true
|
|
423
|
+
}
|
|
424
|
+
];
|
|
425
|
+
}
|
|
426
|
+
return [];
|
|
427
|
+
}
|
|
428
|
+
__name(translateToolCallEvent, "translateToolCallEvent");
|
|
429
|
+
function translateStatusEvent(msg) {
|
|
430
|
+
const s = msg.status;
|
|
431
|
+
if (s === "done" || s === "completed") {
|
|
432
|
+
return [
|
|
433
|
+
{
|
|
434
|
+
type: "done",
|
|
435
|
+
result: "",
|
|
436
|
+
usage: {
|
|
437
|
+
inputTokens: 0,
|
|
438
|
+
outputTokens: 0,
|
|
439
|
+
totalTokens: 0
|
|
440
|
+
},
|
|
441
|
+
durationMs: 0,
|
|
442
|
+
cost: 0
|
|
443
|
+
}
|
|
444
|
+
];
|
|
445
|
+
}
|
|
446
|
+
if (s === "error") {
|
|
447
|
+
return [
|
|
448
|
+
{
|
|
449
|
+
type: "error",
|
|
450
|
+
code: "AGENT_ERROR",
|
|
451
|
+
message: asString(msg.error, "Agent error"),
|
|
452
|
+
retryable: false
|
|
453
|
+
}
|
|
454
|
+
];
|
|
455
|
+
}
|
|
456
|
+
return [];
|
|
457
|
+
}
|
|
458
|
+
__name(translateStatusEvent, "translateStatusEvent");
|
|
459
|
+
function translateSdkEvent(msg, runId) {
|
|
460
|
+
switch (msg.type) {
|
|
461
|
+
case "system":
|
|
462
|
+
return translateSystemEvent(msg, runId);
|
|
463
|
+
case "assistant":
|
|
464
|
+
return translateAssistantEvent(msg);
|
|
465
|
+
case "tool_call":
|
|
466
|
+
return translateToolCallEvent(msg);
|
|
467
|
+
case "thinking":
|
|
468
|
+
return [
|
|
469
|
+
{
|
|
470
|
+
type: "thinking",
|
|
471
|
+
content: asString(msg.content, "")
|
|
472
|
+
}
|
|
473
|
+
];
|
|
474
|
+
case "status":
|
|
475
|
+
return translateStatusEvent(msg);
|
|
476
|
+
default:
|
|
477
|
+
return [];
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
__name(translateSdkEvent, "translateSdkEvent");
|
|
481
|
+
|
|
482
|
+
// src/bridge/sdk-adapter.ts
|
|
483
|
+
function createSdkAgentStream(agentWalk, compiledTools, apiKey, envModel) {
|
|
484
|
+
const model = envModel ?? agentWalk.agentConfig.model ?? "openai/gpt-4o-mini";
|
|
485
|
+
return (message, _sessionId) => ({
|
|
375
486
|
async *[Symbol.asyncIterator]() {
|
|
376
487
|
const runId = `run-${Date.now()}`;
|
|
377
488
|
const t0 = Date.now();
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
{
|
|
386
|
-
role: "system",
|
|
387
|
-
content: agentWalk.agentConfig.systemPrompt ?? "You are a helpful assistant."
|
|
388
|
-
}
|
|
389
|
-
],
|
|
390
|
-
createdAt: Date.now(),
|
|
391
|
-
totalCostUsd: 0
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
const session = sessions.get(sessionId);
|
|
395
|
-
session.messages.push({
|
|
396
|
-
role: "user",
|
|
397
|
-
content: message
|
|
398
|
-
});
|
|
399
|
-
yield {
|
|
400
|
-
type: "run_started",
|
|
401
|
-
runId,
|
|
402
|
-
agentName: agentWalk.agentConfig.name,
|
|
403
|
-
model
|
|
404
|
-
};
|
|
405
|
-
const maxIter = agentWalk.mainLoop.maxIterations ?? 5;
|
|
406
|
-
let inTok = 0, outTok = 0;
|
|
407
|
-
for (let iter = 1; iter <= maxIter; iter++) {
|
|
489
|
+
let Agent;
|
|
490
|
+
let defineTool;
|
|
491
|
+
try {
|
|
492
|
+
const sdk = await import("@theokit/sdk");
|
|
493
|
+
Agent = sdk.Agent;
|
|
494
|
+
defineTool = sdk.defineTool;
|
|
495
|
+
} catch {
|
|
408
496
|
yield {
|
|
409
|
-
type: "
|
|
410
|
-
|
|
411
|
-
|
|
497
|
+
type: "error",
|
|
498
|
+
code: "SDK_NOT_INSTALLED",
|
|
499
|
+
message: "Install @theokit/sdk: pnpm add @theokit/sdk",
|
|
500
|
+
retryable: false
|
|
412
501
|
};
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
const sdkTools = compiledTools.map((t) => defineTool({
|
|
505
|
+
name: t.name,
|
|
506
|
+
description: t.description,
|
|
507
|
+
inputSchema: t.inputSchema,
|
|
508
|
+
handler: t.handler
|
|
509
|
+
}));
|
|
510
|
+
try {
|
|
511
|
+
const agent = await Agent.create({
|
|
512
|
+
apiKey,
|
|
513
|
+
model: {
|
|
514
|
+
id: model
|
|
418
515
|
},
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
messages: session.messages,
|
|
422
|
-
tools: orTools.length ? orTools : void 0,
|
|
423
|
-
max_tokens: 1e3,
|
|
424
|
-
stream: true
|
|
425
|
-
})
|
|
516
|
+
tools: sdkTools,
|
|
517
|
+
systemPrompt: agentWalk.agentConfig.systemPrompt
|
|
426
518
|
});
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
code: "LLM_ERROR",
|
|
433
|
-
message: `LLM request failed (${res.status})`,
|
|
434
|
-
retryable: res.status === 429
|
|
435
|
-
};
|
|
436
|
-
return;
|
|
437
|
-
}
|
|
438
|
-
const reader = res.body.getReader();
|
|
439
|
-
const dec = new TextDecoder();
|
|
440
|
-
let buf = "";
|
|
441
|
-
let content = "";
|
|
442
|
-
let tcs = [];
|
|
443
|
-
let finish = "";
|
|
444
|
-
while (true) {
|
|
445
|
-
const { done, value } = await reader.read();
|
|
446
|
-
if (done) break;
|
|
447
|
-
buf += dec.decode(value, {
|
|
448
|
-
stream: true
|
|
449
|
-
});
|
|
450
|
-
const lines = buf.split("\n");
|
|
451
|
-
buf = lines.pop() ?? "";
|
|
452
|
-
for (const line of lines) {
|
|
453
|
-
if (!line.startsWith("data: ")) continue;
|
|
454
|
-
const d = line.slice(6).trim();
|
|
455
|
-
if (d === "[DONE]") continue;
|
|
456
|
-
try {
|
|
457
|
-
const c = JSON.parse(d);
|
|
458
|
-
const delta = c.choices?.[0]?.delta;
|
|
459
|
-
if (delta?.content) {
|
|
460
|
-
content += delta.content;
|
|
461
|
-
yield {
|
|
462
|
-
type: "text_delta",
|
|
463
|
-
content: delta.content
|
|
464
|
-
};
|
|
465
|
-
}
|
|
466
|
-
if (delta?.tool_calls) {
|
|
467
|
-
for (const tc of delta.tool_calls) {
|
|
468
|
-
if (tc.id) tcs[tc.index] = {
|
|
469
|
-
id: tc.id,
|
|
470
|
-
type: "function",
|
|
471
|
-
function: {
|
|
472
|
-
name: tc.function?.name ?? "",
|
|
473
|
-
arguments: ""
|
|
474
|
-
}
|
|
475
|
-
};
|
|
476
|
-
if (tc.function?.arguments && tcs[tc.index]) tcs[tc.index].function.arguments += tc.function.arguments;
|
|
477
|
-
if (tc.function?.name && tcs[tc.index]) tcs[tc.index].function.name = tc.function.name;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
if (c.choices[0]?.finish_reason) finish = c.choices[0].finish_reason;
|
|
481
|
-
if (c.usage) {
|
|
482
|
-
inTok += c.usage.prompt_tokens;
|
|
483
|
-
outTok += c.usage.completion_tokens;
|
|
484
|
-
if (c.usage.cost) session.totalCostUsd += c.usage.cost;
|
|
485
|
-
}
|
|
486
|
-
} catch (parseErr) {
|
|
487
|
-
console.warn("[theokit:agents] Malformed SSE chunk skipped:", parseErr instanceof Error ? parseErr.message : "unknown");
|
|
488
|
-
}
|
|
519
|
+
const run = await agent.send(message);
|
|
520
|
+
for await (const sdkEvent of run.stream()) {
|
|
521
|
+
const translated = translateSdkEvent(sdkEvent, runId);
|
|
522
|
+
for (const event of translated) {
|
|
523
|
+
yield event;
|
|
489
524
|
}
|
|
490
525
|
}
|
|
491
|
-
if (finish === "tool_calls" && tcs.length > 0) {
|
|
492
|
-
session.messages.push({
|
|
493
|
-
role: "assistant",
|
|
494
|
-
content: null,
|
|
495
|
-
tool_calls: tcs
|
|
496
|
-
});
|
|
497
|
-
for (const tc of tcs) {
|
|
498
|
-
const orig = nameMap.get(tc.function.name) ?? tc.function.name;
|
|
499
|
-
const tool = toolMap.get(tc.function.name);
|
|
500
|
-
yield {
|
|
501
|
-
type: "tool_call",
|
|
502
|
-
callId: tc.id,
|
|
503
|
-
toolName: orig,
|
|
504
|
-
input: JSON.parse(tc.function.arguments || "{}")
|
|
505
|
-
};
|
|
506
|
-
if (!tool) {
|
|
507
|
-
session.messages.push({
|
|
508
|
-
role: "tool",
|
|
509
|
-
content: "Tool not found",
|
|
510
|
-
tool_call_id: tc.id
|
|
511
|
-
});
|
|
512
|
-
yield {
|
|
513
|
-
type: "tool_result",
|
|
514
|
-
callId: tc.id,
|
|
515
|
-
toolName: orig,
|
|
516
|
-
output: "Not found",
|
|
517
|
-
durationMs: 0,
|
|
518
|
-
isError: true
|
|
519
|
-
};
|
|
520
|
-
continue;
|
|
521
|
-
}
|
|
522
|
-
const s = Date.now();
|
|
523
|
-
try {
|
|
524
|
-
const rawArgs = JSON.parse(tc.function.arguments || "{}");
|
|
525
|
-
if (tool.inputSchema && typeof tool.inputSchema === "object" && "safeParse" in tool.inputSchema) {
|
|
526
|
-
const validated = tool.inputSchema.safeParse(rawArgs);
|
|
527
|
-
if (!validated.success) {
|
|
528
|
-
session.messages.push({
|
|
529
|
-
role: "tool",
|
|
530
|
-
content: "Invalid tool arguments",
|
|
531
|
-
tool_call_id: tc.id
|
|
532
|
-
});
|
|
533
|
-
yield {
|
|
534
|
-
type: "tool_result",
|
|
535
|
-
callId: tc.id,
|
|
536
|
-
toolName: orig,
|
|
537
|
-
output: "Invalid tool arguments",
|
|
538
|
-
durationMs: Date.now() - s,
|
|
539
|
-
isError: true
|
|
540
|
-
};
|
|
541
|
-
continue;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
const r = await tool.handler(rawArgs);
|
|
545
|
-
session.messages.push({
|
|
546
|
-
role: "tool",
|
|
547
|
-
content: r,
|
|
548
|
-
tool_call_id: tc.id
|
|
549
|
-
});
|
|
550
|
-
yield {
|
|
551
|
-
type: "tool_result",
|
|
552
|
-
callId: tc.id,
|
|
553
|
-
toolName: orig,
|
|
554
|
-
output: r.substring(0, 200),
|
|
555
|
-
durationMs: Date.now() - s,
|
|
556
|
-
isError: false
|
|
557
|
-
};
|
|
558
|
-
} catch (e) {
|
|
559
|
-
const m = e instanceof Error ? e.message : "Tool execution failed";
|
|
560
|
-
session.messages.push({
|
|
561
|
-
role: "tool",
|
|
562
|
-
content: `Error: ${m}`,
|
|
563
|
-
tool_call_id: tc.id
|
|
564
|
-
});
|
|
565
|
-
yield {
|
|
566
|
-
type: "tool_result",
|
|
567
|
-
callId: tc.id,
|
|
568
|
-
toolName: orig,
|
|
569
|
-
output: "Tool execution failed",
|
|
570
|
-
durationMs: Date.now() - s,
|
|
571
|
-
isError: true
|
|
572
|
-
};
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
tcs = [];
|
|
576
|
-
content = "";
|
|
577
|
-
continue;
|
|
578
|
-
}
|
|
579
|
-
if (content) session.messages.push({
|
|
580
|
-
role: "assistant",
|
|
581
|
-
content
|
|
582
|
-
});
|
|
583
526
|
yield {
|
|
584
527
|
type: "done",
|
|
585
|
-
result:
|
|
528
|
+
result: "",
|
|
586
529
|
usage: {
|
|
587
|
-
inputTokens:
|
|
588
|
-
outputTokens:
|
|
589
|
-
totalTokens:
|
|
530
|
+
inputTokens: 0,
|
|
531
|
+
outputTokens: 0,
|
|
532
|
+
totalTokens: 0
|
|
590
533
|
},
|
|
591
534
|
durationMs: Date.now() - t0,
|
|
592
|
-
cost:
|
|
535
|
+
cost: 0
|
|
536
|
+
};
|
|
537
|
+
await agent.dispose();
|
|
538
|
+
} catch (err) {
|
|
539
|
+
yield {
|
|
540
|
+
type: "error",
|
|
541
|
+
code: "SDK_ERROR",
|
|
542
|
+
message: err instanceof Error ? err.message : "SDK agent error",
|
|
543
|
+
retryable: false
|
|
593
544
|
};
|
|
594
|
-
return;
|
|
595
545
|
}
|
|
596
|
-
yield {
|
|
597
|
-
type: "error",
|
|
598
|
-
code: "MAX_ITERATIONS",
|
|
599
|
-
message: `Max iterations (${maxIter})`,
|
|
600
|
-
retryable: false
|
|
601
|
-
};
|
|
602
546
|
}
|
|
603
547
|
});
|
|
604
548
|
}
|
|
605
|
-
__name(
|
|
606
|
-
function convertZodToJsonSchema(schema) {
|
|
607
|
-
if (!schema || typeof schema !== "object") return {
|
|
608
|
-
type: "object",
|
|
609
|
-
properties: {}
|
|
610
|
-
};
|
|
611
|
-
const { $schema: _, ...rest } = z.toJSONSchema(schema);
|
|
612
|
-
return rest;
|
|
613
|
-
}
|
|
614
|
-
__name(convertZodToJsonSchema, "convertZodToJsonSchema");
|
|
549
|
+
__name(createSdkAgentStream, "createSdkAgentStream");
|
|
615
550
|
|
|
616
551
|
// src/bridge/agent-orchestrator.ts
|
|
617
552
|
var BudgetExceededError = class extends Error {
|
|
@@ -637,68 +572,90 @@ var DelegationError = class extends Error {
|
|
|
637
572
|
this.name = "DelegationError";
|
|
638
573
|
}
|
|
639
574
|
};
|
|
640
|
-
|
|
575
|
+
function asString2(value, fallback) {
|
|
576
|
+
if (typeof value === "string") return value;
|
|
577
|
+
return fallback;
|
|
578
|
+
}
|
|
579
|
+
__name(asString2, "asString");
|
|
580
|
+
function asNumber(value, fallback) {
|
|
581
|
+
if (typeof value === "number") return value;
|
|
582
|
+
return fallback;
|
|
583
|
+
}
|
|
584
|
+
__name(asNumber, "asNumber");
|
|
585
|
+
function requireApiKey(opts, agentName) {
|
|
641
586
|
const apiKey = opts.apiKey ?? "";
|
|
642
587
|
if (!apiKey) {
|
|
643
|
-
throw new DelegationError(
|
|
588
|
+
throw new DelegationError(agentName, "No API key provided. Pass apiKey in DelegateOptions.");
|
|
589
|
+
}
|
|
590
|
+
return apiKey;
|
|
591
|
+
}
|
|
592
|
+
__name(requireApiKey, "requireApiKey");
|
|
593
|
+
function mergeTools(parentTools, subTools) {
|
|
594
|
+
const subToolNames = new Set(subTools.map((t) => t.name));
|
|
595
|
+
const inherited = parentTools.filter((t) => !subToolNames.has(t.name));
|
|
596
|
+
return [
|
|
597
|
+
...inherited,
|
|
598
|
+
...subTools
|
|
599
|
+
];
|
|
600
|
+
}
|
|
601
|
+
__name(mergeTools, "mergeTools");
|
|
602
|
+
function processStreamEvent(event, acc, budget, agentName) {
|
|
603
|
+
if (event.type === "text_delta" && typeof event.content === "string") {
|
|
604
|
+
acc.response += event.content;
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
if (event.type === "tool_result") {
|
|
608
|
+
acc.toolCalls.push({
|
|
609
|
+
name: asString2(event.toolName, "unknown"),
|
|
610
|
+
input: event.input ?? {},
|
|
611
|
+
output: asString2(event.output, "")
|
|
612
|
+
});
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
if (event.type === "done") {
|
|
616
|
+
acc.cost = asNumber(event.cost, 0);
|
|
617
|
+
const usage = event.usage;
|
|
618
|
+
acc.tokens = usage?.totalTokens ?? 0;
|
|
619
|
+
if (Number.isFinite(budget) && acc.cost > budget) {
|
|
620
|
+
throw new BudgetExceededError(agentName, acc.cost, budget);
|
|
621
|
+
}
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
if (event.type === "error") {
|
|
625
|
+
throw new DelegationError(agentName, asString2(event.message, "Unknown agent error"));
|
|
644
626
|
}
|
|
627
|
+
}
|
|
628
|
+
__name(processStreamEvent, "processStreamEvent");
|
|
629
|
+
async function delegate(SubAgentClass, message, opts = {}) {
|
|
630
|
+
const apiKey = requireApiKey(opts, SubAgentClass.name);
|
|
645
631
|
const walk = walkAgentMetadata(SubAgentClass, []);
|
|
646
632
|
const toolboxInstances = new Map(walk.toolboxes.map((tb) => [
|
|
647
633
|
tb.class,
|
|
648
634
|
new tb.class()
|
|
649
635
|
]));
|
|
650
636
|
const compiled = compileAgent(walk, toolboxInstances);
|
|
651
|
-
const
|
|
652
|
-
const subToolNames = new Set(compiled.tools.map((t) => t.name));
|
|
653
|
-
const inherited = parentTools.filter((t) => !subToolNames.has(t.name));
|
|
654
|
-
const allTools = [
|
|
655
|
-
...inherited,
|
|
656
|
-
...compiled.tools
|
|
657
|
-
];
|
|
637
|
+
const allTools = mergeTools(opts.parentTools ?? [], compiled.tools);
|
|
658
638
|
const budget = Math.min(opts.budget ?? Infinity, opts.parentBudgetRemaining ?? Infinity);
|
|
659
|
-
const streamFactory =
|
|
639
|
+
const streamFactory = createSdkAgentStream(walk, allTools, apiKey, walk.agentConfig.model);
|
|
660
640
|
const sessionId = opts.sessionId ?? `sub-${crypto.randomUUID()}`;
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
641
|
+
const acc = {
|
|
642
|
+
response: "",
|
|
643
|
+
toolCalls: [],
|
|
644
|
+
cost: 0,
|
|
645
|
+
tokens: 0
|
|
646
|
+
};
|
|
665
647
|
try {
|
|
666
|
-
const
|
|
667
|
-
|
|
668
|
-
if (event.type === "text_delta" && event.content) {
|
|
669
|
-
response += event.content;
|
|
670
|
-
}
|
|
671
|
-
if (event.type === "tool_result") {
|
|
672
|
-
toolCalls.push({
|
|
673
|
-
name: event.toolName ?? "unknown",
|
|
674
|
-
input: event.input ?? {},
|
|
675
|
-
output: event.output ?? ""
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
|
-
if (event.type === "done") {
|
|
679
|
-
cost = event.cost ?? 0;
|
|
680
|
-
tokens = event.usage?.totalTokens ?? 0;
|
|
681
|
-
if (Number.isFinite(budget) && cost > budget) {
|
|
682
|
-
throw new BudgetExceededError(SubAgentClass.name, cost, budget);
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
if (event.type === "error") {
|
|
686
|
-
throw new DelegationError(SubAgentClass.name, event.message ?? "Unknown agent error");
|
|
687
|
-
}
|
|
648
|
+
for await (const event of streamFactory(message, sessionId)) {
|
|
649
|
+
processStreamEvent(event, acc, budget, SubAgentClass.name);
|
|
688
650
|
}
|
|
689
651
|
} catch (err) {
|
|
690
652
|
if (err instanceof BudgetExceededError || err instanceof DelegationError) throw err;
|
|
691
653
|
throw new DelegationError(SubAgentClass.name, err);
|
|
692
654
|
}
|
|
693
|
-
if (Number.isFinite(budget) && cost > budget) {
|
|
694
|
-
throw new BudgetExceededError(SubAgentClass.name, cost, budget);
|
|
655
|
+
if (Number.isFinite(budget) && acc.cost > budget) {
|
|
656
|
+
throw new BudgetExceededError(SubAgentClass.name, acc.cost, budget);
|
|
695
657
|
}
|
|
696
|
-
return
|
|
697
|
-
response,
|
|
698
|
-
toolCalls,
|
|
699
|
-
cost,
|
|
700
|
-
tokens
|
|
701
|
-
};
|
|
658
|
+
return acc;
|
|
702
659
|
}
|
|
703
660
|
__name(delegate, "delegate");
|
|
704
661
|
|
|
@@ -753,7 +710,7 @@ function agentsPlugin(opts) {
|
|
|
753
710
|
name: "@theokit/agents",
|
|
754
711
|
register(app) {
|
|
755
712
|
app.addHook("onRequest", async (pluginCtx) => {
|
|
756
|
-
|
|
713
|
+
routes ??= initRoutes(opts);
|
|
757
714
|
const request = pluginCtx.request;
|
|
758
715
|
const url = new URL(request.url);
|
|
759
716
|
const method = request.method.toUpperCase();
|
|
@@ -786,11 +743,12 @@ function initRoutes(opts) {
|
|
|
786
743
|
allRoutes.push(...agentRoutes);
|
|
787
744
|
}
|
|
788
745
|
validateUniqueRoutes(walkResults);
|
|
789
|
-
return allRoutes;
|
|
746
|
+
return compileRoutePatterns(allRoutes);
|
|
790
747
|
}
|
|
791
748
|
__name(initRoutes, "initRoutes");
|
|
792
749
|
function defaultCreateRun(compiled) {
|
|
793
750
|
return async function* (_message, _sessionId) {
|
|
751
|
+
await Promise.resolve();
|
|
794
752
|
yield {
|
|
795
753
|
type: "run_started",
|
|
796
754
|
runId: `run-${Date.now()}`,
|
|
@@ -805,13 +763,21 @@ function defaultCreateRun(compiled) {
|
|
|
805
763
|
};
|
|
806
764
|
}
|
|
807
765
|
__name(defaultCreateRun, "defaultCreateRun");
|
|
766
|
+
function compileRoutePatterns(routes) {
|
|
767
|
+
return routes.map((r) => {
|
|
768
|
+
if (!r.path.includes(":")) return r;
|
|
769
|
+
const regexSource = r.path.replace(/:[^/]+/g, "[^/]+");
|
|
770
|
+
return {
|
|
771
|
+
...r,
|
|
772
|
+
regex: RegExp(`^${regexSource}$`)
|
|
773
|
+
};
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
__name(compileRoutePatterns, "compileRoutePatterns");
|
|
808
777
|
function matchRoute(routes, method, pathname) {
|
|
809
778
|
return routes.find((r) => {
|
|
810
779
|
if (r.method !== method) return false;
|
|
811
|
-
if (r.
|
|
812
|
-
const pattern = r.path.replace(/:[^/]+/g, "[^/]+");
|
|
813
|
-
return new RegExp(`^${pattern}$`).test(pathname);
|
|
814
|
-
}
|
|
780
|
+
if (r.regex) return r.regex.test(pathname);
|
|
815
781
|
return r.path === pathname;
|
|
816
782
|
});
|
|
817
783
|
}
|
|
@@ -820,6 +786,7 @@ __name(matchRoute, "matchRoute");
|
|
|
820
786
|
export {
|
|
821
787
|
createAgentExecutionContext,
|
|
822
788
|
isAgentContext,
|
|
789
|
+
AgentWarningCode,
|
|
823
790
|
walkAgentMetadata,
|
|
824
791
|
validateUniqueRoutes,
|
|
825
792
|
compileTools,
|
|
@@ -832,11 +799,12 @@ export {
|
|
|
832
799
|
isError,
|
|
833
800
|
isApprovalRequired,
|
|
834
801
|
generateAgentRoutes,
|
|
835
|
-
|
|
802
|
+
translateSdkEvent,
|
|
803
|
+
createSdkAgentStream,
|
|
836
804
|
BudgetExceededError,
|
|
837
805
|
DelegationError,
|
|
838
806
|
delegate,
|
|
839
807
|
generateAgentManifest,
|
|
840
808
|
agentsPlugin
|
|
841
809
|
};
|
|
842
|
-
//# sourceMappingURL=chunk-
|
|
810
|
+
//# sourceMappingURL=chunk-NC5EE7HN.js.map
|