@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/cron.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');
|
|
@@ -513,6 +513,256 @@ var init_errors = __esm({
|
|
|
513
513
|
};
|
|
514
514
|
}
|
|
515
515
|
});
|
|
516
|
+
function toJsonSchema(schema, options = { unrepresentable: "any" }) {
|
|
517
|
+
return zod.toJSONSchema(schema, options);
|
|
518
|
+
}
|
|
519
|
+
var init_to_json_schema = __esm({
|
|
520
|
+
"src/internal/zod/to-json-schema.ts"() {
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
function requireZod() {
|
|
524
|
+
if (cachedZ !== void 0) return cachedZ;
|
|
525
|
+
const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cron.cjs', document.baseURI).href)));
|
|
526
|
+
let mod;
|
|
527
|
+
try {
|
|
528
|
+
mod = r("zod");
|
|
529
|
+
} catch (cause) {
|
|
530
|
+
throw new ConfigurationError(
|
|
531
|
+
'Structured output requires the optional peer dependency `zod`. Add `"zod": "^3.25.0 || ^4.0.0"` to your package.json and reinstall.',
|
|
532
|
+
{ code: "zod_not_installed", cause }
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
cachedZ = mod.z ?? mod;
|
|
536
|
+
return cachedZ;
|
|
537
|
+
}
|
|
538
|
+
function makeOutputTool(jsonSchema, onCapture) {
|
|
539
|
+
return {
|
|
540
|
+
name: "output",
|
|
541
|
+
description: "Call this tool with your final structured answer. Match the JSON schema exactly.",
|
|
542
|
+
inputSchema: jsonSchema,
|
|
543
|
+
handler: (input) => {
|
|
544
|
+
const out = onCapture(input);
|
|
545
|
+
if (typeof out === "string") return out;
|
|
546
|
+
if (out instanceof Promise) return out;
|
|
547
|
+
return "";
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
function buildTransientAgentOptions(params) {
|
|
552
|
+
return {
|
|
553
|
+
model: params.model,
|
|
554
|
+
local: params.local,
|
|
555
|
+
tools: [params.outputTool],
|
|
556
|
+
systemPrompt: params.systemPrompt ?? "You produce structured output by calling the `output` tool exactly once. Match the JSON schema.",
|
|
557
|
+
...params.apiKey !== void 0 ? { apiKey: params.apiKey } : {},
|
|
558
|
+
...params.providers !== void 0 ? { providers: params.providers } : {}
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
function extractUsage(result) {
|
|
562
|
+
const u = result.usage;
|
|
563
|
+
if (u === void 0) return { inputTokens: 0, outputTokens: 0 };
|
|
564
|
+
return { inputTokens: u.inputTokens ?? 0, outputTokens: u.outputTokens ?? 0 };
|
|
565
|
+
}
|
|
566
|
+
function buildToolPrompt(prompt) {
|
|
567
|
+
return `${prompt}
|
|
568
|
+
|
|
569
|
+
Respond by calling the \`output\` tool with the structured answer that matches the schema.`;
|
|
570
|
+
}
|
|
571
|
+
function setupStructuredOutput(schema, maxRetries) {
|
|
572
|
+
const z6 = requireZod();
|
|
573
|
+
const jsonSchema = toJsonSchema(schema, { unrepresentable: "any" });
|
|
574
|
+
return {
|
|
575
|
+
z: z6,
|
|
576
|
+
jsonSchema,
|
|
577
|
+
maxRetries: maxRetries ?? 1,
|
|
578
|
+
initialUsage: { inputTokens: 0, outputTokens: 0 }
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
async function disposeAndDeleteTransient(agent, deletor) {
|
|
582
|
+
await agent.dispose();
|
|
583
|
+
try {
|
|
584
|
+
await deletor(agent.agentId);
|
|
585
|
+
} catch {
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
var cachedZ;
|
|
589
|
+
var init_structured_output_helpers = __esm({
|
|
590
|
+
"src/internal/structured-output-helpers.ts"() {
|
|
591
|
+
init_errors();
|
|
592
|
+
init_to_json_schema();
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
// src/generate-object.ts
|
|
597
|
+
var generate_object_exports = {};
|
|
598
|
+
__export(generate_object_exports, {
|
|
599
|
+
GenerateObjectError: () => GenerateObjectError,
|
|
600
|
+
generateObjectImpl: () => generateObjectImpl
|
|
601
|
+
});
|
|
602
|
+
function salvagePartial(schema, raw) {
|
|
603
|
+
if (typeof raw !== "object" || raw === null) return raw;
|
|
604
|
+
const shape = schema.shape;
|
|
605
|
+
if (shape === void 0 || typeof shape !== "object") return raw;
|
|
606
|
+
const rawObj = raw;
|
|
607
|
+
const out = {};
|
|
608
|
+
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
609
|
+
if (typeof fieldSchema?.safeParse !== "function") continue;
|
|
610
|
+
const parsed = fieldSchema.safeParse(rawObj[key]);
|
|
611
|
+
if (parsed.success) out[key] = parsed.data;
|
|
612
|
+
}
|
|
613
|
+
return out;
|
|
614
|
+
}
|
|
615
|
+
async function runReasoningPhase(options, deps) {
|
|
616
|
+
const reasoningOptions = {
|
|
617
|
+
model: options.model,
|
|
618
|
+
local: options.local,
|
|
619
|
+
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
620
|
+
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
621
|
+
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
622
|
+
};
|
|
623
|
+
const reasoningAgent = await deps.create(reasoningOptions);
|
|
624
|
+
try {
|
|
625
|
+
const run = await reasoningAgent.send(options.prompt);
|
|
626
|
+
const result = await run.wait();
|
|
627
|
+
const text = result.result;
|
|
628
|
+
return typeof text === "string" ? text : options.prompt;
|
|
629
|
+
} finally {
|
|
630
|
+
await disposeAndDeleteTransient(reasoningAgent, deps.delete);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
async function generateObjectImpl(options, deps) {
|
|
634
|
+
const { jsonSchema, maxRetries, initialUsage } = setupStructuredOutput(
|
|
635
|
+
options.schema,
|
|
636
|
+
options.maxRetries
|
|
637
|
+
);
|
|
638
|
+
let capturedRaw;
|
|
639
|
+
let lastUsage = initialUsage;
|
|
640
|
+
const sentinel = /* @__PURE__ */ Symbol("generate-object-sentinel");
|
|
641
|
+
class CaptureSentinel extends Error {
|
|
642
|
+
constructor(captured) {
|
|
643
|
+
super("generate-object-capture");
|
|
644
|
+
this.captured = captured;
|
|
645
|
+
}
|
|
646
|
+
captured;
|
|
647
|
+
[sentinel] = true;
|
|
648
|
+
}
|
|
649
|
+
const outputTool = makeOutputTool(jsonSchema, (input) => {
|
|
650
|
+
if (capturedRaw === void 0) {
|
|
651
|
+
capturedRaw = input;
|
|
652
|
+
}
|
|
653
|
+
throw new CaptureSentinel(input);
|
|
654
|
+
});
|
|
655
|
+
const reasoningText = options.structuringModel !== void 0 ? await runReasoningPhase(options, deps) : void 0;
|
|
656
|
+
const structuringModel = options.structuringModel ?? options.model;
|
|
657
|
+
const structuringPrompt = reasoningText ?? options.prompt;
|
|
658
|
+
const agentOptions = buildTransientAgentOptions({
|
|
659
|
+
model: structuringModel,
|
|
660
|
+
local: options.local,
|
|
661
|
+
outputTool,
|
|
662
|
+
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
663
|
+
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
664
|
+
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
665
|
+
});
|
|
666
|
+
const agent = await deps.create(agentOptions);
|
|
667
|
+
try {
|
|
668
|
+
const userMessage = buildToolPrompt(structuringPrompt);
|
|
669
|
+
let lastParseError;
|
|
670
|
+
for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
|
|
671
|
+
capturedRaw = void 0;
|
|
672
|
+
const run = await agent.send(userMessage);
|
|
673
|
+
const result = await run.wait();
|
|
674
|
+
lastUsage = extractUsage(result);
|
|
675
|
+
if (capturedRaw === void 0) {
|
|
676
|
+
if (result.status === "error" && result.error !== void 0) {
|
|
677
|
+
throw new GenerateObjectError(
|
|
678
|
+
"no_tool_call",
|
|
679
|
+
`Agent run failed before the model could reply: ${result.error.message ?? "unknown error"} [${result.error.code ?? "?"}]`,
|
|
680
|
+
result.error
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
if (attempt === maxRetries) {
|
|
684
|
+
throw new GenerateObjectError(
|
|
685
|
+
"no_tool_call",
|
|
686
|
+
"The model returned text instead of calling the `output` tool."
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
|
+
const parsed = options.schema.safeParse(capturedRaw);
|
|
692
|
+
if (parsed.success) {
|
|
693
|
+
return {
|
|
694
|
+
object: parsed.data,
|
|
695
|
+
raw: capturedRaw,
|
|
696
|
+
usage: lastUsage,
|
|
697
|
+
finishReason: "tool_use"
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
lastParseError = parsed.error;
|
|
701
|
+
}
|
|
702
|
+
if (options.errorStrategy === "return-raw") {
|
|
703
|
+
return {
|
|
704
|
+
object: capturedRaw,
|
|
705
|
+
raw: capturedRaw,
|
|
706
|
+
usage: lastUsage,
|
|
707
|
+
finishReason: "tool_use"
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
if (options.errorStrategy === "return-partial") {
|
|
711
|
+
return {
|
|
712
|
+
object: salvagePartial(options.schema, capturedRaw),
|
|
713
|
+
raw: capturedRaw,
|
|
714
|
+
usage: lastUsage,
|
|
715
|
+
finishReason: "tool_use"
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
throw new GenerateObjectError(
|
|
719
|
+
"parse_failed",
|
|
720
|
+
"Schema parse failed after all retries.",
|
|
721
|
+
lastParseError
|
|
722
|
+
);
|
|
723
|
+
} finally {
|
|
724
|
+
await disposeAndDeleteTransient(agent, deps.delete);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
var GenerateObjectError;
|
|
728
|
+
var init_generate_object = __esm({
|
|
729
|
+
"src/generate-object.ts"() {
|
|
730
|
+
init_structured_output_helpers();
|
|
731
|
+
GenerateObjectError = class extends Error {
|
|
732
|
+
name = "GenerateObjectError";
|
|
733
|
+
code;
|
|
734
|
+
cause;
|
|
735
|
+
constructor(code, message, cause) {
|
|
736
|
+
super(message);
|
|
737
|
+
this.code = code;
|
|
738
|
+
if (cause !== void 0) this.cause = cause;
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
// src/internal/runtime/registry/agent-factory-registry.ts
|
|
745
|
+
var agent_factory_registry_exports = {};
|
|
746
|
+
__export(agent_factory_registry_exports, {
|
|
747
|
+
getAgentFacade: () => getAgentFacade,
|
|
748
|
+
setAgentFacade: () => setAgentFacade
|
|
749
|
+
});
|
|
750
|
+
function setAgentFacade(facade) {
|
|
751
|
+
registered = facade;
|
|
752
|
+
}
|
|
753
|
+
function getAgentFacade() {
|
|
754
|
+
if (registered === void 0) {
|
|
755
|
+
throw new Error(
|
|
756
|
+
"internal: Agent facade not registered. The `agent.ts` module must be loaded before internal subsystems (LocalAgent.runUntil/fork, eval, scorers, cron) invoke it."
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
return registered;
|
|
760
|
+
}
|
|
761
|
+
var registered;
|
|
762
|
+
var init_agent_factory_registry = __esm({
|
|
763
|
+
"src/internal/runtime/registry/agent-factory-registry.ts"() {
|
|
764
|
+
}
|
|
765
|
+
});
|
|
516
766
|
|
|
517
767
|
// src/internal/persistence/cwd-mutex.ts
|
|
518
768
|
function withCwdMutex(key, fn) {
|
|
@@ -1430,29 +1680,6 @@ var init_judge_call = __esm({
|
|
|
1430
1680
|
}
|
|
1431
1681
|
});
|
|
1432
1682
|
|
|
1433
|
-
// src/internal/runtime/registry/agent-factory-registry.ts
|
|
1434
|
-
var agent_factory_registry_exports = {};
|
|
1435
|
-
__export(agent_factory_registry_exports, {
|
|
1436
|
-
getAgentFacade: () => getAgentFacade,
|
|
1437
|
-
setAgentFacade: () => setAgentFacade
|
|
1438
|
-
});
|
|
1439
|
-
function setAgentFacade(facade) {
|
|
1440
|
-
registered3 = facade;
|
|
1441
|
-
}
|
|
1442
|
-
function getAgentFacade() {
|
|
1443
|
-
if (registered3 === void 0) {
|
|
1444
|
-
throw new Error(
|
|
1445
|
-
"internal: Agent facade not registered. The `agent.ts` module must be loaded before internal subsystems (LocalAgent.runUntil/fork, eval, scorers, cron) invoke it."
|
|
1446
|
-
);
|
|
1447
|
-
}
|
|
1448
|
-
return registered3;
|
|
1449
|
-
}
|
|
1450
|
-
var registered3;
|
|
1451
|
-
var init_agent_factory_registry = __esm({
|
|
1452
|
-
"src/internal/runtime/registry/agent-factory-registry.ts"() {
|
|
1453
|
-
}
|
|
1454
|
-
});
|
|
1455
|
-
|
|
1456
1683
|
// src/internal/runtime/lifecycle/run-to-completion.ts
|
|
1457
1684
|
var run_to_completion_exports = {};
|
|
1458
1685
|
__export(run_to_completion_exports, {
|
|
@@ -1617,14 +1844,14 @@ async function forkAgentImpl(parent, options, deps) {
|
|
|
1617
1844
|
return {
|
|
1618
1845
|
result: result.result,
|
|
1619
1846
|
toolCalls: [],
|
|
1620
|
-
usage:
|
|
1847
|
+
usage: extractUsage2(result)
|
|
1621
1848
|
};
|
|
1622
1849
|
});
|
|
1623
1850
|
} finally {
|
|
1624
1851
|
await fork.dispose();
|
|
1625
1852
|
}
|
|
1626
1853
|
}
|
|
1627
|
-
function
|
|
1854
|
+
function extractUsage2(result) {
|
|
1628
1855
|
if (typeof result !== "object" || result === null) {
|
|
1629
1856
|
return { inputTokens: 0, outputTokens: 0 };
|
|
1630
1857
|
}
|
|
@@ -2057,345 +2284,118 @@ async function runWorkAndFinalize(taskId, aborter, work) {
|
|
|
2057
2284
|
emit(payload) {
|
|
2058
2285
|
void checkCancelRequestedAt(taskId, aborter);
|
|
2059
2286
|
emitToSubscribers(taskId, {
|
|
2060
|
-
type: "progress",
|
|
2061
|
-
taskId,
|
|
2062
|
-
at: Date.now(),
|
|
2063
|
-
payload
|
|
2064
|
-
});
|
|
2065
|
-
}
|
|
2066
|
-
};
|
|
2067
|
-
try {
|
|
2068
|
-
const result = await reentryAls.run(true, () => Promise.resolve().then(() => work(ctx)));
|
|
2069
|
-
if (aborter.signal.aborted) {
|
|
2070
|
-
const cancelledAt = Date.now();
|
|
2071
|
-
await transition(taskId, "cancelled", { cancelledAt });
|
|
2072
|
-
emitToSubscribers(taskId, { type: "cancelled", taskId, cancelledAt });
|
|
2073
|
-
return;
|
|
2074
|
-
}
|
|
2075
|
-
const finishedAt = Date.now();
|
|
2076
|
-
await transition(taskId, "finished", { finishedAt, result });
|
|
2077
|
-
emitToSubscribers(taskId, { type: "finished", taskId, finishedAt, result });
|
|
2078
|
-
} catch (err) {
|
|
2079
|
-
if (aborter.signal.aborted) {
|
|
2080
|
-
const cancelledAt = Date.now();
|
|
2081
|
-
await transition(taskId, "cancelled", { cancelledAt });
|
|
2082
|
-
emitToSubscribers(taskId, { type: "cancelled", taskId, cancelledAt });
|
|
2083
|
-
return;
|
|
2084
|
-
}
|
|
2085
|
-
const erroredAt = Date.now();
|
|
2086
|
-
const error = err instanceof Error ? { code: err.code ?? "work_threw", message: err.message } : { code: "work_threw", message: String(err) };
|
|
2087
|
-
await transition(taskId, "error", { erroredAt, error });
|
|
2088
|
-
emitToSubscribers(taskId, { type: "errored", taskId, erroredAt, error });
|
|
2089
|
-
}
|
|
2090
|
-
}
|
|
2091
|
-
async function checkCancelRequestedAt(taskId, aborter) {
|
|
2092
|
-
if (aborter.signal.aborted) return;
|
|
2093
|
-
try {
|
|
2094
|
-
const handle = await state.store.get(taskId);
|
|
2095
|
-
if (handle?.cancelRequested === true) {
|
|
2096
|
-
aborter.abort("cancelRequested");
|
|
2097
|
-
}
|
|
2098
|
-
} catch {
|
|
2099
|
-
}
|
|
2100
|
-
}
|
|
2101
|
-
async function acquireSlot() {
|
|
2102
|
-
if (reentryAls.getStore() === true) {
|
|
2103
|
-
return () => {
|
|
2104
|
-
};
|
|
2105
|
-
}
|
|
2106
|
-
return state.semaphore.acquire();
|
|
2107
|
-
}
|
|
2108
|
-
async function submit(internal) {
|
|
2109
|
-
state.firstSubmitSeen = true;
|
|
2110
|
-
startEvictTimerIfNeeded();
|
|
2111
|
-
const resolvedId = resolveIdInternal(internal);
|
|
2112
|
-
const submitSpan = startTaskSubmitSpan({ taskId: resolvedId, kind: internal.kind });
|
|
2113
|
-
const existing = await state.store.get(resolvedId);
|
|
2114
|
-
if (existing !== void 0) {
|
|
2115
|
-
submitSpan.end();
|
|
2116
|
-
return existing;
|
|
2117
|
-
}
|
|
2118
|
-
const queuedHandle = await buildAndInsertQueued(internal, resolvedId);
|
|
2119
|
-
submitSpan.end();
|
|
2120
|
-
if (internal.signal?.aborted === true) {
|
|
2121
|
-
return shortCircuitAborted(queuedHandle, internal.signal);
|
|
2122
|
-
}
|
|
2123
|
-
const aborter = new AbortController();
|
|
2124
|
-
state.aborters.set(resolvedId, aborter);
|
|
2125
|
-
if (internal.signal !== void 0) {
|
|
2126
|
-
internal.signal.addEventListener("abort", () => aborter.abort(internal.signal?.reason), {
|
|
2127
|
-
once: true
|
|
2128
|
-
});
|
|
2129
|
-
}
|
|
2130
|
-
const release = await acquireSlot();
|
|
2131
|
-
void (async () => {
|
|
2132
|
-
try {
|
|
2133
|
-
await checkCancelRequestedAt(resolvedId, aborter);
|
|
2134
|
-
if (aborter.signal.aborted) {
|
|
2135
|
-
const cancelledAt = Date.now();
|
|
2136
|
-
await transition(resolvedId, "cancelled", { cancelledAt });
|
|
2137
|
-
emitToSubscribers(resolvedId, { type: "cancelled", taskId: resolvedId, cancelledAt });
|
|
2138
|
-
return;
|
|
2139
|
-
}
|
|
2140
|
-
const startedAt = Date.now();
|
|
2141
|
-
await transition(resolvedId, "running", { startedAt });
|
|
2142
|
-
emitToSubscribers(resolvedId, { type: "started", taskId: resolvedId, startedAt });
|
|
2143
|
-
await runWorkAndFinalize(resolvedId, aborter, internal.work);
|
|
2144
|
-
} finally {
|
|
2145
|
-
release();
|
|
2146
|
-
state.aborters.delete(resolvedId);
|
|
2147
|
-
}
|
|
2148
|
-
})();
|
|
2149
|
-
return queuedHandle;
|
|
2150
|
-
}
|
|
2151
|
-
async function get(id) {
|
|
2152
|
-
if (!isValidTaskId(id, true)) return void 0;
|
|
2153
|
-
return state.store.get(id);
|
|
2154
|
-
}
|
|
2155
|
-
var DEFAULT_CONCURRENCY, DEFAULT_RETENTION_MS, EVICTION_INTERVAL_MS, RING_CAP, reentryAls, state;
|
|
2156
|
-
var init_registry = __esm({
|
|
2157
|
-
"src/internal/task/registry.ts"() {
|
|
2158
|
-
init_errors();
|
|
2159
|
-
init_task();
|
|
2160
|
-
init_async_semaphore();
|
|
2161
|
-
init_ring_buffer();
|
|
2162
|
-
init_store();
|
|
2163
|
-
init_subscribe();
|
|
2164
|
-
init_telemetry();
|
|
2165
|
-
DEFAULT_CONCURRENCY = 8;
|
|
2166
|
-
DEFAULT_RETENTION_MS = 60 * 60 * 1e3;
|
|
2167
|
-
EVICTION_INTERVAL_MS = 5 * 60 * 1e3;
|
|
2168
|
-
RING_CAP = 64;
|
|
2169
|
-
reentryAls = new async_hooks.AsyncLocalStorage();
|
|
2170
|
-
state = buildState({});
|
|
2171
|
-
}
|
|
2172
|
-
});
|
|
2173
|
-
function toJsonSchema(schema, options = { unrepresentable: "any" }) {
|
|
2174
|
-
return zod.toJSONSchema(schema, options);
|
|
2175
|
-
}
|
|
2176
|
-
var init_to_json_schema = __esm({
|
|
2177
|
-
"src/internal/zod/to-json-schema.ts"() {
|
|
2178
|
-
}
|
|
2179
|
-
});
|
|
2180
|
-
function requireZod() {
|
|
2181
|
-
if (cachedZ !== void 0) return cachedZ;
|
|
2182
|
-
const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cron.cjs', document.baseURI).href)));
|
|
2183
|
-
let mod;
|
|
2184
|
-
try {
|
|
2185
|
-
mod = r("zod");
|
|
2186
|
-
} catch (cause) {
|
|
2187
|
-
throw new ConfigurationError(
|
|
2188
|
-
'Structured output requires the optional peer dependency `zod`. Add `"zod": "^3.25.0 || ^4.0.0"` to your package.json and reinstall.',
|
|
2189
|
-
{ code: "zod_not_installed", cause }
|
|
2190
|
-
);
|
|
2191
|
-
}
|
|
2192
|
-
cachedZ = mod.z ?? mod;
|
|
2193
|
-
return cachedZ;
|
|
2194
|
-
}
|
|
2195
|
-
function makeOutputTool(jsonSchema, onCapture) {
|
|
2196
|
-
return {
|
|
2197
|
-
name: "output",
|
|
2198
|
-
description: "Call this tool with your final structured answer. Match the JSON schema exactly.",
|
|
2199
|
-
inputSchema: jsonSchema,
|
|
2200
|
-
handler: (input) => {
|
|
2201
|
-
const out = onCapture(input);
|
|
2202
|
-
if (typeof out === "string") return out;
|
|
2203
|
-
if (out instanceof Promise) return out;
|
|
2204
|
-
return "";
|
|
2205
|
-
}
|
|
2206
|
-
};
|
|
2207
|
-
}
|
|
2208
|
-
function buildTransientAgentOptions(params) {
|
|
2209
|
-
return {
|
|
2210
|
-
model: params.model,
|
|
2211
|
-
local: params.local,
|
|
2212
|
-
tools: [params.outputTool],
|
|
2213
|
-
systemPrompt: params.systemPrompt ?? "You produce structured output by calling the `output` tool exactly once. Match the JSON schema.",
|
|
2214
|
-
...params.apiKey !== void 0 ? { apiKey: params.apiKey } : {},
|
|
2215
|
-
...params.providers !== void 0 ? { providers: params.providers } : {}
|
|
2216
|
-
};
|
|
2217
|
-
}
|
|
2218
|
-
function extractUsage2(result) {
|
|
2219
|
-
const u = result.usage;
|
|
2220
|
-
if (u === void 0) return { inputTokens: 0, outputTokens: 0 };
|
|
2221
|
-
return { inputTokens: u.inputTokens ?? 0, outputTokens: u.outputTokens ?? 0 };
|
|
2222
|
-
}
|
|
2223
|
-
function buildToolPrompt(prompt) {
|
|
2224
|
-
return `${prompt}
|
|
2225
|
-
|
|
2226
|
-
Respond by calling the \`output\` tool with the structured answer that matches the schema.`;
|
|
2227
|
-
}
|
|
2228
|
-
function setupStructuredOutput(schema, maxRetries) {
|
|
2229
|
-
const z6 = requireZod();
|
|
2230
|
-
const jsonSchema = toJsonSchema(schema, { unrepresentable: "any" });
|
|
2231
|
-
return {
|
|
2232
|
-
z: z6,
|
|
2233
|
-
jsonSchema,
|
|
2234
|
-
maxRetries: maxRetries ?? 1,
|
|
2235
|
-
initialUsage: { inputTokens: 0, outputTokens: 0 }
|
|
2236
|
-
};
|
|
2237
|
-
}
|
|
2238
|
-
async function disposeAndDeleteTransient(agent, deletor) {
|
|
2239
|
-
await agent.dispose();
|
|
2240
|
-
try {
|
|
2241
|
-
await deletor(agent.agentId);
|
|
2242
|
-
} catch {
|
|
2243
|
-
}
|
|
2244
|
-
}
|
|
2245
|
-
var cachedZ;
|
|
2246
|
-
var init_structured_output_helpers = __esm({
|
|
2247
|
-
"src/internal/structured-output-helpers.ts"() {
|
|
2248
|
-
init_errors();
|
|
2249
|
-
init_to_json_schema();
|
|
2250
|
-
}
|
|
2251
|
-
});
|
|
2252
|
-
|
|
2253
|
-
// src/generate-object.ts
|
|
2254
|
-
var generate_object_exports = {};
|
|
2255
|
-
__export(generate_object_exports, {
|
|
2256
|
-
GenerateObjectError: () => GenerateObjectError,
|
|
2257
|
-
generateObjectImpl: () => generateObjectImpl
|
|
2258
|
-
});
|
|
2259
|
-
function salvagePartial(schema, raw) {
|
|
2260
|
-
if (typeof raw !== "object" || raw === null) return raw;
|
|
2261
|
-
const shape = schema.shape;
|
|
2262
|
-
if (shape === void 0 || typeof shape !== "object") return raw;
|
|
2263
|
-
const rawObj = raw;
|
|
2264
|
-
const out = {};
|
|
2265
|
-
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
2266
|
-
if (typeof fieldSchema?.safeParse !== "function") continue;
|
|
2267
|
-
const parsed = fieldSchema.safeParse(rawObj[key]);
|
|
2268
|
-
if (parsed.success) out[key] = parsed.data;
|
|
2269
|
-
}
|
|
2270
|
-
return out;
|
|
2271
|
-
}
|
|
2272
|
-
async function runReasoningPhase(options, deps) {
|
|
2273
|
-
const reasoningOptions = {
|
|
2274
|
-
model: options.model,
|
|
2275
|
-
local: options.local,
|
|
2276
|
-
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
2277
|
-
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
2278
|
-
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
2279
|
-
};
|
|
2280
|
-
const reasoningAgent = await deps.create(reasoningOptions);
|
|
2281
|
-
try {
|
|
2282
|
-
const run = await reasoningAgent.send(options.prompt);
|
|
2283
|
-
const result = await run.wait();
|
|
2284
|
-
const text = result.result;
|
|
2285
|
-
return typeof text === "string" ? text : options.prompt;
|
|
2286
|
-
} finally {
|
|
2287
|
-
await disposeAndDeleteTransient(reasoningAgent, deps.delete);
|
|
2288
|
-
}
|
|
2289
|
-
}
|
|
2290
|
-
async function generateObjectImpl(options, deps) {
|
|
2291
|
-
const { jsonSchema, maxRetries, initialUsage } = setupStructuredOutput(
|
|
2292
|
-
options.schema,
|
|
2293
|
-
options.maxRetries
|
|
2294
|
-
);
|
|
2295
|
-
let capturedRaw;
|
|
2296
|
-
let lastUsage = initialUsage;
|
|
2297
|
-
const sentinel = /* @__PURE__ */ Symbol("generate-object-sentinel");
|
|
2298
|
-
class CaptureSentinel extends Error {
|
|
2299
|
-
constructor(captured) {
|
|
2300
|
-
super("generate-object-capture");
|
|
2301
|
-
this.captured = captured;
|
|
2302
|
-
}
|
|
2303
|
-
captured;
|
|
2304
|
-
[sentinel] = true;
|
|
2305
|
-
}
|
|
2306
|
-
const outputTool = makeOutputTool(jsonSchema, (input) => {
|
|
2307
|
-
if (capturedRaw === void 0) {
|
|
2308
|
-
capturedRaw = input;
|
|
2309
|
-
}
|
|
2310
|
-
throw new CaptureSentinel(input);
|
|
2311
|
-
});
|
|
2312
|
-
const reasoningText = options.structuringModel !== void 0 ? await runReasoningPhase(options, deps) : void 0;
|
|
2313
|
-
const structuringModel = options.structuringModel ?? options.model;
|
|
2314
|
-
const structuringPrompt = reasoningText ?? options.prompt;
|
|
2315
|
-
const agentOptions = buildTransientAgentOptions({
|
|
2316
|
-
model: structuringModel,
|
|
2317
|
-
local: options.local,
|
|
2318
|
-
outputTool,
|
|
2319
|
-
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
2320
|
-
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
2321
|
-
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
2322
|
-
});
|
|
2323
|
-
const agent = await deps.create(agentOptions);
|
|
2287
|
+
type: "progress",
|
|
2288
|
+
taskId,
|
|
2289
|
+
at: Date.now(),
|
|
2290
|
+
payload
|
|
2291
|
+
});
|
|
2292
|
+
}
|
|
2293
|
+
};
|
|
2324
2294
|
try {
|
|
2325
|
-
const
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
lastUsage = extractUsage2(result);
|
|
2332
|
-
if (capturedRaw === void 0) {
|
|
2333
|
-
if (result.status === "error" && result.error !== void 0) {
|
|
2334
|
-
throw new GenerateObjectError(
|
|
2335
|
-
"no_tool_call",
|
|
2336
|
-
`Agent run failed before the model could reply: ${result.error.message ?? "unknown error"} [${result.error.code ?? "?"}]`,
|
|
2337
|
-
result.error
|
|
2338
|
-
);
|
|
2339
|
-
}
|
|
2340
|
-
if (attempt === maxRetries) {
|
|
2341
|
-
throw new GenerateObjectError(
|
|
2342
|
-
"no_tool_call",
|
|
2343
|
-
"The model returned text instead of calling the `output` tool."
|
|
2344
|
-
);
|
|
2345
|
-
}
|
|
2346
|
-
continue;
|
|
2347
|
-
}
|
|
2348
|
-
const parsed = options.schema.safeParse(capturedRaw);
|
|
2349
|
-
if (parsed.success) {
|
|
2350
|
-
return {
|
|
2351
|
-
object: parsed.data,
|
|
2352
|
-
raw: capturedRaw,
|
|
2353
|
-
usage: lastUsage,
|
|
2354
|
-
finishReason: "tool_use"
|
|
2355
|
-
};
|
|
2356
|
-
}
|
|
2357
|
-
lastParseError = parsed.error;
|
|
2295
|
+
const result = await reentryAls.run(true, () => Promise.resolve().then(() => work(ctx)));
|
|
2296
|
+
if (aborter.signal.aborted) {
|
|
2297
|
+
const cancelledAt = Date.now();
|
|
2298
|
+
await transition(taskId, "cancelled", { cancelledAt });
|
|
2299
|
+
emitToSubscribers(taskId, { type: "cancelled", taskId, cancelledAt });
|
|
2300
|
+
return;
|
|
2358
2301
|
}
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
};
|
|
2302
|
+
const finishedAt = Date.now();
|
|
2303
|
+
await transition(taskId, "finished", { finishedAt, result });
|
|
2304
|
+
emitToSubscribers(taskId, { type: "finished", taskId, finishedAt, result });
|
|
2305
|
+
} catch (err) {
|
|
2306
|
+
if (aborter.signal.aborted) {
|
|
2307
|
+
const cancelledAt = Date.now();
|
|
2308
|
+
await transition(taskId, "cancelled", { cancelledAt });
|
|
2309
|
+
emitToSubscribers(taskId, { type: "cancelled", taskId, cancelledAt });
|
|
2310
|
+
return;
|
|
2366
2311
|
}
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2312
|
+
const erroredAt = Date.now();
|
|
2313
|
+
const error = err instanceof Error ? { code: err.code ?? "work_threw", message: err.message } : { code: "work_threw", message: String(err) };
|
|
2314
|
+
await transition(taskId, "error", { erroredAt, error });
|
|
2315
|
+
emitToSubscribers(taskId, { type: "errored", taskId, erroredAt, error });
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
async function checkCancelRequestedAt(taskId, aborter) {
|
|
2319
|
+
if (aborter.signal.aborted) return;
|
|
2320
|
+
try {
|
|
2321
|
+
const handle = await state.store.get(taskId);
|
|
2322
|
+
if (handle?.cancelRequested === true) {
|
|
2323
|
+
aborter.abort("cancelRequested");
|
|
2374
2324
|
}
|
|
2375
|
-
|
|
2376
|
-
"parse_failed",
|
|
2377
|
-
"Schema parse failed after all retries.",
|
|
2378
|
-
lastParseError
|
|
2379
|
-
);
|
|
2380
|
-
} finally {
|
|
2381
|
-
await disposeAndDeleteTransient(agent, deps.delete);
|
|
2325
|
+
} catch {
|
|
2382
2326
|
}
|
|
2383
2327
|
}
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
init_structured_output_helpers();
|
|
2388
|
-
GenerateObjectError = class extends Error {
|
|
2389
|
-
name = "GenerateObjectError";
|
|
2390
|
-
code;
|
|
2391
|
-
cause;
|
|
2392
|
-
constructor(code, message, cause) {
|
|
2393
|
-
super(message);
|
|
2394
|
-
this.code = code;
|
|
2395
|
-
if (cause !== void 0) this.cause = cause;
|
|
2396
|
-
}
|
|
2328
|
+
async function acquireSlot() {
|
|
2329
|
+
if (reentryAls.getStore() === true) {
|
|
2330
|
+
return () => {
|
|
2397
2331
|
};
|
|
2398
2332
|
}
|
|
2333
|
+
return state.semaphore.acquire();
|
|
2334
|
+
}
|
|
2335
|
+
async function submit(internal) {
|
|
2336
|
+
state.firstSubmitSeen = true;
|
|
2337
|
+
startEvictTimerIfNeeded();
|
|
2338
|
+
const resolvedId = resolveIdInternal(internal);
|
|
2339
|
+
const submitSpan = startTaskSubmitSpan({ taskId: resolvedId, kind: internal.kind });
|
|
2340
|
+
const existing = await state.store.get(resolvedId);
|
|
2341
|
+
if (existing !== void 0) {
|
|
2342
|
+
submitSpan.end();
|
|
2343
|
+
return existing;
|
|
2344
|
+
}
|
|
2345
|
+
const queuedHandle = await buildAndInsertQueued(internal, resolvedId);
|
|
2346
|
+
submitSpan.end();
|
|
2347
|
+
if (internal.signal?.aborted === true) {
|
|
2348
|
+
return shortCircuitAborted(queuedHandle, internal.signal);
|
|
2349
|
+
}
|
|
2350
|
+
const aborter = new AbortController();
|
|
2351
|
+
state.aborters.set(resolvedId, aborter);
|
|
2352
|
+
if (internal.signal !== void 0) {
|
|
2353
|
+
internal.signal.addEventListener("abort", () => aborter.abort(internal.signal?.reason), {
|
|
2354
|
+
once: true
|
|
2355
|
+
});
|
|
2356
|
+
}
|
|
2357
|
+
const release = await acquireSlot();
|
|
2358
|
+
void (async () => {
|
|
2359
|
+
try {
|
|
2360
|
+
await checkCancelRequestedAt(resolvedId, aborter);
|
|
2361
|
+
if (aborter.signal.aborted) {
|
|
2362
|
+
const cancelledAt = Date.now();
|
|
2363
|
+
await transition(resolvedId, "cancelled", { cancelledAt });
|
|
2364
|
+
emitToSubscribers(resolvedId, { type: "cancelled", taskId: resolvedId, cancelledAt });
|
|
2365
|
+
return;
|
|
2366
|
+
}
|
|
2367
|
+
const startedAt = Date.now();
|
|
2368
|
+
await transition(resolvedId, "running", { startedAt });
|
|
2369
|
+
emitToSubscribers(resolvedId, { type: "started", taskId: resolvedId, startedAt });
|
|
2370
|
+
await runWorkAndFinalize(resolvedId, aborter, internal.work);
|
|
2371
|
+
} finally {
|
|
2372
|
+
release();
|
|
2373
|
+
state.aborters.delete(resolvedId);
|
|
2374
|
+
}
|
|
2375
|
+
})();
|
|
2376
|
+
return queuedHandle;
|
|
2377
|
+
}
|
|
2378
|
+
async function get(id) {
|
|
2379
|
+
if (!isValidTaskId(id, true)) return void 0;
|
|
2380
|
+
return state.store.get(id);
|
|
2381
|
+
}
|
|
2382
|
+
var DEFAULT_CONCURRENCY, DEFAULT_RETENTION_MS, EVICTION_INTERVAL_MS, RING_CAP, reentryAls, state;
|
|
2383
|
+
var init_registry = __esm({
|
|
2384
|
+
"src/internal/task/registry.ts"() {
|
|
2385
|
+
init_errors();
|
|
2386
|
+
init_task();
|
|
2387
|
+
init_async_semaphore();
|
|
2388
|
+
init_ring_buffer();
|
|
2389
|
+
init_store();
|
|
2390
|
+
init_subscribe();
|
|
2391
|
+
init_telemetry();
|
|
2392
|
+
DEFAULT_CONCURRENCY = 8;
|
|
2393
|
+
DEFAULT_RETENTION_MS = 60 * 60 * 1e3;
|
|
2394
|
+
EVICTION_INTERVAL_MS = 5 * 60 * 1e3;
|
|
2395
|
+
RING_CAP = 64;
|
|
2396
|
+
reentryAls = new async_hooks.AsyncLocalStorage();
|
|
2397
|
+
state = buildState({});
|
|
2398
|
+
}
|
|
2399
2399
|
});
|
|
2400
2400
|
|
|
2401
2401
|
// src/stream-object.ts
|
|
@@ -2452,7 +2452,7 @@ async function* streamObjectImpl(options, deps) {
|
|
|
2452
2452
|
}
|
|
2453
2453
|
}
|
|
2454
2454
|
const result = await run.wait();
|
|
2455
|
-
lastUsage =
|
|
2455
|
+
lastUsage = extractUsage(result);
|
|
2456
2456
|
if (capturedRaw === void 0) {
|
|
2457
2457
|
if (result.status === "error" && result.error !== void 0) {
|
|
2458
2458
|
throw new StreamObjectError(
|
|
@@ -2798,6 +2798,7 @@ var AgentBuilder = class {
|
|
|
2798
2798
|
constructor(deps) {
|
|
2799
2799
|
this.deps = deps;
|
|
2800
2800
|
}
|
|
2801
|
+
/** SE8 — accepts a bare-string id shorthand (`"openai/gpt-4o-mini"`) or a {@link ModelSelection}. */
|
|
2801
2802
|
model(m) {
|
|
2802
2803
|
this.opts.model = m;
|
|
2803
2804
|
return this;
|
|
@@ -3151,6 +3152,69 @@ function isLocalAgentId(id) {
|
|
|
3151
3152
|
return id.startsWith(PREFIX.localAgent);
|
|
3152
3153
|
}
|
|
3153
3154
|
|
|
3155
|
+
// src/internal/runtime/config/default-model.ts
|
|
3156
|
+
var DEFAULT_AGENTIC_MODEL_ID = "google/gemini-2.0-flash-001";
|
|
3157
|
+
|
|
3158
|
+
// src/agent-generate.ts
|
|
3159
|
+
async function agentGenerate(agent, agentModel, agentApiKey, agentLocal, input, options) {
|
|
3160
|
+
const { output, maxRetries, errorStrategy, ...sendOptions } = options;
|
|
3161
|
+
const run = await agent.send(input, sendOptions);
|
|
3162
|
+
const result = await run.wait();
|
|
3163
|
+
const { generateObjectImpl: generateObjectImpl2, GenerateObjectError: GenerateObjectError2 } = await Promise.resolve().then(() => (init_generate_object(), generate_object_exports));
|
|
3164
|
+
const answer = structurableAnswerOrThrow(result, GenerateObjectError2);
|
|
3165
|
+
const { getAgentFacade: getAgentFacade2 } = await Promise.resolve().then(() => (init_agent_factory_registry(), agent_factory_registry_exports));
|
|
3166
|
+
const facade = getAgentFacade2();
|
|
3167
|
+
const structured = await generateObjectImpl2(
|
|
3168
|
+
{
|
|
3169
|
+
prompt: answer,
|
|
3170
|
+
schema: output,
|
|
3171
|
+
// `agentModel` arrives already normalized (`this.model` passed through
|
|
3172
|
+
// `normalizeModel` in the LocalAgent/CloudAgent constructor), so the widened
|
|
3173
|
+
// `string | ModelSelection` field only ever receives a `ModelSelection` here.
|
|
3174
|
+
model: agentModel ?? { id: DEFAULT_AGENTIC_MODEL_ID },
|
|
3175
|
+
// `local` is required to keep the transient structuring agent local-only;
|
|
3176
|
+
// default to the process cwd when the agent had no explicit local config.
|
|
3177
|
+
local: agentLocal ?? { cwd: process.cwd() },
|
|
3178
|
+
...agentApiKey !== void 0 ? { apiKey: agentApiKey } : {},
|
|
3179
|
+
...maxRetries !== void 0 ? { maxRetries } : {},
|
|
3180
|
+
...errorStrategy !== void 0 ? { errorStrategy } : {}
|
|
3181
|
+
},
|
|
3182
|
+
{
|
|
3183
|
+
create: (opts) => facade.create(opts),
|
|
3184
|
+
delete: (agentId) => facade.delete(agentId)
|
|
3185
|
+
}
|
|
3186
|
+
);
|
|
3187
|
+
return {
|
|
3188
|
+
object: structured.object,
|
|
3189
|
+
result,
|
|
3190
|
+
raw: structured.raw,
|
|
3191
|
+
usage: structured.usage
|
|
3192
|
+
};
|
|
3193
|
+
}
|
|
3194
|
+
function structurableAnswerOrThrow(result, GenerateObjectError2) {
|
|
3195
|
+
if (result.status === "error") {
|
|
3196
|
+
throw new GenerateObjectError2(
|
|
3197
|
+
"no_tool_call",
|
|
3198
|
+
`Agent run failed before an answer could be structured: ${result.error?.message ?? "unknown error"} [${result.error?.code ?? "?"}]`,
|
|
3199
|
+
result.error
|
|
3200
|
+
);
|
|
3201
|
+
}
|
|
3202
|
+
if (result.status === "cancelled") {
|
|
3203
|
+
throw new GenerateObjectError2(
|
|
3204
|
+
"no_tool_call",
|
|
3205
|
+
"Agent run was cancelled before an answer could be structured."
|
|
3206
|
+
);
|
|
3207
|
+
}
|
|
3208
|
+
const answer = result.result;
|
|
3209
|
+
if (answer === void 0 || answer.length === 0) {
|
|
3210
|
+
throw new GenerateObjectError2(
|
|
3211
|
+
"no_tool_call",
|
|
3212
|
+
"The tool loop finished with no text answer (tool-only completion) \u2014 there is nothing to structure."
|
|
3213
|
+
);
|
|
3214
|
+
}
|
|
3215
|
+
return answer;
|
|
3216
|
+
}
|
|
3217
|
+
|
|
3154
3218
|
// src/internal/runtime/cloud/cloud-agent.ts
|
|
3155
3219
|
init_errors();
|
|
3156
3220
|
init_cwd_mutex();
|
|
@@ -3301,8 +3365,19 @@ function safeFilenameForId(id, options) {
|
|
|
3301
3365
|
return `h-${crypto.createHash("sha256").update(id).digest("hex").slice(0, 16)}`;
|
|
3302
3366
|
}
|
|
3303
3367
|
|
|
3304
|
-
// src/internal/runtime/
|
|
3305
|
-
|
|
3368
|
+
// src/internal/runtime/model-selection.ts
|
|
3369
|
+
init_errors();
|
|
3370
|
+
function normalizeModel(m) {
|
|
3371
|
+
if (m === void 0 || typeof m !== "string") return m;
|
|
3372
|
+
const id = m.trim();
|
|
3373
|
+
if (id.length === 0) {
|
|
3374
|
+
throw new ConfigurationError(
|
|
3375
|
+
'model must be a non-empty "provider/model" id string or a ModelSelection object',
|
|
3376
|
+
{ code: "invalid_model_selection" }
|
|
3377
|
+
);
|
|
3378
|
+
}
|
|
3379
|
+
return { id };
|
|
3380
|
+
}
|
|
3306
3381
|
|
|
3307
3382
|
// src/internal/runtime/registry/agent-registry-store.ts
|
|
3308
3383
|
init_cwd_mutex();
|
|
@@ -3379,7 +3454,10 @@ var REGISTRY_RELATIVE_PATH = path.join(".theokit", "agents", "registry.json");
|
|
|
3379
3454
|
function stripSecretsFromOptions(options) {
|
|
3380
3455
|
return assignDefined({
|
|
3381
3456
|
name: options.name,
|
|
3382
|
-
model:
|
|
3457
|
+
model: (() => {
|
|
3458
|
+
const m = normalizeModel(options.model);
|
|
3459
|
+
return m !== void 0 ? { id: m.id } : void 0;
|
|
3460
|
+
})(),
|
|
3383
3461
|
systemPrompt: typeof options.systemPrompt === "string" ? options.systemPrompt : void 0,
|
|
3384
3462
|
local: serializeLocal(options.local),
|
|
3385
3463
|
cloud: serializeCloud(options.cloud),
|
|
@@ -3664,7 +3742,8 @@ function serializeCloudAgentConfig(options) {
|
|
|
3664
3742
|
cloud: serializeCloud2(options.cloud)
|
|
3665
3743
|
};
|
|
3666
3744
|
if (typeof options.agentId === "string") payload.agentId = options.agentId;
|
|
3667
|
-
|
|
3745
|
+
const cfgModel = normalizeModel(options.model);
|
|
3746
|
+
if (cfgModel !== void 0) payload.model = { id: cfgModel.id };
|
|
3668
3747
|
if (typeof options.systemPrompt === "string") payload.systemPrompt = options.systemPrompt;
|
|
3669
3748
|
const skills = serializeSkills(options.skills);
|
|
3670
3749
|
if (skills !== void 0) payload.skills = skills;
|
|
@@ -4560,6 +4639,7 @@ function applyScriptMetrics(base, script) {
|
|
|
4560
4639
|
if (script.cost !== void 0) base.cost = script.cost;
|
|
4561
4640
|
if (script.stoppedAtIterationLimit === true) base.stoppedAtIterationLimit = true;
|
|
4562
4641
|
if (script.stoppedByDoomLoop === true) base.stoppedByDoomLoop = true;
|
|
4642
|
+
if (script.origin !== void 0) base.origin = script.origin;
|
|
4563
4643
|
}
|
|
4564
4644
|
|
|
4565
4645
|
// src/internal/runtime/cloud/cloud-run.ts
|
|
@@ -4915,7 +4995,7 @@ var CloudAgent = class {
|
|
|
4915
4995
|
disposed = false;
|
|
4916
4996
|
constructor(options, providedAgentId) {
|
|
4917
4997
|
this.agentId = providedAgentId ?? options.agentId ?? generateCloudAgentId();
|
|
4918
|
-
this.model = options.model;
|
|
4998
|
+
this.model = normalizeModel(options.model);
|
|
4919
4999
|
this.options = options;
|
|
4920
5000
|
this.cloudPayload = serializeCloudAgentConfig({ ...options, agentId: this.agentId });
|
|
4921
5001
|
const repoUrls = (options.cloud?.repos ?? []).map((repo) => repo.url);
|
|
@@ -4945,6 +5025,17 @@ var CloudAgent = class {
|
|
|
4945
5025
|
const apiKey = resolveApiKey(this.options.apiKey);
|
|
4946
5026
|
return isFixtureApiKey(apiKey) && getConfiguredBaseUrl() === void 0;
|
|
4947
5027
|
}
|
|
5028
|
+
// SE9 — integrated structured output; delegates to the shared helper.
|
|
5029
|
+
generate(message, options) {
|
|
5030
|
+
return agentGenerate(
|
|
5031
|
+
this,
|
|
5032
|
+
this.model,
|
|
5033
|
+
this.options.apiKey,
|
|
5034
|
+
this.options.local,
|
|
5035
|
+
message,
|
|
5036
|
+
options
|
|
5037
|
+
);
|
|
5038
|
+
}
|
|
4948
5039
|
async send(message, options = {}) {
|
|
4949
5040
|
if (options.tools !== void 0 && options.tools.length > 0) {
|
|
4950
5041
|
throw new ConfigurationError(
|
|
@@ -4975,7 +5066,7 @@ var CloudAgent = class {
|
|
|
4975
5066
|
});
|
|
4976
5067
|
}
|
|
4977
5068
|
async sendLocked(message, options) {
|
|
4978
|
-
const overrideModel = options.model;
|
|
5069
|
+
const overrideModel = normalizeModel(options.model);
|
|
4979
5070
|
if (overrideModel !== void 0) {
|
|
4980
5071
|
this.model = overrideModel;
|
|
4981
5072
|
updateRegisteredAgent(this.agentId, { model: overrideModel });
|
|
@@ -5889,18 +5980,18 @@ var ALL_ADAPTERS = [
|
|
|
5889
5980
|
arizeAdapter,
|
|
5890
5981
|
braintrustAdapter
|
|
5891
5982
|
];
|
|
5892
|
-
var
|
|
5983
|
+
var registered2 = /* @__PURE__ */ new Set();
|
|
5893
5984
|
function tryAutoRegisterAdapters(settings) {
|
|
5894
5985
|
if (settings?.enabled !== true) return;
|
|
5895
5986
|
if (settings.autoDetect === false) return;
|
|
5896
5987
|
const disabled = new Set(settings.disable ?? []);
|
|
5897
5988
|
for (const adapter of ALL_ADAPTERS) {
|
|
5898
|
-
if (
|
|
5989
|
+
if (registered2.has(adapter.moduleName)) continue;
|
|
5899
5990
|
if (disabled.has(adapter.displayName.toLowerCase())) continue;
|
|
5900
5991
|
if (!adapter.detect()) continue;
|
|
5901
5992
|
try {
|
|
5902
5993
|
adapter.register();
|
|
5903
|
-
|
|
5994
|
+
registered2.add(adapter.moduleName);
|
|
5904
5995
|
process.stderr.write(`[theokit-sdk] telemetry: ${adapter.displayName} auto-instrumented.
|
|
5905
5996
|
`);
|
|
5906
5997
|
} catch (cause) {
|
|
@@ -6463,6 +6554,26 @@ function paginate(items, opts) {
|
|
|
6463
6554
|
return items.slice(start, end);
|
|
6464
6555
|
}
|
|
6465
6556
|
|
|
6557
|
+
// src/internal/persistence/session-meta.ts
|
|
6558
|
+
function applyMetaPatch(current, patch) {
|
|
6559
|
+
const next = {};
|
|
6560
|
+
if (current.title !== void 0) next.title = current.title;
|
|
6561
|
+
if (current.tag !== void 0) next.tag = current.tag;
|
|
6562
|
+
if (patch.title === null) delete next.title;
|
|
6563
|
+
else if (patch.title !== void 0) next.title = patch.title;
|
|
6564
|
+
if (patch.tag === null) delete next.tag;
|
|
6565
|
+
else if (patch.tag !== void 0) next.tag = patch.tag;
|
|
6566
|
+
return next;
|
|
6567
|
+
}
|
|
6568
|
+
function coerceSessionMeta(raw) {
|
|
6569
|
+
if (typeof raw !== "object" || raw === null) return void 0;
|
|
6570
|
+
const obj = raw;
|
|
6571
|
+
const meta = {};
|
|
6572
|
+
if (typeof obj.title === "string") meta.title = obj.title;
|
|
6573
|
+
if (typeof obj.tag === "string") meta.tag = obj.tag;
|
|
6574
|
+
return meta.title === void 0 && meta.tag === void 0 ? void 0 : meta;
|
|
6575
|
+
}
|
|
6576
|
+
|
|
6466
6577
|
// src/internal/persistence/conversation-storage-fs.ts
|
|
6467
6578
|
var FileSystemConversationStorage = class {
|
|
6468
6579
|
#root;
|
|
@@ -6513,6 +6624,37 @@ var FileSystemConversationStorage = class {
|
|
|
6513
6624
|
async compact(conversationId, maxTurns) {
|
|
6514
6625
|
await compactSessionFile(this.#root, conversationId, maxTurns);
|
|
6515
6626
|
}
|
|
6627
|
+
// SE4 — session metadata persisted as a per-conversation sidecar
|
|
6628
|
+
// `<root>/.theokit/agents/<safeId>/session.json` (same sanitized perimeter as
|
|
6629
|
+
// the transcript). Kept separate from messages.jsonl so a title/tag write does
|
|
6630
|
+
// not rewrite the append-only log.
|
|
6631
|
+
#metaPath(conversationId) {
|
|
6632
|
+
const safe2 = sanitizeIdentifier(conversationId, { maxLen: 128 });
|
|
6633
|
+
return safePathJoin(this.#root, ".theokit", "agents", safe2, "session.json");
|
|
6634
|
+
}
|
|
6635
|
+
async getSessionMeta(conversationId) {
|
|
6636
|
+
try {
|
|
6637
|
+
const raw = await promises.readFile(this.#metaPath(conversationId), "utf8");
|
|
6638
|
+
return coerceSessionMeta(JSON.parse(raw));
|
|
6639
|
+
} catch (cause) {
|
|
6640
|
+
if (cause.code === "ENOENT") return void 0;
|
|
6641
|
+
throw cause;
|
|
6642
|
+
}
|
|
6643
|
+
}
|
|
6644
|
+
async setSessionMeta(conversationId, patch) {
|
|
6645
|
+
const metaPath = this.#metaPath(conversationId);
|
|
6646
|
+
await promises.mkdir(path.dirname(metaPath), { recursive: true });
|
|
6647
|
+
await withFileLock(metaPath, async () => {
|
|
6648
|
+
let current = {};
|
|
6649
|
+
try {
|
|
6650
|
+
current = coerceSessionMeta(JSON.parse(await promises.readFile(metaPath, "utf8"))) ?? {};
|
|
6651
|
+
} catch (cause) {
|
|
6652
|
+
if (cause.code !== "ENOENT") throw cause;
|
|
6653
|
+
}
|
|
6654
|
+
const next = applyMetaPatch(current, patch);
|
|
6655
|
+
await promises.writeFile(metaPath, redactSecrets(JSON.stringify(next)), "utf8");
|
|
6656
|
+
});
|
|
6657
|
+
}
|
|
6516
6658
|
async dispose() {
|
|
6517
6659
|
}
|
|
6518
6660
|
};
|
|
@@ -8432,7 +8574,7 @@ function bootstrapSubmanagers(args) {
|
|
|
8432
8574
|
const providerCount = (args.options.providers?.routes?.length ?? 0) + enabledPluginNames(args.options.plugins).length;
|
|
8433
8575
|
if (providerCount > 0 || args.options.providers !== void 0) {
|
|
8434
8576
|
out.providers = new ProvidersManagerImpl(
|
|
8435
|
-
args.options.model,
|
|
8577
|
+
normalizeModel(args.options.model),
|
|
8436
8578
|
args.options.providers,
|
|
8437
8579
|
args.options.plugins
|
|
8438
8580
|
);
|
|
@@ -8502,6 +8644,7 @@ function createLocalRun(options) {
|
|
|
8502
8644
|
projectMcpServers: options.projectMcpServers,
|
|
8503
8645
|
...options.persistMemoryFact !== void 0 ? { persistMemoryFact: options.persistMemoryFact } : {}
|
|
8504
8646
|
});
|
|
8647
|
+
if (options.sendOptions.origin !== void 0) script.origin = options.sendOptions.origin;
|
|
8505
8648
|
const handle = new LocalRun({
|
|
8506
8649
|
id,
|
|
8507
8650
|
agentId: options.agentId,
|
|
@@ -9150,6 +9293,15 @@ async function emitReasoningDeltaCallback(inputs, text) {
|
|
|
9150
9293
|
);
|
|
9151
9294
|
}
|
|
9152
9295
|
|
|
9296
|
+
// src/types/run-events.ts
|
|
9297
|
+
function emitRunEvent(sink, event) {
|
|
9298
|
+
if (sink === void 0) return;
|
|
9299
|
+
try {
|
|
9300
|
+
sink(event);
|
|
9301
|
+
} catch {
|
|
9302
|
+
}
|
|
9303
|
+
}
|
|
9304
|
+
|
|
9153
9305
|
// src/internal/agent-loop/tool-dispatch.ts
|
|
9154
9306
|
init_async_local_storage();
|
|
9155
9307
|
|
|
@@ -9247,6 +9399,22 @@ function coerceArgsToSchema(args, schema) {
|
|
|
9247
9399
|
return { value: out, changed };
|
|
9248
9400
|
}
|
|
9249
9401
|
|
|
9402
|
+
// src/tool-error.ts
|
|
9403
|
+
init_errors();
|
|
9404
|
+
var ToolError = class extends TheokitAgentError {
|
|
9405
|
+
name = "ToolError";
|
|
9406
|
+
/** The error content surfaced to the model: a string, or text/image blocks. */
|
|
9407
|
+
content;
|
|
9408
|
+
constructor(content, options = {}) {
|
|
9409
|
+
super(renderToolErrorMessage(content), { ...options, isRetryable: false });
|
|
9410
|
+
this.content = content;
|
|
9411
|
+
}
|
|
9412
|
+
};
|
|
9413
|
+
function renderToolErrorMessage(content) {
|
|
9414
|
+
if (typeof content === "string") return content;
|
|
9415
|
+
return content.map((block) => block.type === "text" ? block.text : `[${block.source.media_type} image]`).join("\n");
|
|
9416
|
+
}
|
|
9417
|
+
|
|
9250
9418
|
// src/internal/runtime/tools/shell-tool.ts
|
|
9251
9419
|
async function runShell(options) {
|
|
9252
9420
|
if (options.sandbox === true && isObviouslyUnsafe(options.command)) {
|
|
@@ -9300,9 +9468,13 @@ async function runHandlerTool(kind, handler, call, signal, context) {
|
|
|
9300
9468
|
return { stdout: "", stderr: `${kind} tool ${call.name} has no handler`, exitCode: 127 };
|
|
9301
9469
|
}
|
|
9302
9470
|
try {
|
|
9303
|
-
const
|
|
9304
|
-
return { stdout, stderr: "", exitCode: 0 };
|
|
9471
|
+
const out = await handler(call.input, { signal, context });
|
|
9472
|
+
if (typeof out !== "string") return { stdout: "", stderr: "", exitCode: 0, content: out };
|
|
9473
|
+
return { stdout: out, stderr: "", exitCode: 0 };
|
|
9305
9474
|
} catch (cause) {
|
|
9475
|
+
if (cause instanceof ToolError) {
|
|
9476
|
+
return { stdout: "", stderr: cause.message, exitCode: 1, content: cause.content };
|
|
9477
|
+
}
|
|
9306
9478
|
const message = cause instanceof Error ? cause.message : String(cause);
|
|
9307
9479
|
return { stdout: "", stderr: message, exitCode: 1 };
|
|
9308
9480
|
}
|
|
@@ -9421,6 +9593,11 @@ async function dispatchSingleCall(inputs, tools, call, events, parentSpan) {
|
|
|
9421
9593
|
toolSpan?.end();
|
|
9422
9594
|
return fileVeto;
|
|
9423
9595
|
}
|
|
9596
|
+
emitRunEvent(inputs.runEventSink, {
|
|
9597
|
+
type: "tool_progress",
|
|
9598
|
+
toolName: workingCall.name,
|
|
9599
|
+
toolCallId: callId
|
|
9600
|
+
});
|
|
9424
9601
|
const result = await runToolWithLifecycle(inputs, resolved, workingCall, callId);
|
|
9425
9602
|
await inputs.pluginManager?.runPostToolCallHooks({
|
|
9426
9603
|
name: workingCall.name,
|
|
@@ -9447,6 +9624,13 @@ function applyRepairAndExtractCall(tools, call) {
|
|
|
9447
9624
|
function vetoFromForkWhitelist(inputs, call, callId, events) {
|
|
9448
9625
|
const whitelistDecision = checkToolWhitelist(call.name);
|
|
9449
9626
|
if (whitelistDecision.allowed) return void 0;
|
|
9627
|
+
emitRunEvent(inputs.runEventSink, {
|
|
9628
|
+
type: "permission_denied",
|
|
9629
|
+
toolName: call.name,
|
|
9630
|
+
toolCallId: callId,
|
|
9631
|
+
source: "fork_whitelist",
|
|
9632
|
+
message: whitelistDecision.reason ?? "tool not available in fork"
|
|
9633
|
+
});
|
|
9450
9634
|
events.push(buildToolUseRunning(inputs, callId, call));
|
|
9451
9635
|
events.push(
|
|
9452
9636
|
buildToolUseCompleted(inputs, callId, call, {
|
|
@@ -9483,6 +9667,13 @@ async function vetoFromPluginPreHook(inputs, call, callId, events) {
|
|
|
9483
9667
|
runId: inputs.runId
|
|
9484
9668
|
});
|
|
9485
9669
|
if (pluginVeto === void 0) return void 0;
|
|
9670
|
+
emitRunEvent(inputs.runEventSink, {
|
|
9671
|
+
type: "permission_denied",
|
|
9672
|
+
toolName: call.name,
|
|
9673
|
+
toolCallId: callId,
|
|
9674
|
+
source: "plugin",
|
|
9675
|
+
message: pluginVeto.message
|
|
9676
|
+
});
|
|
9486
9677
|
events.push(
|
|
9487
9678
|
buildToolUseCompleted(inputs, callId, call, {
|
|
9488
9679
|
stdout: "",
|
|
@@ -9505,6 +9696,13 @@ async function vetoFromFileHookPreDecision(inputs, call, callId, events) {
|
|
|
9505
9696
|
runId: inputs.runId
|
|
9506
9697
|
});
|
|
9507
9698
|
if (!preDecision.blocked) return void 0;
|
|
9699
|
+
emitRunEvent(inputs.runEventSink, {
|
|
9700
|
+
type: "permission_denied",
|
|
9701
|
+
toolName: call.name,
|
|
9702
|
+
toolCallId: callId,
|
|
9703
|
+
source: "file_hook",
|
|
9704
|
+
message: preDecision.reason ?? "blocked by hook"
|
|
9705
|
+
});
|
|
9508
9706
|
events.push(
|
|
9509
9707
|
buildToolUseCompleted(inputs, callId, call, {
|
|
9510
9708
|
stdout: "",
|
|
@@ -9548,7 +9746,9 @@ async function runToolWithLifecycle(inputs, resolved, call, callId) {
|
|
|
9548
9746
|
await safeEmitToolHook(inputs.onToolEnd, {
|
|
9549
9747
|
toolName: call.name,
|
|
9550
9748
|
args: call.input,
|
|
9551
|
-
|
|
9749
|
+
// SE7 — a block-returning handler has empty `stdout`; surface its structured
|
|
9750
|
+
// content to the hook instead of an empty string.
|
|
9751
|
+
result: result.content !== void 0 ? result.content : result.stdout,
|
|
9552
9752
|
conversationId: inputs.agentId,
|
|
9553
9753
|
callId,
|
|
9554
9754
|
durationMs
|
|
@@ -9570,7 +9770,10 @@ function finalizeSpanAndPostHook(inputs, call, callId, result, events, toolSpan)
|
|
|
9570
9770
|
output: {
|
|
9571
9771
|
stdout: result.stdout,
|
|
9572
9772
|
stderr: result.stderr,
|
|
9573
|
-
exitCode: result.exitCode ?? 0
|
|
9773
|
+
exitCode: result.exitCode ?? 0,
|
|
9774
|
+
// SE7 — structured content (text + image blocks) when the handler
|
|
9775
|
+
// returned/threw blocks; absent for the string path.
|
|
9776
|
+
...result.content !== void 0 ? { content: result.content } : {}
|
|
9574
9777
|
},
|
|
9575
9778
|
agentId: inputs.agentId,
|
|
9576
9779
|
runId: inputs.runId
|
|
@@ -9583,7 +9786,9 @@ function finalizeSpanAndPostHook(inputs, call, callId, result, events, toolSpan)
|
|
|
9583
9786
|
return {
|
|
9584
9787
|
type: "tool_result",
|
|
9585
9788
|
toolUseId: call.id,
|
|
9586
|
-
content
|
|
9789
|
+
// SE7 — structured content blocks (handler-returned or ToolError-carried)
|
|
9790
|
+
// are authoritative; otherwise the legacy string rendering.
|
|
9791
|
+
content: result.content !== void 0 ? result.content : renderToolResult(result),
|
|
9587
9792
|
...result.exitCode !== 0 && result.exitCode !== void 0 ? { isError: true } : {}
|
|
9588
9793
|
};
|
|
9589
9794
|
}
|
|
@@ -9632,6 +9837,29 @@ function buildToolUseCompleted(inputs, callId, call, result) {
|
|
|
9632
9837
|
};
|
|
9633
9838
|
}
|
|
9634
9839
|
|
|
9840
|
+
// src/internal/llm/tool-result-content.ts
|
|
9841
|
+
init_errors();
|
|
9842
|
+
function toBlockToolResultContent(content) {
|
|
9843
|
+
return content;
|
|
9844
|
+
}
|
|
9845
|
+
function toStringToolResultContent(content, providerName) {
|
|
9846
|
+
if (typeof content === "string") return content;
|
|
9847
|
+
if (content.some((block) => block.type === "image")) {
|
|
9848
|
+
throw new ConfigurationError(
|
|
9849
|
+
`provider "${providerName}" does not support image content in tool results`
|
|
9850
|
+
);
|
|
9851
|
+
}
|
|
9852
|
+
return content.filter(
|
|
9853
|
+
(block) => block.type === "text"
|
|
9854
|
+
).map((block) => block.text).join("\n");
|
|
9855
|
+
}
|
|
9856
|
+
function renderToolResultContentText(content, fn) {
|
|
9857
|
+
if (typeof content === "string") return fn(content);
|
|
9858
|
+
return content.map(
|
|
9859
|
+
(block) => block.type === "text" ? { type: "text", text: fn(block.text) } : block
|
|
9860
|
+
);
|
|
9861
|
+
}
|
|
9862
|
+
|
|
9635
9863
|
// src/internal/agent-loop/tool-result-guard.ts
|
|
9636
9864
|
var OPEN = "<untrusted-tool-output>";
|
|
9637
9865
|
var CLOSE = "</untrusted-tool-output>";
|
|
@@ -9657,7 +9885,11 @@ ${CLOSE}`;
|
|
|
9657
9885
|
function applyToolResultGuard(parts, opts) {
|
|
9658
9886
|
if (opts.delimit !== true && opts.redactPii !== true) return parts;
|
|
9659
9887
|
return parts.map(
|
|
9660
|
-
(p) =>
|
|
9888
|
+
(p) => (
|
|
9889
|
+
// SE7 — guard the TEXT of a tool result (string or the text blocks of a
|
|
9890
|
+
// structured content); image blocks pass through untouched.
|
|
9891
|
+
p.type === "tool_result" ? { ...p, content: renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
|
|
9892
|
+
)
|
|
9661
9893
|
);
|
|
9662
9894
|
}
|
|
9663
9895
|
|
|
@@ -10574,10 +10806,10 @@ function stripVertexPrefix(modelId) {
|
|
|
10574
10806
|
}
|
|
10575
10807
|
|
|
10576
10808
|
// src/internal/providers/builtin/index.ts
|
|
10577
|
-
var
|
|
10809
|
+
var registered3 = false;
|
|
10578
10810
|
function registerBuiltins() {
|
|
10579
|
-
if (
|
|
10580
|
-
|
|
10811
|
+
if (registered3) return;
|
|
10812
|
+
registered3 = true;
|
|
10581
10813
|
registerProvider(ANTHROPIC);
|
|
10582
10814
|
registerProvider(OPENAI);
|
|
10583
10815
|
registerProvider(OPENROUTER);
|
|
@@ -10805,7 +11037,9 @@ function toAnthropicWireMessage(message) {
|
|
|
10805
11037
|
return {
|
|
10806
11038
|
type: "tool_result",
|
|
10807
11039
|
tool_use_id: part.toolUseId,
|
|
10808
|
-
|
|
11040
|
+
// SE7 — this wire is block-capable: strings pass through, structured
|
|
11041
|
+
// text/image blocks are forwarded natively.
|
|
11042
|
+
content: toBlockToolResultContent(part.content),
|
|
10809
11043
|
...part.isError === true ? { is_error: true } : {}
|
|
10810
11044
|
};
|
|
10811
11045
|
});
|
|
@@ -11597,7 +11831,8 @@ function toOllamaMessages(message) {
|
|
|
11597
11831
|
if (part.type === "tool_result") {
|
|
11598
11832
|
out.push({
|
|
11599
11833
|
role: "tool",
|
|
11600
|
-
|
|
11834
|
+
// SE7 — string-only tool role: text blocks flatten; image fails fast.
|
|
11835
|
+
content: toStringToolResultContent(part.content, "ollama"),
|
|
11601
11836
|
tool_name: part.toolUseId
|
|
11602
11837
|
});
|
|
11603
11838
|
}
|
|
@@ -12134,7 +12369,9 @@ function userOrToolMessages(message) {
|
|
|
12134
12369
|
out.push({
|
|
12135
12370
|
role: "tool",
|
|
12136
12371
|
tool_call_id: part.toolUseId,
|
|
12137
|
-
|
|
12372
|
+
// SE7 — this wire's tool role is string-only: text blocks flatten; an
|
|
12373
|
+
// image block fails fast (ConfigurationError).
|
|
12374
|
+
content: toStringToolResultContent(part.content, "openai")
|
|
12138
12375
|
});
|
|
12139
12376
|
}
|
|
12140
12377
|
}
|
|
@@ -13063,18 +13300,20 @@ function levenshtein(a, b) {
|
|
|
13063
13300
|
function createRealLocalRun(options) {
|
|
13064
13301
|
const { userText, id, startTime } = prepareRunContext(options.message);
|
|
13065
13302
|
const supported = /* @__PURE__ */ new Set(["stream", "wait", "cancel", "conversation"]);
|
|
13066
|
-
const
|
|
13303
|
+
const runScript = {
|
|
13067
13304
|
events: [],
|
|
13068
13305
|
finalStatus: "running",
|
|
13069
13306
|
cancellable: false,
|
|
13070
|
-
conversation: []
|
|
13307
|
+
conversation: [],
|
|
13308
|
+
// SE3 — carry the turn's provenance so buildResult forwards it onto RunResult.origin.
|
|
13309
|
+
...options.sendOptions.origin !== void 0 ? { origin: options.sendOptions.origin } : {}
|
|
13071
13310
|
};
|
|
13072
13311
|
const handle = new RealLocalRun(
|
|
13073
13312
|
{
|
|
13074
13313
|
id,
|
|
13075
13314
|
agentId: options.agentId,
|
|
13076
13315
|
model: options.model,
|
|
13077
|
-
script:
|
|
13316
|
+
script: runScript,
|
|
13078
13317
|
supportedOps: supported,
|
|
13079
13318
|
startTime
|
|
13080
13319
|
},
|
|
@@ -13186,6 +13425,8 @@ function buildLoopInputs(options, runId, userText) {
|
|
|
13186
13425
|
// M7 — forward SendOptions.context to the loop so every tool handler receives
|
|
13187
13426
|
// it on `ctx.context` (shared run config set once, e.g. projectRoot).
|
|
13188
13427
|
...options.sendOptions.context !== void 0 ? { context: options.sendOptions.context } : {},
|
|
13428
|
+
// SE2 — forward the opt-in typed runtime-event sink to the loop.
|
|
13429
|
+
...options.sendOptions.onRunEvent !== void 0 ? { runEventSink: options.sendOptions.onRunEvent } : {},
|
|
13189
13430
|
// #58 / #57 — forward the per-tool timeout + tool-result guard so a consumer
|
|
13190
13431
|
// can enable them via SendOptions (not only internal AgentLoopInputs).
|
|
13191
13432
|
...options.sendOptions.perToolTimeoutMs !== void 0 ? { perToolTimeoutMs: options.sendOptions.perToolTimeoutMs } : {},
|
|
@@ -15878,7 +16119,7 @@ function wrapRunWithPostReplyHook(args) {
|
|
|
15878
16119
|
async function executeSendLocked(inputs, message, options) {
|
|
15879
16120
|
if (inputs.disposed) throw new AgentDisposedError(inputs.agentId);
|
|
15880
16121
|
await consumePending(inputs.agentId, inputs.invalidationPending, inputs.clearInvalidation, inputs.reload);
|
|
15881
|
-
inputs.applyModelOverride(options.model);
|
|
16122
|
+
inputs.applyModelOverride(normalizeModel(options.model));
|
|
15882
16123
|
const userText = typeof message === "string" ? message : message.text;
|
|
15883
16124
|
if (inputs.options.onBeforeSend !== void 0) {
|
|
15884
16125
|
await inputs.options.onBeforeSend({
|
|
@@ -16030,7 +16271,7 @@ var LocalAgent = class {
|
|
|
16030
16271
|
constructor(options) {
|
|
16031
16272
|
this.agentId = options.agentId ?? generateLocalAgentId();
|
|
16032
16273
|
this._telemetry = createTelemetry(options.telemetry);
|
|
16033
|
-
this.model = options.model;
|
|
16274
|
+
this.model = normalizeModel(options.model);
|
|
16034
16275
|
this.options = options;
|
|
16035
16276
|
this.workspaceCwd = resolveCwd(options.local?.cwd);
|
|
16036
16277
|
this.conversationStorage = options.conversationStorage;
|
|
@@ -16097,6 +16338,11 @@ var LocalAgent = class {
|
|
|
16097
16338
|
hooks() {
|
|
16098
16339
|
return this.hooksExecutor;
|
|
16099
16340
|
}
|
|
16341
|
+
// SE9 — integrated structured output; delegates to the shared helper.
|
|
16342
|
+
generate(message, options) {
|
|
16343
|
+
const { apiKey, local } = this.options;
|
|
16344
|
+
return agentGenerate(this, this.model, apiKey, local, message, options);
|
|
16345
|
+
}
|
|
16100
16346
|
async send(message, options = {}) {
|
|
16101
16347
|
if (options.tools !== void 0 && options.tools.length > 0) {
|
|
16102
16348
|
validateToolCatalog(options.tools);
|
|
@@ -16336,6 +16582,7 @@ function includesSetting(options, source) {
|
|
|
16336
16582
|
|
|
16337
16583
|
// src/agent-helpers.ts
|
|
16338
16584
|
async function runCreateUnderSpan(options, span) {
|
|
16585
|
+
options = { ...options, model: normalizeModel(options.model) };
|
|
16339
16586
|
validateAgentOptions(options);
|
|
16340
16587
|
validateCloudToolParity(options);
|
|
16341
16588
|
await guardAgainstIdCollision(options);
|
|
@@ -16409,7 +16656,10 @@ async function createLocalAgent(options) {
|
|
|
16409
16656
|
const willFlowToProvider = !isFixtureApiKey(apiKey) && !shouldUseRealLocalRuntime(apiKey);
|
|
16410
16657
|
const shape = validateApiKeyShape(apiKey, {
|
|
16411
16658
|
strict: willFlowToProvider,
|
|
16412
|
-
|
|
16659
|
+
// `options.model` is already normalized by `runCreateUnderSpan`; `normalizeModel`
|
|
16660
|
+
// here is the idempotent narrowing of the widened public type (`{id}` passes
|
|
16661
|
+
// through by reference) — cleaner than an `as` cast.
|
|
16662
|
+
...willFlowToProvider ? { provider: providerFromModelId(normalizeModel(options.model)?.id) } : {}
|
|
16413
16663
|
});
|
|
16414
16664
|
if (shape.malformed) {
|
|
16415
16665
|
throw new AuthenticationError(shape.message, { code: "malformed_api_key" });
|
|
@@ -16475,6 +16725,10 @@ async function rehydrateExistingAgent(agentId, existing, options) {
|
|
|
16475
16725
|
...existing.options,
|
|
16476
16726
|
...options,
|
|
16477
16727
|
...mergedLocal !== void 0 ? { local: mergedLocal } : {},
|
|
16728
|
+
// SE8 — normalize a caller-supplied bare-string model override at this resume
|
|
16729
|
+
// boundary (Agent.resume never flows through runCreateUnderSpan). Cloud resume
|
|
16730
|
+
// honors it; local resume forces the persisted model below.
|
|
16731
|
+
model: normalizeModel(options.model ?? existing.options.model),
|
|
16478
16732
|
mcpServers: void 0,
|
|
16479
16733
|
agentId
|
|
16480
16734
|
};
|
|
@@ -16841,6 +17095,7 @@ async function getOrCreateUncached(agentId, options) {
|
|
|
16841
17095
|
}
|
|
16842
17096
|
setAgentFacade({
|
|
16843
17097
|
create: (options) => Agent.create(options),
|
|
17098
|
+
delete: (agentId) => Agent.delete(agentId),
|
|
16844
17099
|
prompt: (message, options) => Agent.prompt(message, options),
|
|
16845
17100
|
get: (agentId) => Agent.get(agentId),
|
|
16846
17101
|
resume: (agentId, options) => Agent.resume(agentId, options),
|