@theokit/sdk 2.20.0 → 2.21.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/CHANGELOG.md +115 -0
- package/dist/a2a/index.cjs +592 -290
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.js +593 -291
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/types.d.cts +7 -0
- package/dist/a2a/types.d.ts +7 -0
- package/dist/agent-builder.d.ts +2 -1
- package/dist/agent-generate.d.ts +12 -0
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +5 -0
- package/dist/client/index.d.ts +5 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/theokit-client.d.cts +6 -0
- package/dist/client/theokit-client.d.ts +6 -0
- package/dist/client/types.d.cts +2 -0
- package/dist/client/types.d.ts +2 -0
- package/dist/{cron-D2yLOrk2.d.ts → cron-YrmsszEN.d.cts} +53 -3
- package/dist/{cron-B8fqui49.d.cts → cron-dpvtRoro.d.ts} +53 -3
- package/dist/cron.cjs +642 -387
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.d.cts +3 -2
- package/dist/cron.d.ts +3 -2
- package/dist/cron.js +643 -388
- package/dist/cron.js.map +1 -1
- package/dist/{errors-5lj1EWgs.d.ts → errors-C4vZPqXf.d.ts} +2 -2
- package/dist/{errors-CE-lMBi2.d.cts → errors-DrcpYVfZ.d.cts} +2 -2
- package/dist/errors.d.cts +3 -2
- package/dist/eval.cjs +642 -387
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +642 -387
- package/dist/eval.js.map +1 -1
- package/dist/generate-object.d.ts +4 -3
- package/dist/index.cjs +788 -390
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +259 -17
- package/dist/index.d.ts +259 -17
- package/dist/index.js +786 -392
- package/dist/index.js.map +1 -1
- package/dist/internal/agent-loop/loop-types.d.ts +2 -0
- package/dist/internal/agent-loop/tool-result-guard.d.ts +1 -0
- package/dist/internal/llm/tool-result-content.d.ts +40 -0
- package/dist/internal/llm/types.d.ts +6 -1
- package/dist/internal/persistence/conversation-storage-fs.d.cts +3 -1
- package/dist/internal/persistence/conversation-storage-fs.d.ts +3 -1
- package/dist/internal/persistence/conversation-storage-memory.d.cts +3 -1
- package/dist/internal/persistence/conversation-storage-memory.d.ts +3 -1
- package/dist/internal/persistence/session-meta.d.cts +13 -0
- package/dist/internal/persistence/session-meta.d.ts +13 -0
- package/dist/internal/runtime/model-selection.d.ts +14 -0
- package/dist/internal/structured-output-helpers.d.ts +1 -1
- package/dist/permission-engine.d.ts +32 -1
- package/dist/{run-BgfBWX-z.d.cts → run-BMo8yRwK.d.cts} +262 -19
- package/dist/{run-BgfBWX-z.d.ts → run-BMo8yRwK.d.ts} +262 -19
- package/dist/stream-object.d.ts +2 -1
- package/dist/tool-error.d.ts +30 -0
- package/dist/types/agent-prims.d.ts +10 -8
- package/dist/types/agent.d.ts +12 -1
- package/dist/types/content-blocks.d.ts +47 -0
- package/dist/types/conversation-storage.d.ts +38 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/messages.d.ts +2 -9
- package/dist/types/run-events.d.ts +84 -0
- package/dist/types/run.d.ts +115 -1
- package/dist/types/session.d.ts +99 -0
- package/dist/types/workflow.d.ts +7 -0
- package/dist/workflow.cjs +7 -2
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +2 -0
- package/dist/workflow.d.ts +2 -0
- package/dist/workflow.js +7 -2
- package/dist/workflow.js.map +1 -1
- package/package.json +14 -34
- package/dist/internal/observability/context.d.cts +0 -23
- package/dist/internal/observability/context.d.ts +0 -23
- package/dist/internal/observability/index.cjs +0 -38
- package/dist/internal/observability/index.cjs.map +0 -1
- package/dist/internal/observability/index.d.cts +0 -8
- package/dist/internal/observability/index.d.ts +0 -8
- package/dist/internal/observability/index.js +0 -33
- package/dist/internal/observability/index.js.map +0 -1
- package/dist/internal/plugins/index.cjs +0 -363
- package/dist/internal/plugins/index.cjs.map +0 -1
- package/dist/internal/plugins/index.js +0 -357
- package/dist/internal/plugins/index.js.map +0 -1
- package/dist/internal/workflow/index.d.ts +0 -12
- package/dist/server/adapter/index.d.cts +0 -8
- package/dist/server/adapter/index.d.ts +0 -8
package/dist/eval.cjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var zod = require('zod');
|
|
4
|
+
var module$1 = require('module');
|
|
3
5
|
var crypto = require('crypto');
|
|
4
6
|
var promises = require('fs/promises');
|
|
5
7
|
var path = require('path');
|
|
6
|
-
var zod = require('zod');
|
|
7
8
|
var fs = require('fs');
|
|
8
9
|
var async_hooks = require('async_hooks');
|
|
9
|
-
var module$1 = require('module');
|
|
10
10
|
var os = require('os');
|
|
11
11
|
var child_process = require('child_process');
|
|
12
12
|
var url = require('url');
|
|
@@ -512,6 +512,256 @@ var init_errors = __esm({
|
|
|
512
512
|
};
|
|
513
513
|
}
|
|
514
514
|
});
|
|
515
|
+
function toJsonSchema(schema, options = { unrepresentable: "any" }) {
|
|
516
|
+
return zod.toJSONSchema(schema, options);
|
|
517
|
+
}
|
|
518
|
+
var init_to_json_schema = __esm({
|
|
519
|
+
"src/internal/zod/to-json-schema.ts"() {
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
function requireZod() {
|
|
523
|
+
if (cachedZ !== void 0) return cachedZ;
|
|
524
|
+
const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('eval.cjs', document.baseURI).href)));
|
|
525
|
+
let mod;
|
|
526
|
+
try {
|
|
527
|
+
mod = r("zod");
|
|
528
|
+
} catch (cause) {
|
|
529
|
+
throw new ConfigurationError(
|
|
530
|
+
'Structured output requires the optional peer dependency `zod`. Add `"zod": "^3.25.0 || ^4.0.0"` to your package.json and reinstall.',
|
|
531
|
+
{ code: "zod_not_installed", cause }
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
cachedZ = mod.z ?? mod;
|
|
535
|
+
return cachedZ;
|
|
536
|
+
}
|
|
537
|
+
function makeOutputTool(jsonSchema, onCapture) {
|
|
538
|
+
return {
|
|
539
|
+
name: "output",
|
|
540
|
+
description: "Call this tool with your final structured answer. Match the JSON schema exactly.",
|
|
541
|
+
inputSchema: jsonSchema,
|
|
542
|
+
handler: (input) => {
|
|
543
|
+
const out = onCapture(input);
|
|
544
|
+
if (typeof out === "string") return out;
|
|
545
|
+
if (out instanceof Promise) return out;
|
|
546
|
+
return "";
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
function buildTransientAgentOptions(params) {
|
|
551
|
+
return {
|
|
552
|
+
model: params.model,
|
|
553
|
+
local: params.local,
|
|
554
|
+
tools: [params.outputTool],
|
|
555
|
+
systemPrompt: params.systemPrompt ?? "You produce structured output by calling the `output` tool exactly once. Match the JSON schema.",
|
|
556
|
+
...params.apiKey !== void 0 ? { apiKey: params.apiKey } : {},
|
|
557
|
+
...params.providers !== void 0 ? { providers: params.providers } : {}
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
function extractUsage(result) {
|
|
561
|
+
const u = result.usage;
|
|
562
|
+
if (u === void 0) return { inputTokens: 0, outputTokens: 0 };
|
|
563
|
+
return { inputTokens: u.inputTokens ?? 0, outputTokens: u.outputTokens ?? 0 };
|
|
564
|
+
}
|
|
565
|
+
function buildToolPrompt(prompt) {
|
|
566
|
+
return `${prompt}
|
|
567
|
+
|
|
568
|
+
Respond by calling the \`output\` tool with the structured answer that matches the schema.`;
|
|
569
|
+
}
|
|
570
|
+
function setupStructuredOutput(schema, maxRetries) {
|
|
571
|
+
const z7 = requireZod();
|
|
572
|
+
const jsonSchema = toJsonSchema(schema, { unrepresentable: "any" });
|
|
573
|
+
return {
|
|
574
|
+
z: z7,
|
|
575
|
+
jsonSchema,
|
|
576
|
+
maxRetries: maxRetries ?? 1,
|
|
577
|
+
initialUsage: { inputTokens: 0, outputTokens: 0 }
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
async function disposeAndDeleteTransient(agent, deletor) {
|
|
581
|
+
await agent.dispose();
|
|
582
|
+
try {
|
|
583
|
+
await deletor(agent.agentId);
|
|
584
|
+
} catch {
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
var cachedZ;
|
|
588
|
+
var init_structured_output_helpers = __esm({
|
|
589
|
+
"src/internal/structured-output-helpers.ts"() {
|
|
590
|
+
init_errors();
|
|
591
|
+
init_to_json_schema();
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
// src/generate-object.ts
|
|
596
|
+
var generate_object_exports = {};
|
|
597
|
+
__export(generate_object_exports, {
|
|
598
|
+
GenerateObjectError: () => GenerateObjectError,
|
|
599
|
+
generateObjectImpl: () => generateObjectImpl
|
|
600
|
+
});
|
|
601
|
+
function salvagePartial(schema, raw) {
|
|
602
|
+
if (typeof raw !== "object" || raw === null) return raw;
|
|
603
|
+
const shape = schema.shape;
|
|
604
|
+
if (shape === void 0 || typeof shape !== "object") return raw;
|
|
605
|
+
const rawObj = raw;
|
|
606
|
+
const out = {};
|
|
607
|
+
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
608
|
+
if (typeof fieldSchema?.safeParse !== "function") continue;
|
|
609
|
+
const parsed = fieldSchema.safeParse(rawObj[key]);
|
|
610
|
+
if (parsed.success) out[key] = parsed.data;
|
|
611
|
+
}
|
|
612
|
+
return out;
|
|
613
|
+
}
|
|
614
|
+
async function runReasoningPhase(options, deps) {
|
|
615
|
+
const reasoningOptions = {
|
|
616
|
+
model: options.model,
|
|
617
|
+
local: options.local,
|
|
618
|
+
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
619
|
+
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
620
|
+
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
621
|
+
};
|
|
622
|
+
const reasoningAgent = await deps.create(reasoningOptions);
|
|
623
|
+
try {
|
|
624
|
+
const run = await reasoningAgent.send(options.prompt);
|
|
625
|
+
const result = await run.wait();
|
|
626
|
+
const text = result.result;
|
|
627
|
+
return typeof text === "string" ? text : options.prompt;
|
|
628
|
+
} finally {
|
|
629
|
+
await disposeAndDeleteTransient(reasoningAgent, deps.delete);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
async function generateObjectImpl(options, deps) {
|
|
633
|
+
const { jsonSchema, maxRetries, initialUsage } = setupStructuredOutput(
|
|
634
|
+
options.schema,
|
|
635
|
+
options.maxRetries
|
|
636
|
+
);
|
|
637
|
+
let capturedRaw;
|
|
638
|
+
let lastUsage = initialUsage;
|
|
639
|
+
const sentinel = /* @__PURE__ */ Symbol("generate-object-sentinel");
|
|
640
|
+
class CaptureSentinel extends Error {
|
|
641
|
+
constructor(captured) {
|
|
642
|
+
super("generate-object-capture");
|
|
643
|
+
this.captured = captured;
|
|
644
|
+
}
|
|
645
|
+
captured;
|
|
646
|
+
[sentinel] = true;
|
|
647
|
+
}
|
|
648
|
+
const outputTool = makeOutputTool(jsonSchema, (input) => {
|
|
649
|
+
if (capturedRaw === void 0) {
|
|
650
|
+
capturedRaw = input;
|
|
651
|
+
}
|
|
652
|
+
throw new CaptureSentinel(input);
|
|
653
|
+
});
|
|
654
|
+
const reasoningText = options.structuringModel !== void 0 ? await runReasoningPhase(options, deps) : void 0;
|
|
655
|
+
const structuringModel = options.structuringModel ?? options.model;
|
|
656
|
+
const structuringPrompt = reasoningText ?? options.prompt;
|
|
657
|
+
const agentOptions = buildTransientAgentOptions({
|
|
658
|
+
model: structuringModel,
|
|
659
|
+
local: options.local,
|
|
660
|
+
outputTool,
|
|
661
|
+
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
662
|
+
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
663
|
+
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
664
|
+
});
|
|
665
|
+
const agent = await deps.create(agentOptions);
|
|
666
|
+
try {
|
|
667
|
+
const userMessage = buildToolPrompt(structuringPrompt);
|
|
668
|
+
let lastParseError;
|
|
669
|
+
for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
|
|
670
|
+
capturedRaw = void 0;
|
|
671
|
+
const run = await agent.send(userMessage);
|
|
672
|
+
const result = await run.wait();
|
|
673
|
+
lastUsage = extractUsage(result);
|
|
674
|
+
if (capturedRaw === void 0) {
|
|
675
|
+
if (result.status === "error" && result.error !== void 0) {
|
|
676
|
+
throw new GenerateObjectError(
|
|
677
|
+
"no_tool_call",
|
|
678
|
+
`Agent run failed before the model could reply: ${result.error.message ?? "unknown error"} [${result.error.code ?? "?"}]`,
|
|
679
|
+
result.error
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
if (attempt === maxRetries) {
|
|
683
|
+
throw new GenerateObjectError(
|
|
684
|
+
"no_tool_call",
|
|
685
|
+
"The model returned text instead of calling the `output` tool."
|
|
686
|
+
);
|
|
687
|
+
}
|
|
688
|
+
continue;
|
|
689
|
+
}
|
|
690
|
+
const parsed = options.schema.safeParse(capturedRaw);
|
|
691
|
+
if (parsed.success) {
|
|
692
|
+
return {
|
|
693
|
+
object: parsed.data,
|
|
694
|
+
raw: capturedRaw,
|
|
695
|
+
usage: lastUsage,
|
|
696
|
+
finishReason: "tool_use"
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
lastParseError = parsed.error;
|
|
700
|
+
}
|
|
701
|
+
if (options.errorStrategy === "return-raw") {
|
|
702
|
+
return {
|
|
703
|
+
object: capturedRaw,
|
|
704
|
+
raw: capturedRaw,
|
|
705
|
+
usage: lastUsage,
|
|
706
|
+
finishReason: "tool_use"
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
if (options.errorStrategy === "return-partial") {
|
|
710
|
+
return {
|
|
711
|
+
object: salvagePartial(options.schema, capturedRaw),
|
|
712
|
+
raw: capturedRaw,
|
|
713
|
+
usage: lastUsage,
|
|
714
|
+
finishReason: "tool_use"
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
throw new GenerateObjectError(
|
|
718
|
+
"parse_failed",
|
|
719
|
+
"Schema parse failed after all retries.",
|
|
720
|
+
lastParseError
|
|
721
|
+
);
|
|
722
|
+
} finally {
|
|
723
|
+
await disposeAndDeleteTransient(agent, deps.delete);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
var GenerateObjectError;
|
|
727
|
+
var init_generate_object = __esm({
|
|
728
|
+
"src/generate-object.ts"() {
|
|
729
|
+
init_structured_output_helpers();
|
|
730
|
+
GenerateObjectError = class extends Error {
|
|
731
|
+
name = "GenerateObjectError";
|
|
732
|
+
code;
|
|
733
|
+
cause;
|
|
734
|
+
constructor(code, message, cause) {
|
|
735
|
+
super(message);
|
|
736
|
+
this.code = code;
|
|
737
|
+
if (cause !== void 0) this.cause = cause;
|
|
738
|
+
}
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
// src/internal/runtime/registry/agent-factory-registry.ts
|
|
744
|
+
var agent_factory_registry_exports = {};
|
|
745
|
+
__export(agent_factory_registry_exports, {
|
|
746
|
+
getAgentFacade: () => getAgentFacade,
|
|
747
|
+
setAgentFacade: () => setAgentFacade
|
|
748
|
+
});
|
|
749
|
+
function setAgentFacade(facade) {
|
|
750
|
+
registered = facade;
|
|
751
|
+
}
|
|
752
|
+
function getAgentFacade() {
|
|
753
|
+
if (registered === void 0) {
|
|
754
|
+
throw new Error(
|
|
755
|
+
"internal: Agent facade not registered. The `agent.ts` module must be loaded before internal subsystems (LocalAgent.runUntil/fork, eval, scorers, cron) invoke it."
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
return registered;
|
|
759
|
+
}
|
|
760
|
+
var registered;
|
|
761
|
+
var init_agent_factory_registry = __esm({
|
|
762
|
+
"src/internal/runtime/registry/agent-factory-registry.ts"() {
|
|
763
|
+
}
|
|
764
|
+
});
|
|
515
765
|
|
|
516
766
|
// src/internal/persistence/cwd-mutex.ts
|
|
517
767
|
function withCwdMutex(key, fn) {
|
|
@@ -1429,29 +1679,6 @@ var init_judge_call = __esm({
|
|
|
1429
1679
|
}
|
|
1430
1680
|
});
|
|
1431
1681
|
|
|
1432
|
-
// src/internal/runtime/registry/agent-factory-registry.ts
|
|
1433
|
-
var agent_factory_registry_exports = {};
|
|
1434
|
-
__export(agent_factory_registry_exports, {
|
|
1435
|
-
getAgentFacade: () => getAgentFacade,
|
|
1436
|
-
setAgentFacade: () => setAgentFacade
|
|
1437
|
-
});
|
|
1438
|
-
function setAgentFacade(facade) {
|
|
1439
|
-
registered3 = facade;
|
|
1440
|
-
}
|
|
1441
|
-
function getAgentFacade() {
|
|
1442
|
-
if (registered3 === void 0) {
|
|
1443
|
-
throw new Error(
|
|
1444
|
-
"internal: Agent facade not registered. The `agent.ts` module must be loaded before internal subsystems (LocalAgent.runUntil/fork, eval, scorers, cron) invoke it."
|
|
1445
|
-
);
|
|
1446
|
-
}
|
|
1447
|
-
return registered3;
|
|
1448
|
-
}
|
|
1449
|
-
var registered3;
|
|
1450
|
-
var init_agent_factory_registry = __esm({
|
|
1451
|
-
"src/internal/runtime/registry/agent-factory-registry.ts"() {
|
|
1452
|
-
}
|
|
1453
|
-
});
|
|
1454
|
-
|
|
1455
1682
|
// src/internal/runtime/lifecycle/run-to-completion.ts
|
|
1456
1683
|
var run_to_completion_exports = {};
|
|
1457
1684
|
__export(run_to_completion_exports, {
|
|
@@ -1616,14 +1843,14 @@ async function forkAgentImpl(parent, options, deps) {
|
|
|
1616
1843
|
return {
|
|
1617
1844
|
result: result.result,
|
|
1618
1845
|
toolCalls: [],
|
|
1619
|
-
usage:
|
|
1846
|
+
usage: extractUsage2(result)
|
|
1620
1847
|
};
|
|
1621
1848
|
});
|
|
1622
1849
|
} finally {
|
|
1623
1850
|
await fork.dispose();
|
|
1624
1851
|
}
|
|
1625
1852
|
}
|
|
1626
|
-
function
|
|
1853
|
+
function extractUsage2(result) {
|
|
1627
1854
|
if (typeof result !== "object" || result === null) {
|
|
1628
1855
|
return { inputTokens: 0, outputTokens: 0 };
|
|
1629
1856
|
}
|
|
@@ -2056,345 +2283,118 @@ async function runWorkAndFinalize(taskId, aborter, work) {
|
|
|
2056
2283
|
emit(payload) {
|
|
2057
2284
|
void checkCancelRequestedAt(taskId, aborter);
|
|
2058
2285
|
emitToSubscribers(taskId, {
|
|
2059
|
-
type: "progress",
|
|
2060
|
-
taskId,
|
|
2061
|
-
at: Date.now(),
|
|
2062
|
-
payload
|
|
2063
|
-
});
|
|
2064
|
-
}
|
|
2065
|
-
};
|
|
2066
|
-
try {
|
|
2067
|
-
const result = await reentryAls.run(true, () => Promise.resolve().then(() => work(ctx)));
|
|
2068
|
-
if (aborter.signal.aborted) {
|
|
2069
|
-
const cancelledAt = Date.now();
|
|
2070
|
-
await transition(taskId, "cancelled", { cancelledAt });
|
|
2071
|
-
emitToSubscribers(taskId, { type: "cancelled", taskId, cancelledAt });
|
|
2072
|
-
return;
|
|
2073
|
-
}
|
|
2074
|
-
const finishedAt = Date.now();
|
|
2075
|
-
await transition(taskId, "finished", { finishedAt, result });
|
|
2076
|
-
emitToSubscribers(taskId, { type: "finished", taskId, finishedAt, result });
|
|
2077
|
-
} catch (err) {
|
|
2078
|
-
if (aborter.signal.aborted) {
|
|
2079
|
-
const cancelledAt = Date.now();
|
|
2080
|
-
await transition(taskId, "cancelled", { cancelledAt });
|
|
2081
|
-
emitToSubscribers(taskId, { type: "cancelled", taskId, cancelledAt });
|
|
2082
|
-
return;
|
|
2083
|
-
}
|
|
2084
|
-
const erroredAt = Date.now();
|
|
2085
|
-
const error = err instanceof Error ? { code: err.code ?? "work_threw", message: err.message } : { code: "work_threw", message: String(err) };
|
|
2086
|
-
await transition(taskId, "error", { erroredAt, error });
|
|
2087
|
-
emitToSubscribers(taskId, { type: "errored", taskId, erroredAt, error });
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
|
-
async function checkCancelRequestedAt(taskId, aborter) {
|
|
2091
|
-
if (aborter.signal.aborted) return;
|
|
2092
|
-
try {
|
|
2093
|
-
const handle = await state.store.get(taskId);
|
|
2094
|
-
if (handle?.cancelRequested === true) {
|
|
2095
|
-
aborter.abort("cancelRequested");
|
|
2096
|
-
}
|
|
2097
|
-
} catch {
|
|
2098
|
-
}
|
|
2099
|
-
}
|
|
2100
|
-
async function acquireSlot() {
|
|
2101
|
-
if (reentryAls.getStore() === true) {
|
|
2102
|
-
return () => {
|
|
2103
|
-
};
|
|
2104
|
-
}
|
|
2105
|
-
return state.semaphore.acquire();
|
|
2106
|
-
}
|
|
2107
|
-
async function submit(internal) {
|
|
2108
|
-
state.firstSubmitSeen = true;
|
|
2109
|
-
startEvictTimerIfNeeded();
|
|
2110
|
-
const resolvedId = resolveIdInternal(internal);
|
|
2111
|
-
const submitSpan = startTaskSubmitSpan({ taskId: resolvedId, kind: internal.kind });
|
|
2112
|
-
const existing = await state.store.get(resolvedId);
|
|
2113
|
-
if (existing !== void 0) {
|
|
2114
|
-
submitSpan.end();
|
|
2115
|
-
return existing;
|
|
2116
|
-
}
|
|
2117
|
-
const queuedHandle = await buildAndInsertQueued(internal, resolvedId);
|
|
2118
|
-
submitSpan.end();
|
|
2119
|
-
if (internal.signal?.aborted === true) {
|
|
2120
|
-
return shortCircuitAborted(queuedHandle, internal.signal);
|
|
2121
|
-
}
|
|
2122
|
-
const aborter = new AbortController();
|
|
2123
|
-
state.aborters.set(resolvedId, aborter);
|
|
2124
|
-
if (internal.signal !== void 0) {
|
|
2125
|
-
internal.signal.addEventListener("abort", () => aborter.abort(internal.signal?.reason), {
|
|
2126
|
-
once: true
|
|
2127
|
-
});
|
|
2128
|
-
}
|
|
2129
|
-
const release = await acquireSlot();
|
|
2130
|
-
void (async () => {
|
|
2131
|
-
try {
|
|
2132
|
-
await checkCancelRequestedAt(resolvedId, aborter);
|
|
2133
|
-
if (aborter.signal.aborted) {
|
|
2134
|
-
const cancelledAt = Date.now();
|
|
2135
|
-
await transition(resolvedId, "cancelled", { cancelledAt });
|
|
2136
|
-
emitToSubscribers(resolvedId, { type: "cancelled", taskId: resolvedId, cancelledAt });
|
|
2137
|
-
return;
|
|
2138
|
-
}
|
|
2139
|
-
const startedAt = Date.now();
|
|
2140
|
-
await transition(resolvedId, "running", { startedAt });
|
|
2141
|
-
emitToSubscribers(resolvedId, { type: "started", taskId: resolvedId, startedAt });
|
|
2142
|
-
await runWorkAndFinalize(resolvedId, aborter, internal.work);
|
|
2143
|
-
} finally {
|
|
2144
|
-
release();
|
|
2145
|
-
state.aborters.delete(resolvedId);
|
|
2146
|
-
}
|
|
2147
|
-
})();
|
|
2148
|
-
return queuedHandle;
|
|
2149
|
-
}
|
|
2150
|
-
async function get(id) {
|
|
2151
|
-
if (!isValidTaskId(id, true)) return void 0;
|
|
2152
|
-
return state.store.get(id);
|
|
2153
|
-
}
|
|
2154
|
-
var DEFAULT_CONCURRENCY, DEFAULT_RETENTION_MS, EVICTION_INTERVAL_MS, RING_CAP, reentryAls, state;
|
|
2155
|
-
var init_registry = __esm({
|
|
2156
|
-
"src/internal/task/registry.ts"() {
|
|
2157
|
-
init_errors();
|
|
2158
|
-
init_task();
|
|
2159
|
-
init_async_semaphore();
|
|
2160
|
-
init_ring_buffer();
|
|
2161
|
-
init_store();
|
|
2162
|
-
init_subscribe();
|
|
2163
|
-
init_telemetry();
|
|
2164
|
-
DEFAULT_CONCURRENCY = 8;
|
|
2165
|
-
DEFAULT_RETENTION_MS = 60 * 60 * 1e3;
|
|
2166
|
-
EVICTION_INTERVAL_MS = 5 * 60 * 1e3;
|
|
2167
|
-
RING_CAP = 64;
|
|
2168
|
-
reentryAls = new async_hooks.AsyncLocalStorage();
|
|
2169
|
-
state = buildState({});
|
|
2170
|
-
}
|
|
2171
|
-
});
|
|
2172
|
-
function toJsonSchema(schema, options = { unrepresentable: "any" }) {
|
|
2173
|
-
return zod.toJSONSchema(schema, options);
|
|
2174
|
-
}
|
|
2175
|
-
var init_to_json_schema = __esm({
|
|
2176
|
-
"src/internal/zod/to-json-schema.ts"() {
|
|
2177
|
-
}
|
|
2178
|
-
});
|
|
2179
|
-
function requireZod() {
|
|
2180
|
-
if (cachedZ !== void 0) return cachedZ;
|
|
2181
|
-
const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('eval.cjs', document.baseURI).href)));
|
|
2182
|
-
let mod;
|
|
2183
|
-
try {
|
|
2184
|
-
mod = r("zod");
|
|
2185
|
-
} catch (cause) {
|
|
2186
|
-
throw new ConfigurationError(
|
|
2187
|
-
'Structured output requires the optional peer dependency `zod`. Add `"zod": "^3.25.0 || ^4.0.0"` to your package.json and reinstall.',
|
|
2188
|
-
{ code: "zod_not_installed", cause }
|
|
2189
|
-
);
|
|
2190
|
-
}
|
|
2191
|
-
cachedZ = mod.z ?? mod;
|
|
2192
|
-
return cachedZ;
|
|
2193
|
-
}
|
|
2194
|
-
function makeOutputTool(jsonSchema, onCapture) {
|
|
2195
|
-
return {
|
|
2196
|
-
name: "output",
|
|
2197
|
-
description: "Call this tool with your final structured answer. Match the JSON schema exactly.",
|
|
2198
|
-
inputSchema: jsonSchema,
|
|
2199
|
-
handler: (input) => {
|
|
2200
|
-
const out = onCapture(input);
|
|
2201
|
-
if (typeof out === "string") return out;
|
|
2202
|
-
if (out instanceof Promise) return out;
|
|
2203
|
-
return "";
|
|
2204
|
-
}
|
|
2205
|
-
};
|
|
2206
|
-
}
|
|
2207
|
-
function buildTransientAgentOptions(params) {
|
|
2208
|
-
return {
|
|
2209
|
-
model: params.model,
|
|
2210
|
-
local: params.local,
|
|
2211
|
-
tools: [params.outputTool],
|
|
2212
|
-
systemPrompt: params.systemPrompt ?? "You produce structured output by calling the `output` tool exactly once. Match the JSON schema.",
|
|
2213
|
-
...params.apiKey !== void 0 ? { apiKey: params.apiKey } : {},
|
|
2214
|
-
...params.providers !== void 0 ? { providers: params.providers } : {}
|
|
2215
|
-
};
|
|
2216
|
-
}
|
|
2217
|
-
function extractUsage2(result) {
|
|
2218
|
-
const u = result.usage;
|
|
2219
|
-
if (u === void 0) return { inputTokens: 0, outputTokens: 0 };
|
|
2220
|
-
return { inputTokens: u.inputTokens ?? 0, outputTokens: u.outputTokens ?? 0 };
|
|
2221
|
-
}
|
|
2222
|
-
function buildToolPrompt(prompt) {
|
|
2223
|
-
return `${prompt}
|
|
2224
|
-
|
|
2225
|
-
Respond by calling the \`output\` tool with the structured answer that matches the schema.`;
|
|
2226
|
-
}
|
|
2227
|
-
function setupStructuredOutput(schema, maxRetries) {
|
|
2228
|
-
const z7 = requireZod();
|
|
2229
|
-
const jsonSchema = toJsonSchema(schema, { unrepresentable: "any" });
|
|
2230
|
-
return {
|
|
2231
|
-
z: z7,
|
|
2232
|
-
jsonSchema,
|
|
2233
|
-
maxRetries: maxRetries ?? 1,
|
|
2234
|
-
initialUsage: { inputTokens: 0, outputTokens: 0 }
|
|
2235
|
-
};
|
|
2236
|
-
}
|
|
2237
|
-
async function disposeAndDeleteTransient(agent, deletor) {
|
|
2238
|
-
await agent.dispose();
|
|
2239
|
-
try {
|
|
2240
|
-
await deletor(agent.agentId);
|
|
2241
|
-
} catch {
|
|
2242
|
-
}
|
|
2243
|
-
}
|
|
2244
|
-
var cachedZ;
|
|
2245
|
-
var init_structured_output_helpers = __esm({
|
|
2246
|
-
"src/internal/structured-output-helpers.ts"() {
|
|
2247
|
-
init_errors();
|
|
2248
|
-
init_to_json_schema();
|
|
2249
|
-
}
|
|
2250
|
-
});
|
|
2251
|
-
|
|
2252
|
-
// src/generate-object.ts
|
|
2253
|
-
var generate_object_exports = {};
|
|
2254
|
-
__export(generate_object_exports, {
|
|
2255
|
-
GenerateObjectError: () => GenerateObjectError,
|
|
2256
|
-
generateObjectImpl: () => generateObjectImpl
|
|
2257
|
-
});
|
|
2258
|
-
function salvagePartial(schema, raw) {
|
|
2259
|
-
if (typeof raw !== "object" || raw === null) return raw;
|
|
2260
|
-
const shape = schema.shape;
|
|
2261
|
-
if (shape === void 0 || typeof shape !== "object") return raw;
|
|
2262
|
-
const rawObj = raw;
|
|
2263
|
-
const out = {};
|
|
2264
|
-
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
2265
|
-
if (typeof fieldSchema?.safeParse !== "function") continue;
|
|
2266
|
-
const parsed = fieldSchema.safeParse(rawObj[key]);
|
|
2267
|
-
if (parsed.success) out[key] = parsed.data;
|
|
2268
|
-
}
|
|
2269
|
-
return out;
|
|
2270
|
-
}
|
|
2271
|
-
async function runReasoningPhase(options, deps) {
|
|
2272
|
-
const reasoningOptions = {
|
|
2273
|
-
model: options.model,
|
|
2274
|
-
local: options.local,
|
|
2275
|
-
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
2276
|
-
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
2277
|
-
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
2278
|
-
};
|
|
2279
|
-
const reasoningAgent = await deps.create(reasoningOptions);
|
|
2280
|
-
try {
|
|
2281
|
-
const run = await reasoningAgent.send(options.prompt);
|
|
2282
|
-
const result = await run.wait();
|
|
2283
|
-
const text = result.result;
|
|
2284
|
-
return typeof text === "string" ? text : options.prompt;
|
|
2285
|
-
} finally {
|
|
2286
|
-
await disposeAndDeleteTransient(reasoningAgent, deps.delete);
|
|
2287
|
-
}
|
|
2288
|
-
}
|
|
2289
|
-
async function generateObjectImpl(options, deps) {
|
|
2290
|
-
const { jsonSchema, maxRetries, initialUsage } = setupStructuredOutput(
|
|
2291
|
-
options.schema,
|
|
2292
|
-
options.maxRetries
|
|
2293
|
-
);
|
|
2294
|
-
let capturedRaw;
|
|
2295
|
-
let lastUsage = initialUsage;
|
|
2296
|
-
const sentinel = /* @__PURE__ */ Symbol("generate-object-sentinel");
|
|
2297
|
-
class CaptureSentinel extends Error {
|
|
2298
|
-
constructor(captured) {
|
|
2299
|
-
super("generate-object-capture");
|
|
2300
|
-
this.captured = captured;
|
|
2301
|
-
}
|
|
2302
|
-
captured;
|
|
2303
|
-
[sentinel] = true;
|
|
2304
|
-
}
|
|
2305
|
-
const outputTool = makeOutputTool(jsonSchema, (input) => {
|
|
2306
|
-
if (capturedRaw === void 0) {
|
|
2307
|
-
capturedRaw = input;
|
|
2308
|
-
}
|
|
2309
|
-
throw new CaptureSentinel(input);
|
|
2310
|
-
});
|
|
2311
|
-
const reasoningText = options.structuringModel !== void 0 ? await runReasoningPhase(options, deps) : void 0;
|
|
2312
|
-
const structuringModel = options.structuringModel ?? options.model;
|
|
2313
|
-
const structuringPrompt = reasoningText ?? options.prompt;
|
|
2314
|
-
const agentOptions = buildTransientAgentOptions({
|
|
2315
|
-
model: structuringModel,
|
|
2316
|
-
local: options.local,
|
|
2317
|
-
outputTool,
|
|
2318
|
-
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
2319
|
-
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
2320
|
-
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
2321
|
-
});
|
|
2322
|
-
const agent = await deps.create(agentOptions);
|
|
2286
|
+
type: "progress",
|
|
2287
|
+
taskId,
|
|
2288
|
+
at: Date.now(),
|
|
2289
|
+
payload
|
|
2290
|
+
});
|
|
2291
|
+
}
|
|
2292
|
+
};
|
|
2323
2293
|
try {
|
|
2324
|
-
const
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
lastUsage = extractUsage2(result);
|
|
2331
|
-
if (capturedRaw === void 0) {
|
|
2332
|
-
if (result.status === "error" && result.error !== void 0) {
|
|
2333
|
-
throw new GenerateObjectError(
|
|
2334
|
-
"no_tool_call",
|
|
2335
|
-
`Agent run failed before the model could reply: ${result.error.message ?? "unknown error"} [${result.error.code ?? "?"}]`,
|
|
2336
|
-
result.error
|
|
2337
|
-
);
|
|
2338
|
-
}
|
|
2339
|
-
if (attempt === maxRetries) {
|
|
2340
|
-
throw new GenerateObjectError(
|
|
2341
|
-
"no_tool_call",
|
|
2342
|
-
"The model returned text instead of calling the `output` tool."
|
|
2343
|
-
);
|
|
2344
|
-
}
|
|
2345
|
-
continue;
|
|
2346
|
-
}
|
|
2347
|
-
const parsed = options.schema.safeParse(capturedRaw);
|
|
2348
|
-
if (parsed.success) {
|
|
2349
|
-
return {
|
|
2350
|
-
object: parsed.data,
|
|
2351
|
-
raw: capturedRaw,
|
|
2352
|
-
usage: lastUsage,
|
|
2353
|
-
finishReason: "tool_use"
|
|
2354
|
-
};
|
|
2355
|
-
}
|
|
2356
|
-
lastParseError = parsed.error;
|
|
2294
|
+
const result = await reentryAls.run(true, () => Promise.resolve().then(() => work(ctx)));
|
|
2295
|
+
if (aborter.signal.aborted) {
|
|
2296
|
+
const cancelledAt = Date.now();
|
|
2297
|
+
await transition(taskId, "cancelled", { cancelledAt });
|
|
2298
|
+
emitToSubscribers(taskId, { type: "cancelled", taskId, cancelledAt });
|
|
2299
|
+
return;
|
|
2357
2300
|
}
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
};
|
|
2301
|
+
const finishedAt = Date.now();
|
|
2302
|
+
await transition(taskId, "finished", { finishedAt, result });
|
|
2303
|
+
emitToSubscribers(taskId, { type: "finished", taskId, finishedAt, result });
|
|
2304
|
+
} catch (err) {
|
|
2305
|
+
if (aborter.signal.aborted) {
|
|
2306
|
+
const cancelledAt = Date.now();
|
|
2307
|
+
await transition(taskId, "cancelled", { cancelledAt });
|
|
2308
|
+
emitToSubscribers(taskId, { type: "cancelled", taskId, cancelledAt });
|
|
2309
|
+
return;
|
|
2365
2310
|
}
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2311
|
+
const erroredAt = Date.now();
|
|
2312
|
+
const error = err instanceof Error ? { code: err.code ?? "work_threw", message: err.message } : { code: "work_threw", message: String(err) };
|
|
2313
|
+
await transition(taskId, "error", { erroredAt, error });
|
|
2314
|
+
emitToSubscribers(taskId, { type: "errored", taskId, erroredAt, error });
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
async function checkCancelRequestedAt(taskId, aborter) {
|
|
2318
|
+
if (aborter.signal.aborted) return;
|
|
2319
|
+
try {
|
|
2320
|
+
const handle = await state.store.get(taskId);
|
|
2321
|
+
if (handle?.cancelRequested === true) {
|
|
2322
|
+
aborter.abort("cancelRequested");
|
|
2373
2323
|
}
|
|
2374
|
-
|
|
2375
|
-
"parse_failed",
|
|
2376
|
-
"Schema parse failed after all retries.",
|
|
2377
|
-
lastParseError
|
|
2378
|
-
);
|
|
2379
|
-
} finally {
|
|
2380
|
-
await disposeAndDeleteTransient(agent, deps.delete);
|
|
2324
|
+
} catch {
|
|
2381
2325
|
}
|
|
2382
2326
|
}
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
init_structured_output_helpers();
|
|
2387
|
-
GenerateObjectError = class extends Error {
|
|
2388
|
-
name = "GenerateObjectError";
|
|
2389
|
-
code;
|
|
2390
|
-
cause;
|
|
2391
|
-
constructor(code, message, cause) {
|
|
2392
|
-
super(message);
|
|
2393
|
-
this.code = code;
|
|
2394
|
-
if (cause !== void 0) this.cause = cause;
|
|
2395
|
-
}
|
|
2327
|
+
async function acquireSlot() {
|
|
2328
|
+
if (reentryAls.getStore() === true) {
|
|
2329
|
+
return () => {
|
|
2396
2330
|
};
|
|
2397
2331
|
}
|
|
2332
|
+
return state.semaphore.acquire();
|
|
2333
|
+
}
|
|
2334
|
+
async function submit(internal) {
|
|
2335
|
+
state.firstSubmitSeen = true;
|
|
2336
|
+
startEvictTimerIfNeeded();
|
|
2337
|
+
const resolvedId = resolveIdInternal(internal);
|
|
2338
|
+
const submitSpan = startTaskSubmitSpan({ taskId: resolvedId, kind: internal.kind });
|
|
2339
|
+
const existing = await state.store.get(resolvedId);
|
|
2340
|
+
if (existing !== void 0) {
|
|
2341
|
+
submitSpan.end();
|
|
2342
|
+
return existing;
|
|
2343
|
+
}
|
|
2344
|
+
const queuedHandle = await buildAndInsertQueued(internal, resolvedId);
|
|
2345
|
+
submitSpan.end();
|
|
2346
|
+
if (internal.signal?.aborted === true) {
|
|
2347
|
+
return shortCircuitAborted(queuedHandle, internal.signal);
|
|
2348
|
+
}
|
|
2349
|
+
const aborter = new AbortController();
|
|
2350
|
+
state.aborters.set(resolvedId, aborter);
|
|
2351
|
+
if (internal.signal !== void 0) {
|
|
2352
|
+
internal.signal.addEventListener("abort", () => aborter.abort(internal.signal?.reason), {
|
|
2353
|
+
once: true
|
|
2354
|
+
});
|
|
2355
|
+
}
|
|
2356
|
+
const release = await acquireSlot();
|
|
2357
|
+
void (async () => {
|
|
2358
|
+
try {
|
|
2359
|
+
await checkCancelRequestedAt(resolvedId, aborter);
|
|
2360
|
+
if (aborter.signal.aborted) {
|
|
2361
|
+
const cancelledAt = Date.now();
|
|
2362
|
+
await transition(resolvedId, "cancelled", { cancelledAt });
|
|
2363
|
+
emitToSubscribers(resolvedId, { type: "cancelled", taskId: resolvedId, cancelledAt });
|
|
2364
|
+
return;
|
|
2365
|
+
}
|
|
2366
|
+
const startedAt = Date.now();
|
|
2367
|
+
await transition(resolvedId, "running", { startedAt });
|
|
2368
|
+
emitToSubscribers(resolvedId, { type: "started", taskId: resolvedId, startedAt });
|
|
2369
|
+
await runWorkAndFinalize(resolvedId, aborter, internal.work);
|
|
2370
|
+
} finally {
|
|
2371
|
+
release();
|
|
2372
|
+
state.aborters.delete(resolvedId);
|
|
2373
|
+
}
|
|
2374
|
+
})();
|
|
2375
|
+
return queuedHandle;
|
|
2376
|
+
}
|
|
2377
|
+
async function get(id) {
|
|
2378
|
+
if (!isValidTaskId(id, true)) return void 0;
|
|
2379
|
+
return state.store.get(id);
|
|
2380
|
+
}
|
|
2381
|
+
var DEFAULT_CONCURRENCY, DEFAULT_RETENTION_MS, EVICTION_INTERVAL_MS, RING_CAP, reentryAls, state;
|
|
2382
|
+
var init_registry = __esm({
|
|
2383
|
+
"src/internal/task/registry.ts"() {
|
|
2384
|
+
init_errors();
|
|
2385
|
+
init_task();
|
|
2386
|
+
init_async_semaphore();
|
|
2387
|
+
init_ring_buffer();
|
|
2388
|
+
init_store();
|
|
2389
|
+
init_subscribe();
|
|
2390
|
+
init_telemetry();
|
|
2391
|
+
DEFAULT_CONCURRENCY = 8;
|
|
2392
|
+
DEFAULT_RETENTION_MS = 60 * 60 * 1e3;
|
|
2393
|
+
EVICTION_INTERVAL_MS = 5 * 60 * 1e3;
|
|
2394
|
+
RING_CAP = 64;
|
|
2395
|
+
reentryAls = new async_hooks.AsyncLocalStorage();
|
|
2396
|
+
state = buildState({});
|
|
2397
|
+
}
|
|
2398
2398
|
});
|
|
2399
2399
|
|
|
2400
2400
|
// src/stream-object.ts
|
|
@@ -2451,7 +2451,7 @@ async function* streamObjectImpl(options, deps) {
|
|
|
2451
2451
|
}
|
|
2452
2452
|
}
|
|
2453
2453
|
const result = await run.wait();
|
|
2454
|
-
lastUsage =
|
|
2454
|
+
lastUsage = extractUsage(result);
|
|
2455
2455
|
if (capturedRaw === void 0) {
|
|
2456
2456
|
if (result.status === "error" && result.error !== void 0) {
|
|
2457
2457
|
throw new StreamObjectError(
|
|
@@ -2797,6 +2797,7 @@ var AgentBuilder = class {
|
|
|
2797
2797
|
constructor(deps) {
|
|
2798
2798
|
this.deps = deps;
|
|
2799
2799
|
}
|
|
2800
|
+
/** SE8 — accepts a bare-string id shorthand (`"openai/gpt-4o-mini"`) or a {@link ModelSelection}. */
|
|
2800
2801
|
model(m) {
|
|
2801
2802
|
this.opts.model = m;
|
|
2802
2803
|
return this;
|
|
@@ -3146,6 +3147,69 @@ function isLocalAgentId(id) {
|
|
|
3146
3147
|
return id.startsWith(PREFIX.localAgent);
|
|
3147
3148
|
}
|
|
3148
3149
|
|
|
3150
|
+
// src/internal/runtime/config/default-model.ts
|
|
3151
|
+
var DEFAULT_AGENTIC_MODEL_ID = "google/gemini-2.0-flash-001";
|
|
3152
|
+
|
|
3153
|
+
// src/agent-generate.ts
|
|
3154
|
+
async function agentGenerate(agent, agentModel, agentApiKey, agentLocal, input, options) {
|
|
3155
|
+
const { output, maxRetries, errorStrategy, ...sendOptions } = options;
|
|
3156
|
+
const run = await agent.send(input, sendOptions);
|
|
3157
|
+
const result = await run.wait();
|
|
3158
|
+
const { generateObjectImpl: generateObjectImpl2, GenerateObjectError: GenerateObjectError2 } = await Promise.resolve().then(() => (init_generate_object(), generate_object_exports));
|
|
3159
|
+
const answer = structurableAnswerOrThrow(result, GenerateObjectError2);
|
|
3160
|
+
const { getAgentFacade: getAgentFacade2 } = await Promise.resolve().then(() => (init_agent_factory_registry(), agent_factory_registry_exports));
|
|
3161
|
+
const facade = getAgentFacade2();
|
|
3162
|
+
const structured = await generateObjectImpl2(
|
|
3163
|
+
{
|
|
3164
|
+
prompt: answer,
|
|
3165
|
+
schema: output,
|
|
3166
|
+
// `agentModel` arrives already normalized (`this.model` passed through
|
|
3167
|
+
// `normalizeModel` in the LocalAgent/CloudAgent constructor), so the widened
|
|
3168
|
+
// `string | ModelSelection` field only ever receives a `ModelSelection` here.
|
|
3169
|
+
model: agentModel ?? { id: DEFAULT_AGENTIC_MODEL_ID },
|
|
3170
|
+
// `local` is required to keep the transient structuring agent local-only;
|
|
3171
|
+
// default to the process cwd when the agent had no explicit local config.
|
|
3172
|
+
local: agentLocal ?? { cwd: process.cwd() },
|
|
3173
|
+
...agentApiKey !== void 0 ? { apiKey: agentApiKey } : {},
|
|
3174
|
+
...maxRetries !== void 0 ? { maxRetries } : {},
|
|
3175
|
+
...errorStrategy !== void 0 ? { errorStrategy } : {}
|
|
3176
|
+
},
|
|
3177
|
+
{
|
|
3178
|
+
create: (opts) => facade.create(opts),
|
|
3179
|
+
delete: (agentId) => facade.delete(agentId)
|
|
3180
|
+
}
|
|
3181
|
+
);
|
|
3182
|
+
return {
|
|
3183
|
+
object: structured.object,
|
|
3184
|
+
result,
|
|
3185
|
+
raw: structured.raw,
|
|
3186
|
+
usage: structured.usage
|
|
3187
|
+
};
|
|
3188
|
+
}
|
|
3189
|
+
function structurableAnswerOrThrow(result, GenerateObjectError2) {
|
|
3190
|
+
if (result.status === "error") {
|
|
3191
|
+
throw new GenerateObjectError2(
|
|
3192
|
+
"no_tool_call",
|
|
3193
|
+
`Agent run failed before an answer could be structured: ${result.error?.message ?? "unknown error"} [${result.error?.code ?? "?"}]`,
|
|
3194
|
+
result.error
|
|
3195
|
+
);
|
|
3196
|
+
}
|
|
3197
|
+
if (result.status === "cancelled") {
|
|
3198
|
+
throw new GenerateObjectError2(
|
|
3199
|
+
"no_tool_call",
|
|
3200
|
+
"Agent run was cancelled before an answer could be structured."
|
|
3201
|
+
);
|
|
3202
|
+
}
|
|
3203
|
+
const answer = result.result;
|
|
3204
|
+
if (answer === void 0 || answer.length === 0) {
|
|
3205
|
+
throw new GenerateObjectError2(
|
|
3206
|
+
"no_tool_call",
|
|
3207
|
+
"The tool loop finished with no text answer (tool-only completion) \u2014 there is nothing to structure."
|
|
3208
|
+
);
|
|
3209
|
+
}
|
|
3210
|
+
return answer;
|
|
3211
|
+
}
|
|
3212
|
+
|
|
3149
3213
|
// src/internal/runtime/cloud/cloud-agent.ts
|
|
3150
3214
|
init_errors();
|
|
3151
3215
|
init_cwd_mutex();
|
|
@@ -3296,8 +3360,19 @@ function safeFilenameForId(id, options) {
|
|
|
3296
3360
|
return `h-${crypto.createHash("sha256").update(id).digest("hex").slice(0, 16)}`;
|
|
3297
3361
|
}
|
|
3298
3362
|
|
|
3299
|
-
// src/internal/runtime/
|
|
3300
|
-
|
|
3363
|
+
// src/internal/runtime/model-selection.ts
|
|
3364
|
+
init_errors();
|
|
3365
|
+
function normalizeModel(m) {
|
|
3366
|
+
if (m === void 0 || typeof m !== "string") return m;
|
|
3367
|
+
const id = m.trim();
|
|
3368
|
+
if (id.length === 0) {
|
|
3369
|
+
throw new ConfigurationError(
|
|
3370
|
+
'model must be a non-empty "provider/model" id string or a ModelSelection object',
|
|
3371
|
+
{ code: "invalid_model_selection" }
|
|
3372
|
+
);
|
|
3373
|
+
}
|
|
3374
|
+
return { id };
|
|
3375
|
+
}
|
|
3301
3376
|
|
|
3302
3377
|
// src/internal/runtime/registry/agent-registry-store.ts
|
|
3303
3378
|
init_cwd_mutex();
|
|
@@ -3374,7 +3449,10 @@ var REGISTRY_RELATIVE_PATH = path.join(".theokit", "agents", "registry.json");
|
|
|
3374
3449
|
function stripSecretsFromOptions(options) {
|
|
3375
3450
|
return assignDefined({
|
|
3376
3451
|
name: options.name,
|
|
3377
|
-
model:
|
|
3452
|
+
model: (() => {
|
|
3453
|
+
const m = normalizeModel(options.model);
|
|
3454
|
+
return m !== void 0 ? { id: m.id } : void 0;
|
|
3455
|
+
})(),
|
|
3378
3456
|
systemPrompt: typeof options.systemPrompt === "string" ? options.systemPrompt : void 0,
|
|
3379
3457
|
local: serializeLocal(options.local),
|
|
3380
3458
|
cloud: serializeCloud(options.cloud),
|
|
@@ -3659,7 +3737,8 @@ function serializeCloudAgentConfig(options) {
|
|
|
3659
3737
|
cloud: serializeCloud2(options.cloud)
|
|
3660
3738
|
};
|
|
3661
3739
|
if (typeof options.agentId === "string") payload.agentId = options.agentId;
|
|
3662
|
-
|
|
3740
|
+
const cfgModel = normalizeModel(options.model);
|
|
3741
|
+
if (cfgModel !== void 0) payload.model = { id: cfgModel.id };
|
|
3663
3742
|
if (typeof options.systemPrompt === "string") payload.systemPrompt = options.systemPrompt;
|
|
3664
3743
|
const skills = serializeSkills(options.skills);
|
|
3665
3744
|
if (skills !== void 0) payload.skills = skills;
|
|
@@ -4555,6 +4634,7 @@ function applyScriptMetrics(base, script) {
|
|
|
4555
4634
|
if (script.cost !== void 0) base.cost = script.cost;
|
|
4556
4635
|
if (script.stoppedAtIterationLimit === true) base.stoppedAtIterationLimit = true;
|
|
4557
4636
|
if (script.stoppedByDoomLoop === true) base.stoppedByDoomLoop = true;
|
|
4637
|
+
if (script.origin !== void 0) base.origin = script.origin;
|
|
4558
4638
|
}
|
|
4559
4639
|
|
|
4560
4640
|
// src/internal/runtime/cloud/cloud-run.ts
|
|
@@ -4910,7 +4990,7 @@ var CloudAgent = class {
|
|
|
4910
4990
|
disposed = false;
|
|
4911
4991
|
constructor(options, providedAgentId) {
|
|
4912
4992
|
this.agentId = providedAgentId ?? options.agentId ?? generateCloudAgentId();
|
|
4913
|
-
this.model = options.model;
|
|
4993
|
+
this.model = normalizeModel(options.model);
|
|
4914
4994
|
this.options = options;
|
|
4915
4995
|
this.cloudPayload = serializeCloudAgentConfig({ ...options, agentId: this.agentId });
|
|
4916
4996
|
const repoUrls = (options.cloud?.repos ?? []).map((repo) => repo.url);
|
|
@@ -4940,6 +5020,17 @@ var CloudAgent = class {
|
|
|
4940
5020
|
const apiKey = resolveApiKey(this.options.apiKey);
|
|
4941
5021
|
return isFixtureApiKey(apiKey) && getConfiguredBaseUrl() === void 0;
|
|
4942
5022
|
}
|
|
5023
|
+
// SE9 — integrated structured output; delegates to the shared helper.
|
|
5024
|
+
generate(message, options) {
|
|
5025
|
+
return agentGenerate(
|
|
5026
|
+
this,
|
|
5027
|
+
this.model,
|
|
5028
|
+
this.options.apiKey,
|
|
5029
|
+
this.options.local,
|
|
5030
|
+
message,
|
|
5031
|
+
options
|
|
5032
|
+
);
|
|
5033
|
+
}
|
|
4943
5034
|
async send(message, options = {}) {
|
|
4944
5035
|
if (options.tools !== void 0 && options.tools.length > 0) {
|
|
4945
5036
|
throw new ConfigurationError(
|
|
@@ -4970,7 +5061,7 @@ var CloudAgent = class {
|
|
|
4970
5061
|
});
|
|
4971
5062
|
}
|
|
4972
5063
|
async sendLocked(message, options) {
|
|
4973
|
-
const overrideModel = options.model;
|
|
5064
|
+
const overrideModel = normalizeModel(options.model);
|
|
4974
5065
|
if (overrideModel !== void 0) {
|
|
4975
5066
|
this.model = overrideModel;
|
|
4976
5067
|
updateRegisteredAgent(this.agentId, { model: overrideModel });
|
|
@@ -5884,18 +5975,18 @@ var ALL_ADAPTERS = [
|
|
|
5884
5975
|
arizeAdapter,
|
|
5885
5976
|
braintrustAdapter
|
|
5886
5977
|
];
|
|
5887
|
-
var
|
|
5978
|
+
var registered2 = /* @__PURE__ */ new Set();
|
|
5888
5979
|
function tryAutoRegisterAdapters(settings) {
|
|
5889
5980
|
if (settings?.enabled !== true) return;
|
|
5890
5981
|
if (settings.autoDetect === false) return;
|
|
5891
5982
|
const disabled = new Set(settings.disable ?? []);
|
|
5892
5983
|
for (const adapter of ALL_ADAPTERS) {
|
|
5893
|
-
if (
|
|
5984
|
+
if (registered2.has(adapter.moduleName)) continue;
|
|
5894
5985
|
if (disabled.has(adapter.displayName.toLowerCase())) continue;
|
|
5895
5986
|
if (!adapter.detect()) continue;
|
|
5896
5987
|
try {
|
|
5897
5988
|
adapter.register();
|
|
5898
|
-
|
|
5989
|
+
registered2.add(adapter.moduleName);
|
|
5899
5990
|
process.stderr.write(`[theokit-sdk] telemetry: ${adapter.displayName} auto-instrumented.
|
|
5900
5991
|
`);
|
|
5901
5992
|
} catch (cause) {
|
|
@@ -6458,6 +6549,26 @@ function paginate(items, opts) {
|
|
|
6458
6549
|
return items.slice(start, end);
|
|
6459
6550
|
}
|
|
6460
6551
|
|
|
6552
|
+
// src/internal/persistence/session-meta.ts
|
|
6553
|
+
function applyMetaPatch(current, patch) {
|
|
6554
|
+
const next = {};
|
|
6555
|
+
if (current.title !== void 0) next.title = current.title;
|
|
6556
|
+
if (current.tag !== void 0) next.tag = current.tag;
|
|
6557
|
+
if (patch.title === null) delete next.title;
|
|
6558
|
+
else if (patch.title !== void 0) next.title = patch.title;
|
|
6559
|
+
if (patch.tag === null) delete next.tag;
|
|
6560
|
+
else if (patch.tag !== void 0) next.tag = patch.tag;
|
|
6561
|
+
return next;
|
|
6562
|
+
}
|
|
6563
|
+
function coerceSessionMeta(raw) {
|
|
6564
|
+
if (typeof raw !== "object" || raw === null) return void 0;
|
|
6565
|
+
const obj = raw;
|
|
6566
|
+
const meta = {};
|
|
6567
|
+
if (typeof obj.title === "string") meta.title = obj.title;
|
|
6568
|
+
if (typeof obj.tag === "string") meta.tag = obj.tag;
|
|
6569
|
+
return meta.title === void 0 && meta.tag === void 0 ? void 0 : meta;
|
|
6570
|
+
}
|
|
6571
|
+
|
|
6461
6572
|
// src/internal/persistence/conversation-storage-fs.ts
|
|
6462
6573
|
var FileSystemConversationStorage = class {
|
|
6463
6574
|
#root;
|
|
@@ -6508,6 +6619,37 @@ var FileSystemConversationStorage = class {
|
|
|
6508
6619
|
async compact(conversationId, maxTurns) {
|
|
6509
6620
|
await compactSessionFile(this.#root, conversationId, maxTurns);
|
|
6510
6621
|
}
|
|
6622
|
+
// SE4 — session metadata persisted as a per-conversation sidecar
|
|
6623
|
+
// `<root>/.theokit/agents/<safeId>/session.json` (same sanitized perimeter as
|
|
6624
|
+
// the transcript). Kept separate from messages.jsonl so a title/tag write does
|
|
6625
|
+
// not rewrite the append-only log.
|
|
6626
|
+
#metaPath(conversationId) {
|
|
6627
|
+
const safe3 = sanitizeIdentifier(conversationId, { maxLen: 128 });
|
|
6628
|
+
return safePathJoin(this.#root, ".theokit", "agents", safe3, "session.json");
|
|
6629
|
+
}
|
|
6630
|
+
async getSessionMeta(conversationId) {
|
|
6631
|
+
try {
|
|
6632
|
+
const raw = await promises.readFile(this.#metaPath(conversationId), "utf8");
|
|
6633
|
+
return coerceSessionMeta(JSON.parse(raw));
|
|
6634
|
+
} catch (cause) {
|
|
6635
|
+
if (cause.code === "ENOENT") return void 0;
|
|
6636
|
+
throw cause;
|
|
6637
|
+
}
|
|
6638
|
+
}
|
|
6639
|
+
async setSessionMeta(conversationId, patch) {
|
|
6640
|
+
const metaPath = this.#metaPath(conversationId);
|
|
6641
|
+
await promises.mkdir(path.dirname(metaPath), { recursive: true });
|
|
6642
|
+
await withFileLock(metaPath, async () => {
|
|
6643
|
+
let current = {};
|
|
6644
|
+
try {
|
|
6645
|
+
current = coerceSessionMeta(JSON.parse(await promises.readFile(metaPath, "utf8"))) ?? {};
|
|
6646
|
+
} catch (cause) {
|
|
6647
|
+
if (cause.code !== "ENOENT") throw cause;
|
|
6648
|
+
}
|
|
6649
|
+
const next = applyMetaPatch(current, patch);
|
|
6650
|
+
await promises.writeFile(metaPath, redactSecrets(JSON.stringify(next)), "utf8");
|
|
6651
|
+
});
|
|
6652
|
+
}
|
|
6511
6653
|
async dispose() {
|
|
6512
6654
|
}
|
|
6513
6655
|
};
|
|
@@ -8427,7 +8569,7 @@ function bootstrapSubmanagers(args) {
|
|
|
8427
8569
|
const providerCount = (args.options.providers?.routes?.length ?? 0) + enabledPluginNames(args.options.plugins).length;
|
|
8428
8570
|
if (providerCount > 0 || args.options.providers !== void 0) {
|
|
8429
8571
|
out.providers = new ProvidersManagerImpl(
|
|
8430
|
-
args.options.model,
|
|
8572
|
+
normalizeModel(args.options.model),
|
|
8431
8573
|
args.options.providers,
|
|
8432
8574
|
args.options.plugins
|
|
8433
8575
|
);
|
|
@@ -8497,6 +8639,7 @@ function createLocalRun(options) {
|
|
|
8497
8639
|
projectMcpServers: options.projectMcpServers,
|
|
8498
8640
|
...options.persistMemoryFact !== void 0 ? { persistMemoryFact: options.persistMemoryFact } : {}
|
|
8499
8641
|
});
|
|
8642
|
+
if (options.sendOptions.origin !== void 0) script.origin = options.sendOptions.origin;
|
|
8500
8643
|
const handle = new LocalRun({
|
|
8501
8644
|
id,
|
|
8502
8645
|
agentId: options.agentId,
|
|
@@ -9145,6 +9288,15 @@ async function emitReasoningDeltaCallback(inputs, text) {
|
|
|
9145
9288
|
);
|
|
9146
9289
|
}
|
|
9147
9290
|
|
|
9291
|
+
// src/types/run-events.ts
|
|
9292
|
+
function emitRunEvent(sink, event) {
|
|
9293
|
+
if (sink === void 0) return;
|
|
9294
|
+
try {
|
|
9295
|
+
sink(event);
|
|
9296
|
+
} catch {
|
|
9297
|
+
}
|
|
9298
|
+
}
|
|
9299
|
+
|
|
9148
9300
|
// src/internal/agent-loop/tool-dispatch.ts
|
|
9149
9301
|
init_async_local_storage();
|
|
9150
9302
|
|
|
@@ -9242,6 +9394,22 @@ function coerceArgsToSchema(args, schema) {
|
|
|
9242
9394
|
return { value: out, changed };
|
|
9243
9395
|
}
|
|
9244
9396
|
|
|
9397
|
+
// src/tool-error.ts
|
|
9398
|
+
init_errors();
|
|
9399
|
+
var ToolError = class extends TheokitAgentError {
|
|
9400
|
+
name = "ToolError";
|
|
9401
|
+
/** The error content surfaced to the model: a string, or text/image blocks. */
|
|
9402
|
+
content;
|
|
9403
|
+
constructor(content, options = {}) {
|
|
9404
|
+
super(renderToolErrorMessage(content), { ...options, isRetryable: false });
|
|
9405
|
+
this.content = content;
|
|
9406
|
+
}
|
|
9407
|
+
};
|
|
9408
|
+
function renderToolErrorMessage(content) {
|
|
9409
|
+
if (typeof content === "string") return content;
|
|
9410
|
+
return content.map((block) => block.type === "text" ? block.text : `[${block.source.media_type} image]`).join("\n");
|
|
9411
|
+
}
|
|
9412
|
+
|
|
9245
9413
|
// src/internal/runtime/tools/shell-tool.ts
|
|
9246
9414
|
async function runShell(options) {
|
|
9247
9415
|
if (options.sandbox === true && isObviouslyUnsafe(options.command)) {
|
|
@@ -9295,9 +9463,13 @@ async function runHandlerTool(kind, handler, call, signal, context) {
|
|
|
9295
9463
|
return { stdout: "", stderr: `${kind} tool ${call.name} has no handler`, exitCode: 127 };
|
|
9296
9464
|
}
|
|
9297
9465
|
try {
|
|
9298
|
-
const
|
|
9299
|
-
return { stdout, stderr: "", exitCode: 0 };
|
|
9466
|
+
const out = await handler(call.input, { signal, context });
|
|
9467
|
+
if (typeof out !== "string") return { stdout: "", stderr: "", exitCode: 0, content: out };
|
|
9468
|
+
return { stdout: out, stderr: "", exitCode: 0 };
|
|
9300
9469
|
} catch (cause) {
|
|
9470
|
+
if (cause instanceof ToolError) {
|
|
9471
|
+
return { stdout: "", stderr: cause.message, exitCode: 1, content: cause.content };
|
|
9472
|
+
}
|
|
9301
9473
|
const message = cause instanceof Error ? cause.message : String(cause);
|
|
9302
9474
|
return { stdout: "", stderr: message, exitCode: 1 };
|
|
9303
9475
|
}
|
|
@@ -9416,6 +9588,11 @@ async function dispatchSingleCall(inputs, tools, call, events, parentSpan) {
|
|
|
9416
9588
|
toolSpan?.end();
|
|
9417
9589
|
return fileVeto;
|
|
9418
9590
|
}
|
|
9591
|
+
emitRunEvent(inputs.runEventSink, {
|
|
9592
|
+
type: "tool_progress",
|
|
9593
|
+
toolName: workingCall.name,
|
|
9594
|
+
toolCallId: callId
|
|
9595
|
+
});
|
|
9419
9596
|
const result = await runToolWithLifecycle(inputs, resolved, workingCall, callId);
|
|
9420
9597
|
await inputs.pluginManager?.runPostToolCallHooks({
|
|
9421
9598
|
name: workingCall.name,
|
|
@@ -9442,6 +9619,13 @@ function applyRepairAndExtractCall(tools, call) {
|
|
|
9442
9619
|
function vetoFromForkWhitelist(inputs, call, callId, events) {
|
|
9443
9620
|
const whitelistDecision = checkToolWhitelist(call.name);
|
|
9444
9621
|
if (whitelistDecision.allowed) return void 0;
|
|
9622
|
+
emitRunEvent(inputs.runEventSink, {
|
|
9623
|
+
type: "permission_denied",
|
|
9624
|
+
toolName: call.name,
|
|
9625
|
+
toolCallId: callId,
|
|
9626
|
+
source: "fork_whitelist",
|
|
9627
|
+
message: whitelistDecision.reason ?? "tool not available in fork"
|
|
9628
|
+
});
|
|
9445
9629
|
events.push(buildToolUseRunning(inputs, callId, call));
|
|
9446
9630
|
events.push(
|
|
9447
9631
|
buildToolUseCompleted(inputs, callId, call, {
|
|
@@ -9478,6 +9662,13 @@ async function vetoFromPluginPreHook(inputs, call, callId, events) {
|
|
|
9478
9662
|
runId: inputs.runId
|
|
9479
9663
|
});
|
|
9480
9664
|
if (pluginVeto === void 0) return void 0;
|
|
9665
|
+
emitRunEvent(inputs.runEventSink, {
|
|
9666
|
+
type: "permission_denied",
|
|
9667
|
+
toolName: call.name,
|
|
9668
|
+
toolCallId: callId,
|
|
9669
|
+
source: "plugin",
|
|
9670
|
+
message: pluginVeto.message
|
|
9671
|
+
});
|
|
9481
9672
|
events.push(
|
|
9482
9673
|
buildToolUseCompleted(inputs, callId, call, {
|
|
9483
9674
|
stdout: "",
|
|
@@ -9500,6 +9691,13 @@ async function vetoFromFileHookPreDecision(inputs, call, callId, events) {
|
|
|
9500
9691
|
runId: inputs.runId
|
|
9501
9692
|
});
|
|
9502
9693
|
if (!preDecision.blocked) return void 0;
|
|
9694
|
+
emitRunEvent(inputs.runEventSink, {
|
|
9695
|
+
type: "permission_denied",
|
|
9696
|
+
toolName: call.name,
|
|
9697
|
+
toolCallId: callId,
|
|
9698
|
+
source: "file_hook",
|
|
9699
|
+
message: preDecision.reason ?? "blocked by hook"
|
|
9700
|
+
});
|
|
9503
9701
|
events.push(
|
|
9504
9702
|
buildToolUseCompleted(inputs, callId, call, {
|
|
9505
9703
|
stdout: "",
|
|
@@ -9543,7 +9741,9 @@ async function runToolWithLifecycle(inputs, resolved, call, callId) {
|
|
|
9543
9741
|
await safeEmitToolHook(inputs.onToolEnd, {
|
|
9544
9742
|
toolName: call.name,
|
|
9545
9743
|
args: call.input,
|
|
9546
|
-
|
|
9744
|
+
// SE7 — a block-returning handler has empty `stdout`; surface its structured
|
|
9745
|
+
// content to the hook instead of an empty string.
|
|
9746
|
+
result: result.content !== void 0 ? result.content : result.stdout,
|
|
9547
9747
|
conversationId: inputs.agentId,
|
|
9548
9748
|
callId,
|
|
9549
9749
|
durationMs
|
|
@@ -9565,7 +9765,10 @@ function finalizeSpanAndPostHook(inputs, call, callId, result, events, toolSpan)
|
|
|
9565
9765
|
output: {
|
|
9566
9766
|
stdout: result.stdout,
|
|
9567
9767
|
stderr: result.stderr,
|
|
9568
|
-
exitCode: result.exitCode ?? 0
|
|
9768
|
+
exitCode: result.exitCode ?? 0,
|
|
9769
|
+
// SE7 — structured content (text + image blocks) when the handler
|
|
9770
|
+
// returned/threw blocks; absent for the string path.
|
|
9771
|
+
...result.content !== void 0 ? { content: result.content } : {}
|
|
9569
9772
|
},
|
|
9570
9773
|
agentId: inputs.agentId,
|
|
9571
9774
|
runId: inputs.runId
|
|
@@ -9578,7 +9781,9 @@ function finalizeSpanAndPostHook(inputs, call, callId, result, events, toolSpan)
|
|
|
9578
9781
|
return {
|
|
9579
9782
|
type: "tool_result",
|
|
9580
9783
|
toolUseId: call.id,
|
|
9581
|
-
content
|
|
9784
|
+
// SE7 — structured content blocks (handler-returned or ToolError-carried)
|
|
9785
|
+
// are authoritative; otherwise the legacy string rendering.
|
|
9786
|
+
content: result.content !== void 0 ? result.content : renderToolResult(result),
|
|
9582
9787
|
...result.exitCode !== 0 && result.exitCode !== void 0 ? { isError: true } : {}
|
|
9583
9788
|
};
|
|
9584
9789
|
}
|
|
@@ -9627,6 +9832,29 @@ function buildToolUseCompleted(inputs, callId, call, result) {
|
|
|
9627
9832
|
};
|
|
9628
9833
|
}
|
|
9629
9834
|
|
|
9835
|
+
// src/internal/llm/tool-result-content.ts
|
|
9836
|
+
init_errors();
|
|
9837
|
+
function toBlockToolResultContent(content) {
|
|
9838
|
+
return content;
|
|
9839
|
+
}
|
|
9840
|
+
function toStringToolResultContent(content, providerName) {
|
|
9841
|
+
if (typeof content === "string") return content;
|
|
9842
|
+
if (content.some((block) => block.type === "image")) {
|
|
9843
|
+
throw new ConfigurationError(
|
|
9844
|
+
`provider "${providerName}" does not support image content in tool results`
|
|
9845
|
+
);
|
|
9846
|
+
}
|
|
9847
|
+
return content.filter(
|
|
9848
|
+
(block) => block.type === "text"
|
|
9849
|
+
).map((block) => block.text).join("\n");
|
|
9850
|
+
}
|
|
9851
|
+
function renderToolResultContentText(content, fn) {
|
|
9852
|
+
if (typeof content === "string") return fn(content);
|
|
9853
|
+
return content.map(
|
|
9854
|
+
(block) => block.type === "text" ? { type: "text", text: fn(block.text) } : block
|
|
9855
|
+
);
|
|
9856
|
+
}
|
|
9857
|
+
|
|
9630
9858
|
// src/internal/agent-loop/tool-result-guard.ts
|
|
9631
9859
|
var OPEN = "<untrusted-tool-output>";
|
|
9632
9860
|
var CLOSE = "</untrusted-tool-output>";
|
|
@@ -9652,7 +9880,11 @@ ${CLOSE}`;
|
|
|
9652
9880
|
function applyToolResultGuard(parts, opts) {
|
|
9653
9881
|
if (opts.delimit !== true && opts.redactPii !== true) return parts;
|
|
9654
9882
|
return parts.map(
|
|
9655
|
-
(p) =>
|
|
9883
|
+
(p) => (
|
|
9884
|
+
// SE7 — guard the TEXT of a tool result (string or the text blocks of a
|
|
9885
|
+
// structured content); image blocks pass through untouched.
|
|
9886
|
+
p.type === "tool_result" ? { ...p, content: renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
|
|
9887
|
+
)
|
|
9656
9888
|
);
|
|
9657
9889
|
}
|
|
9658
9890
|
|
|
@@ -10569,10 +10801,10 @@ function stripVertexPrefix(modelId) {
|
|
|
10569
10801
|
}
|
|
10570
10802
|
|
|
10571
10803
|
// src/internal/providers/builtin/index.ts
|
|
10572
|
-
var
|
|
10804
|
+
var registered3 = false;
|
|
10573
10805
|
function registerBuiltins() {
|
|
10574
|
-
if (
|
|
10575
|
-
|
|
10806
|
+
if (registered3) return;
|
|
10807
|
+
registered3 = true;
|
|
10576
10808
|
registerProvider(ANTHROPIC);
|
|
10577
10809
|
registerProvider(OPENAI);
|
|
10578
10810
|
registerProvider(OPENROUTER);
|
|
@@ -10800,7 +11032,9 @@ function toAnthropicWireMessage(message) {
|
|
|
10800
11032
|
return {
|
|
10801
11033
|
type: "tool_result",
|
|
10802
11034
|
tool_use_id: part.toolUseId,
|
|
10803
|
-
|
|
11035
|
+
// SE7 — this wire is block-capable: strings pass through, structured
|
|
11036
|
+
// text/image blocks are forwarded natively.
|
|
11037
|
+
content: toBlockToolResultContent(part.content),
|
|
10804
11038
|
...part.isError === true ? { is_error: true } : {}
|
|
10805
11039
|
};
|
|
10806
11040
|
});
|
|
@@ -11592,7 +11826,8 @@ function toOllamaMessages(message) {
|
|
|
11592
11826
|
if (part.type === "tool_result") {
|
|
11593
11827
|
out.push({
|
|
11594
11828
|
role: "tool",
|
|
11595
|
-
|
|
11829
|
+
// SE7 — string-only tool role: text blocks flatten; image fails fast.
|
|
11830
|
+
content: toStringToolResultContent(part.content, "ollama"),
|
|
11596
11831
|
tool_name: part.toolUseId
|
|
11597
11832
|
});
|
|
11598
11833
|
}
|
|
@@ -12129,7 +12364,9 @@ function userOrToolMessages(message) {
|
|
|
12129
12364
|
out.push({
|
|
12130
12365
|
role: "tool",
|
|
12131
12366
|
tool_call_id: part.toolUseId,
|
|
12132
|
-
|
|
12367
|
+
// SE7 — this wire's tool role is string-only: text blocks flatten; an
|
|
12368
|
+
// image block fails fast (ConfigurationError).
|
|
12369
|
+
content: toStringToolResultContent(part.content, "openai")
|
|
12133
12370
|
});
|
|
12134
12371
|
}
|
|
12135
12372
|
}
|
|
@@ -13058,18 +13295,20 @@ function levenshtein(a, b) {
|
|
|
13058
13295
|
function createRealLocalRun(options) {
|
|
13059
13296
|
const { userText, id, startTime } = prepareRunContext(options.message);
|
|
13060
13297
|
const supported = /* @__PURE__ */ new Set(["stream", "wait", "cancel", "conversation"]);
|
|
13061
|
-
const
|
|
13298
|
+
const runScript = {
|
|
13062
13299
|
events: [],
|
|
13063
13300
|
finalStatus: "running",
|
|
13064
13301
|
cancellable: false,
|
|
13065
|
-
conversation: []
|
|
13302
|
+
conversation: [],
|
|
13303
|
+
// SE3 — carry the turn's provenance so buildResult forwards it onto RunResult.origin.
|
|
13304
|
+
...options.sendOptions.origin !== void 0 ? { origin: options.sendOptions.origin } : {}
|
|
13066
13305
|
};
|
|
13067
13306
|
const handle = new RealLocalRun(
|
|
13068
13307
|
{
|
|
13069
13308
|
id,
|
|
13070
13309
|
agentId: options.agentId,
|
|
13071
13310
|
model: options.model,
|
|
13072
|
-
script:
|
|
13311
|
+
script: runScript,
|
|
13073
13312
|
supportedOps: supported,
|
|
13074
13313
|
startTime
|
|
13075
13314
|
},
|
|
@@ -13181,6 +13420,8 @@ function buildLoopInputs(options, runId, userText) {
|
|
|
13181
13420
|
// M7 — forward SendOptions.context to the loop so every tool handler receives
|
|
13182
13421
|
// it on `ctx.context` (shared run config set once, e.g. projectRoot).
|
|
13183
13422
|
...options.sendOptions.context !== void 0 ? { context: options.sendOptions.context } : {},
|
|
13423
|
+
// SE2 — forward the opt-in typed runtime-event sink to the loop.
|
|
13424
|
+
...options.sendOptions.onRunEvent !== void 0 ? { runEventSink: options.sendOptions.onRunEvent } : {},
|
|
13184
13425
|
// #58 / #57 — forward the per-tool timeout + tool-result guard so a consumer
|
|
13185
13426
|
// can enable them via SendOptions (not only internal AgentLoopInputs).
|
|
13186
13427
|
...options.sendOptions.perToolTimeoutMs !== void 0 ? { perToolTimeoutMs: options.sendOptions.perToolTimeoutMs } : {},
|
|
@@ -15873,7 +16114,7 @@ function wrapRunWithPostReplyHook(args) {
|
|
|
15873
16114
|
async function executeSendLocked(inputs, message, options) {
|
|
15874
16115
|
if (inputs.disposed) throw new AgentDisposedError(inputs.agentId);
|
|
15875
16116
|
await consumePending(inputs.agentId, inputs.invalidationPending, inputs.clearInvalidation, inputs.reload);
|
|
15876
|
-
inputs.applyModelOverride(options.model);
|
|
16117
|
+
inputs.applyModelOverride(normalizeModel(options.model));
|
|
15877
16118
|
const userText = typeof message === "string" ? message : message.text;
|
|
15878
16119
|
if (inputs.options.onBeforeSend !== void 0) {
|
|
15879
16120
|
await inputs.options.onBeforeSend({
|
|
@@ -16025,7 +16266,7 @@ var LocalAgent = class {
|
|
|
16025
16266
|
constructor(options) {
|
|
16026
16267
|
this.agentId = options.agentId ?? generateLocalAgentId();
|
|
16027
16268
|
this._telemetry = createTelemetry(options.telemetry);
|
|
16028
|
-
this.model = options.model;
|
|
16269
|
+
this.model = normalizeModel(options.model);
|
|
16029
16270
|
this.options = options;
|
|
16030
16271
|
this.workspaceCwd = resolveCwd(options.local?.cwd);
|
|
16031
16272
|
this.conversationStorage = options.conversationStorage;
|
|
@@ -16092,6 +16333,11 @@ var LocalAgent = class {
|
|
|
16092
16333
|
hooks() {
|
|
16093
16334
|
return this.hooksExecutor;
|
|
16094
16335
|
}
|
|
16336
|
+
// SE9 — integrated structured output; delegates to the shared helper.
|
|
16337
|
+
generate(message, options) {
|
|
16338
|
+
const { apiKey, local } = this.options;
|
|
16339
|
+
return agentGenerate(this, this.model, apiKey, local, message, options);
|
|
16340
|
+
}
|
|
16095
16341
|
async send(message, options = {}) {
|
|
16096
16342
|
if (options.tools !== void 0 && options.tools.length > 0) {
|
|
16097
16343
|
validateToolCatalog(options.tools);
|
|
@@ -16331,6 +16577,7 @@ function includesSetting(options, source) {
|
|
|
16331
16577
|
|
|
16332
16578
|
// src/agent-helpers.ts
|
|
16333
16579
|
async function runCreateUnderSpan(options, span) {
|
|
16580
|
+
options = { ...options, model: normalizeModel(options.model) };
|
|
16334
16581
|
validateAgentOptions(options);
|
|
16335
16582
|
validateCloudToolParity(options);
|
|
16336
16583
|
await guardAgainstIdCollision(options);
|
|
@@ -16404,7 +16651,10 @@ async function createLocalAgent(options) {
|
|
|
16404
16651
|
const willFlowToProvider = !isFixtureApiKey(apiKey) && !shouldUseRealLocalRuntime(apiKey);
|
|
16405
16652
|
const shape = validateApiKeyShape(apiKey, {
|
|
16406
16653
|
strict: willFlowToProvider,
|
|
16407
|
-
|
|
16654
|
+
// `options.model` is already normalized by `runCreateUnderSpan`; `normalizeModel`
|
|
16655
|
+
// here is the idempotent narrowing of the widened public type (`{id}` passes
|
|
16656
|
+
// through by reference) — cleaner than an `as` cast.
|
|
16657
|
+
...willFlowToProvider ? { provider: providerFromModelId(normalizeModel(options.model)?.id) } : {}
|
|
16408
16658
|
});
|
|
16409
16659
|
if (shape.malformed) {
|
|
16410
16660
|
throw new AuthenticationError(shape.message, { code: "malformed_api_key" });
|
|
@@ -16470,6 +16720,10 @@ async function rehydrateExistingAgent(agentId, existing, options) {
|
|
|
16470
16720
|
...existing.options,
|
|
16471
16721
|
...options,
|
|
16472
16722
|
...mergedLocal !== void 0 ? { local: mergedLocal } : {},
|
|
16723
|
+
// SE8 — normalize a caller-supplied bare-string model override at this resume
|
|
16724
|
+
// boundary (Agent.resume never flows through runCreateUnderSpan). Cloud resume
|
|
16725
|
+
// honors it; local resume forces the persisted model below.
|
|
16726
|
+
model: normalizeModel(options.model ?? existing.options.model),
|
|
16473
16727
|
mcpServers: void 0,
|
|
16474
16728
|
agentId
|
|
16475
16729
|
};
|
|
@@ -16836,6 +17090,7 @@ async function getOrCreateUncached(agentId, options) {
|
|
|
16836
17090
|
}
|
|
16837
17091
|
setAgentFacade({
|
|
16838
17092
|
create: (options) => Agent.create(options),
|
|
17093
|
+
delete: (agentId) => Agent.delete(agentId),
|
|
16839
17094
|
prompt: (message, options) => Agent.prompt(message, options),
|
|
16840
17095
|
get: (agentId) => Agent.get(agentId),
|
|
16841
17096
|
resume: (agentId, options) => Agent.resume(agentId, options),
|