@theokit/sdk 2.19.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 +123 -0
- package/dist/a2a/index.cjs +611 -274
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.js +612 -275
- 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/create-skill.d.ts +29 -0
- package/dist/{cron-D_wK1S-0.d.cts → cron-YrmsszEN.d.cts} +110 -3
- package/dist/{cron-Cep07kTz.d.ts → cron-dpvtRoro.d.ts} +110 -3
- package/dist/cron.cjs +660 -370
- 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 +661 -371
- 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 +660 -370
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +660 -370
- package/dist/eval.js.map +1 -1
- package/dist/generate-object.d.ts +19 -4
- package/dist/index.cjs +867 -371
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +274 -16
- package/dist/index.d.ts +274 -16
- package/dist/index.js +863 -373
- 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 +22 -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 +3 -23
- 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/index.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 fs = require('fs');
|
|
5
7
|
var path = require('path');
|
|
6
8
|
var promises = require('fs/promises');
|
|
7
|
-
var zod = require('zod');
|
|
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');
|
|
@@ -519,6 +519,256 @@ var init_errors = __esm({
|
|
|
519
519
|
};
|
|
520
520
|
}
|
|
521
521
|
});
|
|
522
|
+
function toJsonSchema(schema, options = { unrepresentable: "any" }) {
|
|
523
|
+
return zod.toJSONSchema(schema, options);
|
|
524
|
+
}
|
|
525
|
+
var init_to_json_schema = __esm({
|
|
526
|
+
"src/internal/zod/to-json-schema.ts"() {
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
function requireZod() {
|
|
530
|
+
if (cachedZ !== void 0) return cachedZ;
|
|
531
|
+
const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
532
|
+
let mod;
|
|
533
|
+
try {
|
|
534
|
+
mod = r("zod");
|
|
535
|
+
} catch (cause) {
|
|
536
|
+
throw new exports.ConfigurationError(
|
|
537
|
+
'Structured output requires the optional peer dependency `zod`. Add `"zod": "^3.25.0 || ^4.0.0"` to your package.json and reinstall.',
|
|
538
|
+
{ code: "zod_not_installed", cause }
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
cachedZ = mod.z ?? mod;
|
|
542
|
+
return cachedZ;
|
|
543
|
+
}
|
|
544
|
+
function makeOutputTool(jsonSchema, onCapture) {
|
|
545
|
+
return {
|
|
546
|
+
name: "output",
|
|
547
|
+
description: "Call this tool with your final structured answer. Match the JSON schema exactly.",
|
|
548
|
+
inputSchema: jsonSchema,
|
|
549
|
+
handler: (input) => {
|
|
550
|
+
const out = onCapture(input);
|
|
551
|
+
if (typeof out === "string") return out;
|
|
552
|
+
if (out instanceof Promise) return out;
|
|
553
|
+
return "";
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
function buildTransientAgentOptions(params) {
|
|
558
|
+
return {
|
|
559
|
+
model: params.model,
|
|
560
|
+
local: params.local,
|
|
561
|
+
tools: [params.outputTool],
|
|
562
|
+
systemPrompt: params.systemPrompt ?? "You produce structured output by calling the `output` tool exactly once. Match the JSON schema.",
|
|
563
|
+
...params.apiKey !== void 0 ? { apiKey: params.apiKey } : {},
|
|
564
|
+
...params.providers !== void 0 ? { providers: params.providers } : {}
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
function extractUsage(result) {
|
|
568
|
+
const u = result.usage;
|
|
569
|
+
if (u === void 0) return { inputTokens: 0, outputTokens: 0 };
|
|
570
|
+
return { inputTokens: u.inputTokens ?? 0, outputTokens: u.outputTokens ?? 0 };
|
|
571
|
+
}
|
|
572
|
+
function buildToolPrompt(prompt) {
|
|
573
|
+
return `${prompt}
|
|
574
|
+
|
|
575
|
+
Respond by calling the \`output\` tool with the structured answer that matches the schema.`;
|
|
576
|
+
}
|
|
577
|
+
function setupStructuredOutput(schema, maxRetries) {
|
|
578
|
+
const z8 = requireZod();
|
|
579
|
+
const jsonSchema = toJsonSchema(schema, { unrepresentable: "any" });
|
|
580
|
+
return {
|
|
581
|
+
z: z8,
|
|
582
|
+
jsonSchema,
|
|
583
|
+
maxRetries: maxRetries ?? 1,
|
|
584
|
+
initialUsage: { inputTokens: 0, outputTokens: 0 }
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
async function disposeAndDeleteTransient(agent, deletor) {
|
|
588
|
+
await agent.dispose();
|
|
589
|
+
try {
|
|
590
|
+
await deletor(agent.agentId);
|
|
591
|
+
} catch {
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
var cachedZ;
|
|
595
|
+
var init_structured_output_helpers = __esm({
|
|
596
|
+
"src/internal/structured-output-helpers.ts"() {
|
|
597
|
+
init_errors();
|
|
598
|
+
init_to_json_schema();
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
// src/generate-object.ts
|
|
603
|
+
var generate_object_exports = {};
|
|
604
|
+
__export(generate_object_exports, {
|
|
605
|
+
GenerateObjectError: () => exports.GenerateObjectError,
|
|
606
|
+
generateObjectImpl: () => generateObjectImpl
|
|
607
|
+
});
|
|
608
|
+
function salvagePartial(schema, raw) {
|
|
609
|
+
if (typeof raw !== "object" || raw === null) return raw;
|
|
610
|
+
const shape = schema.shape;
|
|
611
|
+
if (shape === void 0 || typeof shape !== "object") return raw;
|
|
612
|
+
const rawObj = raw;
|
|
613
|
+
const out = {};
|
|
614
|
+
for (const [key2, fieldSchema] of Object.entries(shape)) {
|
|
615
|
+
if (typeof fieldSchema?.safeParse !== "function") continue;
|
|
616
|
+
const parsed = fieldSchema.safeParse(rawObj[key2]);
|
|
617
|
+
if (parsed.success) out[key2] = parsed.data;
|
|
618
|
+
}
|
|
619
|
+
return out;
|
|
620
|
+
}
|
|
621
|
+
async function runReasoningPhase(options, deps) {
|
|
622
|
+
const reasoningOptions = {
|
|
623
|
+
model: options.model,
|
|
624
|
+
local: options.local,
|
|
625
|
+
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
626
|
+
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
627
|
+
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
628
|
+
};
|
|
629
|
+
const reasoningAgent = await deps.create(reasoningOptions);
|
|
630
|
+
try {
|
|
631
|
+
const run = await reasoningAgent.send(options.prompt);
|
|
632
|
+
const result = await run.wait();
|
|
633
|
+
const text = result.result;
|
|
634
|
+
return typeof text === "string" ? text : options.prompt;
|
|
635
|
+
} finally {
|
|
636
|
+
await disposeAndDeleteTransient(reasoningAgent, deps.delete);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
async function generateObjectImpl(options, deps) {
|
|
640
|
+
const { jsonSchema, maxRetries, initialUsage } = setupStructuredOutput(
|
|
641
|
+
options.schema,
|
|
642
|
+
options.maxRetries
|
|
643
|
+
);
|
|
644
|
+
let capturedRaw;
|
|
645
|
+
let lastUsage = initialUsage;
|
|
646
|
+
const sentinel = /* @__PURE__ */ Symbol("generate-object-sentinel");
|
|
647
|
+
class CaptureSentinel extends Error {
|
|
648
|
+
constructor(captured) {
|
|
649
|
+
super("generate-object-capture");
|
|
650
|
+
this.captured = captured;
|
|
651
|
+
}
|
|
652
|
+
captured;
|
|
653
|
+
[sentinel] = true;
|
|
654
|
+
}
|
|
655
|
+
const outputTool = makeOutputTool(jsonSchema, (input) => {
|
|
656
|
+
if (capturedRaw === void 0) {
|
|
657
|
+
capturedRaw = input;
|
|
658
|
+
}
|
|
659
|
+
throw new CaptureSentinel(input);
|
|
660
|
+
});
|
|
661
|
+
const reasoningText = options.structuringModel !== void 0 ? await runReasoningPhase(options, deps) : void 0;
|
|
662
|
+
const structuringModel = options.structuringModel ?? options.model;
|
|
663
|
+
const structuringPrompt = reasoningText ?? options.prompt;
|
|
664
|
+
const agentOptions = buildTransientAgentOptions({
|
|
665
|
+
model: structuringModel,
|
|
666
|
+
local: options.local,
|
|
667
|
+
outputTool,
|
|
668
|
+
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
669
|
+
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
670
|
+
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
671
|
+
});
|
|
672
|
+
const agent = await deps.create(agentOptions);
|
|
673
|
+
try {
|
|
674
|
+
const userMessage = buildToolPrompt(structuringPrompt);
|
|
675
|
+
let lastParseError;
|
|
676
|
+
for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
|
|
677
|
+
capturedRaw = void 0;
|
|
678
|
+
const run = await agent.send(userMessage);
|
|
679
|
+
const result = await run.wait();
|
|
680
|
+
lastUsage = extractUsage(result);
|
|
681
|
+
if (capturedRaw === void 0) {
|
|
682
|
+
if (result.status === "error" && result.error !== void 0) {
|
|
683
|
+
throw new exports.GenerateObjectError(
|
|
684
|
+
"no_tool_call",
|
|
685
|
+
`Agent run failed before the model could reply: ${result.error.message ?? "unknown error"} [${result.error.code ?? "?"}]`,
|
|
686
|
+
result.error
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
if (attempt === maxRetries) {
|
|
690
|
+
throw new exports.GenerateObjectError(
|
|
691
|
+
"no_tool_call",
|
|
692
|
+
"The model returned text instead of calling the `output` tool."
|
|
693
|
+
);
|
|
694
|
+
}
|
|
695
|
+
continue;
|
|
696
|
+
}
|
|
697
|
+
const parsed = options.schema.safeParse(capturedRaw);
|
|
698
|
+
if (parsed.success) {
|
|
699
|
+
return {
|
|
700
|
+
object: parsed.data,
|
|
701
|
+
raw: capturedRaw,
|
|
702
|
+
usage: lastUsage,
|
|
703
|
+
finishReason: "tool_use"
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
lastParseError = parsed.error;
|
|
707
|
+
}
|
|
708
|
+
if (options.errorStrategy === "return-raw") {
|
|
709
|
+
return {
|
|
710
|
+
object: capturedRaw,
|
|
711
|
+
raw: capturedRaw,
|
|
712
|
+
usage: lastUsage,
|
|
713
|
+
finishReason: "tool_use"
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
if (options.errorStrategy === "return-partial") {
|
|
717
|
+
return {
|
|
718
|
+
object: salvagePartial(options.schema, capturedRaw),
|
|
719
|
+
raw: capturedRaw,
|
|
720
|
+
usage: lastUsage,
|
|
721
|
+
finishReason: "tool_use"
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
throw new exports.GenerateObjectError(
|
|
725
|
+
"parse_failed",
|
|
726
|
+
"Schema parse failed after all retries.",
|
|
727
|
+
lastParseError
|
|
728
|
+
);
|
|
729
|
+
} finally {
|
|
730
|
+
await disposeAndDeleteTransient(agent, deps.delete);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
exports.GenerateObjectError = void 0;
|
|
734
|
+
var init_generate_object = __esm({
|
|
735
|
+
"src/generate-object.ts"() {
|
|
736
|
+
init_structured_output_helpers();
|
|
737
|
+
exports.GenerateObjectError = class extends Error {
|
|
738
|
+
name = "GenerateObjectError";
|
|
739
|
+
code;
|
|
740
|
+
cause;
|
|
741
|
+
constructor(code, message, cause) {
|
|
742
|
+
super(message);
|
|
743
|
+
this.code = code;
|
|
744
|
+
if (cause !== void 0) this.cause = cause;
|
|
745
|
+
}
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
});
|
|
749
|
+
|
|
750
|
+
// src/internal/runtime/registry/agent-factory-registry.ts
|
|
751
|
+
var agent_factory_registry_exports = {};
|
|
752
|
+
__export(agent_factory_registry_exports, {
|
|
753
|
+
getAgentFacade: () => getAgentFacade,
|
|
754
|
+
setAgentFacade: () => setAgentFacade
|
|
755
|
+
});
|
|
756
|
+
function setAgentFacade(facade) {
|
|
757
|
+
registered = facade;
|
|
758
|
+
}
|
|
759
|
+
function getAgentFacade() {
|
|
760
|
+
if (registered === void 0) {
|
|
761
|
+
throw new Error(
|
|
762
|
+
"internal: Agent facade not registered. The `agent.ts` module must be loaded before internal subsystems (LocalAgent.runUntil/fork, eval, scorers, cron) invoke it."
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
return registered;
|
|
766
|
+
}
|
|
767
|
+
var registered;
|
|
768
|
+
var init_agent_factory_registry = __esm({
|
|
769
|
+
"src/internal/runtime/registry/agent-factory-registry.ts"() {
|
|
770
|
+
}
|
|
771
|
+
});
|
|
522
772
|
|
|
523
773
|
// src/internal/persistence/cwd-mutex.ts
|
|
524
774
|
function withCwdMutex(key2, fn) {
|
|
@@ -2789,29 +3039,6 @@ var init_judge_call = __esm({
|
|
|
2789
3039
|
}
|
|
2790
3040
|
});
|
|
2791
3041
|
|
|
2792
|
-
// src/internal/runtime/registry/agent-factory-registry.ts
|
|
2793
|
-
var agent_factory_registry_exports = {};
|
|
2794
|
-
__export(agent_factory_registry_exports, {
|
|
2795
|
-
getAgentFacade: () => getAgentFacade,
|
|
2796
|
-
setAgentFacade: () => setAgentFacade
|
|
2797
|
-
});
|
|
2798
|
-
function setAgentFacade(facade) {
|
|
2799
|
-
registered3 = facade;
|
|
2800
|
-
}
|
|
2801
|
-
function getAgentFacade() {
|
|
2802
|
-
if (registered3 === void 0) {
|
|
2803
|
-
throw new Error(
|
|
2804
|
-
"internal: Agent facade not registered. The `agent.ts` module must be loaded before internal subsystems (LocalAgent.runUntil/fork, eval, scorers, cron) invoke it."
|
|
2805
|
-
);
|
|
2806
|
-
}
|
|
2807
|
-
return registered3;
|
|
2808
|
-
}
|
|
2809
|
-
var registered3;
|
|
2810
|
-
var init_agent_factory_registry = __esm({
|
|
2811
|
-
"src/internal/runtime/registry/agent-factory-registry.ts"() {
|
|
2812
|
-
}
|
|
2813
|
-
});
|
|
2814
|
-
|
|
2815
3042
|
// src/internal/runtime/lifecycle/run-to-completion.ts
|
|
2816
3043
|
var run_to_completion_exports = {};
|
|
2817
3044
|
__export(run_to_completion_exports, {
|
|
@@ -2976,14 +3203,14 @@ async function forkAgentImpl(parent, options, deps) {
|
|
|
2976
3203
|
return {
|
|
2977
3204
|
result: result.result,
|
|
2978
3205
|
toolCalls: [],
|
|
2979
|
-
usage:
|
|
3206
|
+
usage: extractUsage2(result)
|
|
2980
3207
|
};
|
|
2981
3208
|
});
|
|
2982
3209
|
} finally {
|
|
2983
3210
|
await fork.dispose();
|
|
2984
3211
|
}
|
|
2985
3212
|
}
|
|
2986
|
-
function
|
|
3213
|
+
function extractUsage2(result) {
|
|
2987
3214
|
if (typeof result !== "object" || result === null) {
|
|
2988
3215
|
return { inputTokens: 0, outputTokens: 0 };
|
|
2989
3216
|
}
|
|
@@ -3615,309 +3842,103 @@ async function submit(internal) {
|
|
|
3615
3842
|
});
|
|
3616
3843
|
}
|
|
3617
3844
|
const release = await acquireSlot();
|
|
3618
|
-
void (async () => {
|
|
3619
|
-
try {
|
|
3620
|
-
await checkCancelRequestedAt(resolvedId, aborter);
|
|
3621
|
-
if (aborter.signal.aborted) {
|
|
3622
|
-
const cancelledAt = Date.now();
|
|
3623
|
-
await transition(resolvedId, "cancelled", { cancelledAt });
|
|
3624
|
-
emitToSubscribers(resolvedId, { type: "cancelled", taskId: resolvedId, cancelledAt });
|
|
3625
|
-
return;
|
|
3626
|
-
}
|
|
3627
|
-
const startedAt = Date.now();
|
|
3628
|
-
await transition(resolvedId, "running", { startedAt });
|
|
3629
|
-
emitToSubscribers(resolvedId, { type: "started", taskId: resolvedId, startedAt });
|
|
3630
|
-
await runWorkAndFinalize(resolvedId, aborter, internal.work);
|
|
3631
|
-
} finally {
|
|
3632
|
-
release();
|
|
3633
|
-
state.aborters.delete(resolvedId);
|
|
3634
|
-
}
|
|
3635
|
-
})();
|
|
3636
|
-
return queuedHandle;
|
|
3637
|
-
}
|
|
3638
|
-
async function list(filter = {}) {
|
|
3639
|
-
return state.store.list(filter);
|
|
3640
|
-
}
|
|
3641
|
-
async function get(id) {
|
|
3642
|
-
if (!isValidTaskId(id, true)) return void 0;
|
|
3643
|
-
return state.store.get(id);
|
|
3644
|
-
}
|
|
3645
|
-
async function cancel(id, reason) {
|
|
3646
|
-
if (!isValidTaskId(id, true)) return { cancelled: false, alreadyTerminal: false };
|
|
3647
|
-
const handle = await state.store.get(id);
|
|
3648
|
-
if (handle === void 0) return { cancelled: false, alreadyTerminal: false };
|
|
3649
|
-
if (handle.state === "finished" || handle.state === "error" || handle.state === "cancelled") {
|
|
3650
|
-
return { cancelled: false, alreadyTerminal: true };
|
|
3651
|
-
}
|
|
3652
|
-
const span = startTaskCancelSpan({
|
|
3653
|
-
taskId: id,
|
|
3654
|
-
...reason !== void 0 ? { reason } : {},
|
|
3655
|
-
via: "api"
|
|
3656
|
-
});
|
|
3657
|
-
try {
|
|
3658
|
-
return await cancelInternal(id, handle.state, reason);
|
|
3659
|
-
} finally {
|
|
3660
|
-
span.end();
|
|
3661
|
-
}
|
|
3662
|
-
}
|
|
3663
|
-
async function cancelInternal(id, currentState, reason) {
|
|
3664
|
-
if (currentState === "queued") {
|
|
3665
|
-
const cancelledAt = Date.now();
|
|
3666
|
-
await transition(id, "cancelled", { cancelledAt });
|
|
3667
|
-
emitToSubscribers(id, {
|
|
3668
|
-
type: "cancelled",
|
|
3669
|
-
taskId: id,
|
|
3670
|
-
cancelledAt,
|
|
3671
|
-
...reason !== void 0 ? { reason } : {}
|
|
3672
|
-
});
|
|
3673
|
-
state.aborters.delete(id);
|
|
3674
|
-
return { cancelled: true, alreadyTerminal: false };
|
|
3675
|
-
}
|
|
3676
|
-
const aborter = state.aborters.get(id);
|
|
3677
|
-
if (aborter !== void 0) aborter.abort(reason ?? "cancelled");
|
|
3678
|
-
return { cancelled: true, alreadyTerminal: false };
|
|
3679
|
-
}
|
|
3680
|
-
async function evictNow(now = Date.now()) {
|
|
3681
|
-
return state.store.evictTerminalOlderThan(now - state.retentionMs);
|
|
3682
|
-
}
|
|
3683
|
-
var DEFAULT_CONCURRENCY, DEFAULT_RETENTION_MS, EVICTION_INTERVAL_MS, RING_CAP, reentryAls, state, subscribe;
|
|
3684
|
-
var init_registry = __esm({
|
|
3685
|
-
"src/internal/task/registry.ts"() {
|
|
3686
|
-
init_errors();
|
|
3687
|
-
init_task();
|
|
3688
|
-
init_async_semaphore();
|
|
3689
|
-
init_ring_buffer();
|
|
3690
|
-
init_store();
|
|
3691
|
-
init_subscribe();
|
|
3692
|
-
init_telemetry();
|
|
3693
|
-
DEFAULT_CONCURRENCY = 8;
|
|
3694
|
-
DEFAULT_RETENTION_MS = 60 * 60 * 1e3;
|
|
3695
|
-
EVICTION_INTERVAL_MS = 5 * 60 * 1e3;
|
|
3696
|
-
RING_CAP = 64;
|
|
3697
|
-
reentryAls = new async_hooks.AsyncLocalStorage();
|
|
3698
|
-
state = buildState({});
|
|
3699
|
-
subscribe = buildSubscribe({
|
|
3700
|
-
getBuffer: (id) => state.buffers.get(id),
|
|
3701
|
-
getOrCreateSubscriberSet: (id) => {
|
|
3702
|
-
let subs = state.subscribers.get(id);
|
|
3703
|
-
if (subs === void 0) {
|
|
3704
|
-
subs = /* @__PURE__ */ new Set();
|
|
3705
|
-
state.subscribers.set(id, subs);
|
|
3706
|
-
}
|
|
3707
|
-
return subs;
|
|
3708
|
-
},
|
|
3709
|
-
removeSubscriber: (id, cb) => {
|
|
3710
|
-
const set = state.subscribers.get(id);
|
|
3711
|
-
set?.delete(cb);
|
|
3712
|
-
if (set !== void 0 && set.size === 0) state.subscribers.delete(id);
|
|
3713
|
-
}
|
|
3714
|
-
});
|
|
3715
|
-
}
|
|
3716
|
-
});
|
|
3717
|
-
function toJsonSchema(schema, options = { unrepresentable: "any" }) {
|
|
3718
|
-
return zod.toJSONSchema(schema, options);
|
|
3719
|
-
}
|
|
3720
|
-
var init_to_json_schema = __esm({
|
|
3721
|
-
"src/internal/zod/to-json-schema.ts"() {
|
|
3722
|
-
}
|
|
3723
|
-
});
|
|
3724
|
-
function requireZod() {
|
|
3725
|
-
if (cachedZ !== void 0) return cachedZ;
|
|
3726
|
-
const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
3727
|
-
let mod;
|
|
3728
|
-
try {
|
|
3729
|
-
mod = r("zod");
|
|
3730
|
-
} catch (cause) {
|
|
3731
|
-
throw new exports.ConfigurationError(
|
|
3732
|
-
'Structured output requires the optional peer dependency `zod`. Add `"zod": "^3.25.0 || ^4.0.0"` to your package.json and reinstall.',
|
|
3733
|
-
{ code: "zod_not_installed", cause }
|
|
3734
|
-
);
|
|
3735
|
-
}
|
|
3736
|
-
cachedZ = mod.z ?? mod;
|
|
3737
|
-
return cachedZ;
|
|
3738
|
-
}
|
|
3739
|
-
function makeOutputTool(jsonSchema, onCapture) {
|
|
3740
|
-
return {
|
|
3741
|
-
name: "output",
|
|
3742
|
-
description: "Call this tool with your final structured answer. Match the JSON schema exactly.",
|
|
3743
|
-
inputSchema: jsonSchema,
|
|
3744
|
-
handler: (input) => {
|
|
3745
|
-
const out = onCapture(input);
|
|
3746
|
-
if (typeof out === "string") return out;
|
|
3747
|
-
if (out instanceof Promise) return out;
|
|
3748
|
-
return "";
|
|
3749
|
-
}
|
|
3750
|
-
};
|
|
3751
|
-
}
|
|
3752
|
-
function buildTransientAgentOptions(params) {
|
|
3753
|
-
return {
|
|
3754
|
-
model: params.model,
|
|
3755
|
-
local: params.local,
|
|
3756
|
-
tools: [params.outputTool],
|
|
3757
|
-
systemPrompt: params.systemPrompt ?? "You produce structured output by calling the `output` tool exactly once. Match the JSON schema.",
|
|
3758
|
-
...params.apiKey !== void 0 ? { apiKey: params.apiKey } : {},
|
|
3759
|
-
...params.providers !== void 0 ? { providers: params.providers } : {}
|
|
3760
|
-
};
|
|
3761
|
-
}
|
|
3762
|
-
function extractUsage2(result) {
|
|
3763
|
-
const u = result.usage;
|
|
3764
|
-
if (u === void 0) return { inputTokens: 0, outputTokens: 0 };
|
|
3765
|
-
return { inputTokens: u.inputTokens ?? 0, outputTokens: u.outputTokens ?? 0 };
|
|
3766
|
-
}
|
|
3767
|
-
function buildToolPrompt(prompt) {
|
|
3768
|
-
return `${prompt}
|
|
3769
|
-
|
|
3770
|
-
Respond by calling the \`output\` tool with the structured answer that matches the schema.`;
|
|
3771
|
-
}
|
|
3772
|
-
function setupStructuredOutput(schema, maxRetries) {
|
|
3773
|
-
const z8 = requireZod();
|
|
3774
|
-
const jsonSchema = toJsonSchema(schema, { unrepresentable: "any" });
|
|
3775
|
-
return {
|
|
3776
|
-
z: z8,
|
|
3777
|
-
jsonSchema,
|
|
3778
|
-
maxRetries: maxRetries ?? 1,
|
|
3779
|
-
initialUsage: { inputTokens: 0, outputTokens: 0 }
|
|
3780
|
-
};
|
|
3781
|
-
}
|
|
3782
|
-
async function disposeAndDeleteTransient(agent, deletor) {
|
|
3783
|
-
await agent.dispose();
|
|
3784
|
-
try {
|
|
3785
|
-
await deletor(agent.agentId);
|
|
3786
|
-
} catch {
|
|
3787
|
-
}
|
|
3788
|
-
}
|
|
3789
|
-
var cachedZ;
|
|
3790
|
-
var init_structured_output_helpers = __esm({
|
|
3791
|
-
"src/internal/structured-output-helpers.ts"() {
|
|
3792
|
-
init_errors();
|
|
3793
|
-
init_to_json_schema();
|
|
3794
|
-
}
|
|
3795
|
-
});
|
|
3796
|
-
|
|
3797
|
-
// src/generate-object.ts
|
|
3798
|
-
var generate_object_exports = {};
|
|
3799
|
-
__export(generate_object_exports, {
|
|
3800
|
-
GenerateObjectError: () => exports.GenerateObjectError,
|
|
3801
|
-
generateObjectImpl: () => generateObjectImpl
|
|
3802
|
-
});
|
|
3803
|
-
function salvagePartial(schema, raw) {
|
|
3804
|
-
if (typeof raw !== "object" || raw === null) return raw;
|
|
3805
|
-
const shape = schema.shape;
|
|
3806
|
-
if (shape === void 0 || typeof shape !== "object") return raw;
|
|
3807
|
-
const rawObj = raw;
|
|
3808
|
-
const out = {};
|
|
3809
|
-
for (const [key2, fieldSchema] of Object.entries(shape)) {
|
|
3810
|
-
if (typeof fieldSchema?.safeParse !== "function") continue;
|
|
3811
|
-
const parsed = fieldSchema.safeParse(rawObj[key2]);
|
|
3812
|
-
if (parsed.success) out[key2] = parsed.data;
|
|
3813
|
-
}
|
|
3814
|
-
return out;
|
|
3815
|
-
}
|
|
3816
|
-
async function generateObjectImpl(options, deps) {
|
|
3817
|
-
const { jsonSchema, maxRetries, initialUsage } = setupStructuredOutput(
|
|
3818
|
-
options.schema,
|
|
3819
|
-
options.maxRetries
|
|
3820
|
-
);
|
|
3821
|
-
let capturedRaw;
|
|
3822
|
-
let lastUsage = initialUsage;
|
|
3823
|
-
const sentinel = /* @__PURE__ */ Symbol("generate-object-sentinel");
|
|
3824
|
-
class CaptureSentinel extends Error {
|
|
3825
|
-
constructor(captured) {
|
|
3826
|
-
super("generate-object-capture");
|
|
3827
|
-
this.captured = captured;
|
|
3828
|
-
}
|
|
3829
|
-
captured;
|
|
3830
|
-
[sentinel] = true;
|
|
3831
|
-
}
|
|
3832
|
-
const outputTool = makeOutputTool(jsonSchema, (input) => {
|
|
3833
|
-
if (capturedRaw === void 0) {
|
|
3834
|
-
capturedRaw = input;
|
|
3835
|
-
}
|
|
3836
|
-
throw new CaptureSentinel(input);
|
|
3837
|
-
});
|
|
3838
|
-
const agentOptions = buildTransientAgentOptions({
|
|
3839
|
-
model: options.model,
|
|
3840
|
-
local: options.local,
|
|
3841
|
-
outputTool,
|
|
3842
|
-
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
3843
|
-
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
3844
|
-
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
3845
|
-
});
|
|
3846
|
-
const agent = await deps.create(agentOptions);
|
|
3847
|
-
try {
|
|
3848
|
-
const userMessage = buildToolPrompt(options.prompt);
|
|
3849
|
-
let lastParseError;
|
|
3850
|
-
for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
|
|
3851
|
-
capturedRaw = void 0;
|
|
3852
|
-
const run = await agent.send(userMessage);
|
|
3853
|
-
const result = await run.wait();
|
|
3854
|
-
lastUsage = extractUsage2(result);
|
|
3855
|
-
if (capturedRaw === void 0) {
|
|
3856
|
-
if (result.status === "error" && result.error !== void 0) {
|
|
3857
|
-
throw new exports.GenerateObjectError(
|
|
3858
|
-
"no_tool_call",
|
|
3859
|
-
`Agent run failed before the model could reply: ${result.error.message ?? "unknown error"} [${result.error.code ?? "?"}]`,
|
|
3860
|
-
result.error
|
|
3861
|
-
);
|
|
3862
|
-
}
|
|
3863
|
-
if (attempt === maxRetries) {
|
|
3864
|
-
throw new exports.GenerateObjectError(
|
|
3865
|
-
"no_tool_call",
|
|
3866
|
-
"The model returned text instead of calling the `output` tool."
|
|
3867
|
-
);
|
|
3868
|
-
}
|
|
3869
|
-
continue;
|
|
3870
|
-
}
|
|
3871
|
-
const parsed = options.schema.safeParse(capturedRaw);
|
|
3872
|
-
if (parsed.success) {
|
|
3873
|
-
return {
|
|
3874
|
-
object: parsed.data,
|
|
3875
|
-
raw: capturedRaw,
|
|
3876
|
-
usage: lastUsage,
|
|
3877
|
-
finishReason: "tool_use"
|
|
3878
|
-
};
|
|
3879
|
-
}
|
|
3880
|
-
lastParseError = parsed.error;
|
|
3881
|
-
}
|
|
3882
|
-
if (options.errorStrategy === "return-raw") {
|
|
3883
|
-
return {
|
|
3884
|
-
object: capturedRaw,
|
|
3885
|
-
raw: capturedRaw,
|
|
3886
|
-
usage: lastUsage,
|
|
3887
|
-
finishReason: "tool_use"
|
|
3888
|
-
};
|
|
3889
|
-
}
|
|
3890
|
-
if (options.errorStrategy === "return-partial") {
|
|
3891
|
-
return {
|
|
3892
|
-
object: salvagePartial(options.schema, capturedRaw),
|
|
3893
|
-
raw: capturedRaw,
|
|
3894
|
-
usage: lastUsage,
|
|
3895
|
-
finishReason: "tool_use"
|
|
3896
|
-
};
|
|
3845
|
+
void (async () => {
|
|
3846
|
+
try {
|
|
3847
|
+
await checkCancelRequestedAt(resolvedId, aborter);
|
|
3848
|
+
if (aborter.signal.aborted) {
|
|
3849
|
+
const cancelledAt = Date.now();
|
|
3850
|
+
await transition(resolvedId, "cancelled", { cancelledAt });
|
|
3851
|
+
emitToSubscribers(resolvedId, { type: "cancelled", taskId: resolvedId, cancelledAt });
|
|
3852
|
+
return;
|
|
3853
|
+
}
|
|
3854
|
+
const startedAt = Date.now();
|
|
3855
|
+
await transition(resolvedId, "running", { startedAt });
|
|
3856
|
+
emitToSubscribers(resolvedId, { type: "started", taskId: resolvedId, startedAt });
|
|
3857
|
+
await runWorkAndFinalize(resolvedId, aborter, internal.work);
|
|
3858
|
+
} finally {
|
|
3859
|
+
release();
|
|
3860
|
+
state.aborters.delete(resolvedId);
|
|
3897
3861
|
}
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3862
|
+
})();
|
|
3863
|
+
return queuedHandle;
|
|
3864
|
+
}
|
|
3865
|
+
async function list(filter = {}) {
|
|
3866
|
+
return state.store.list(filter);
|
|
3867
|
+
}
|
|
3868
|
+
async function get(id) {
|
|
3869
|
+
if (!isValidTaskId(id, true)) return void 0;
|
|
3870
|
+
return state.store.get(id);
|
|
3871
|
+
}
|
|
3872
|
+
async function cancel(id, reason) {
|
|
3873
|
+
if (!isValidTaskId(id, true)) return { cancelled: false, alreadyTerminal: false };
|
|
3874
|
+
const handle = await state.store.get(id);
|
|
3875
|
+
if (handle === void 0) return { cancelled: false, alreadyTerminal: false };
|
|
3876
|
+
if (handle.state === "finished" || handle.state === "error" || handle.state === "cancelled") {
|
|
3877
|
+
return { cancelled: false, alreadyTerminal: true };
|
|
3878
|
+
}
|
|
3879
|
+
const span = startTaskCancelSpan({
|
|
3880
|
+
taskId: id,
|
|
3881
|
+
...reason !== void 0 ? { reason } : {},
|
|
3882
|
+
via: "api"
|
|
3883
|
+
});
|
|
3884
|
+
try {
|
|
3885
|
+
return await cancelInternal(id, handle.state, reason);
|
|
3903
3886
|
} finally {
|
|
3904
|
-
|
|
3887
|
+
span.end();
|
|
3905
3888
|
}
|
|
3906
3889
|
}
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3890
|
+
async function cancelInternal(id, currentState, reason) {
|
|
3891
|
+
if (currentState === "queued") {
|
|
3892
|
+
const cancelledAt = Date.now();
|
|
3893
|
+
await transition(id, "cancelled", { cancelledAt });
|
|
3894
|
+
emitToSubscribers(id, {
|
|
3895
|
+
type: "cancelled",
|
|
3896
|
+
taskId: id,
|
|
3897
|
+
cancelledAt,
|
|
3898
|
+
...reason !== void 0 ? { reason } : {}
|
|
3899
|
+
});
|
|
3900
|
+
state.aborters.delete(id);
|
|
3901
|
+
return { cancelled: true, alreadyTerminal: false };
|
|
3902
|
+
}
|
|
3903
|
+
const aborter = state.aborters.get(id);
|
|
3904
|
+
if (aborter !== void 0) aborter.abort(reason ?? "cancelled");
|
|
3905
|
+
return { cancelled: true, alreadyTerminal: false };
|
|
3906
|
+
}
|
|
3907
|
+
async function evictNow(now = Date.now()) {
|
|
3908
|
+
return state.store.evictTerminalOlderThan(now - state.retentionMs);
|
|
3909
|
+
}
|
|
3910
|
+
var DEFAULT_CONCURRENCY, DEFAULT_RETENTION_MS, EVICTION_INTERVAL_MS, RING_CAP, reentryAls, state, subscribe;
|
|
3911
|
+
var init_registry = __esm({
|
|
3912
|
+
"src/internal/task/registry.ts"() {
|
|
3913
|
+
init_errors();
|
|
3914
|
+
init_task();
|
|
3915
|
+
init_async_semaphore();
|
|
3916
|
+
init_ring_buffer();
|
|
3917
|
+
init_store();
|
|
3918
|
+
init_subscribe();
|
|
3919
|
+
init_telemetry();
|
|
3920
|
+
DEFAULT_CONCURRENCY = 8;
|
|
3921
|
+
DEFAULT_RETENTION_MS = 60 * 60 * 1e3;
|
|
3922
|
+
EVICTION_INTERVAL_MS = 5 * 60 * 1e3;
|
|
3923
|
+
RING_CAP = 64;
|
|
3924
|
+
reentryAls = new async_hooks.AsyncLocalStorage();
|
|
3925
|
+
state = buildState({});
|
|
3926
|
+
subscribe = buildSubscribe({
|
|
3927
|
+
getBuffer: (id) => state.buffers.get(id),
|
|
3928
|
+
getOrCreateSubscriberSet: (id) => {
|
|
3929
|
+
let subs = state.subscribers.get(id);
|
|
3930
|
+
if (subs === void 0) {
|
|
3931
|
+
subs = /* @__PURE__ */ new Set();
|
|
3932
|
+
state.subscribers.set(id, subs);
|
|
3933
|
+
}
|
|
3934
|
+
return subs;
|
|
3935
|
+
},
|
|
3936
|
+
removeSubscriber: (id, cb) => {
|
|
3937
|
+
const set = state.subscribers.get(id);
|
|
3938
|
+
set?.delete(cb);
|
|
3939
|
+
if (set !== void 0 && set.size === 0) state.subscribers.delete(id);
|
|
3919
3940
|
}
|
|
3920
|
-
};
|
|
3941
|
+
});
|
|
3921
3942
|
}
|
|
3922
3943
|
});
|
|
3923
3944
|
|
|
@@ -3975,7 +3996,7 @@ async function* streamObjectImpl(options, deps) {
|
|
|
3975
3996
|
}
|
|
3976
3997
|
}
|
|
3977
3998
|
const result = await run.wait();
|
|
3978
|
-
lastUsage =
|
|
3999
|
+
lastUsage = extractUsage(result);
|
|
3979
4000
|
if (capturedRaw === void 0) {
|
|
3980
4001
|
if (result.status === "error" && result.error !== void 0) {
|
|
3981
4002
|
throw new exports.StreamObjectError(
|
|
@@ -4727,7 +4748,10 @@ async function runAgentStep(step, input, ctx) {
|
|
|
4727
4748
|
};
|
|
4728
4749
|
}
|
|
4729
4750
|
const exec = async () => {
|
|
4730
|
-
const run = await step.agent.send(
|
|
4751
|
+
const run = await step.agent.send(
|
|
4752
|
+
prompt,
|
|
4753
|
+
step.origin !== void 0 ? { origin: step.origin } : void 0
|
|
4754
|
+
);
|
|
4731
4755
|
const result = await run.wait();
|
|
4732
4756
|
if (result.status === "finished") {
|
|
4733
4757
|
return result.result ?? "";
|
|
@@ -5499,6 +5523,7 @@ var AgentBuilder = class {
|
|
|
5499
5523
|
constructor(deps) {
|
|
5500
5524
|
this.deps = deps;
|
|
5501
5525
|
}
|
|
5526
|
+
/** SE8 — accepts a bare-string id shorthand (`"openai/gpt-4o-mini"`) or a {@link ModelSelection}. */
|
|
5502
5527
|
model(m) {
|
|
5503
5528
|
this.opts.model = m;
|
|
5504
5529
|
return this;
|
|
@@ -5856,13 +5881,87 @@ function isLocalAgentId(id) {
|
|
|
5856
5881
|
return id.startsWith(PREFIX.localAgent);
|
|
5857
5882
|
}
|
|
5858
5883
|
|
|
5884
|
+
// src/internal/runtime/config/default-model.ts
|
|
5885
|
+
var DEFAULT_AGENTIC_MODEL_ID = "google/gemini-2.0-flash-001";
|
|
5886
|
+
|
|
5887
|
+
// src/agent-generate.ts
|
|
5888
|
+
async function agentGenerate(agent, agentModel, agentApiKey, agentLocal, input, options) {
|
|
5889
|
+
const { output, maxRetries, errorStrategy, ...sendOptions } = options;
|
|
5890
|
+
const run = await agent.send(input, sendOptions);
|
|
5891
|
+
const result = await run.wait();
|
|
5892
|
+
const { generateObjectImpl: generateObjectImpl2, GenerateObjectError: GenerateObjectError2 } = await Promise.resolve().then(() => (init_generate_object(), generate_object_exports));
|
|
5893
|
+
const answer = structurableAnswerOrThrow(result, GenerateObjectError2);
|
|
5894
|
+
const { getAgentFacade: getAgentFacade2 } = await Promise.resolve().then(() => (init_agent_factory_registry(), agent_factory_registry_exports));
|
|
5895
|
+
const facade = getAgentFacade2();
|
|
5896
|
+
const structured = await generateObjectImpl2(
|
|
5897
|
+
{
|
|
5898
|
+
prompt: answer,
|
|
5899
|
+
schema: output,
|
|
5900
|
+
// `agentModel` arrives already normalized (`this.model` passed through
|
|
5901
|
+
// `normalizeModel` in the LocalAgent/CloudAgent constructor), so the widened
|
|
5902
|
+
// `string | ModelSelection` field only ever receives a `ModelSelection` here.
|
|
5903
|
+
model: agentModel ?? { id: DEFAULT_AGENTIC_MODEL_ID },
|
|
5904
|
+
// `local` is required to keep the transient structuring agent local-only;
|
|
5905
|
+
// default to the process cwd when the agent had no explicit local config.
|
|
5906
|
+
local: agentLocal ?? { cwd: process.cwd() },
|
|
5907
|
+
...agentApiKey !== void 0 ? { apiKey: agentApiKey } : {},
|
|
5908
|
+
...maxRetries !== void 0 ? { maxRetries } : {},
|
|
5909
|
+
...errorStrategy !== void 0 ? { errorStrategy } : {}
|
|
5910
|
+
},
|
|
5911
|
+
{
|
|
5912
|
+
create: (opts) => facade.create(opts),
|
|
5913
|
+
delete: (agentId) => facade.delete(agentId)
|
|
5914
|
+
}
|
|
5915
|
+
);
|
|
5916
|
+
return {
|
|
5917
|
+
object: structured.object,
|
|
5918
|
+
result,
|
|
5919
|
+
raw: structured.raw,
|
|
5920
|
+
usage: structured.usage
|
|
5921
|
+
};
|
|
5922
|
+
}
|
|
5923
|
+
function structurableAnswerOrThrow(result, GenerateObjectError2) {
|
|
5924
|
+
if (result.status === "error") {
|
|
5925
|
+
throw new GenerateObjectError2(
|
|
5926
|
+
"no_tool_call",
|
|
5927
|
+
`Agent run failed before an answer could be structured: ${result.error?.message ?? "unknown error"} [${result.error?.code ?? "?"}]`,
|
|
5928
|
+
result.error
|
|
5929
|
+
);
|
|
5930
|
+
}
|
|
5931
|
+
if (result.status === "cancelled") {
|
|
5932
|
+
throw new GenerateObjectError2(
|
|
5933
|
+
"no_tool_call",
|
|
5934
|
+
"Agent run was cancelled before an answer could be structured."
|
|
5935
|
+
);
|
|
5936
|
+
}
|
|
5937
|
+
const answer = result.result;
|
|
5938
|
+
if (answer === void 0 || answer.length === 0) {
|
|
5939
|
+
throw new GenerateObjectError2(
|
|
5940
|
+
"no_tool_call",
|
|
5941
|
+
"The tool loop finished with no text answer (tool-only completion) \u2014 there is nothing to structure."
|
|
5942
|
+
);
|
|
5943
|
+
}
|
|
5944
|
+
return answer;
|
|
5945
|
+
}
|
|
5946
|
+
|
|
5859
5947
|
// src/internal/runtime/cloud/cloud-agent.ts
|
|
5860
5948
|
init_errors();
|
|
5861
5949
|
init_cwd_mutex();
|
|
5862
5950
|
init_path_guard();
|
|
5863
5951
|
|
|
5864
|
-
// src/internal/runtime/
|
|
5865
|
-
|
|
5952
|
+
// src/internal/runtime/model-selection.ts
|
|
5953
|
+
init_errors();
|
|
5954
|
+
function normalizeModel(m) {
|
|
5955
|
+
if (m === void 0 || typeof m !== "string") return m;
|
|
5956
|
+
const id = m.trim();
|
|
5957
|
+
if (id.length === 0) {
|
|
5958
|
+
throw new exports.ConfigurationError(
|
|
5959
|
+
'model must be a non-empty "provider/model" id string or a ModelSelection object',
|
|
5960
|
+
{ code: "invalid_model_selection" }
|
|
5961
|
+
);
|
|
5962
|
+
}
|
|
5963
|
+
return { id };
|
|
5964
|
+
}
|
|
5866
5965
|
|
|
5867
5966
|
// src/internal/runtime/registry/agent-registry-store.ts
|
|
5868
5967
|
init_cwd_mutex();
|
|
@@ -5939,7 +6038,10 @@ var REGISTRY_RELATIVE_PATH = path.join(".theokit", "agents", "registry.json");
|
|
|
5939
6038
|
function stripSecretsFromOptions(options) {
|
|
5940
6039
|
return assignDefined({
|
|
5941
6040
|
name: options.name,
|
|
5942
|
-
model:
|
|
6041
|
+
model: (() => {
|
|
6042
|
+
const m = normalizeModel(options.model);
|
|
6043
|
+
return m !== void 0 ? { id: m.id } : void 0;
|
|
6044
|
+
})(),
|
|
5943
6045
|
systemPrompt: typeof options.systemPrompt === "string" ? options.systemPrompt : void 0,
|
|
5944
6046
|
local: serializeLocal(options.local),
|
|
5945
6047
|
cloud: serializeCloud(options.cloud),
|
|
@@ -6224,7 +6326,8 @@ function serializeCloudAgentConfig(options) {
|
|
|
6224
6326
|
cloud: serializeCloud2(options.cloud)
|
|
6225
6327
|
};
|
|
6226
6328
|
if (typeof options.agentId === "string") payload.agentId = options.agentId;
|
|
6227
|
-
|
|
6329
|
+
const cfgModel = normalizeModel(options.model);
|
|
6330
|
+
if (cfgModel !== void 0) payload.model = { id: cfgModel.id };
|
|
6228
6331
|
if (typeof options.systemPrompt === "string") payload.systemPrompt = options.systemPrompt;
|
|
6229
6332
|
const skills = serializeSkills(options.skills);
|
|
6230
6333
|
if (skills !== void 0) payload.skills = skills;
|
|
@@ -7029,6 +7132,7 @@ function applyScriptMetrics(base, script) {
|
|
|
7029
7132
|
if (script.cost !== void 0) base.cost = script.cost;
|
|
7030
7133
|
if (script.stoppedAtIterationLimit === true) base.stoppedAtIterationLimit = true;
|
|
7031
7134
|
if (script.stoppedByDoomLoop === true) base.stoppedByDoomLoop = true;
|
|
7135
|
+
if (script.origin !== void 0) base.origin = script.origin;
|
|
7032
7136
|
}
|
|
7033
7137
|
|
|
7034
7138
|
// src/internal/runtime/cloud/cloud-run.ts
|
|
@@ -7384,7 +7488,7 @@ var CloudAgent = class {
|
|
|
7384
7488
|
disposed = false;
|
|
7385
7489
|
constructor(options, providedAgentId) {
|
|
7386
7490
|
this.agentId = providedAgentId ?? options.agentId ?? generateCloudAgentId();
|
|
7387
|
-
this.model = options.model;
|
|
7491
|
+
this.model = normalizeModel(options.model);
|
|
7388
7492
|
this.options = options;
|
|
7389
7493
|
this.cloudPayload = serializeCloudAgentConfig({ ...options, agentId: this.agentId });
|
|
7390
7494
|
const repoUrls = (options.cloud?.repos ?? []).map((repo) => repo.url);
|
|
@@ -7414,6 +7518,17 @@ var CloudAgent = class {
|
|
|
7414
7518
|
const apiKey = resolveApiKey(this.options.apiKey);
|
|
7415
7519
|
return isFixtureApiKey(apiKey) && getConfiguredBaseUrl() === void 0;
|
|
7416
7520
|
}
|
|
7521
|
+
// SE9 — integrated structured output; delegates to the shared helper.
|
|
7522
|
+
generate(message, options) {
|
|
7523
|
+
return agentGenerate(
|
|
7524
|
+
this,
|
|
7525
|
+
this.model,
|
|
7526
|
+
this.options.apiKey,
|
|
7527
|
+
this.options.local,
|
|
7528
|
+
message,
|
|
7529
|
+
options
|
|
7530
|
+
);
|
|
7531
|
+
}
|
|
7417
7532
|
async send(message, options = {}) {
|
|
7418
7533
|
if (options.tools !== void 0 && options.tools.length > 0) {
|
|
7419
7534
|
throw new exports.ConfigurationError(
|
|
@@ -7444,7 +7559,7 @@ var CloudAgent = class {
|
|
|
7444
7559
|
});
|
|
7445
7560
|
}
|
|
7446
7561
|
async sendLocked(message, options) {
|
|
7447
|
-
const overrideModel = options.model;
|
|
7562
|
+
const overrideModel = normalizeModel(options.model);
|
|
7448
7563
|
if (overrideModel !== void 0) {
|
|
7449
7564
|
this.model = overrideModel;
|
|
7450
7565
|
updateRegisteredAgent(this.agentId, { model: overrideModel });
|
|
@@ -8361,18 +8476,18 @@ var ALL_ADAPTERS = [
|
|
|
8361
8476
|
arizeAdapter,
|
|
8362
8477
|
braintrustAdapter
|
|
8363
8478
|
];
|
|
8364
|
-
var
|
|
8479
|
+
var registered2 = /* @__PURE__ */ new Set();
|
|
8365
8480
|
function tryAutoRegisterAdapters(settings) {
|
|
8366
8481
|
if (settings?.enabled !== true) return;
|
|
8367
8482
|
if (settings.autoDetect === false) return;
|
|
8368
8483
|
const disabled = new Set(settings.disable ?? []);
|
|
8369
8484
|
for (const adapter of ALL_ADAPTERS) {
|
|
8370
|
-
if (
|
|
8485
|
+
if (registered2.has(adapter.moduleName)) continue;
|
|
8371
8486
|
if (disabled.has(adapter.displayName.toLowerCase())) continue;
|
|
8372
8487
|
if (!adapter.detect()) continue;
|
|
8373
8488
|
try {
|
|
8374
8489
|
adapter.register();
|
|
8375
|
-
|
|
8490
|
+
registered2.add(adapter.moduleName);
|
|
8376
8491
|
process.stderr.write(`[theokit-sdk] telemetry: ${adapter.displayName} auto-instrumented.
|
|
8377
8492
|
`);
|
|
8378
8493
|
} catch (cause) {
|
|
@@ -8902,6 +9017,26 @@ function paginate(items, opts) {
|
|
|
8902
9017
|
return items.slice(start, end);
|
|
8903
9018
|
}
|
|
8904
9019
|
|
|
9020
|
+
// src/internal/persistence/session-meta.ts
|
|
9021
|
+
function applyMetaPatch(current, patch) {
|
|
9022
|
+
const next = {};
|
|
9023
|
+
if (current.title !== void 0) next.title = current.title;
|
|
9024
|
+
if (current.tag !== void 0) next.tag = current.tag;
|
|
9025
|
+
if (patch.title === null) delete next.title;
|
|
9026
|
+
else if (patch.title !== void 0) next.title = patch.title;
|
|
9027
|
+
if (patch.tag === null) delete next.tag;
|
|
9028
|
+
else if (patch.tag !== void 0) next.tag = patch.tag;
|
|
9029
|
+
return next;
|
|
9030
|
+
}
|
|
9031
|
+
function coerceSessionMeta(raw) {
|
|
9032
|
+
if (typeof raw !== "object" || raw === null) return void 0;
|
|
9033
|
+
const obj = raw;
|
|
9034
|
+
const meta = {};
|
|
9035
|
+
if (typeof obj.title === "string") meta.title = obj.title;
|
|
9036
|
+
if (typeof obj.tag === "string") meta.tag = obj.tag;
|
|
9037
|
+
return meta.title === void 0 && meta.tag === void 0 ? void 0 : meta;
|
|
9038
|
+
}
|
|
9039
|
+
|
|
8905
9040
|
// src/internal/persistence/conversation-storage-fs.ts
|
|
8906
9041
|
var FileSystemConversationStorage = class {
|
|
8907
9042
|
#root;
|
|
@@ -8952,6 +9087,37 @@ var FileSystemConversationStorage = class {
|
|
|
8952
9087
|
async compact(conversationId, maxTurns) {
|
|
8953
9088
|
await compactSessionFile(this.#root, conversationId, maxTurns);
|
|
8954
9089
|
}
|
|
9090
|
+
// SE4 — session metadata persisted as a per-conversation sidecar
|
|
9091
|
+
// `<root>/.theokit/agents/<safeId>/session.json` (same sanitized perimeter as
|
|
9092
|
+
// the transcript). Kept separate from messages.jsonl so a title/tag write does
|
|
9093
|
+
// not rewrite the append-only log.
|
|
9094
|
+
#metaPath(conversationId) {
|
|
9095
|
+
const safe2 = sanitizeIdentifier(conversationId, { maxLen: 128 });
|
|
9096
|
+
return safePathJoin(this.#root, ".theokit", "agents", safe2, "session.json");
|
|
9097
|
+
}
|
|
9098
|
+
async getSessionMeta(conversationId) {
|
|
9099
|
+
try {
|
|
9100
|
+
const raw = await promises.readFile(this.#metaPath(conversationId), "utf8");
|
|
9101
|
+
return coerceSessionMeta(JSON.parse(raw));
|
|
9102
|
+
} catch (cause) {
|
|
9103
|
+
if (cause.code === "ENOENT") return void 0;
|
|
9104
|
+
throw cause;
|
|
9105
|
+
}
|
|
9106
|
+
}
|
|
9107
|
+
async setSessionMeta(conversationId, patch) {
|
|
9108
|
+
const metaPath = this.#metaPath(conversationId);
|
|
9109
|
+
await promises.mkdir(path.dirname(metaPath), { recursive: true });
|
|
9110
|
+
await withFileLock(metaPath, async () => {
|
|
9111
|
+
let current = {};
|
|
9112
|
+
try {
|
|
9113
|
+
current = coerceSessionMeta(JSON.parse(await promises.readFile(metaPath, "utf8"))) ?? {};
|
|
9114
|
+
} catch (cause) {
|
|
9115
|
+
if (cause.code !== "ENOENT") throw cause;
|
|
9116
|
+
}
|
|
9117
|
+
const next = applyMetaPatch(current, patch);
|
|
9118
|
+
await promises.writeFile(metaPath, redactSecrets(JSON.stringify(next)), "utf8");
|
|
9119
|
+
});
|
|
9120
|
+
}
|
|
8955
9121
|
async dispose() {
|
|
8956
9122
|
}
|
|
8957
9123
|
};
|
|
@@ -10803,23 +10969,27 @@ function tryParseSkill(raw, fallbackName, source, options) {
|
|
|
10803
10969
|
|
|
10804
10970
|
// src/internal/runtime/skills/skills-manager.ts
|
|
10805
10971
|
var SkillsManager = class {
|
|
10806
|
-
constructor(cwd, _enabled, settingSourcesIncludeProject) {
|
|
10972
|
+
constructor(cwd, _enabled, settingSourcesIncludeProject, skillsDir, inline) {
|
|
10807
10973
|
this.cwd = cwd;
|
|
10808
10974
|
this.settingSourcesIncludeProject = settingSourcesIncludeProject;
|
|
10975
|
+
this.skillsDir = skillsDir;
|
|
10976
|
+
this.inline = inline;
|
|
10809
10977
|
}
|
|
10810
10978
|
cwd;
|
|
10811
10979
|
settingSourcesIncludeProject;
|
|
10980
|
+
skillsDir;
|
|
10981
|
+
inline;
|
|
10812
10982
|
skills = [];
|
|
10813
10983
|
async initialize() {
|
|
10814
10984
|
if (!this.settingSourcesIncludeProject) {
|
|
10815
|
-
this.skills = [];
|
|
10985
|
+
this.skills = this.mergeInline([]);
|
|
10816
10986
|
return;
|
|
10817
10987
|
}
|
|
10818
10988
|
await this.refresh();
|
|
10819
10989
|
}
|
|
10820
10990
|
async refresh() {
|
|
10821
|
-
const skillsRoot = path.join(this.cwd, ".theokit", "skills");
|
|
10822
|
-
|
|
10991
|
+
const skillsRoot = this.skillsDir ?? path.join(this.cwd, ".theokit", "skills");
|
|
10992
|
+
const discovered = await discoverSkills(skillsRoot, {
|
|
10823
10993
|
onInvalidSkill: (info) => {
|
|
10824
10994
|
process.stderr.write(
|
|
10825
10995
|
`[theokit-sdk] skill ${info.name} skipped (${info.code}): ${info.message}
|
|
@@ -10827,6 +10997,13 @@ var SkillsManager = class {
|
|
|
10827
10997
|
);
|
|
10828
10998
|
}
|
|
10829
10999
|
});
|
|
11000
|
+
this.skills = this.mergeInline(discovered);
|
|
11001
|
+
}
|
|
11002
|
+
/** M22 — merge inline skills over discovered ones; inline wins on a name conflict. */
|
|
11003
|
+
mergeInline(discovered) {
|
|
11004
|
+
if (this.inline === void 0 || this.inline.length === 0) return discovered;
|
|
11005
|
+
const inlineNames = new Set(this.inline.map((s) => s.name));
|
|
11006
|
+
return [...discovered.filter((s) => !inlineNames.has(s.name)), ...this.inline];
|
|
10830
11007
|
}
|
|
10831
11008
|
list() {
|
|
10832
11009
|
return Promise.resolve(this.skills);
|
|
@@ -10862,7 +11039,7 @@ function bootstrapSubmanagers(args) {
|
|
|
10862
11039
|
const providerCount = (args.options.providers?.routes?.length ?? 0) + enabledPluginNames(args.options.plugins).length;
|
|
10863
11040
|
if (providerCount > 0 || args.options.providers !== void 0) {
|
|
10864
11041
|
out.providers = new ProvidersManagerImpl(
|
|
10865
|
-
args.options.model,
|
|
11042
|
+
normalizeModel(args.options.model),
|
|
10866
11043
|
args.options.providers,
|
|
10867
11044
|
args.options.plugins
|
|
10868
11045
|
);
|
|
@@ -10871,7 +11048,10 @@ function bootstrapSubmanagers(args) {
|
|
|
10871
11048
|
out.skillsManager = new SkillsManager(
|
|
10872
11049
|
args.workspaceCwd,
|
|
10873
11050
|
args.options.skills?.enabled,
|
|
10874
|
-
args.settingSourcesIncludeProject
|
|
11051
|
+
args.settingSourcesIncludeProject,
|
|
11052
|
+
// M22 — custom skills directory + inline (code-defined) skills.
|
|
11053
|
+
args.options.skills?.skillsDir,
|
|
11054
|
+
args.options.skills?.inline
|
|
10875
11055
|
);
|
|
10876
11056
|
const localSkills = out.skillsManager;
|
|
10877
11057
|
out.skills = { list: () => localSkills.list() };
|
|
@@ -10929,6 +11109,7 @@ function createLocalRun(options) {
|
|
|
10929
11109
|
projectMcpServers: options.projectMcpServers,
|
|
10930
11110
|
...options.persistMemoryFact !== void 0 ? { persistMemoryFact: options.persistMemoryFact } : {}
|
|
10931
11111
|
});
|
|
11112
|
+
if (options.sendOptions.origin !== void 0) script.origin = options.sendOptions.origin;
|
|
10932
11113
|
const handle = new LocalRun({
|
|
10933
11114
|
id,
|
|
10934
11115
|
agentId: options.agentId,
|
|
@@ -11577,6 +11758,15 @@ async function emitReasoningDeltaCallback(inputs, text) {
|
|
|
11577
11758
|
);
|
|
11578
11759
|
}
|
|
11579
11760
|
|
|
11761
|
+
// src/types/run-events.ts
|
|
11762
|
+
function emitRunEvent(sink, event) {
|
|
11763
|
+
if (sink === void 0) return;
|
|
11764
|
+
try {
|
|
11765
|
+
sink(event);
|
|
11766
|
+
} catch {
|
|
11767
|
+
}
|
|
11768
|
+
}
|
|
11769
|
+
|
|
11580
11770
|
// src/internal/agent-loop/tool-dispatch.ts
|
|
11581
11771
|
init_async_local_storage();
|
|
11582
11772
|
|
|
@@ -11674,6 +11864,22 @@ function coerceArgsToSchema(args, schema) {
|
|
|
11674
11864
|
return { value: out, changed };
|
|
11675
11865
|
}
|
|
11676
11866
|
|
|
11867
|
+
// src/tool-error.ts
|
|
11868
|
+
init_errors();
|
|
11869
|
+
var ToolError = class extends exports.TheokitAgentError {
|
|
11870
|
+
name = "ToolError";
|
|
11871
|
+
/** The error content surfaced to the model: a string, or text/image blocks. */
|
|
11872
|
+
content;
|
|
11873
|
+
constructor(content, options = {}) {
|
|
11874
|
+
super(renderToolErrorMessage(content), { ...options, isRetryable: false });
|
|
11875
|
+
this.content = content;
|
|
11876
|
+
}
|
|
11877
|
+
};
|
|
11878
|
+
function renderToolErrorMessage(content) {
|
|
11879
|
+
if (typeof content === "string") return content;
|
|
11880
|
+
return content.map((block) => block.type === "text" ? block.text : `[${block.source.media_type} image]`).join("\n");
|
|
11881
|
+
}
|
|
11882
|
+
|
|
11677
11883
|
// src/internal/runtime/tools/shell-tool.ts
|
|
11678
11884
|
async function runShell(options) {
|
|
11679
11885
|
if (options.sandbox === true && isObviouslyUnsafe(options.command)) {
|
|
@@ -11727,9 +11933,13 @@ async function runHandlerTool(kind, handler, call, signal, context) {
|
|
|
11727
11933
|
return { stdout: "", stderr: `${kind} tool ${call.name} has no handler`, exitCode: 127 };
|
|
11728
11934
|
}
|
|
11729
11935
|
try {
|
|
11730
|
-
const
|
|
11731
|
-
return { stdout, stderr: "", exitCode: 0 };
|
|
11936
|
+
const out = await handler(call.input, { signal, context });
|
|
11937
|
+
if (typeof out !== "string") return { stdout: "", stderr: "", exitCode: 0, content: out };
|
|
11938
|
+
return { stdout: out, stderr: "", exitCode: 0 };
|
|
11732
11939
|
} catch (cause) {
|
|
11940
|
+
if (cause instanceof ToolError) {
|
|
11941
|
+
return { stdout: "", stderr: cause.message, exitCode: 1, content: cause.content };
|
|
11942
|
+
}
|
|
11733
11943
|
const message = cause instanceof Error ? cause.message : String(cause);
|
|
11734
11944
|
return { stdout: "", stderr: message, exitCode: 1 };
|
|
11735
11945
|
}
|
|
@@ -11848,6 +12058,11 @@ async function dispatchSingleCall(inputs, tools, call, events, parentSpan) {
|
|
|
11848
12058
|
toolSpan?.end();
|
|
11849
12059
|
return fileVeto;
|
|
11850
12060
|
}
|
|
12061
|
+
emitRunEvent(inputs.runEventSink, {
|
|
12062
|
+
type: "tool_progress",
|
|
12063
|
+
toolName: workingCall.name,
|
|
12064
|
+
toolCallId: callId
|
|
12065
|
+
});
|
|
11851
12066
|
const result = await runToolWithLifecycle(inputs, resolved, workingCall, callId);
|
|
11852
12067
|
await inputs.pluginManager?.runPostToolCallHooks({
|
|
11853
12068
|
name: workingCall.name,
|
|
@@ -11874,6 +12089,13 @@ function applyRepairAndExtractCall(tools, call) {
|
|
|
11874
12089
|
function vetoFromForkWhitelist(inputs, call, callId, events) {
|
|
11875
12090
|
const whitelistDecision = checkToolWhitelist(call.name);
|
|
11876
12091
|
if (whitelistDecision.allowed) return void 0;
|
|
12092
|
+
emitRunEvent(inputs.runEventSink, {
|
|
12093
|
+
type: "permission_denied",
|
|
12094
|
+
toolName: call.name,
|
|
12095
|
+
toolCallId: callId,
|
|
12096
|
+
source: "fork_whitelist",
|
|
12097
|
+
message: whitelistDecision.reason ?? "tool not available in fork"
|
|
12098
|
+
});
|
|
11877
12099
|
events.push(buildToolUseRunning(inputs, callId, call));
|
|
11878
12100
|
events.push(
|
|
11879
12101
|
buildToolUseCompleted(inputs, callId, call, {
|
|
@@ -11910,6 +12132,13 @@ async function vetoFromPluginPreHook(inputs, call, callId, events) {
|
|
|
11910
12132
|
runId: inputs.runId
|
|
11911
12133
|
});
|
|
11912
12134
|
if (pluginVeto === void 0) return void 0;
|
|
12135
|
+
emitRunEvent(inputs.runEventSink, {
|
|
12136
|
+
type: "permission_denied",
|
|
12137
|
+
toolName: call.name,
|
|
12138
|
+
toolCallId: callId,
|
|
12139
|
+
source: "plugin",
|
|
12140
|
+
message: pluginVeto.message
|
|
12141
|
+
});
|
|
11913
12142
|
events.push(
|
|
11914
12143
|
buildToolUseCompleted(inputs, callId, call, {
|
|
11915
12144
|
stdout: "",
|
|
@@ -11932,6 +12161,13 @@ async function vetoFromFileHookPreDecision(inputs, call, callId, events) {
|
|
|
11932
12161
|
runId: inputs.runId
|
|
11933
12162
|
});
|
|
11934
12163
|
if (!preDecision.blocked) return void 0;
|
|
12164
|
+
emitRunEvent(inputs.runEventSink, {
|
|
12165
|
+
type: "permission_denied",
|
|
12166
|
+
toolName: call.name,
|
|
12167
|
+
toolCallId: callId,
|
|
12168
|
+
source: "file_hook",
|
|
12169
|
+
message: preDecision.reason ?? "blocked by hook"
|
|
12170
|
+
});
|
|
11935
12171
|
events.push(
|
|
11936
12172
|
buildToolUseCompleted(inputs, callId, call, {
|
|
11937
12173
|
stdout: "",
|
|
@@ -11975,7 +12211,9 @@ async function runToolWithLifecycle(inputs, resolved, call, callId) {
|
|
|
11975
12211
|
await safeEmitToolHook(inputs.onToolEnd, {
|
|
11976
12212
|
toolName: call.name,
|
|
11977
12213
|
args: call.input,
|
|
11978
|
-
|
|
12214
|
+
// SE7 — a block-returning handler has empty `stdout`; surface its structured
|
|
12215
|
+
// content to the hook instead of an empty string.
|
|
12216
|
+
result: result.content !== void 0 ? result.content : result.stdout,
|
|
11979
12217
|
conversationId: inputs.agentId,
|
|
11980
12218
|
callId,
|
|
11981
12219
|
durationMs
|
|
@@ -11997,7 +12235,10 @@ function finalizeSpanAndPostHook(inputs, call, callId, result, events, toolSpan)
|
|
|
11997
12235
|
output: {
|
|
11998
12236
|
stdout: result.stdout,
|
|
11999
12237
|
stderr: result.stderr,
|
|
12000
|
-
exitCode: result.exitCode ?? 0
|
|
12238
|
+
exitCode: result.exitCode ?? 0,
|
|
12239
|
+
// SE7 — structured content (text + image blocks) when the handler
|
|
12240
|
+
// returned/threw blocks; absent for the string path.
|
|
12241
|
+
...result.content !== void 0 ? { content: result.content } : {}
|
|
12001
12242
|
},
|
|
12002
12243
|
agentId: inputs.agentId,
|
|
12003
12244
|
runId: inputs.runId
|
|
@@ -12010,7 +12251,9 @@ function finalizeSpanAndPostHook(inputs, call, callId, result, events, toolSpan)
|
|
|
12010
12251
|
return {
|
|
12011
12252
|
type: "tool_result",
|
|
12012
12253
|
toolUseId: call.id,
|
|
12013
|
-
content
|
|
12254
|
+
// SE7 — structured content blocks (handler-returned or ToolError-carried)
|
|
12255
|
+
// are authoritative; otherwise the legacy string rendering.
|
|
12256
|
+
content: result.content !== void 0 ? result.content : renderToolResult(result),
|
|
12014
12257
|
...result.exitCode !== 0 && result.exitCode !== void 0 ? { isError: true } : {}
|
|
12015
12258
|
};
|
|
12016
12259
|
}
|
|
@@ -12059,6 +12302,29 @@ function buildToolUseCompleted(inputs, callId, call, result) {
|
|
|
12059
12302
|
};
|
|
12060
12303
|
}
|
|
12061
12304
|
|
|
12305
|
+
// src/internal/llm/tool-result-content.ts
|
|
12306
|
+
init_errors();
|
|
12307
|
+
function toBlockToolResultContent(content) {
|
|
12308
|
+
return content;
|
|
12309
|
+
}
|
|
12310
|
+
function toStringToolResultContent(content, providerName) {
|
|
12311
|
+
if (typeof content === "string") return content;
|
|
12312
|
+
if (content.some((block) => block.type === "image")) {
|
|
12313
|
+
throw new exports.ConfigurationError(
|
|
12314
|
+
`provider "${providerName}" does not support image content in tool results`
|
|
12315
|
+
);
|
|
12316
|
+
}
|
|
12317
|
+
return content.filter(
|
|
12318
|
+
(block) => block.type === "text"
|
|
12319
|
+
).map((block) => block.text).join("\n");
|
|
12320
|
+
}
|
|
12321
|
+
function renderToolResultContentText(content, fn) {
|
|
12322
|
+
if (typeof content === "string") return fn(content);
|
|
12323
|
+
return content.map(
|
|
12324
|
+
(block) => block.type === "text" ? { type: "text", text: fn(block.text) } : block
|
|
12325
|
+
);
|
|
12326
|
+
}
|
|
12327
|
+
|
|
12062
12328
|
// src/internal/agent-loop/tool-result-guard.ts
|
|
12063
12329
|
var OPEN = "<untrusted-tool-output>";
|
|
12064
12330
|
var CLOSE = "</untrusted-tool-output>";
|
|
@@ -12084,7 +12350,11 @@ ${CLOSE}`;
|
|
|
12084
12350
|
function applyToolResultGuard(parts, opts) {
|
|
12085
12351
|
if (opts.delimit !== true && opts.redactPii !== true) return parts;
|
|
12086
12352
|
return parts.map(
|
|
12087
|
-
(p) =>
|
|
12353
|
+
(p) => (
|
|
12354
|
+
// SE7 — guard the TEXT of a tool result (string or the text blocks of a
|
|
12355
|
+
// structured content); image blocks pass through untouched.
|
|
12356
|
+
p.type === "tool_result" ? { ...p, content: renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
|
|
12357
|
+
)
|
|
12088
12358
|
);
|
|
12089
12359
|
}
|
|
12090
12360
|
|
|
@@ -13015,10 +13285,10 @@ function stripVertexPrefix(modelId) {
|
|
|
13015
13285
|
}
|
|
13016
13286
|
|
|
13017
13287
|
// src/internal/providers/builtin/index.ts
|
|
13018
|
-
var
|
|
13288
|
+
var registered3 = false;
|
|
13019
13289
|
function registerBuiltins() {
|
|
13020
|
-
if (
|
|
13021
|
-
|
|
13290
|
+
if (registered3) return;
|
|
13291
|
+
registered3 = true;
|
|
13022
13292
|
registerProvider(ANTHROPIC);
|
|
13023
13293
|
registerProvider(OPENAI);
|
|
13024
13294
|
registerProvider(OPENROUTER);
|
|
@@ -13247,7 +13517,9 @@ function toAnthropicWireMessage(message) {
|
|
|
13247
13517
|
return {
|
|
13248
13518
|
type: "tool_result",
|
|
13249
13519
|
tool_use_id: part.toolUseId,
|
|
13250
|
-
|
|
13520
|
+
// SE7 — this wire is block-capable: strings pass through, structured
|
|
13521
|
+
// text/image blocks are forwarded natively.
|
|
13522
|
+
content: toBlockToolResultContent(part.content),
|
|
13251
13523
|
...part.isError === true ? { is_error: true } : {}
|
|
13252
13524
|
};
|
|
13253
13525
|
});
|
|
@@ -14039,7 +14311,8 @@ function toOllamaMessages(message) {
|
|
|
14039
14311
|
if (part.type === "tool_result") {
|
|
14040
14312
|
out.push({
|
|
14041
14313
|
role: "tool",
|
|
14042
|
-
|
|
14314
|
+
// SE7 — string-only tool role: text blocks flatten; image fails fast.
|
|
14315
|
+
content: toStringToolResultContent(part.content, "ollama"),
|
|
14043
14316
|
tool_name: part.toolUseId
|
|
14044
14317
|
});
|
|
14045
14318
|
}
|
|
@@ -14576,7 +14849,9 @@ function userOrToolMessages(message) {
|
|
|
14576
14849
|
out.push({
|
|
14577
14850
|
role: "tool",
|
|
14578
14851
|
tool_call_id: part.toolUseId,
|
|
14579
|
-
|
|
14852
|
+
// SE7 — this wire's tool role is string-only: text blocks flatten; an
|
|
14853
|
+
// image block fails fast (ConfigurationError).
|
|
14854
|
+
content: toStringToolResultContent(part.content, "openai")
|
|
14580
14855
|
});
|
|
14581
14856
|
}
|
|
14582
14857
|
}
|
|
@@ -15506,18 +15781,20 @@ function levenshtein(a, b) {
|
|
|
15506
15781
|
function createRealLocalRun(options) {
|
|
15507
15782
|
const { userText, id, startTime } = prepareRunContext(options.message);
|
|
15508
15783
|
const supported = /* @__PURE__ */ new Set(["stream", "wait", "cancel", "conversation"]);
|
|
15509
|
-
const
|
|
15784
|
+
const runScript = {
|
|
15510
15785
|
events: [],
|
|
15511
15786
|
finalStatus: "running",
|
|
15512
15787
|
cancellable: false,
|
|
15513
|
-
conversation: []
|
|
15788
|
+
conversation: [],
|
|
15789
|
+
// SE3 — carry the turn's provenance so buildResult forwards it onto RunResult.origin.
|
|
15790
|
+
...options.sendOptions.origin !== void 0 ? { origin: options.sendOptions.origin } : {}
|
|
15514
15791
|
};
|
|
15515
15792
|
const handle = new RealLocalRun(
|
|
15516
15793
|
{
|
|
15517
15794
|
id,
|
|
15518
15795
|
agentId: options.agentId,
|
|
15519
15796
|
model: options.model,
|
|
15520
|
-
script:
|
|
15797
|
+
script: runScript,
|
|
15521
15798
|
supportedOps: supported,
|
|
15522
15799
|
startTime
|
|
15523
15800
|
},
|
|
@@ -15629,6 +15906,8 @@ function buildLoopInputs(options, runId, userText) {
|
|
|
15629
15906
|
// M7 — forward SendOptions.context to the loop so every tool handler receives
|
|
15630
15907
|
// it on `ctx.context` (shared run config set once, e.g. projectRoot).
|
|
15631
15908
|
...options.sendOptions.context !== void 0 ? { context: options.sendOptions.context } : {},
|
|
15909
|
+
// SE2 — forward the opt-in typed runtime-event sink to the loop.
|
|
15910
|
+
...options.sendOptions.onRunEvent !== void 0 ? { runEventSink: options.sendOptions.onRunEvent } : {},
|
|
15632
15911
|
// #58 / #57 — forward the per-tool timeout + tool-result guard so a consumer
|
|
15633
15912
|
// can enable them via SendOptions (not only internal AgentLoopInputs).
|
|
15634
15913
|
...options.sendOptions.perToolTimeoutMs !== void 0 ? { perToolTimeoutMs: options.sendOptions.perToolTimeoutMs } : {},
|
|
@@ -17373,7 +17652,7 @@ function wrapRunWithPostReplyHook(args) {
|
|
|
17373
17652
|
async function executeSendLocked(inputs, message, options) {
|
|
17374
17653
|
if (inputs.disposed) throw new exports.AgentDisposedError(inputs.agentId);
|
|
17375
17654
|
await consumePending(inputs.agentId, inputs.invalidationPending, inputs.clearInvalidation, inputs.reload);
|
|
17376
|
-
inputs.applyModelOverride(options.model);
|
|
17655
|
+
inputs.applyModelOverride(normalizeModel(options.model));
|
|
17377
17656
|
const userText = typeof message === "string" ? message : message.text;
|
|
17378
17657
|
if (inputs.options.onBeforeSend !== void 0) {
|
|
17379
17658
|
await inputs.options.onBeforeSend({
|
|
@@ -17525,7 +17804,7 @@ var LocalAgent = class {
|
|
|
17525
17804
|
constructor(options) {
|
|
17526
17805
|
this.agentId = options.agentId ?? generateLocalAgentId();
|
|
17527
17806
|
this._telemetry = createTelemetry(options.telemetry);
|
|
17528
|
-
this.model = options.model;
|
|
17807
|
+
this.model = normalizeModel(options.model);
|
|
17529
17808
|
this.options = options;
|
|
17530
17809
|
this.workspaceCwd = resolveCwd(options.local?.cwd);
|
|
17531
17810
|
this.conversationStorage = options.conversationStorage;
|
|
@@ -17592,6 +17871,11 @@ var LocalAgent = class {
|
|
|
17592
17871
|
hooks() {
|
|
17593
17872
|
return this.hooksExecutor;
|
|
17594
17873
|
}
|
|
17874
|
+
// SE9 — integrated structured output; delegates to the shared helper.
|
|
17875
|
+
generate(message, options) {
|
|
17876
|
+
const { apiKey, local } = this.options;
|
|
17877
|
+
return agentGenerate(this, this.model, apiKey, local, message, options);
|
|
17878
|
+
}
|
|
17595
17879
|
async send(message, options = {}) {
|
|
17596
17880
|
if (options.tools !== void 0 && options.tools.length > 0) {
|
|
17597
17881
|
validateToolCatalog(options.tools);
|
|
@@ -17831,6 +18115,7 @@ function includesSetting(options, source) {
|
|
|
17831
18115
|
|
|
17832
18116
|
// src/agent-helpers.ts
|
|
17833
18117
|
async function runCreateUnderSpan(options, span) {
|
|
18118
|
+
options = { ...options, model: normalizeModel(options.model) };
|
|
17834
18119
|
validateAgentOptions(options);
|
|
17835
18120
|
validateCloudToolParity(options);
|
|
17836
18121
|
await guardAgainstIdCollision(options);
|
|
@@ -17904,7 +18189,10 @@ async function createLocalAgent(options) {
|
|
|
17904
18189
|
const willFlowToProvider = !isFixtureApiKey(apiKey) && !shouldUseRealLocalRuntime(apiKey);
|
|
17905
18190
|
const shape = validateApiKeyShape(apiKey, {
|
|
17906
18191
|
strict: willFlowToProvider,
|
|
17907
|
-
|
|
18192
|
+
// `options.model` is already normalized by `runCreateUnderSpan`; `normalizeModel`
|
|
18193
|
+
// here is the idempotent narrowing of the widened public type (`{id}` passes
|
|
18194
|
+
// through by reference) — cleaner than an `as` cast.
|
|
18195
|
+
...willFlowToProvider ? { provider: providerFromModelId(normalizeModel(options.model)?.id) } : {}
|
|
17908
18196
|
});
|
|
17909
18197
|
if (shape.malformed) {
|
|
17910
18198
|
throw new exports.AuthenticationError(shape.message, { code: "malformed_api_key" });
|
|
@@ -17970,6 +18258,10 @@ async function rehydrateExistingAgent(agentId, existing, options) {
|
|
|
17970
18258
|
...existing.options,
|
|
17971
18259
|
...options,
|
|
17972
18260
|
...mergedLocal !== void 0 ? { local: mergedLocal } : {},
|
|
18261
|
+
// SE8 — normalize a caller-supplied bare-string model override at this resume
|
|
18262
|
+
// boundary (Agent.resume never flows through runCreateUnderSpan). Cloud resume
|
|
18263
|
+
// honors it; local resume forces the persisted model below.
|
|
18264
|
+
model: normalizeModel(options.model ?? existing.options.model),
|
|
17973
18265
|
mcpServers: void 0,
|
|
17974
18266
|
agentId
|
|
17975
18267
|
};
|
|
@@ -18336,6 +18628,7 @@ async function getOrCreateUncached(agentId, options) {
|
|
|
18336
18628
|
}
|
|
18337
18629
|
setAgentFacade({
|
|
18338
18630
|
create: (options) => Agent.create(options),
|
|
18631
|
+
delete: (agentId) => Agent.delete(agentId),
|
|
18339
18632
|
prompt: (message, options) => Agent.prompt(message, options),
|
|
18340
18633
|
get: (agentId) => Agent.get(agentId),
|
|
18341
18634
|
resume: (agentId, options) => Agent.resume(agentId, options),
|
|
@@ -18773,6 +19066,20 @@ var Budget = class {
|
|
|
18773
19066
|
}
|
|
18774
19067
|
};
|
|
18775
19068
|
|
|
19069
|
+
// src/create-skill.ts
|
|
19070
|
+
function createSkill(spec) {
|
|
19071
|
+
if (!spec.name) throw new Error("createSkill: `name` is required.");
|
|
19072
|
+
if (!spec.description) throw new Error("createSkill: `description` is required.");
|
|
19073
|
+
return {
|
|
19074
|
+
name: spec.name,
|
|
19075
|
+
description: spec.description,
|
|
19076
|
+
source: `inline://${spec.name}`,
|
|
19077
|
+
instructions: spec.instructions,
|
|
19078
|
+
...spec.category !== void 0 ? { category: spec.category } : {},
|
|
19079
|
+
...spec.dependencies !== void 0 ? { dependencies: spec.dependencies } : {}
|
|
19080
|
+
};
|
|
19081
|
+
}
|
|
19082
|
+
|
|
18776
19083
|
// src/cron.ts
|
|
18777
19084
|
init_errors();
|
|
18778
19085
|
|
|
@@ -19282,6 +19589,8 @@ init_generate_object();
|
|
|
19282
19589
|
// src/internal/persistence/conversation-storage-memory.ts
|
|
19283
19590
|
var InMemoryConversationStorage = class {
|
|
19284
19591
|
#store = /* @__PURE__ */ new Map();
|
|
19592
|
+
// SE4 — session-level metadata (title/tag), kept beside the transcript.
|
|
19593
|
+
#meta = /* @__PURE__ */ new Map();
|
|
19285
19594
|
async getMessages(conversationId, opts) {
|
|
19286
19595
|
const existing = this.#store.get(conversationId);
|
|
19287
19596
|
return existing === void 0 ? [] : paginate(existing.slice(), opts);
|
|
@@ -19310,15 +19619,20 @@ var InMemoryConversationStorage = class {
|
|
|
19310
19619
|
}
|
|
19311
19620
|
async deleteConversation(conversationId) {
|
|
19312
19621
|
this.#store.delete(conversationId);
|
|
19622
|
+
this.#meta.delete(conversationId);
|
|
19313
19623
|
}
|
|
19314
19624
|
async deleteScope(prefix) {
|
|
19315
19625
|
let n = 0;
|
|
19316
19626
|
for (const id of [...this.#store.keys()]) {
|
|
19317
19627
|
if (id.startsWith(prefix)) {
|
|
19318
19628
|
this.#store.delete(id);
|
|
19629
|
+
this.#meta.delete(id);
|
|
19319
19630
|
n += 1;
|
|
19320
19631
|
}
|
|
19321
19632
|
}
|
|
19633
|
+
for (const id of [...this.#meta.keys()]) {
|
|
19634
|
+
if (id.startsWith(prefix)) this.#meta.delete(id);
|
|
19635
|
+
}
|
|
19322
19636
|
return n;
|
|
19323
19637
|
}
|
|
19324
19638
|
async listConversationIds(opts) {
|
|
@@ -19326,8 +19640,17 @@ var InMemoryConversationStorage = class {
|
|
|
19326
19640
|
if (opts?.limit !== void 0) return all.slice(0, opts.limit);
|
|
19327
19641
|
return all;
|
|
19328
19642
|
}
|
|
19643
|
+
async getSessionMeta(conversationId) {
|
|
19644
|
+
const meta = this.#meta.get(conversationId);
|
|
19645
|
+
return meta === void 0 ? void 0 : { ...meta };
|
|
19646
|
+
}
|
|
19647
|
+
async setSessionMeta(conversationId, patch) {
|
|
19648
|
+
const current = this.#meta.get(conversationId) ?? {};
|
|
19649
|
+
this.#meta.set(conversationId, applyMetaPatch(current, patch));
|
|
19650
|
+
}
|
|
19329
19651
|
async dispose() {
|
|
19330
19652
|
this.#store.clear();
|
|
19653
|
+
this.#meta.clear();
|
|
19331
19654
|
}
|
|
19332
19655
|
};
|
|
19333
19656
|
|
|
@@ -20067,6 +20390,21 @@ async function migrateSqliteToLance2(options) {
|
|
|
20067
20390
|
}
|
|
20068
20391
|
|
|
20069
20392
|
// src/permission-engine.ts
|
|
20393
|
+
function applyMode(verdict, mode, explicit) {
|
|
20394
|
+
if (verdict === "deny") return "deny";
|
|
20395
|
+
switch (mode) {
|
|
20396
|
+
case "default":
|
|
20397
|
+
return verdict;
|
|
20398
|
+
case "plan":
|
|
20399
|
+
return verdict === "allow" ? "allow" : "deny";
|
|
20400
|
+
case "acceptEdits":
|
|
20401
|
+
if (verdict === "ask") return explicit ? "ask" : "allow";
|
|
20402
|
+
return verdict;
|
|
20403
|
+
// allow stays allow
|
|
20404
|
+
case "bypass":
|
|
20405
|
+
return "allow";
|
|
20406
|
+
}
|
|
20407
|
+
}
|
|
20070
20408
|
function argMatches(matcher, value) {
|
|
20071
20409
|
if (typeof matcher === "function") return matcher(value);
|
|
20072
20410
|
if (value === void 0) return false;
|
|
@@ -20087,14 +20425,14 @@ var PermissionEngine = class {
|
|
|
20087
20425
|
* argument values, so the same tool name can resolve to different actions
|
|
20088
20426
|
* depending on what it is asked to do.
|
|
20089
20427
|
*/
|
|
20090
|
-
evaluate(toolName, args) {
|
|
20428
|
+
evaluate(toolName, args, mode = "default") {
|
|
20091
20429
|
for (const rule of this.rules) {
|
|
20092
20430
|
const nameMatches = typeof rule.tool === "string" ? rule.tool === toolName : rule.tool.test(toolName);
|
|
20093
20431
|
if (!nameMatches) continue;
|
|
20094
20432
|
if (rule.args !== void 0 && !this.#argsMatch(rule.args, args)) continue;
|
|
20095
|
-
return rule.action;
|
|
20433
|
+
return applyMode(rule.action, mode, true);
|
|
20096
20434
|
}
|
|
20097
|
-
return this.defaultAction;
|
|
20435
|
+
return applyMode(this.defaultAction, mode, false);
|
|
20098
20436
|
}
|
|
20099
20437
|
#argsMatch(matchers, args) {
|
|
20100
20438
|
const call = args ?? {};
|
|
@@ -20106,27 +20444,85 @@ var PermissionEngine = class {
|
|
|
20106
20444
|
};
|
|
20107
20445
|
|
|
20108
20446
|
// src/permission-plugin.ts
|
|
20447
|
+
async function resolveAsk(opts, name, args, mode) {
|
|
20448
|
+
if (opts.canUseTool !== void 0) {
|
|
20449
|
+
let decision;
|
|
20450
|
+
try {
|
|
20451
|
+
decision = await opts.canUseTool(name, args, { toolName: name, mode });
|
|
20452
|
+
} catch {
|
|
20453
|
+
return { block: true, message: `permission gate error (fail-closed): ${name}` };
|
|
20454
|
+
}
|
|
20455
|
+
return decision.behavior === "deny" ? { block: true, message: decision.message ?? `denied: ${name}` } : void 0;
|
|
20456
|
+
}
|
|
20457
|
+
return opts.onAsk ? opts.onAsk(name) : { block: true, message: `requires approval: ${name}` };
|
|
20458
|
+
}
|
|
20109
20459
|
function createPermissionPlugin(engine, opts = {}) {
|
|
20460
|
+
const mode = opts.mode ?? "default";
|
|
20110
20461
|
return definePlugin({
|
|
20111
20462
|
name: opts.name ?? "permission-engine",
|
|
20112
20463
|
version: "1.0.0",
|
|
20113
20464
|
kind: "general",
|
|
20114
20465
|
register(ctx) {
|
|
20115
|
-
ctx.on("pre_tool_call", (rawCtx) => {
|
|
20466
|
+
ctx.on("pre_tool_call", async (rawCtx) => {
|
|
20116
20467
|
const { name, args } = rawCtx;
|
|
20117
|
-
const action = engine.evaluate(name, args);
|
|
20468
|
+
const action = engine.evaluate(name, args, mode);
|
|
20118
20469
|
if (action === "deny") {
|
|
20119
20470
|
return { block: true, message: `denied by permission engine: ${name}` };
|
|
20120
20471
|
}
|
|
20121
|
-
if (action === "ask")
|
|
20122
|
-
return opts.onAsk ? opts.onAsk(name) : { block: true, message: `requires approval: ${name}` };
|
|
20123
|
-
}
|
|
20472
|
+
if (action === "ask") return resolveAsk(opts, name, args, mode);
|
|
20124
20473
|
return void 0;
|
|
20125
20474
|
});
|
|
20126
20475
|
}
|
|
20127
20476
|
});
|
|
20128
20477
|
}
|
|
20129
20478
|
|
|
20479
|
+
// src/schema-normalizer.ts
|
|
20480
|
+
init_to_json_schema();
|
|
20481
|
+
function isJsonSchemaObject(s) {
|
|
20482
|
+
if (typeof s !== "object" || s === null) return false;
|
|
20483
|
+
const o = s;
|
|
20484
|
+
if ("$schema" in o) return true;
|
|
20485
|
+
return o.type === "object" && typeof o.properties === "object" && o.properties !== null;
|
|
20486
|
+
}
|
|
20487
|
+
function hasToJsonSchemaMethod(s) {
|
|
20488
|
+
return typeof s === "object" && s !== null && typeof s.toJsonSchema === "function";
|
|
20489
|
+
}
|
|
20490
|
+
function isZodSchema(s) {
|
|
20491
|
+
if (typeof s !== "object" || s === null) return false;
|
|
20492
|
+
const o = s;
|
|
20493
|
+
return typeof o.safeParse === "function" && ("_def" in o || "def" in o);
|
|
20494
|
+
}
|
|
20495
|
+
function isValibotSchema(s) {
|
|
20496
|
+
if (typeof s !== "object" || s === null) return false;
|
|
20497
|
+
const o = s;
|
|
20498
|
+
return o.kind === "schema" && "type" in o && typeof o.toJsonSchema !== "function";
|
|
20499
|
+
}
|
|
20500
|
+
async function normalizeSchema(schema) {
|
|
20501
|
+
if (isJsonSchemaObject(schema)) return schema;
|
|
20502
|
+
if (isValibotSchema(schema)) {
|
|
20503
|
+
const specifier = "@valibot/to-json-schema";
|
|
20504
|
+
try {
|
|
20505
|
+
const mod = await import(specifier);
|
|
20506
|
+
return mod.toJsonSchema(schema);
|
|
20507
|
+
} catch (err) {
|
|
20508
|
+
const missing = err instanceof Error && /Cannot find|Cannot resolve|ERR_MODULE_NOT_FOUND/.test(err.message);
|
|
20509
|
+
if (missing) {
|
|
20510
|
+
throw new Error(
|
|
20511
|
+
"normalizeSchema: a Valibot schema requires the optional '@valibot/to-json-schema' package. Install it, or use a Zod schema (the default recommendation)."
|
|
20512
|
+
);
|
|
20513
|
+
}
|
|
20514
|
+
throw err;
|
|
20515
|
+
}
|
|
20516
|
+
}
|
|
20517
|
+
if (isZodSchema(schema)) {
|
|
20518
|
+
return toJsonSchema(schema, { unrepresentable: "any" });
|
|
20519
|
+
}
|
|
20520
|
+
if (hasToJsonSchemaMethod(schema)) return schema.toJsonSchema();
|
|
20521
|
+
throw new Error(
|
|
20522
|
+
"normalizeSchema: unsupported schema. Supported: Zod (default), JSON Schema, ArkType (.toJsonSchema()), Valibot (with @valibot/to-json-schema)."
|
|
20523
|
+
);
|
|
20524
|
+
}
|
|
20525
|
+
|
|
20130
20526
|
// src/security.ts
|
|
20131
20527
|
init_security();
|
|
20132
20528
|
var Security = class {
|
|
@@ -20179,6 +20575,96 @@ var Security = class {
|
|
|
20179
20575
|
}
|
|
20180
20576
|
};
|
|
20181
20577
|
|
|
20578
|
+
// src/session-manager.ts
|
|
20579
|
+
var SUMMARY_PREVIEW_MAX = 80;
|
|
20580
|
+
function createSessionManager(storage2) {
|
|
20581
|
+
return {
|
|
20582
|
+
async listSessions(opts) {
|
|
20583
|
+
if (typeof storage2.listConversationIds !== "function") {
|
|
20584
|
+
return {
|
|
20585
|
+
supported: false,
|
|
20586
|
+
reason: "storage adapter does not support listing conversations (listConversationIds)"
|
|
20587
|
+
};
|
|
20588
|
+
}
|
|
20589
|
+
const ids = await storage2.listConversationIds();
|
|
20590
|
+
if (ids === void 0) {
|
|
20591
|
+
return {
|
|
20592
|
+
supported: false,
|
|
20593
|
+
reason: "storage adapter reported listing as unsupported (listConversationIds \u2192 undefined)"
|
|
20594
|
+
};
|
|
20595
|
+
}
|
|
20596
|
+
const windowed = windowIds(ids, opts);
|
|
20597
|
+
const summaries = [];
|
|
20598
|
+
for (const id of windowed) {
|
|
20599
|
+
summaries.push(await buildSummary(storage2, id));
|
|
20600
|
+
}
|
|
20601
|
+
return { supported: true, value: summaries };
|
|
20602
|
+
},
|
|
20603
|
+
getSessionMessages(id, opts) {
|
|
20604
|
+
return storage2.getMessages(id, opts);
|
|
20605
|
+
},
|
|
20606
|
+
async renameSession(id, title) {
|
|
20607
|
+
if (typeof storage2.setSessionMeta !== "function") {
|
|
20608
|
+
return unsupportedWrite();
|
|
20609
|
+
}
|
|
20610
|
+
await storage2.setSessionMeta(id, { title });
|
|
20611
|
+
return { supported: true, value: void 0 };
|
|
20612
|
+
},
|
|
20613
|
+
async tagSession(id, tag) {
|
|
20614
|
+
if (typeof storage2.setSessionMeta !== "function") {
|
|
20615
|
+
return unsupportedWrite();
|
|
20616
|
+
}
|
|
20617
|
+
await storage2.setSessionMeta(id, { tag });
|
|
20618
|
+
return { supported: true, value: void 0 };
|
|
20619
|
+
}
|
|
20620
|
+
};
|
|
20621
|
+
}
|
|
20622
|
+
function unsupportedWrite() {
|
|
20623
|
+
return {
|
|
20624
|
+
supported: false,
|
|
20625
|
+
reason: "storage adapter does not support writing session metadata (setSessionMeta)"
|
|
20626
|
+
};
|
|
20627
|
+
}
|
|
20628
|
+
function windowIds(ids, opts) {
|
|
20629
|
+
const start = opts?.offset !== void 0 && opts.offset > 0 ? opts.offset : 0;
|
|
20630
|
+
const rawLimit = opts?.limit;
|
|
20631
|
+
if (rawLimit !== void 0 && rawLimit <= 0) return [];
|
|
20632
|
+
const end = rawLimit !== void 0 ? start + rawLimit : void 0;
|
|
20633
|
+
return ids.slice(start, end);
|
|
20634
|
+
}
|
|
20635
|
+
async function buildSummary(storage2, id) {
|
|
20636
|
+
const messages = await storage2.getMessages(id);
|
|
20637
|
+
const firstUser = messages.find((m) => m.role === "user")?.content;
|
|
20638
|
+
const firstPrompt = firstUser !== void 0 && firstUser.length > 0 ? firstUser : void 0;
|
|
20639
|
+
const lastModified = deriveLastModified(messages);
|
|
20640
|
+
const meta = typeof storage2.getSessionMeta === "function" ? await storage2.getSessionMeta(id) : void 0;
|
|
20641
|
+
const title = meta?.title;
|
|
20642
|
+
const tag = meta?.tag;
|
|
20643
|
+
const summary = title ?? previewOf(firstPrompt);
|
|
20644
|
+
return {
|
|
20645
|
+
id,
|
|
20646
|
+
messageCount: messages.length,
|
|
20647
|
+
...firstPrompt !== void 0 ? { firstPrompt } : {},
|
|
20648
|
+
...lastModified !== void 0 ? { lastModified } : {},
|
|
20649
|
+
...title !== void 0 ? { title } : {},
|
|
20650
|
+
...tag !== void 0 ? { tag } : {},
|
|
20651
|
+
...summary !== void 0 ? { summary } : {}
|
|
20652
|
+
};
|
|
20653
|
+
}
|
|
20654
|
+
function deriveLastModified(messages) {
|
|
20655
|
+
let last;
|
|
20656
|
+
for (const m of messages) {
|
|
20657
|
+
if (m.at !== void 0 && (last === void 0 || m.at > last)) last = m.at;
|
|
20658
|
+
}
|
|
20659
|
+
return last;
|
|
20660
|
+
}
|
|
20661
|
+
function previewOf(text) {
|
|
20662
|
+
if (text === void 0) return void 0;
|
|
20663
|
+
const oneLine = text.replace(/\s+/g, " ").trim();
|
|
20664
|
+
if (oneLine.length === 0) return void 0;
|
|
20665
|
+
return oneLine.length > SUMMARY_PREVIEW_MAX ? `${oneLine.slice(0, SUMMARY_PREVIEW_MAX - 1)}\u2026` : oneLine;
|
|
20666
|
+
}
|
|
20667
|
+
|
|
20182
20668
|
// src/session-scope.ts
|
|
20183
20669
|
function scopedConversationId(scope, id) {
|
|
20184
20670
|
return `${scope}__${id}`;
|
|
@@ -20199,7 +20685,7 @@ var PersistenceSchema = zod.z.object({
|
|
|
20199
20685
|
// src/workflow.ts
|
|
20200
20686
|
init_path_guard();
|
|
20201
20687
|
init_workflow();
|
|
20202
|
-
zod.z.object({
|
|
20688
|
+
var RetryPolicySchema = zod.z.object({
|
|
20203
20689
|
// EC-3 absorbed: maxAttempts MUST be a finite int in [1, 20].
|
|
20204
20690
|
maxAttempts: zod.z.number().int("retry.maxAttempts must be integer").min(1, "retry.maxAttempts must be >= 1").max(20, "retry.maxAttempts must be <= 20"),
|
|
20205
20691
|
initialBackoffMs: zod.z.number().int().min(0).optional(),
|
|
@@ -20397,12 +20883,15 @@ var Workflow = class {
|
|
|
20397
20883
|
};
|
|
20398
20884
|
function agentStep(id, agent, promptTemplate, opts) {
|
|
20399
20885
|
validateStepId(id);
|
|
20886
|
+
if (opts?.retry !== void 0) RetryPolicySchema.parse(opts.retry);
|
|
20400
20887
|
return {
|
|
20401
20888
|
kind: "agent",
|
|
20402
20889
|
id,
|
|
20403
20890
|
agent,
|
|
20404
20891
|
promptTemplate,
|
|
20405
|
-
...{}
|
|
20892
|
+
...opts?.retry !== void 0 ? { retry: opts.retry } : {},
|
|
20893
|
+
// SE3 — carry the turn's provenance down to `agent.send()` (metadata-only).
|
|
20894
|
+
...opts?.origin !== void 0 ? { origin: opts.origin } : {}
|
|
20406
20895
|
};
|
|
20407
20896
|
}
|
|
20408
20897
|
function validateStepId(id) {
|
|
@@ -20450,7 +20939,8 @@ function createSquad(options) {
|
|
|
20450
20939
|
for (let i = 0; i < agents2.length; i++) {
|
|
20451
20940
|
const agent = agents2[i];
|
|
20452
20941
|
if (agent === void 0) continue;
|
|
20453
|
-
|
|
20942
|
+
const opts = i > 0 ? { origin: { kind: "peer", from: `agent-${i - 1}` } } : void 0;
|
|
20943
|
+
builder = builder.then(agentStep(`agent-${i}`, agent, (prev) => String(prev), opts));
|
|
20454
20944
|
}
|
|
20455
20945
|
const run = await builder.commit().run(input);
|
|
20456
20946
|
return { result: run.output, status: run.status, steps: run.stepResults };
|
|
@@ -20917,7 +21407,9 @@ exports.PermissionEngine = PermissionEngine;
|
|
|
20917
21407
|
exports.Security = Security;
|
|
20918
21408
|
exports.Task = Task;
|
|
20919
21409
|
exports.Theokit = Theokit;
|
|
21410
|
+
exports.ToolError = ToolError;
|
|
20920
21411
|
exports.UsageAccumulator = UsageAccumulator;
|
|
21412
|
+
exports.applyMode = applyMode;
|
|
20921
21413
|
exports.buildReplayHistory = buildReplayHistory;
|
|
20922
21414
|
exports.chargeAndCheckThresholds = chargeAndCheckThresholds;
|
|
20923
21415
|
exports.computeCost = computeCost;
|
|
@@ -20925,16 +21417,20 @@ exports.createAgentFactory = createAgentFactory;
|
|
|
20925
21417
|
exports.createCounterBudgetTracker = createCounterBudgetTracker;
|
|
20926
21418
|
exports.createNoopMemoryProvider = createNoopMemoryProvider;
|
|
20927
21419
|
exports.createPermissionPlugin = createPermissionPlugin;
|
|
21420
|
+
exports.createSessionManager = createSessionManager;
|
|
21421
|
+
exports.createSkill = createSkill;
|
|
20928
21422
|
exports.createSquad = createSquad;
|
|
20929
21423
|
exports.definePlugin = definePlugin;
|
|
20930
21424
|
exports.defineProvider = defineProvider;
|
|
20931
21425
|
exports.defineTool = defineTool;
|
|
21426
|
+
exports.emitRunEvent = emitRunEvent;
|
|
20932
21427
|
exports.extractRawId = extractRawId;
|
|
20933
21428
|
exports.getPricingEntry = getPricingEntry;
|
|
20934
21429
|
exports.inferApiMode = inferApiMode;
|
|
20935
21430
|
exports.isTransientError = isTransientError;
|
|
20936
21431
|
exports.migrateSqliteToLance = migrateSqliteToLance2;
|
|
20937
21432
|
exports.mkMemoryId = mkMemoryId;
|
|
21433
|
+
exports.normalizeSchema = normalizeSchema;
|
|
20938
21434
|
exports.normalizeUsage = normalizeUsage;
|
|
20939
21435
|
exports.preflightCheck = preflightCheck;
|
|
20940
21436
|
exports.scopedConversationId = scopedConversationId;
|