@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.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { z, toJSONSchema } from 'zod';
|
|
2
|
+
import { createRequire } from 'module';
|
|
1
3
|
import { createHash, randomUUID, randomBytes } from 'crypto';
|
|
2
4
|
import { existsSync, rmSync, mkdirSync, renameSync, readFileSync, realpathSync, lstatSync, readlinkSync, readdirSync } from 'fs';
|
|
3
5
|
import { join, dirname, relative, resolve, sep, isAbsolute } from 'path';
|
|
4
|
-
import { readFile, stat, rm, readdir, mkdir, rename, open, unlink, statfs, access,
|
|
5
|
-
import { z, toJSONSchema } from 'zod';
|
|
6
|
+
import { readFile, stat, rm, readdir, mkdir, appendFile, rename, open, unlink, statfs, access, writeFile } from 'fs/promises';
|
|
6
7
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
7
|
-
import { createRequire } from 'module';
|
|
8
8
|
import { homedir } from 'os';
|
|
9
9
|
import { spawn } from 'child_process';
|
|
10
10
|
import { fileURLToPath } from 'url';
|
|
@@ -516,6 +516,256 @@ var init_errors = __esm({
|
|
|
516
516
|
};
|
|
517
517
|
}
|
|
518
518
|
});
|
|
519
|
+
function toJsonSchema(schema, options = { unrepresentable: "any" }) {
|
|
520
|
+
return toJSONSchema(schema, options);
|
|
521
|
+
}
|
|
522
|
+
var init_to_json_schema = __esm({
|
|
523
|
+
"src/internal/zod/to-json-schema.ts"() {
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
function requireZod() {
|
|
527
|
+
if (cachedZ !== void 0) return cachedZ;
|
|
528
|
+
const r = createRequire(import.meta.url);
|
|
529
|
+
let mod;
|
|
530
|
+
try {
|
|
531
|
+
mod = r("zod");
|
|
532
|
+
} catch (cause) {
|
|
533
|
+
throw new ConfigurationError(
|
|
534
|
+
'Structured output requires the optional peer dependency `zod`. Add `"zod": "^3.25.0 || ^4.0.0"` to your package.json and reinstall.',
|
|
535
|
+
{ code: "zod_not_installed", cause }
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
cachedZ = mod.z ?? mod;
|
|
539
|
+
return cachedZ;
|
|
540
|
+
}
|
|
541
|
+
function makeOutputTool(jsonSchema, onCapture) {
|
|
542
|
+
return {
|
|
543
|
+
name: "output",
|
|
544
|
+
description: "Call this tool with your final structured answer. Match the JSON schema exactly.",
|
|
545
|
+
inputSchema: jsonSchema,
|
|
546
|
+
handler: (input) => {
|
|
547
|
+
const out = onCapture(input);
|
|
548
|
+
if (typeof out === "string") return out;
|
|
549
|
+
if (out instanceof Promise) return out;
|
|
550
|
+
return "";
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
function buildTransientAgentOptions(params) {
|
|
555
|
+
return {
|
|
556
|
+
model: params.model,
|
|
557
|
+
local: params.local,
|
|
558
|
+
tools: [params.outputTool],
|
|
559
|
+
systemPrompt: params.systemPrompt ?? "You produce structured output by calling the `output` tool exactly once. Match the JSON schema.",
|
|
560
|
+
...params.apiKey !== void 0 ? { apiKey: params.apiKey } : {},
|
|
561
|
+
...params.providers !== void 0 ? { providers: params.providers } : {}
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
function extractUsage(result) {
|
|
565
|
+
const u = result.usage;
|
|
566
|
+
if (u === void 0) return { inputTokens: 0, outputTokens: 0 };
|
|
567
|
+
return { inputTokens: u.inputTokens ?? 0, outputTokens: u.outputTokens ?? 0 };
|
|
568
|
+
}
|
|
569
|
+
function buildToolPrompt(prompt) {
|
|
570
|
+
return `${prompt}
|
|
571
|
+
|
|
572
|
+
Respond by calling the \`output\` tool with the structured answer that matches the schema.`;
|
|
573
|
+
}
|
|
574
|
+
function setupStructuredOutput(schema, maxRetries) {
|
|
575
|
+
const z8 = requireZod();
|
|
576
|
+
const jsonSchema = toJsonSchema(schema, { unrepresentable: "any" });
|
|
577
|
+
return {
|
|
578
|
+
z: z8,
|
|
579
|
+
jsonSchema,
|
|
580
|
+
maxRetries: maxRetries ?? 1,
|
|
581
|
+
initialUsage: { inputTokens: 0, outputTokens: 0 }
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
async function disposeAndDeleteTransient(agent, deletor) {
|
|
585
|
+
await agent.dispose();
|
|
586
|
+
try {
|
|
587
|
+
await deletor(agent.agentId);
|
|
588
|
+
} catch {
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
var cachedZ;
|
|
592
|
+
var init_structured_output_helpers = __esm({
|
|
593
|
+
"src/internal/structured-output-helpers.ts"() {
|
|
594
|
+
init_errors();
|
|
595
|
+
init_to_json_schema();
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
// src/generate-object.ts
|
|
600
|
+
var generate_object_exports = {};
|
|
601
|
+
__export(generate_object_exports, {
|
|
602
|
+
GenerateObjectError: () => GenerateObjectError,
|
|
603
|
+
generateObjectImpl: () => generateObjectImpl
|
|
604
|
+
});
|
|
605
|
+
function salvagePartial(schema, raw) {
|
|
606
|
+
if (typeof raw !== "object" || raw === null) return raw;
|
|
607
|
+
const shape = schema.shape;
|
|
608
|
+
if (shape === void 0 || typeof shape !== "object") return raw;
|
|
609
|
+
const rawObj = raw;
|
|
610
|
+
const out = {};
|
|
611
|
+
for (const [key2, fieldSchema] of Object.entries(shape)) {
|
|
612
|
+
if (typeof fieldSchema?.safeParse !== "function") continue;
|
|
613
|
+
const parsed = fieldSchema.safeParse(rawObj[key2]);
|
|
614
|
+
if (parsed.success) out[key2] = parsed.data;
|
|
615
|
+
}
|
|
616
|
+
return out;
|
|
617
|
+
}
|
|
618
|
+
async function runReasoningPhase(options, deps) {
|
|
619
|
+
const reasoningOptions = {
|
|
620
|
+
model: options.model,
|
|
621
|
+
local: options.local,
|
|
622
|
+
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
623
|
+
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
624
|
+
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
625
|
+
};
|
|
626
|
+
const reasoningAgent = await deps.create(reasoningOptions);
|
|
627
|
+
try {
|
|
628
|
+
const run = await reasoningAgent.send(options.prompt);
|
|
629
|
+
const result = await run.wait();
|
|
630
|
+
const text = result.result;
|
|
631
|
+
return typeof text === "string" ? text : options.prompt;
|
|
632
|
+
} finally {
|
|
633
|
+
await disposeAndDeleteTransient(reasoningAgent, deps.delete);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
async function generateObjectImpl(options, deps) {
|
|
637
|
+
const { jsonSchema, maxRetries, initialUsage } = setupStructuredOutput(
|
|
638
|
+
options.schema,
|
|
639
|
+
options.maxRetries
|
|
640
|
+
);
|
|
641
|
+
let capturedRaw;
|
|
642
|
+
let lastUsage = initialUsage;
|
|
643
|
+
const sentinel = /* @__PURE__ */ Symbol("generate-object-sentinel");
|
|
644
|
+
class CaptureSentinel extends Error {
|
|
645
|
+
constructor(captured) {
|
|
646
|
+
super("generate-object-capture");
|
|
647
|
+
this.captured = captured;
|
|
648
|
+
}
|
|
649
|
+
captured;
|
|
650
|
+
[sentinel] = true;
|
|
651
|
+
}
|
|
652
|
+
const outputTool = makeOutputTool(jsonSchema, (input) => {
|
|
653
|
+
if (capturedRaw === void 0) {
|
|
654
|
+
capturedRaw = input;
|
|
655
|
+
}
|
|
656
|
+
throw new CaptureSentinel(input);
|
|
657
|
+
});
|
|
658
|
+
const reasoningText = options.structuringModel !== void 0 ? await runReasoningPhase(options, deps) : void 0;
|
|
659
|
+
const structuringModel = options.structuringModel ?? options.model;
|
|
660
|
+
const structuringPrompt = reasoningText ?? options.prompt;
|
|
661
|
+
const agentOptions = buildTransientAgentOptions({
|
|
662
|
+
model: structuringModel,
|
|
663
|
+
local: options.local,
|
|
664
|
+
outputTool,
|
|
665
|
+
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
666
|
+
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
667
|
+
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
668
|
+
});
|
|
669
|
+
const agent = await deps.create(agentOptions);
|
|
670
|
+
try {
|
|
671
|
+
const userMessage = buildToolPrompt(structuringPrompt);
|
|
672
|
+
let lastParseError;
|
|
673
|
+
for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
|
|
674
|
+
capturedRaw = void 0;
|
|
675
|
+
const run = await agent.send(userMessage);
|
|
676
|
+
const result = await run.wait();
|
|
677
|
+
lastUsage = extractUsage(result);
|
|
678
|
+
if (capturedRaw === void 0) {
|
|
679
|
+
if (result.status === "error" && result.error !== void 0) {
|
|
680
|
+
throw new GenerateObjectError(
|
|
681
|
+
"no_tool_call",
|
|
682
|
+
`Agent run failed before the model could reply: ${result.error.message ?? "unknown error"} [${result.error.code ?? "?"}]`,
|
|
683
|
+
result.error
|
|
684
|
+
);
|
|
685
|
+
}
|
|
686
|
+
if (attempt === maxRetries) {
|
|
687
|
+
throw new GenerateObjectError(
|
|
688
|
+
"no_tool_call",
|
|
689
|
+
"The model returned text instead of calling the `output` tool."
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
continue;
|
|
693
|
+
}
|
|
694
|
+
const parsed = options.schema.safeParse(capturedRaw);
|
|
695
|
+
if (parsed.success) {
|
|
696
|
+
return {
|
|
697
|
+
object: parsed.data,
|
|
698
|
+
raw: capturedRaw,
|
|
699
|
+
usage: lastUsage,
|
|
700
|
+
finishReason: "tool_use"
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
lastParseError = parsed.error;
|
|
704
|
+
}
|
|
705
|
+
if (options.errorStrategy === "return-raw") {
|
|
706
|
+
return {
|
|
707
|
+
object: capturedRaw,
|
|
708
|
+
raw: capturedRaw,
|
|
709
|
+
usage: lastUsage,
|
|
710
|
+
finishReason: "tool_use"
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
if (options.errorStrategy === "return-partial") {
|
|
714
|
+
return {
|
|
715
|
+
object: salvagePartial(options.schema, capturedRaw),
|
|
716
|
+
raw: capturedRaw,
|
|
717
|
+
usage: lastUsage,
|
|
718
|
+
finishReason: "tool_use"
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
throw new GenerateObjectError(
|
|
722
|
+
"parse_failed",
|
|
723
|
+
"Schema parse failed after all retries.",
|
|
724
|
+
lastParseError
|
|
725
|
+
);
|
|
726
|
+
} finally {
|
|
727
|
+
await disposeAndDeleteTransient(agent, deps.delete);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
var GenerateObjectError;
|
|
731
|
+
var init_generate_object = __esm({
|
|
732
|
+
"src/generate-object.ts"() {
|
|
733
|
+
init_structured_output_helpers();
|
|
734
|
+
GenerateObjectError = class extends Error {
|
|
735
|
+
name = "GenerateObjectError";
|
|
736
|
+
code;
|
|
737
|
+
cause;
|
|
738
|
+
constructor(code, message, cause) {
|
|
739
|
+
super(message);
|
|
740
|
+
this.code = code;
|
|
741
|
+
if (cause !== void 0) this.cause = cause;
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
}
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
// src/internal/runtime/registry/agent-factory-registry.ts
|
|
748
|
+
var agent_factory_registry_exports = {};
|
|
749
|
+
__export(agent_factory_registry_exports, {
|
|
750
|
+
getAgentFacade: () => getAgentFacade,
|
|
751
|
+
setAgentFacade: () => setAgentFacade
|
|
752
|
+
});
|
|
753
|
+
function setAgentFacade(facade) {
|
|
754
|
+
registered = facade;
|
|
755
|
+
}
|
|
756
|
+
function getAgentFacade() {
|
|
757
|
+
if (registered === void 0) {
|
|
758
|
+
throw new Error(
|
|
759
|
+
"internal: Agent facade not registered. The `agent.ts` module must be loaded before internal subsystems (LocalAgent.runUntil/fork, eval, scorers, cron) invoke it."
|
|
760
|
+
);
|
|
761
|
+
}
|
|
762
|
+
return registered;
|
|
763
|
+
}
|
|
764
|
+
var registered;
|
|
765
|
+
var init_agent_factory_registry = __esm({
|
|
766
|
+
"src/internal/runtime/registry/agent-factory-registry.ts"() {
|
|
767
|
+
}
|
|
768
|
+
});
|
|
519
769
|
|
|
520
770
|
// src/internal/persistence/cwd-mutex.ts
|
|
521
771
|
function withCwdMutex(key2, fn) {
|
|
@@ -2786,29 +3036,6 @@ var init_judge_call = __esm({
|
|
|
2786
3036
|
}
|
|
2787
3037
|
});
|
|
2788
3038
|
|
|
2789
|
-
// src/internal/runtime/registry/agent-factory-registry.ts
|
|
2790
|
-
var agent_factory_registry_exports = {};
|
|
2791
|
-
__export(agent_factory_registry_exports, {
|
|
2792
|
-
getAgentFacade: () => getAgentFacade,
|
|
2793
|
-
setAgentFacade: () => setAgentFacade
|
|
2794
|
-
});
|
|
2795
|
-
function setAgentFacade(facade) {
|
|
2796
|
-
registered3 = facade;
|
|
2797
|
-
}
|
|
2798
|
-
function getAgentFacade() {
|
|
2799
|
-
if (registered3 === void 0) {
|
|
2800
|
-
throw new Error(
|
|
2801
|
-
"internal: Agent facade not registered. The `agent.ts` module must be loaded before internal subsystems (LocalAgent.runUntil/fork, eval, scorers, cron) invoke it."
|
|
2802
|
-
);
|
|
2803
|
-
}
|
|
2804
|
-
return registered3;
|
|
2805
|
-
}
|
|
2806
|
-
var registered3;
|
|
2807
|
-
var init_agent_factory_registry = __esm({
|
|
2808
|
-
"src/internal/runtime/registry/agent-factory-registry.ts"() {
|
|
2809
|
-
}
|
|
2810
|
-
});
|
|
2811
|
-
|
|
2812
3039
|
// src/internal/runtime/lifecycle/run-to-completion.ts
|
|
2813
3040
|
var run_to_completion_exports = {};
|
|
2814
3041
|
__export(run_to_completion_exports, {
|
|
@@ -2973,14 +3200,14 @@ async function forkAgentImpl(parent, options, deps) {
|
|
|
2973
3200
|
return {
|
|
2974
3201
|
result: result.result,
|
|
2975
3202
|
toolCalls: [],
|
|
2976
|
-
usage:
|
|
3203
|
+
usage: extractUsage2(result)
|
|
2977
3204
|
};
|
|
2978
3205
|
});
|
|
2979
3206
|
} finally {
|
|
2980
3207
|
await fork.dispose();
|
|
2981
3208
|
}
|
|
2982
3209
|
}
|
|
2983
|
-
function
|
|
3210
|
+
function extractUsage2(result) {
|
|
2984
3211
|
if (typeof result !== "object" || result === null) {
|
|
2985
3212
|
return { inputTokens: 0, outputTokens: 0 };
|
|
2986
3213
|
}
|
|
@@ -3612,309 +3839,103 @@ async function submit(internal) {
|
|
|
3612
3839
|
});
|
|
3613
3840
|
}
|
|
3614
3841
|
const release = await acquireSlot();
|
|
3615
|
-
void (async () => {
|
|
3616
|
-
try {
|
|
3617
|
-
await checkCancelRequestedAt(resolvedId, aborter);
|
|
3618
|
-
if (aborter.signal.aborted) {
|
|
3619
|
-
const cancelledAt = Date.now();
|
|
3620
|
-
await transition(resolvedId, "cancelled", { cancelledAt });
|
|
3621
|
-
emitToSubscribers(resolvedId, { type: "cancelled", taskId: resolvedId, cancelledAt });
|
|
3622
|
-
return;
|
|
3623
|
-
}
|
|
3624
|
-
const startedAt = Date.now();
|
|
3625
|
-
await transition(resolvedId, "running", { startedAt });
|
|
3626
|
-
emitToSubscribers(resolvedId, { type: "started", taskId: resolvedId, startedAt });
|
|
3627
|
-
await runWorkAndFinalize(resolvedId, aborter, internal.work);
|
|
3628
|
-
} finally {
|
|
3629
|
-
release();
|
|
3630
|
-
state.aborters.delete(resolvedId);
|
|
3631
|
-
}
|
|
3632
|
-
})();
|
|
3633
|
-
return queuedHandle;
|
|
3634
|
-
}
|
|
3635
|
-
async function list(filter = {}) {
|
|
3636
|
-
return state.store.list(filter);
|
|
3637
|
-
}
|
|
3638
|
-
async function get(id) {
|
|
3639
|
-
if (!isValidTaskId(id, true)) return void 0;
|
|
3640
|
-
return state.store.get(id);
|
|
3641
|
-
}
|
|
3642
|
-
async function cancel(id, reason) {
|
|
3643
|
-
if (!isValidTaskId(id, true)) return { cancelled: false, alreadyTerminal: false };
|
|
3644
|
-
const handle = await state.store.get(id);
|
|
3645
|
-
if (handle === void 0) return { cancelled: false, alreadyTerminal: false };
|
|
3646
|
-
if (handle.state === "finished" || handle.state === "error" || handle.state === "cancelled") {
|
|
3647
|
-
return { cancelled: false, alreadyTerminal: true };
|
|
3648
|
-
}
|
|
3649
|
-
const span = startTaskCancelSpan({
|
|
3650
|
-
taskId: id,
|
|
3651
|
-
...reason !== void 0 ? { reason } : {},
|
|
3652
|
-
via: "api"
|
|
3653
|
-
});
|
|
3654
|
-
try {
|
|
3655
|
-
return await cancelInternal(id, handle.state, reason);
|
|
3656
|
-
} finally {
|
|
3657
|
-
span.end();
|
|
3658
|
-
}
|
|
3659
|
-
}
|
|
3660
|
-
async function cancelInternal(id, currentState, reason) {
|
|
3661
|
-
if (currentState === "queued") {
|
|
3662
|
-
const cancelledAt = Date.now();
|
|
3663
|
-
await transition(id, "cancelled", { cancelledAt });
|
|
3664
|
-
emitToSubscribers(id, {
|
|
3665
|
-
type: "cancelled",
|
|
3666
|
-
taskId: id,
|
|
3667
|
-
cancelledAt,
|
|
3668
|
-
...reason !== void 0 ? { reason } : {}
|
|
3669
|
-
});
|
|
3670
|
-
state.aborters.delete(id);
|
|
3671
|
-
return { cancelled: true, alreadyTerminal: false };
|
|
3672
|
-
}
|
|
3673
|
-
const aborter = state.aborters.get(id);
|
|
3674
|
-
if (aborter !== void 0) aborter.abort(reason ?? "cancelled");
|
|
3675
|
-
return { cancelled: true, alreadyTerminal: false };
|
|
3676
|
-
}
|
|
3677
|
-
async function evictNow(now = Date.now()) {
|
|
3678
|
-
return state.store.evictTerminalOlderThan(now - state.retentionMs);
|
|
3679
|
-
}
|
|
3680
|
-
var DEFAULT_CONCURRENCY, DEFAULT_RETENTION_MS, EVICTION_INTERVAL_MS, RING_CAP, reentryAls, state, subscribe;
|
|
3681
|
-
var init_registry = __esm({
|
|
3682
|
-
"src/internal/task/registry.ts"() {
|
|
3683
|
-
init_errors();
|
|
3684
|
-
init_task();
|
|
3685
|
-
init_async_semaphore();
|
|
3686
|
-
init_ring_buffer();
|
|
3687
|
-
init_store();
|
|
3688
|
-
init_subscribe();
|
|
3689
|
-
init_telemetry();
|
|
3690
|
-
DEFAULT_CONCURRENCY = 8;
|
|
3691
|
-
DEFAULT_RETENTION_MS = 60 * 60 * 1e3;
|
|
3692
|
-
EVICTION_INTERVAL_MS = 5 * 60 * 1e3;
|
|
3693
|
-
RING_CAP = 64;
|
|
3694
|
-
reentryAls = new AsyncLocalStorage();
|
|
3695
|
-
state = buildState({});
|
|
3696
|
-
subscribe = buildSubscribe({
|
|
3697
|
-
getBuffer: (id) => state.buffers.get(id),
|
|
3698
|
-
getOrCreateSubscriberSet: (id) => {
|
|
3699
|
-
let subs = state.subscribers.get(id);
|
|
3700
|
-
if (subs === void 0) {
|
|
3701
|
-
subs = /* @__PURE__ */ new Set();
|
|
3702
|
-
state.subscribers.set(id, subs);
|
|
3703
|
-
}
|
|
3704
|
-
return subs;
|
|
3705
|
-
},
|
|
3706
|
-
removeSubscriber: (id, cb) => {
|
|
3707
|
-
const set = state.subscribers.get(id);
|
|
3708
|
-
set?.delete(cb);
|
|
3709
|
-
if (set !== void 0 && set.size === 0) state.subscribers.delete(id);
|
|
3710
|
-
}
|
|
3711
|
-
});
|
|
3712
|
-
}
|
|
3713
|
-
});
|
|
3714
|
-
function toJsonSchema(schema, options = { unrepresentable: "any" }) {
|
|
3715
|
-
return toJSONSchema(schema, options);
|
|
3716
|
-
}
|
|
3717
|
-
var init_to_json_schema = __esm({
|
|
3718
|
-
"src/internal/zod/to-json-schema.ts"() {
|
|
3719
|
-
}
|
|
3720
|
-
});
|
|
3721
|
-
function requireZod() {
|
|
3722
|
-
if (cachedZ !== void 0) return cachedZ;
|
|
3723
|
-
const r = createRequire(import.meta.url);
|
|
3724
|
-
let mod;
|
|
3725
|
-
try {
|
|
3726
|
-
mod = r("zod");
|
|
3727
|
-
} catch (cause) {
|
|
3728
|
-
throw new ConfigurationError(
|
|
3729
|
-
'Structured output requires the optional peer dependency `zod`. Add `"zod": "^3.25.0 || ^4.0.0"` to your package.json and reinstall.',
|
|
3730
|
-
{ code: "zod_not_installed", cause }
|
|
3731
|
-
);
|
|
3732
|
-
}
|
|
3733
|
-
cachedZ = mod.z ?? mod;
|
|
3734
|
-
return cachedZ;
|
|
3735
|
-
}
|
|
3736
|
-
function makeOutputTool(jsonSchema, onCapture) {
|
|
3737
|
-
return {
|
|
3738
|
-
name: "output",
|
|
3739
|
-
description: "Call this tool with your final structured answer. Match the JSON schema exactly.",
|
|
3740
|
-
inputSchema: jsonSchema,
|
|
3741
|
-
handler: (input) => {
|
|
3742
|
-
const out = onCapture(input);
|
|
3743
|
-
if (typeof out === "string") return out;
|
|
3744
|
-
if (out instanceof Promise) return out;
|
|
3745
|
-
return "";
|
|
3746
|
-
}
|
|
3747
|
-
};
|
|
3748
|
-
}
|
|
3749
|
-
function buildTransientAgentOptions(params) {
|
|
3750
|
-
return {
|
|
3751
|
-
model: params.model,
|
|
3752
|
-
local: params.local,
|
|
3753
|
-
tools: [params.outputTool],
|
|
3754
|
-
systemPrompt: params.systemPrompt ?? "You produce structured output by calling the `output` tool exactly once. Match the JSON schema.",
|
|
3755
|
-
...params.apiKey !== void 0 ? { apiKey: params.apiKey } : {},
|
|
3756
|
-
...params.providers !== void 0 ? { providers: params.providers } : {}
|
|
3757
|
-
};
|
|
3758
|
-
}
|
|
3759
|
-
function extractUsage2(result) {
|
|
3760
|
-
const u = result.usage;
|
|
3761
|
-
if (u === void 0) return { inputTokens: 0, outputTokens: 0 };
|
|
3762
|
-
return { inputTokens: u.inputTokens ?? 0, outputTokens: u.outputTokens ?? 0 };
|
|
3763
|
-
}
|
|
3764
|
-
function buildToolPrompt(prompt) {
|
|
3765
|
-
return `${prompt}
|
|
3766
|
-
|
|
3767
|
-
Respond by calling the \`output\` tool with the structured answer that matches the schema.`;
|
|
3768
|
-
}
|
|
3769
|
-
function setupStructuredOutput(schema, maxRetries) {
|
|
3770
|
-
const z8 = requireZod();
|
|
3771
|
-
const jsonSchema = toJsonSchema(schema, { unrepresentable: "any" });
|
|
3772
|
-
return {
|
|
3773
|
-
z: z8,
|
|
3774
|
-
jsonSchema,
|
|
3775
|
-
maxRetries: maxRetries ?? 1,
|
|
3776
|
-
initialUsage: { inputTokens: 0, outputTokens: 0 }
|
|
3777
|
-
};
|
|
3778
|
-
}
|
|
3779
|
-
async function disposeAndDeleteTransient(agent, deletor) {
|
|
3780
|
-
await agent.dispose();
|
|
3781
|
-
try {
|
|
3782
|
-
await deletor(agent.agentId);
|
|
3783
|
-
} catch {
|
|
3784
|
-
}
|
|
3785
|
-
}
|
|
3786
|
-
var cachedZ;
|
|
3787
|
-
var init_structured_output_helpers = __esm({
|
|
3788
|
-
"src/internal/structured-output-helpers.ts"() {
|
|
3789
|
-
init_errors();
|
|
3790
|
-
init_to_json_schema();
|
|
3791
|
-
}
|
|
3792
|
-
});
|
|
3793
|
-
|
|
3794
|
-
// src/generate-object.ts
|
|
3795
|
-
var generate_object_exports = {};
|
|
3796
|
-
__export(generate_object_exports, {
|
|
3797
|
-
GenerateObjectError: () => GenerateObjectError,
|
|
3798
|
-
generateObjectImpl: () => generateObjectImpl
|
|
3799
|
-
});
|
|
3800
|
-
function salvagePartial(schema, raw) {
|
|
3801
|
-
if (typeof raw !== "object" || raw === null) return raw;
|
|
3802
|
-
const shape = schema.shape;
|
|
3803
|
-
if (shape === void 0 || typeof shape !== "object") return raw;
|
|
3804
|
-
const rawObj = raw;
|
|
3805
|
-
const out = {};
|
|
3806
|
-
for (const [key2, fieldSchema] of Object.entries(shape)) {
|
|
3807
|
-
if (typeof fieldSchema?.safeParse !== "function") continue;
|
|
3808
|
-
const parsed = fieldSchema.safeParse(rawObj[key2]);
|
|
3809
|
-
if (parsed.success) out[key2] = parsed.data;
|
|
3810
|
-
}
|
|
3811
|
-
return out;
|
|
3812
|
-
}
|
|
3813
|
-
async function generateObjectImpl(options, deps) {
|
|
3814
|
-
const { jsonSchema, maxRetries, initialUsage } = setupStructuredOutput(
|
|
3815
|
-
options.schema,
|
|
3816
|
-
options.maxRetries
|
|
3817
|
-
);
|
|
3818
|
-
let capturedRaw;
|
|
3819
|
-
let lastUsage = initialUsage;
|
|
3820
|
-
const sentinel = /* @__PURE__ */ Symbol("generate-object-sentinel");
|
|
3821
|
-
class CaptureSentinel extends Error {
|
|
3822
|
-
constructor(captured) {
|
|
3823
|
-
super("generate-object-capture");
|
|
3824
|
-
this.captured = captured;
|
|
3825
|
-
}
|
|
3826
|
-
captured;
|
|
3827
|
-
[sentinel] = true;
|
|
3828
|
-
}
|
|
3829
|
-
const outputTool = makeOutputTool(jsonSchema, (input) => {
|
|
3830
|
-
if (capturedRaw === void 0) {
|
|
3831
|
-
capturedRaw = input;
|
|
3832
|
-
}
|
|
3833
|
-
throw new CaptureSentinel(input);
|
|
3834
|
-
});
|
|
3835
|
-
const agentOptions = buildTransientAgentOptions({
|
|
3836
|
-
model: options.model,
|
|
3837
|
-
local: options.local,
|
|
3838
|
-
outputTool,
|
|
3839
|
-
...options.systemPrompt !== void 0 ? { systemPrompt: options.systemPrompt } : {},
|
|
3840
|
-
...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
3841
|
-
...options.providers !== void 0 ? { providers: options.providers } : {}
|
|
3842
|
-
});
|
|
3843
|
-
const agent = await deps.create(agentOptions);
|
|
3844
|
-
try {
|
|
3845
|
-
const userMessage = buildToolPrompt(options.prompt);
|
|
3846
|
-
let lastParseError;
|
|
3847
|
-
for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
|
|
3848
|
-
capturedRaw = void 0;
|
|
3849
|
-
const run = await agent.send(userMessage);
|
|
3850
|
-
const result = await run.wait();
|
|
3851
|
-
lastUsage = extractUsage2(result);
|
|
3852
|
-
if (capturedRaw === void 0) {
|
|
3853
|
-
if (result.status === "error" && result.error !== void 0) {
|
|
3854
|
-
throw new GenerateObjectError(
|
|
3855
|
-
"no_tool_call",
|
|
3856
|
-
`Agent run failed before the model could reply: ${result.error.message ?? "unknown error"} [${result.error.code ?? "?"}]`,
|
|
3857
|
-
result.error
|
|
3858
|
-
);
|
|
3859
|
-
}
|
|
3860
|
-
if (attempt === maxRetries) {
|
|
3861
|
-
throw new GenerateObjectError(
|
|
3862
|
-
"no_tool_call",
|
|
3863
|
-
"The model returned text instead of calling the `output` tool."
|
|
3864
|
-
);
|
|
3865
|
-
}
|
|
3866
|
-
continue;
|
|
3867
|
-
}
|
|
3868
|
-
const parsed = options.schema.safeParse(capturedRaw);
|
|
3869
|
-
if (parsed.success) {
|
|
3870
|
-
return {
|
|
3871
|
-
object: parsed.data,
|
|
3872
|
-
raw: capturedRaw,
|
|
3873
|
-
usage: lastUsage,
|
|
3874
|
-
finishReason: "tool_use"
|
|
3875
|
-
};
|
|
3876
|
-
}
|
|
3877
|
-
lastParseError = parsed.error;
|
|
3878
|
-
}
|
|
3879
|
-
if (options.errorStrategy === "return-raw") {
|
|
3880
|
-
return {
|
|
3881
|
-
object: capturedRaw,
|
|
3882
|
-
raw: capturedRaw,
|
|
3883
|
-
usage: lastUsage,
|
|
3884
|
-
finishReason: "tool_use"
|
|
3885
|
-
};
|
|
3886
|
-
}
|
|
3887
|
-
if (options.errorStrategy === "return-partial") {
|
|
3888
|
-
return {
|
|
3889
|
-
object: salvagePartial(options.schema, capturedRaw),
|
|
3890
|
-
raw: capturedRaw,
|
|
3891
|
-
usage: lastUsage,
|
|
3892
|
-
finishReason: "tool_use"
|
|
3893
|
-
};
|
|
3842
|
+
void (async () => {
|
|
3843
|
+
try {
|
|
3844
|
+
await checkCancelRequestedAt(resolvedId, aborter);
|
|
3845
|
+
if (aborter.signal.aborted) {
|
|
3846
|
+
const cancelledAt = Date.now();
|
|
3847
|
+
await transition(resolvedId, "cancelled", { cancelledAt });
|
|
3848
|
+
emitToSubscribers(resolvedId, { type: "cancelled", taskId: resolvedId, cancelledAt });
|
|
3849
|
+
return;
|
|
3850
|
+
}
|
|
3851
|
+
const startedAt = Date.now();
|
|
3852
|
+
await transition(resolvedId, "running", { startedAt });
|
|
3853
|
+
emitToSubscribers(resolvedId, { type: "started", taskId: resolvedId, startedAt });
|
|
3854
|
+
await runWorkAndFinalize(resolvedId, aborter, internal.work);
|
|
3855
|
+
} finally {
|
|
3856
|
+
release();
|
|
3857
|
+
state.aborters.delete(resolvedId);
|
|
3894
3858
|
}
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3859
|
+
})();
|
|
3860
|
+
return queuedHandle;
|
|
3861
|
+
}
|
|
3862
|
+
async function list(filter = {}) {
|
|
3863
|
+
return state.store.list(filter);
|
|
3864
|
+
}
|
|
3865
|
+
async function get(id) {
|
|
3866
|
+
if (!isValidTaskId(id, true)) return void 0;
|
|
3867
|
+
return state.store.get(id);
|
|
3868
|
+
}
|
|
3869
|
+
async function cancel(id, reason) {
|
|
3870
|
+
if (!isValidTaskId(id, true)) return { cancelled: false, alreadyTerminal: false };
|
|
3871
|
+
const handle = await state.store.get(id);
|
|
3872
|
+
if (handle === void 0) return { cancelled: false, alreadyTerminal: false };
|
|
3873
|
+
if (handle.state === "finished" || handle.state === "error" || handle.state === "cancelled") {
|
|
3874
|
+
return { cancelled: false, alreadyTerminal: true };
|
|
3875
|
+
}
|
|
3876
|
+
const span = startTaskCancelSpan({
|
|
3877
|
+
taskId: id,
|
|
3878
|
+
...reason !== void 0 ? { reason } : {},
|
|
3879
|
+
via: "api"
|
|
3880
|
+
});
|
|
3881
|
+
try {
|
|
3882
|
+
return await cancelInternal(id, handle.state, reason);
|
|
3900
3883
|
} finally {
|
|
3901
|
-
|
|
3884
|
+
span.end();
|
|
3902
3885
|
}
|
|
3903
3886
|
}
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3887
|
+
async function cancelInternal(id, currentState, reason) {
|
|
3888
|
+
if (currentState === "queued") {
|
|
3889
|
+
const cancelledAt = Date.now();
|
|
3890
|
+
await transition(id, "cancelled", { cancelledAt });
|
|
3891
|
+
emitToSubscribers(id, {
|
|
3892
|
+
type: "cancelled",
|
|
3893
|
+
taskId: id,
|
|
3894
|
+
cancelledAt,
|
|
3895
|
+
...reason !== void 0 ? { reason } : {}
|
|
3896
|
+
});
|
|
3897
|
+
state.aborters.delete(id);
|
|
3898
|
+
return { cancelled: true, alreadyTerminal: false };
|
|
3899
|
+
}
|
|
3900
|
+
const aborter = state.aborters.get(id);
|
|
3901
|
+
if (aborter !== void 0) aborter.abort(reason ?? "cancelled");
|
|
3902
|
+
return { cancelled: true, alreadyTerminal: false };
|
|
3903
|
+
}
|
|
3904
|
+
async function evictNow(now = Date.now()) {
|
|
3905
|
+
return state.store.evictTerminalOlderThan(now - state.retentionMs);
|
|
3906
|
+
}
|
|
3907
|
+
var DEFAULT_CONCURRENCY, DEFAULT_RETENTION_MS, EVICTION_INTERVAL_MS, RING_CAP, reentryAls, state, subscribe;
|
|
3908
|
+
var init_registry = __esm({
|
|
3909
|
+
"src/internal/task/registry.ts"() {
|
|
3910
|
+
init_errors();
|
|
3911
|
+
init_task();
|
|
3912
|
+
init_async_semaphore();
|
|
3913
|
+
init_ring_buffer();
|
|
3914
|
+
init_store();
|
|
3915
|
+
init_subscribe();
|
|
3916
|
+
init_telemetry();
|
|
3917
|
+
DEFAULT_CONCURRENCY = 8;
|
|
3918
|
+
DEFAULT_RETENTION_MS = 60 * 60 * 1e3;
|
|
3919
|
+
EVICTION_INTERVAL_MS = 5 * 60 * 1e3;
|
|
3920
|
+
RING_CAP = 64;
|
|
3921
|
+
reentryAls = new AsyncLocalStorage();
|
|
3922
|
+
state = buildState({});
|
|
3923
|
+
subscribe = buildSubscribe({
|
|
3924
|
+
getBuffer: (id) => state.buffers.get(id),
|
|
3925
|
+
getOrCreateSubscriberSet: (id) => {
|
|
3926
|
+
let subs = state.subscribers.get(id);
|
|
3927
|
+
if (subs === void 0) {
|
|
3928
|
+
subs = /* @__PURE__ */ new Set();
|
|
3929
|
+
state.subscribers.set(id, subs);
|
|
3930
|
+
}
|
|
3931
|
+
return subs;
|
|
3932
|
+
},
|
|
3933
|
+
removeSubscriber: (id, cb) => {
|
|
3934
|
+
const set = state.subscribers.get(id);
|
|
3935
|
+
set?.delete(cb);
|
|
3936
|
+
if (set !== void 0 && set.size === 0) state.subscribers.delete(id);
|
|
3916
3937
|
}
|
|
3917
|
-
};
|
|
3938
|
+
});
|
|
3918
3939
|
}
|
|
3919
3940
|
});
|
|
3920
3941
|
|
|
@@ -3972,7 +3993,7 @@ async function* streamObjectImpl(options, deps) {
|
|
|
3972
3993
|
}
|
|
3973
3994
|
}
|
|
3974
3995
|
const result = await run.wait();
|
|
3975
|
-
lastUsage =
|
|
3996
|
+
lastUsage = extractUsage(result);
|
|
3976
3997
|
if (capturedRaw === void 0) {
|
|
3977
3998
|
if (result.status === "error" && result.error !== void 0) {
|
|
3978
3999
|
throw new StreamObjectError(
|
|
@@ -4724,7 +4745,10 @@ async function runAgentStep(step, input, ctx) {
|
|
|
4724
4745
|
};
|
|
4725
4746
|
}
|
|
4726
4747
|
const exec = async () => {
|
|
4727
|
-
const run = await step.agent.send(
|
|
4748
|
+
const run = await step.agent.send(
|
|
4749
|
+
prompt,
|
|
4750
|
+
step.origin !== void 0 ? { origin: step.origin } : void 0
|
|
4751
|
+
);
|
|
4728
4752
|
const result = await run.wait();
|
|
4729
4753
|
if (result.status === "finished") {
|
|
4730
4754
|
return result.result ?? "";
|
|
@@ -5496,6 +5520,7 @@ var AgentBuilder = class {
|
|
|
5496
5520
|
constructor(deps) {
|
|
5497
5521
|
this.deps = deps;
|
|
5498
5522
|
}
|
|
5523
|
+
/** SE8 — accepts a bare-string id shorthand (`"openai/gpt-4o-mini"`) or a {@link ModelSelection}. */
|
|
5499
5524
|
model(m) {
|
|
5500
5525
|
this.opts.model = m;
|
|
5501
5526
|
return this;
|
|
@@ -5853,13 +5878,87 @@ function isLocalAgentId(id) {
|
|
|
5853
5878
|
return id.startsWith(PREFIX.localAgent);
|
|
5854
5879
|
}
|
|
5855
5880
|
|
|
5881
|
+
// src/internal/runtime/config/default-model.ts
|
|
5882
|
+
var DEFAULT_AGENTIC_MODEL_ID = "google/gemini-2.0-flash-001";
|
|
5883
|
+
|
|
5884
|
+
// src/agent-generate.ts
|
|
5885
|
+
async function agentGenerate(agent, agentModel, agentApiKey, agentLocal, input, options) {
|
|
5886
|
+
const { output, maxRetries, errorStrategy, ...sendOptions } = options;
|
|
5887
|
+
const run = await agent.send(input, sendOptions);
|
|
5888
|
+
const result = await run.wait();
|
|
5889
|
+
const { generateObjectImpl: generateObjectImpl2, GenerateObjectError: GenerateObjectError2 } = await Promise.resolve().then(() => (init_generate_object(), generate_object_exports));
|
|
5890
|
+
const answer = structurableAnswerOrThrow(result, GenerateObjectError2);
|
|
5891
|
+
const { getAgentFacade: getAgentFacade2 } = await Promise.resolve().then(() => (init_agent_factory_registry(), agent_factory_registry_exports));
|
|
5892
|
+
const facade = getAgentFacade2();
|
|
5893
|
+
const structured = await generateObjectImpl2(
|
|
5894
|
+
{
|
|
5895
|
+
prompt: answer,
|
|
5896
|
+
schema: output,
|
|
5897
|
+
// `agentModel` arrives already normalized (`this.model` passed through
|
|
5898
|
+
// `normalizeModel` in the LocalAgent/CloudAgent constructor), so the widened
|
|
5899
|
+
// `string | ModelSelection` field only ever receives a `ModelSelection` here.
|
|
5900
|
+
model: agentModel ?? { id: DEFAULT_AGENTIC_MODEL_ID },
|
|
5901
|
+
// `local` is required to keep the transient structuring agent local-only;
|
|
5902
|
+
// default to the process cwd when the agent had no explicit local config.
|
|
5903
|
+
local: agentLocal ?? { cwd: process.cwd() },
|
|
5904
|
+
...agentApiKey !== void 0 ? { apiKey: agentApiKey } : {},
|
|
5905
|
+
...maxRetries !== void 0 ? { maxRetries } : {},
|
|
5906
|
+
...errorStrategy !== void 0 ? { errorStrategy } : {}
|
|
5907
|
+
},
|
|
5908
|
+
{
|
|
5909
|
+
create: (opts) => facade.create(opts),
|
|
5910
|
+
delete: (agentId) => facade.delete(agentId)
|
|
5911
|
+
}
|
|
5912
|
+
);
|
|
5913
|
+
return {
|
|
5914
|
+
object: structured.object,
|
|
5915
|
+
result,
|
|
5916
|
+
raw: structured.raw,
|
|
5917
|
+
usage: structured.usage
|
|
5918
|
+
};
|
|
5919
|
+
}
|
|
5920
|
+
function structurableAnswerOrThrow(result, GenerateObjectError2) {
|
|
5921
|
+
if (result.status === "error") {
|
|
5922
|
+
throw new GenerateObjectError2(
|
|
5923
|
+
"no_tool_call",
|
|
5924
|
+
`Agent run failed before an answer could be structured: ${result.error?.message ?? "unknown error"} [${result.error?.code ?? "?"}]`,
|
|
5925
|
+
result.error
|
|
5926
|
+
);
|
|
5927
|
+
}
|
|
5928
|
+
if (result.status === "cancelled") {
|
|
5929
|
+
throw new GenerateObjectError2(
|
|
5930
|
+
"no_tool_call",
|
|
5931
|
+
"Agent run was cancelled before an answer could be structured."
|
|
5932
|
+
);
|
|
5933
|
+
}
|
|
5934
|
+
const answer = result.result;
|
|
5935
|
+
if (answer === void 0 || answer.length === 0) {
|
|
5936
|
+
throw new GenerateObjectError2(
|
|
5937
|
+
"no_tool_call",
|
|
5938
|
+
"The tool loop finished with no text answer (tool-only completion) \u2014 there is nothing to structure."
|
|
5939
|
+
);
|
|
5940
|
+
}
|
|
5941
|
+
return answer;
|
|
5942
|
+
}
|
|
5943
|
+
|
|
5856
5944
|
// src/internal/runtime/cloud/cloud-agent.ts
|
|
5857
5945
|
init_errors();
|
|
5858
5946
|
init_cwd_mutex();
|
|
5859
5947
|
init_path_guard();
|
|
5860
5948
|
|
|
5861
|
-
// src/internal/runtime/
|
|
5862
|
-
|
|
5949
|
+
// src/internal/runtime/model-selection.ts
|
|
5950
|
+
init_errors();
|
|
5951
|
+
function normalizeModel(m) {
|
|
5952
|
+
if (m === void 0 || typeof m !== "string") return m;
|
|
5953
|
+
const id = m.trim();
|
|
5954
|
+
if (id.length === 0) {
|
|
5955
|
+
throw new ConfigurationError(
|
|
5956
|
+
'model must be a non-empty "provider/model" id string or a ModelSelection object',
|
|
5957
|
+
{ code: "invalid_model_selection" }
|
|
5958
|
+
);
|
|
5959
|
+
}
|
|
5960
|
+
return { id };
|
|
5961
|
+
}
|
|
5863
5962
|
|
|
5864
5963
|
// src/internal/runtime/registry/agent-registry-store.ts
|
|
5865
5964
|
init_cwd_mutex();
|
|
@@ -5936,7 +6035,10 @@ var REGISTRY_RELATIVE_PATH = join(".theokit", "agents", "registry.json");
|
|
|
5936
6035
|
function stripSecretsFromOptions(options) {
|
|
5937
6036
|
return assignDefined({
|
|
5938
6037
|
name: options.name,
|
|
5939
|
-
model:
|
|
6038
|
+
model: (() => {
|
|
6039
|
+
const m = normalizeModel(options.model);
|
|
6040
|
+
return m !== void 0 ? { id: m.id } : void 0;
|
|
6041
|
+
})(),
|
|
5940
6042
|
systemPrompt: typeof options.systemPrompt === "string" ? options.systemPrompt : void 0,
|
|
5941
6043
|
local: serializeLocal(options.local),
|
|
5942
6044
|
cloud: serializeCloud(options.cloud),
|
|
@@ -6221,7 +6323,8 @@ function serializeCloudAgentConfig(options) {
|
|
|
6221
6323
|
cloud: serializeCloud2(options.cloud)
|
|
6222
6324
|
};
|
|
6223
6325
|
if (typeof options.agentId === "string") payload.agentId = options.agentId;
|
|
6224
|
-
|
|
6326
|
+
const cfgModel = normalizeModel(options.model);
|
|
6327
|
+
if (cfgModel !== void 0) payload.model = { id: cfgModel.id };
|
|
6225
6328
|
if (typeof options.systemPrompt === "string") payload.systemPrompt = options.systemPrompt;
|
|
6226
6329
|
const skills = serializeSkills(options.skills);
|
|
6227
6330
|
if (skills !== void 0) payload.skills = skills;
|
|
@@ -7026,6 +7129,7 @@ function applyScriptMetrics(base, script) {
|
|
|
7026
7129
|
if (script.cost !== void 0) base.cost = script.cost;
|
|
7027
7130
|
if (script.stoppedAtIterationLimit === true) base.stoppedAtIterationLimit = true;
|
|
7028
7131
|
if (script.stoppedByDoomLoop === true) base.stoppedByDoomLoop = true;
|
|
7132
|
+
if (script.origin !== void 0) base.origin = script.origin;
|
|
7029
7133
|
}
|
|
7030
7134
|
|
|
7031
7135
|
// src/internal/runtime/cloud/cloud-run.ts
|
|
@@ -7381,7 +7485,7 @@ var CloudAgent = class {
|
|
|
7381
7485
|
disposed = false;
|
|
7382
7486
|
constructor(options, providedAgentId) {
|
|
7383
7487
|
this.agentId = providedAgentId ?? options.agentId ?? generateCloudAgentId();
|
|
7384
|
-
this.model = options.model;
|
|
7488
|
+
this.model = normalizeModel(options.model);
|
|
7385
7489
|
this.options = options;
|
|
7386
7490
|
this.cloudPayload = serializeCloudAgentConfig({ ...options, agentId: this.agentId });
|
|
7387
7491
|
const repoUrls = (options.cloud?.repos ?? []).map((repo) => repo.url);
|
|
@@ -7411,6 +7515,17 @@ var CloudAgent = class {
|
|
|
7411
7515
|
const apiKey = resolveApiKey(this.options.apiKey);
|
|
7412
7516
|
return isFixtureApiKey(apiKey) && getConfiguredBaseUrl() === void 0;
|
|
7413
7517
|
}
|
|
7518
|
+
// SE9 — integrated structured output; delegates to the shared helper.
|
|
7519
|
+
generate(message, options) {
|
|
7520
|
+
return agentGenerate(
|
|
7521
|
+
this,
|
|
7522
|
+
this.model,
|
|
7523
|
+
this.options.apiKey,
|
|
7524
|
+
this.options.local,
|
|
7525
|
+
message,
|
|
7526
|
+
options
|
|
7527
|
+
);
|
|
7528
|
+
}
|
|
7414
7529
|
async send(message, options = {}) {
|
|
7415
7530
|
if (options.tools !== void 0 && options.tools.length > 0) {
|
|
7416
7531
|
throw new ConfigurationError(
|
|
@@ -7441,7 +7556,7 @@ var CloudAgent = class {
|
|
|
7441
7556
|
});
|
|
7442
7557
|
}
|
|
7443
7558
|
async sendLocked(message, options) {
|
|
7444
|
-
const overrideModel = options.model;
|
|
7559
|
+
const overrideModel = normalizeModel(options.model);
|
|
7445
7560
|
if (overrideModel !== void 0) {
|
|
7446
7561
|
this.model = overrideModel;
|
|
7447
7562
|
updateRegisteredAgent(this.agentId, { model: overrideModel });
|
|
@@ -8358,18 +8473,18 @@ var ALL_ADAPTERS = [
|
|
|
8358
8473
|
arizeAdapter,
|
|
8359
8474
|
braintrustAdapter
|
|
8360
8475
|
];
|
|
8361
|
-
var
|
|
8476
|
+
var registered2 = /* @__PURE__ */ new Set();
|
|
8362
8477
|
function tryAutoRegisterAdapters(settings) {
|
|
8363
8478
|
if (settings?.enabled !== true) return;
|
|
8364
8479
|
if (settings.autoDetect === false) return;
|
|
8365
8480
|
const disabled = new Set(settings.disable ?? []);
|
|
8366
8481
|
for (const adapter of ALL_ADAPTERS) {
|
|
8367
|
-
if (
|
|
8482
|
+
if (registered2.has(adapter.moduleName)) continue;
|
|
8368
8483
|
if (disabled.has(adapter.displayName.toLowerCase())) continue;
|
|
8369
8484
|
if (!adapter.detect()) continue;
|
|
8370
8485
|
try {
|
|
8371
8486
|
adapter.register();
|
|
8372
|
-
|
|
8487
|
+
registered2.add(adapter.moduleName);
|
|
8373
8488
|
process.stderr.write(`[theokit-sdk] telemetry: ${adapter.displayName} auto-instrumented.
|
|
8374
8489
|
`);
|
|
8375
8490
|
} catch (cause) {
|
|
@@ -8899,6 +9014,26 @@ function paginate(items, opts) {
|
|
|
8899
9014
|
return items.slice(start, end);
|
|
8900
9015
|
}
|
|
8901
9016
|
|
|
9017
|
+
// src/internal/persistence/session-meta.ts
|
|
9018
|
+
function applyMetaPatch(current, patch) {
|
|
9019
|
+
const next = {};
|
|
9020
|
+
if (current.title !== void 0) next.title = current.title;
|
|
9021
|
+
if (current.tag !== void 0) next.tag = current.tag;
|
|
9022
|
+
if (patch.title === null) delete next.title;
|
|
9023
|
+
else if (patch.title !== void 0) next.title = patch.title;
|
|
9024
|
+
if (patch.tag === null) delete next.tag;
|
|
9025
|
+
else if (patch.tag !== void 0) next.tag = patch.tag;
|
|
9026
|
+
return next;
|
|
9027
|
+
}
|
|
9028
|
+
function coerceSessionMeta(raw) {
|
|
9029
|
+
if (typeof raw !== "object" || raw === null) return void 0;
|
|
9030
|
+
const obj = raw;
|
|
9031
|
+
const meta = {};
|
|
9032
|
+
if (typeof obj.title === "string") meta.title = obj.title;
|
|
9033
|
+
if (typeof obj.tag === "string") meta.tag = obj.tag;
|
|
9034
|
+
return meta.title === void 0 && meta.tag === void 0 ? void 0 : meta;
|
|
9035
|
+
}
|
|
9036
|
+
|
|
8902
9037
|
// src/internal/persistence/conversation-storage-fs.ts
|
|
8903
9038
|
var FileSystemConversationStorage = class {
|
|
8904
9039
|
#root;
|
|
@@ -8949,6 +9084,37 @@ var FileSystemConversationStorage = class {
|
|
|
8949
9084
|
async compact(conversationId, maxTurns) {
|
|
8950
9085
|
await compactSessionFile(this.#root, conversationId, maxTurns);
|
|
8951
9086
|
}
|
|
9087
|
+
// SE4 — session metadata persisted as a per-conversation sidecar
|
|
9088
|
+
// `<root>/.theokit/agents/<safeId>/session.json` (same sanitized perimeter as
|
|
9089
|
+
// the transcript). Kept separate from messages.jsonl so a title/tag write does
|
|
9090
|
+
// not rewrite the append-only log.
|
|
9091
|
+
#metaPath(conversationId) {
|
|
9092
|
+
const safe2 = sanitizeIdentifier(conversationId, { maxLen: 128 });
|
|
9093
|
+
return safePathJoin(this.#root, ".theokit", "agents", safe2, "session.json");
|
|
9094
|
+
}
|
|
9095
|
+
async getSessionMeta(conversationId) {
|
|
9096
|
+
try {
|
|
9097
|
+
const raw = await readFile(this.#metaPath(conversationId), "utf8");
|
|
9098
|
+
return coerceSessionMeta(JSON.parse(raw));
|
|
9099
|
+
} catch (cause) {
|
|
9100
|
+
if (cause.code === "ENOENT") return void 0;
|
|
9101
|
+
throw cause;
|
|
9102
|
+
}
|
|
9103
|
+
}
|
|
9104
|
+
async setSessionMeta(conversationId, patch) {
|
|
9105
|
+
const metaPath = this.#metaPath(conversationId);
|
|
9106
|
+
await mkdir(dirname(metaPath), { recursive: true });
|
|
9107
|
+
await withFileLock(metaPath, async () => {
|
|
9108
|
+
let current = {};
|
|
9109
|
+
try {
|
|
9110
|
+
current = coerceSessionMeta(JSON.parse(await readFile(metaPath, "utf8"))) ?? {};
|
|
9111
|
+
} catch (cause) {
|
|
9112
|
+
if (cause.code !== "ENOENT") throw cause;
|
|
9113
|
+
}
|
|
9114
|
+
const next = applyMetaPatch(current, patch);
|
|
9115
|
+
await writeFile(metaPath, redactSecrets(JSON.stringify(next)), "utf8");
|
|
9116
|
+
});
|
|
9117
|
+
}
|
|
8952
9118
|
async dispose() {
|
|
8953
9119
|
}
|
|
8954
9120
|
};
|
|
@@ -10800,23 +10966,27 @@ function tryParseSkill(raw, fallbackName, source, options) {
|
|
|
10800
10966
|
|
|
10801
10967
|
// src/internal/runtime/skills/skills-manager.ts
|
|
10802
10968
|
var SkillsManager = class {
|
|
10803
|
-
constructor(cwd, _enabled, settingSourcesIncludeProject) {
|
|
10969
|
+
constructor(cwd, _enabled, settingSourcesIncludeProject, skillsDir, inline) {
|
|
10804
10970
|
this.cwd = cwd;
|
|
10805
10971
|
this.settingSourcesIncludeProject = settingSourcesIncludeProject;
|
|
10972
|
+
this.skillsDir = skillsDir;
|
|
10973
|
+
this.inline = inline;
|
|
10806
10974
|
}
|
|
10807
10975
|
cwd;
|
|
10808
10976
|
settingSourcesIncludeProject;
|
|
10977
|
+
skillsDir;
|
|
10978
|
+
inline;
|
|
10809
10979
|
skills = [];
|
|
10810
10980
|
async initialize() {
|
|
10811
10981
|
if (!this.settingSourcesIncludeProject) {
|
|
10812
|
-
this.skills = [];
|
|
10982
|
+
this.skills = this.mergeInline([]);
|
|
10813
10983
|
return;
|
|
10814
10984
|
}
|
|
10815
10985
|
await this.refresh();
|
|
10816
10986
|
}
|
|
10817
10987
|
async refresh() {
|
|
10818
|
-
const skillsRoot = join(this.cwd, ".theokit", "skills");
|
|
10819
|
-
|
|
10988
|
+
const skillsRoot = this.skillsDir ?? join(this.cwd, ".theokit", "skills");
|
|
10989
|
+
const discovered = await discoverSkills(skillsRoot, {
|
|
10820
10990
|
onInvalidSkill: (info) => {
|
|
10821
10991
|
process.stderr.write(
|
|
10822
10992
|
`[theokit-sdk] skill ${info.name} skipped (${info.code}): ${info.message}
|
|
@@ -10824,6 +10994,13 @@ var SkillsManager = class {
|
|
|
10824
10994
|
);
|
|
10825
10995
|
}
|
|
10826
10996
|
});
|
|
10997
|
+
this.skills = this.mergeInline(discovered);
|
|
10998
|
+
}
|
|
10999
|
+
/** M22 — merge inline skills over discovered ones; inline wins on a name conflict. */
|
|
11000
|
+
mergeInline(discovered) {
|
|
11001
|
+
if (this.inline === void 0 || this.inline.length === 0) return discovered;
|
|
11002
|
+
const inlineNames = new Set(this.inline.map((s) => s.name));
|
|
11003
|
+
return [...discovered.filter((s) => !inlineNames.has(s.name)), ...this.inline];
|
|
10827
11004
|
}
|
|
10828
11005
|
list() {
|
|
10829
11006
|
return Promise.resolve(this.skills);
|
|
@@ -10859,7 +11036,7 @@ function bootstrapSubmanagers(args) {
|
|
|
10859
11036
|
const providerCount = (args.options.providers?.routes?.length ?? 0) + enabledPluginNames(args.options.plugins).length;
|
|
10860
11037
|
if (providerCount > 0 || args.options.providers !== void 0) {
|
|
10861
11038
|
out.providers = new ProvidersManagerImpl(
|
|
10862
|
-
args.options.model,
|
|
11039
|
+
normalizeModel(args.options.model),
|
|
10863
11040
|
args.options.providers,
|
|
10864
11041
|
args.options.plugins
|
|
10865
11042
|
);
|
|
@@ -10868,7 +11045,10 @@ function bootstrapSubmanagers(args) {
|
|
|
10868
11045
|
out.skillsManager = new SkillsManager(
|
|
10869
11046
|
args.workspaceCwd,
|
|
10870
11047
|
args.options.skills?.enabled,
|
|
10871
|
-
args.settingSourcesIncludeProject
|
|
11048
|
+
args.settingSourcesIncludeProject,
|
|
11049
|
+
// M22 — custom skills directory + inline (code-defined) skills.
|
|
11050
|
+
args.options.skills?.skillsDir,
|
|
11051
|
+
args.options.skills?.inline
|
|
10872
11052
|
);
|
|
10873
11053
|
const localSkills = out.skillsManager;
|
|
10874
11054
|
out.skills = { list: () => localSkills.list() };
|
|
@@ -10926,6 +11106,7 @@ function createLocalRun(options) {
|
|
|
10926
11106
|
projectMcpServers: options.projectMcpServers,
|
|
10927
11107
|
...options.persistMemoryFact !== void 0 ? { persistMemoryFact: options.persistMemoryFact } : {}
|
|
10928
11108
|
});
|
|
11109
|
+
if (options.sendOptions.origin !== void 0) script.origin = options.sendOptions.origin;
|
|
10929
11110
|
const handle = new LocalRun({
|
|
10930
11111
|
id,
|
|
10931
11112
|
agentId: options.agentId,
|
|
@@ -11574,6 +11755,15 @@ async function emitReasoningDeltaCallback(inputs, text) {
|
|
|
11574
11755
|
);
|
|
11575
11756
|
}
|
|
11576
11757
|
|
|
11758
|
+
// src/types/run-events.ts
|
|
11759
|
+
function emitRunEvent(sink, event) {
|
|
11760
|
+
if (sink === void 0) return;
|
|
11761
|
+
try {
|
|
11762
|
+
sink(event);
|
|
11763
|
+
} catch {
|
|
11764
|
+
}
|
|
11765
|
+
}
|
|
11766
|
+
|
|
11577
11767
|
// src/internal/agent-loop/tool-dispatch.ts
|
|
11578
11768
|
init_async_local_storage();
|
|
11579
11769
|
|
|
@@ -11671,6 +11861,22 @@ function coerceArgsToSchema(args, schema) {
|
|
|
11671
11861
|
return { value: out, changed };
|
|
11672
11862
|
}
|
|
11673
11863
|
|
|
11864
|
+
// src/tool-error.ts
|
|
11865
|
+
init_errors();
|
|
11866
|
+
var ToolError = class extends TheokitAgentError {
|
|
11867
|
+
name = "ToolError";
|
|
11868
|
+
/** The error content surfaced to the model: a string, or text/image blocks. */
|
|
11869
|
+
content;
|
|
11870
|
+
constructor(content, options = {}) {
|
|
11871
|
+
super(renderToolErrorMessage(content), { ...options, isRetryable: false });
|
|
11872
|
+
this.content = content;
|
|
11873
|
+
}
|
|
11874
|
+
};
|
|
11875
|
+
function renderToolErrorMessage(content) {
|
|
11876
|
+
if (typeof content === "string") return content;
|
|
11877
|
+
return content.map((block) => block.type === "text" ? block.text : `[${block.source.media_type} image]`).join("\n");
|
|
11878
|
+
}
|
|
11879
|
+
|
|
11674
11880
|
// src/internal/runtime/tools/shell-tool.ts
|
|
11675
11881
|
async function runShell(options) {
|
|
11676
11882
|
if (options.sandbox === true && isObviouslyUnsafe(options.command)) {
|
|
@@ -11724,9 +11930,13 @@ async function runHandlerTool(kind, handler, call, signal, context) {
|
|
|
11724
11930
|
return { stdout: "", stderr: `${kind} tool ${call.name} has no handler`, exitCode: 127 };
|
|
11725
11931
|
}
|
|
11726
11932
|
try {
|
|
11727
|
-
const
|
|
11728
|
-
return { stdout, stderr: "", exitCode: 0 };
|
|
11933
|
+
const out = await handler(call.input, { signal, context });
|
|
11934
|
+
if (typeof out !== "string") return { stdout: "", stderr: "", exitCode: 0, content: out };
|
|
11935
|
+
return { stdout: out, stderr: "", exitCode: 0 };
|
|
11729
11936
|
} catch (cause) {
|
|
11937
|
+
if (cause instanceof ToolError) {
|
|
11938
|
+
return { stdout: "", stderr: cause.message, exitCode: 1, content: cause.content };
|
|
11939
|
+
}
|
|
11730
11940
|
const message = cause instanceof Error ? cause.message : String(cause);
|
|
11731
11941
|
return { stdout: "", stderr: message, exitCode: 1 };
|
|
11732
11942
|
}
|
|
@@ -11845,6 +12055,11 @@ async function dispatchSingleCall(inputs, tools, call, events, parentSpan) {
|
|
|
11845
12055
|
toolSpan?.end();
|
|
11846
12056
|
return fileVeto;
|
|
11847
12057
|
}
|
|
12058
|
+
emitRunEvent(inputs.runEventSink, {
|
|
12059
|
+
type: "tool_progress",
|
|
12060
|
+
toolName: workingCall.name,
|
|
12061
|
+
toolCallId: callId
|
|
12062
|
+
});
|
|
11848
12063
|
const result = await runToolWithLifecycle(inputs, resolved, workingCall, callId);
|
|
11849
12064
|
await inputs.pluginManager?.runPostToolCallHooks({
|
|
11850
12065
|
name: workingCall.name,
|
|
@@ -11871,6 +12086,13 @@ function applyRepairAndExtractCall(tools, call) {
|
|
|
11871
12086
|
function vetoFromForkWhitelist(inputs, call, callId, events) {
|
|
11872
12087
|
const whitelistDecision = checkToolWhitelist(call.name);
|
|
11873
12088
|
if (whitelistDecision.allowed) return void 0;
|
|
12089
|
+
emitRunEvent(inputs.runEventSink, {
|
|
12090
|
+
type: "permission_denied",
|
|
12091
|
+
toolName: call.name,
|
|
12092
|
+
toolCallId: callId,
|
|
12093
|
+
source: "fork_whitelist",
|
|
12094
|
+
message: whitelistDecision.reason ?? "tool not available in fork"
|
|
12095
|
+
});
|
|
11874
12096
|
events.push(buildToolUseRunning(inputs, callId, call));
|
|
11875
12097
|
events.push(
|
|
11876
12098
|
buildToolUseCompleted(inputs, callId, call, {
|
|
@@ -11907,6 +12129,13 @@ async function vetoFromPluginPreHook(inputs, call, callId, events) {
|
|
|
11907
12129
|
runId: inputs.runId
|
|
11908
12130
|
});
|
|
11909
12131
|
if (pluginVeto === void 0) return void 0;
|
|
12132
|
+
emitRunEvent(inputs.runEventSink, {
|
|
12133
|
+
type: "permission_denied",
|
|
12134
|
+
toolName: call.name,
|
|
12135
|
+
toolCallId: callId,
|
|
12136
|
+
source: "plugin",
|
|
12137
|
+
message: pluginVeto.message
|
|
12138
|
+
});
|
|
11910
12139
|
events.push(
|
|
11911
12140
|
buildToolUseCompleted(inputs, callId, call, {
|
|
11912
12141
|
stdout: "",
|
|
@@ -11929,6 +12158,13 @@ async function vetoFromFileHookPreDecision(inputs, call, callId, events) {
|
|
|
11929
12158
|
runId: inputs.runId
|
|
11930
12159
|
});
|
|
11931
12160
|
if (!preDecision.blocked) return void 0;
|
|
12161
|
+
emitRunEvent(inputs.runEventSink, {
|
|
12162
|
+
type: "permission_denied",
|
|
12163
|
+
toolName: call.name,
|
|
12164
|
+
toolCallId: callId,
|
|
12165
|
+
source: "file_hook",
|
|
12166
|
+
message: preDecision.reason ?? "blocked by hook"
|
|
12167
|
+
});
|
|
11932
12168
|
events.push(
|
|
11933
12169
|
buildToolUseCompleted(inputs, callId, call, {
|
|
11934
12170
|
stdout: "",
|
|
@@ -11972,7 +12208,9 @@ async function runToolWithLifecycle(inputs, resolved, call, callId) {
|
|
|
11972
12208
|
await safeEmitToolHook(inputs.onToolEnd, {
|
|
11973
12209
|
toolName: call.name,
|
|
11974
12210
|
args: call.input,
|
|
11975
|
-
|
|
12211
|
+
// SE7 — a block-returning handler has empty `stdout`; surface its structured
|
|
12212
|
+
// content to the hook instead of an empty string.
|
|
12213
|
+
result: result.content !== void 0 ? result.content : result.stdout,
|
|
11976
12214
|
conversationId: inputs.agentId,
|
|
11977
12215
|
callId,
|
|
11978
12216
|
durationMs
|
|
@@ -11994,7 +12232,10 @@ function finalizeSpanAndPostHook(inputs, call, callId, result, events, toolSpan)
|
|
|
11994
12232
|
output: {
|
|
11995
12233
|
stdout: result.stdout,
|
|
11996
12234
|
stderr: result.stderr,
|
|
11997
|
-
exitCode: result.exitCode ?? 0
|
|
12235
|
+
exitCode: result.exitCode ?? 0,
|
|
12236
|
+
// SE7 — structured content (text + image blocks) when the handler
|
|
12237
|
+
// returned/threw blocks; absent for the string path.
|
|
12238
|
+
...result.content !== void 0 ? { content: result.content } : {}
|
|
11998
12239
|
},
|
|
11999
12240
|
agentId: inputs.agentId,
|
|
12000
12241
|
runId: inputs.runId
|
|
@@ -12007,7 +12248,9 @@ function finalizeSpanAndPostHook(inputs, call, callId, result, events, toolSpan)
|
|
|
12007
12248
|
return {
|
|
12008
12249
|
type: "tool_result",
|
|
12009
12250
|
toolUseId: call.id,
|
|
12010
|
-
content
|
|
12251
|
+
// SE7 — structured content blocks (handler-returned or ToolError-carried)
|
|
12252
|
+
// are authoritative; otherwise the legacy string rendering.
|
|
12253
|
+
content: result.content !== void 0 ? result.content : renderToolResult(result),
|
|
12011
12254
|
...result.exitCode !== 0 && result.exitCode !== void 0 ? { isError: true } : {}
|
|
12012
12255
|
};
|
|
12013
12256
|
}
|
|
@@ -12056,6 +12299,29 @@ function buildToolUseCompleted(inputs, callId, call, result) {
|
|
|
12056
12299
|
};
|
|
12057
12300
|
}
|
|
12058
12301
|
|
|
12302
|
+
// src/internal/llm/tool-result-content.ts
|
|
12303
|
+
init_errors();
|
|
12304
|
+
function toBlockToolResultContent(content) {
|
|
12305
|
+
return content;
|
|
12306
|
+
}
|
|
12307
|
+
function toStringToolResultContent(content, providerName) {
|
|
12308
|
+
if (typeof content === "string") return content;
|
|
12309
|
+
if (content.some((block) => block.type === "image")) {
|
|
12310
|
+
throw new ConfigurationError(
|
|
12311
|
+
`provider "${providerName}" does not support image content in tool results`
|
|
12312
|
+
);
|
|
12313
|
+
}
|
|
12314
|
+
return content.filter(
|
|
12315
|
+
(block) => block.type === "text"
|
|
12316
|
+
).map((block) => block.text).join("\n");
|
|
12317
|
+
}
|
|
12318
|
+
function renderToolResultContentText(content, fn) {
|
|
12319
|
+
if (typeof content === "string") return fn(content);
|
|
12320
|
+
return content.map(
|
|
12321
|
+
(block) => block.type === "text" ? { type: "text", text: fn(block.text) } : block
|
|
12322
|
+
);
|
|
12323
|
+
}
|
|
12324
|
+
|
|
12059
12325
|
// src/internal/agent-loop/tool-result-guard.ts
|
|
12060
12326
|
var OPEN = "<untrusted-tool-output>";
|
|
12061
12327
|
var CLOSE = "</untrusted-tool-output>";
|
|
@@ -12081,7 +12347,11 @@ ${CLOSE}`;
|
|
|
12081
12347
|
function applyToolResultGuard(parts, opts) {
|
|
12082
12348
|
if (opts.delimit !== true && opts.redactPii !== true) return parts;
|
|
12083
12349
|
return parts.map(
|
|
12084
|
-
(p) =>
|
|
12350
|
+
(p) => (
|
|
12351
|
+
// SE7 — guard the TEXT of a tool result (string or the text blocks of a
|
|
12352
|
+
// structured content); image blocks pass through untouched.
|
|
12353
|
+
p.type === "tool_result" ? { ...p, content: renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
|
|
12354
|
+
)
|
|
12085
12355
|
);
|
|
12086
12356
|
}
|
|
12087
12357
|
|
|
@@ -13012,10 +13282,10 @@ function stripVertexPrefix(modelId) {
|
|
|
13012
13282
|
}
|
|
13013
13283
|
|
|
13014
13284
|
// src/internal/providers/builtin/index.ts
|
|
13015
|
-
var
|
|
13285
|
+
var registered3 = false;
|
|
13016
13286
|
function registerBuiltins() {
|
|
13017
|
-
if (
|
|
13018
|
-
|
|
13287
|
+
if (registered3) return;
|
|
13288
|
+
registered3 = true;
|
|
13019
13289
|
registerProvider(ANTHROPIC);
|
|
13020
13290
|
registerProvider(OPENAI);
|
|
13021
13291
|
registerProvider(OPENROUTER);
|
|
@@ -13244,7 +13514,9 @@ function toAnthropicWireMessage(message) {
|
|
|
13244
13514
|
return {
|
|
13245
13515
|
type: "tool_result",
|
|
13246
13516
|
tool_use_id: part.toolUseId,
|
|
13247
|
-
|
|
13517
|
+
// SE7 — this wire is block-capable: strings pass through, structured
|
|
13518
|
+
// text/image blocks are forwarded natively.
|
|
13519
|
+
content: toBlockToolResultContent(part.content),
|
|
13248
13520
|
...part.isError === true ? { is_error: true } : {}
|
|
13249
13521
|
};
|
|
13250
13522
|
});
|
|
@@ -14036,7 +14308,8 @@ function toOllamaMessages(message) {
|
|
|
14036
14308
|
if (part.type === "tool_result") {
|
|
14037
14309
|
out.push({
|
|
14038
14310
|
role: "tool",
|
|
14039
|
-
|
|
14311
|
+
// SE7 — string-only tool role: text blocks flatten; image fails fast.
|
|
14312
|
+
content: toStringToolResultContent(part.content, "ollama"),
|
|
14040
14313
|
tool_name: part.toolUseId
|
|
14041
14314
|
});
|
|
14042
14315
|
}
|
|
@@ -14573,7 +14846,9 @@ function userOrToolMessages(message) {
|
|
|
14573
14846
|
out.push({
|
|
14574
14847
|
role: "tool",
|
|
14575
14848
|
tool_call_id: part.toolUseId,
|
|
14576
|
-
|
|
14849
|
+
// SE7 — this wire's tool role is string-only: text blocks flatten; an
|
|
14850
|
+
// image block fails fast (ConfigurationError).
|
|
14851
|
+
content: toStringToolResultContent(part.content, "openai")
|
|
14577
14852
|
});
|
|
14578
14853
|
}
|
|
14579
14854
|
}
|
|
@@ -15503,18 +15778,20 @@ function levenshtein(a, b) {
|
|
|
15503
15778
|
function createRealLocalRun(options) {
|
|
15504
15779
|
const { userText, id, startTime } = prepareRunContext(options.message);
|
|
15505
15780
|
const supported = /* @__PURE__ */ new Set(["stream", "wait", "cancel", "conversation"]);
|
|
15506
|
-
const
|
|
15781
|
+
const runScript = {
|
|
15507
15782
|
events: [],
|
|
15508
15783
|
finalStatus: "running",
|
|
15509
15784
|
cancellable: false,
|
|
15510
|
-
conversation: []
|
|
15785
|
+
conversation: [],
|
|
15786
|
+
// SE3 — carry the turn's provenance so buildResult forwards it onto RunResult.origin.
|
|
15787
|
+
...options.sendOptions.origin !== void 0 ? { origin: options.sendOptions.origin } : {}
|
|
15511
15788
|
};
|
|
15512
15789
|
const handle = new RealLocalRun(
|
|
15513
15790
|
{
|
|
15514
15791
|
id,
|
|
15515
15792
|
agentId: options.agentId,
|
|
15516
15793
|
model: options.model,
|
|
15517
|
-
script:
|
|
15794
|
+
script: runScript,
|
|
15518
15795
|
supportedOps: supported,
|
|
15519
15796
|
startTime
|
|
15520
15797
|
},
|
|
@@ -15626,6 +15903,8 @@ function buildLoopInputs(options, runId, userText) {
|
|
|
15626
15903
|
// M7 — forward SendOptions.context to the loop so every tool handler receives
|
|
15627
15904
|
// it on `ctx.context` (shared run config set once, e.g. projectRoot).
|
|
15628
15905
|
...options.sendOptions.context !== void 0 ? { context: options.sendOptions.context } : {},
|
|
15906
|
+
// SE2 — forward the opt-in typed runtime-event sink to the loop.
|
|
15907
|
+
...options.sendOptions.onRunEvent !== void 0 ? { runEventSink: options.sendOptions.onRunEvent } : {},
|
|
15629
15908
|
// #58 / #57 — forward the per-tool timeout + tool-result guard so a consumer
|
|
15630
15909
|
// can enable them via SendOptions (not only internal AgentLoopInputs).
|
|
15631
15910
|
...options.sendOptions.perToolTimeoutMs !== void 0 ? { perToolTimeoutMs: options.sendOptions.perToolTimeoutMs } : {},
|
|
@@ -17370,7 +17649,7 @@ function wrapRunWithPostReplyHook(args) {
|
|
|
17370
17649
|
async function executeSendLocked(inputs, message, options) {
|
|
17371
17650
|
if (inputs.disposed) throw new AgentDisposedError(inputs.agentId);
|
|
17372
17651
|
await consumePending(inputs.agentId, inputs.invalidationPending, inputs.clearInvalidation, inputs.reload);
|
|
17373
|
-
inputs.applyModelOverride(options.model);
|
|
17652
|
+
inputs.applyModelOverride(normalizeModel(options.model));
|
|
17374
17653
|
const userText = typeof message === "string" ? message : message.text;
|
|
17375
17654
|
if (inputs.options.onBeforeSend !== void 0) {
|
|
17376
17655
|
await inputs.options.onBeforeSend({
|
|
@@ -17522,7 +17801,7 @@ var LocalAgent = class {
|
|
|
17522
17801
|
constructor(options) {
|
|
17523
17802
|
this.agentId = options.agentId ?? generateLocalAgentId();
|
|
17524
17803
|
this._telemetry = createTelemetry(options.telemetry);
|
|
17525
|
-
this.model = options.model;
|
|
17804
|
+
this.model = normalizeModel(options.model);
|
|
17526
17805
|
this.options = options;
|
|
17527
17806
|
this.workspaceCwd = resolveCwd(options.local?.cwd);
|
|
17528
17807
|
this.conversationStorage = options.conversationStorage;
|
|
@@ -17589,6 +17868,11 @@ var LocalAgent = class {
|
|
|
17589
17868
|
hooks() {
|
|
17590
17869
|
return this.hooksExecutor;
|
|
17591
17870
|
}
|
|
17871
|
+
// SE9 — integrated structured output; delegates to the shared helper.
|
|
17872
|
+
generate(message, options) {
|
|
17873
|
+
const { apiKey, local } = this.options;
|
|
17874
|
+
return agentGenerate(this, this.model, apiKey, local, message, options);
|
|
17875
|
+
}
|
|
17592
17876
|
async send(message, options = {}) {
|
|
17593
17877
|
if (options.tools !== void 0 && options.tools.length > 0) {
|
|
17594
17878
|
validateToolCatalog(options.tools);
|
|
@@ -17828,6 +18112,7 @@ function includesSetting(options, source) {
|
|
|
17828
18112
|
|
|
17829
18113
|
// src/agent-helpers.ts
|
|
17830
18114
|
async function runCreateUnderSpan(options, span) {
|
|
18115
|
+
options = { ...options, model: normalizeModel(options.model) };
|
|
17831
18116
|
validateAgentOptions(options);
|
|
17832
18117
|
validateCloudToolParity(options);
|
|
17833
18118
|
await guardAgainstIdCollision(options);
|
|
@@ -17901,7 +18186,10 @@ async function createLocalAgent(options) {
|
|
|
17901
18186
|
const willFlowToProvider = !isFixtureApiKey(apiKey) && !shouldUseRealLocalRuntime(apiKey);
|
|
17902
18187
|
const shape = validateApiKeyShape(apiKey, {
|
|
17903
18188
|
strict: willFlowToProvider,
|
|
17904
|
-
|
|
18189
|
+
// `options.model` is already normalized by `runCreateUnderSpan`; `normalizeModel`
|
|
18190
|
+
// here is the idempotent narrowing of the widened public type (`{id}` passes
|
|
18191
|
+
// through by reference) — cleaner than an `as` cast.
|
|
18192
|
+
...willFlowToProvider ? { provider: providerFromModelId(normalizeModel(options.model)?.id) } : {}
|
|
17905
18193
|
});
|
|
17906
18194
|
if (shape.malformed) {
|
|
17907
18195
|
throw new AuthenticationError(shape.message, { code: "malformed_api_key" });
|
|
@@ -17967,6 +18255,10 @@ async function rehydrateExistingAgent(agentId, existing, options) {
|
|
|
17967
18255
|
...existing.options,
|
|
17968
18256
|
...options,
|
|
17969
18257
|
...mergedLocal !== void 0 ? { local: mergedLocal } : {},
|
|
18258
|
+
// SE8 — normalize a caller-supplied bare-string model override at this resume
|
|
18259
|
+
// boundary (Agent.resume never flows through runCreateUnderSpan). Cloud resume
|
|
18260
|
+
// honors it; local resume forces the persisted model below.
|
|
18261
|
+
model: normalizeModel(options.model ?? existing.options.model),
|
|
17970
18262
|
mcpServers: void 0,
|
|
17971
18263
|
agentId
|
|
17972
18264
|
};
|
|
@@ -18333,6 +18625,7 @@ async function getOrCreateUncached(agentId, options) {
|
|
|
18333
18625
|
}
|
|
18334
18626
|
setAgentFacade({
|
|
18335
18627
|
create: (options) => Agent.create(options),
|
|
18628
|
+
delete: (agentId) => Agent.delete(agentId),
|
|
18336
18629
|
prompt: (message, options) => Agent.prompt(message, options),
|
|
18337
18630
|
get: (agentId) => Agent.get(agentId),
|
|
18338
18631
|
resume: (agentId, options) => Agent.resume(agentId, options),
|
|
@@ -18770,6 +19063,20 @@ var Budget = class {
|
|
|
18770
19063
|
}
|
|
18771
19064
|
};
|
|
18772
19065
|
|
|
19066
|
+
// src/create-skill.ts
|
|
19067
|
+
function createSkill(spec) {
|
|
19068
|
+
if (!spec.name) throw new Error("createSkill: `name` is required.");
|
|
19069
|
+
if (!spec.description) throw new Error("createSkill: `description` is required.");
|
|
19070
|
+
return {
|
|
19071
|
+
name: spec.name,
|
|
19072
|
+
description: spec.description,
|
|
19073
|
+
source: `inline://${spec.name}`,
|
|
19074
|
+
instructions: spec.instructions,
|
|
19075
|
+
...spec.category !== void 0 ? { category: spec.category } : {},
|
|
19076
|
+
...spec.dependencies !== void 0 ? { dependencies: spec.dependencies } : {}
|
|
19077
|
+
};
|
|
19078
|
+
}
|
|
19079
|
+
|
|
18773
19080
|
// src/cron.ts
|
|
18774
19081
|
init_errors();
|
|
18775
19082
|
|
|
@@ -19279,6 +19586,8 @@ init_generate_object();
|
|
|
19279
19586
|
// src/internal/persistence/conversation-storage-memory.ts
|
|
19280
19587
|
var InMemoryConversationStorage = class {
|
|
19281
19588
|
#store = /* @__PURE__ */ new Map();
|
|
19589
|
+
// SE4 — session-level metadata (title/tag), kept beside the transcript.
|
|
19590
|
+
#meta = /* @__PURE__ */ new Map();
|
|
19282
19591
|
async getMessages(conversationId, opts) {
|
|
19283
19592
|
const existing = this.#store.get(conversationId);
|
|
19284
19593
|
return existing === void 0 ? [] : paginate(existing.slice(), opts);
|
|
@@ -19307,15 +19616,20 @@ var InMemoryConversationStorage = class {
|
|
|
19307
19616
|
}
|
|
19308
19617
|
async deleteConversation(conversationId) {
|
|
19309
19618
|
this.#store.delete(conversationId);
|
|
19619
|
+
this.#meta.delete(conversationId);
|
|
19310
19620
|
}
|
|
19311
19621
|
async deleteScope(prefix) {
|
|
19312
19622
|
let n = 0;
|
|
19313
19623
|
for (const id of [...this.#store.keys()]) {
|
|
19314
19624
|
if (id.startsWith(prefix)) {
|
|
19315
19625
|
this.#store.delete(id);
|
|
19626
|
+
this.#meta.delete(id);
|
|
19316
19627
|
n += 1;
|
|
19317
19628
|
}
|
|
19318
19629
|
}
|
|
19630
|
+
for (const id of [...this.#meta.keys()]) {
|
|
19631
|
+
if (id.startsWith(prefix)) this.#meta.delete(id);
|
|
19632
|
+
}
|
|
19319
19633
|
return n;
|
|
19320
19634
|
}
|
|
19321
19635
|
async listConversationIds(opts) {
|
|
@@ -19323,8 +19637,17 @@ var InMemoryConversationStorage = class {
|
|
|
19323
19637
|
if (opts?.limit !== void 0) return all.slice(0, opts.limit);
|
|
19324
19638
|
return all;
|
|
19325
19639
|
}
|
|
19640
|
+
async getSessionMeta(conversationId) {
|
|
19641
|
+
const meta = this.#meta.get(conversationId);
|
|
19642
|
+
return meta === void 0 ? void 0 : { ...meta };
|
|
19643
|
+
}
|
|
19644
|
+
async setSessionMeta(conversationId, patch) {
|
|
19645
|
+
const current = this.#meta.get(conversationId) ?? {};
|
|
19646
|
+
this.#meta.set(conversationId, applyMetaPatch(current, patch));
|
|
19647
|
+
}
|
|
19326
19648
|
async dispose() {
|
|
19327
19649
|
this.#store.clear();
|
|
19650
|
+
this.#meta.clear();
|
|
19328
19651
|
}
|
|
19329
19652
|
};
|
|
19330
19653
|
|
|
@@ -20064,6 +20387,21 @@ async function migrateSqliteToLance2(options) {
|
|
|
20064
20387
|
}
|
|
20065
20388
|
|
|
20066
20389
|
// src/permission-engine.ts
|
|
20390
|
+
function applyMode(verdict, mode, explicit) {
|
|
20391
|
+
if (verdict === "deny") return "deny";
|
|
20392
|
+
switch (mode) {
|
|
20393
|
+
case "default":
|
|
20394
|
+
return verdict;
|
|
20395
|
+
case "plan":
|
|
20396
|
+
return verdict === "allow" ? "allow" : "deny";
|
|
20397
|
+
case "acceptEdits":
|
|
20398
|
+
if (verdict === "ask") return explicit ? "ask" : "allow";
|
|
20399
|
+
return verdict;
|
|
20400
|
+
// allow stays allow
|
|
20401
|
+
case "bypass":
|
|
20402
|
+
return "allow";
|
|
20403
|
+
}
|
|
20404
|
+
}
|
|
20067
20405
|
function argMatches(matcher, value) {
|
|
20068
20406
|
if (typeof matcher === "function") return matcher(value);
|
|
20069
20407
|
if (value === void 0) return false;
|
|
@@ -20084,14 +20422,14 @@ var PermissionEngine = class {
|
|
|
20084
20422
|
* argument values, so the same tool name can resolve to different actions
|
|
20085
20423
|
* depending on what it is asked to do.
|
|
20086
20424
|
*/
|
|
20087
|
-
evaluate(toolName, args) {
|
|
20425
|
+
evaluate(toolName, args, mode = "default") {
|
|
20088
20426
|
for (const rule of this.rules) {
|
|
20089
20427
|
const nameMatches = typeof rule.tool === "string" ? rule.tool === toolName : rule.tool.test(toolName);
|
|
20090
20428
|
if (!nameMatches) continue;
|
|
20091
20429
|
if (rule.args !== void 0 && !this.#argsMatch(rule.args, args)) continue;
|
|
20092
|
-
return rule.action;
|
|
20430
|
+
return applyMode(rule.action, mode, true);
|
|
20093
20431
|
}
|
|
20094
|
-
return this.defaultAction;
|
|
20432
|
+
return applyMode(this.defaultAction, mode, false);
|
|
20095
20433
|
}
|
|
20096
20434
|
#argsMatch(matchers, args) {
|
|
20097
20435
|
const call = args ?? {};
|
|
@@ -20103,27 +20441,85 @@ var PermissionEngine = class {
|
|
|
20103
20441
|
};
|
|
20104
20442
|
|
|
20105
20443
|
// src/permission-plugin.ts
|
|
20444
|
+
async function resolveAsk(opts, name, args, mode) {
|
|
20445
|
+
if (opts.canUseTool !== void 0) {
|
|
20446
|
+
let decision;
|
|
20447
|
+
try {
|
|
20448
|
+
decision = await opts.canUseTool(name, args, { toolName: name, mode });
|
|
20449
|
+
} catch {
|
|
20450
|
+
return { block: true, message: `permission gate error (fail-closed): ${name}` };
|
|
20451
|
+
}
|
|
20452
|
+
return decision.behavior === "deny" ? { block: true, message: decision.message ?? `denied: ${name}` } : void 0;
|
|
20453
|
+
}
|
|
20454
|
+
return opts.onAsk ? opts.onAsk(name) : { block: true, message: `requires approval: ${name}` };
|
|
20455
|
+
}
|
|
20106
20456
|
function createPermissionPlugin(engine, opts = {}) {
|
|
20457
|
+
const mode = opts.mode ?? "default";
|
|
20107
20458
|
return definePlugin({
|
|
20108
20459
|
name: opts.name ?? "permission-engine",
|
|
20109
20460
|
version: "1.0.0",
|
|
20110
20461
|
kind: "general",
|
|
20111
20462
|
register(ctx) {
|
|
20112
|
-
ctx.on("pre_tool_call", (rawCtx) => {
|
|
20463
|
+
ctx.on("pre_tool_call", async (rawCtx) => {
|
|
20113
20464
|
const { name, args } = rawCtx;
|
|
20114
|
-
const action = engine.evaluate(name, args);
|
|
20465
|
+
const action = engine.evaluate(name, args, mode);
|
|
20115
20466
|
if (action === "deny") {
|
|
20116
20467
|
return { block: true, message: `denied by permission engine: ${name}` };
|
|
20117
20468
|
}
|
|
20118
|
-
if (action === "ask")
|
|
20119
|
-
return opts.onAsk ? opts.onAsk(name) : { block: true, message: `requires approval: ${name}` };
|
|
20120
|
-
}
|
|
20469
|
+
if (action === "ask") return resolveAsk(opts, name, args, mode);
|
|
20121
20470
|
return void 0;
|
|
20122
20471
|
});
|
|
20123
20472
|
}
|
|
20124
20473
|
});
|
|
20125
20474
|
}
|
|
20126
20475
|
|
|
20476
|
+
// src/schema-normalizer.ts
|
|
20477
|
+
init_to_json_schema();
|
|
20478
|
+
function isJsonSchemaObject(s) {
|
|
20479
|
+
if (typeof s !== "object" || s === null) return false;
|
|
20480
|
+
const o = s;
|
|
20481
|
+
if ("$schema" in o) return true;
|
|
20482
|
+
return o.type === "object" && typeof o.properties === "object" && o.properties !== null;
|
|
20483
|
+
}
|
|
20484
|
+
function hasToJsonSchemaMethod(s) {
|
|
20485
|
+
return typeof s === "object" && s !== null && typeof s.toJsonSchema === "function";
|
|
20486
|
+
}
|
|
20487
|
+
function isZodSchema(s) {
|
|
20488
|
+
if (typeof s !== "object" || s === null) return false;
|
|
20489
|
+
const o = s;
|
|
20490
|
+
return typeof o.safeParse === "function" && ("_def" in o || "def" in o);
|
|
20491
|
+
}
|
|
20492
|
+
function isValibotSchema(s) {
|
|
20493
|
+
if (typeof s !== "object" || s === null) return false;
|
|
20494
|
+
const o = s;
|
|
20495
|
+
return o.kind === "schema" && "type" in o && typeof o.toJsonSchema !== "function";
|
|
20496
|
+
}
|
|
20497
|
+
async function normalizeSchema(schema) {
|
|
20498
|
+
if (isJsonSchemaObject(schema)) return schema;
|
|
20499
|
+
if (isValibotSchema(schema)) {
|
|
20500
|
+
const specifier = "@valibot/to-json-schema";
|
|
20501
|
+
try {
|
|
20502
|
+
const mod = await import(specifier);
|
|
20503
|
+
return mod.toJsonSchema(schema);
|
|
20504
|
+
} catch (err) {
|
|
20505
|
+
const missing = err instanceof Error && /Cannot find|Cannot resolve|ERR_MODULE_NOT_FOUND/.test(err.message);
|
|
20506
|
+
if (missing) {
|
|
20507
|
+
throw new Error(
|
|
20508
|
+
"normalizeSchema: a Valibot schema requires the optional '@valibot/to-json-schema' package. Install it, or use a Zod schema (the default recommendation)."
|
|
20509
|
+
);
|
|
20510
|
+
}
|
|
20511
|
+
throw err;
|
|
20512
|
+
}
|
|
20513
|
+
}
|
|
20514
|
+
if (isZodSchema(schema)) {
|
|
20515
|
+
return toJsonSchema(schema, { unrepresentable: "any" });
|
|
20516
|
+
}
|
|
20517
|
+
if (hasToJsonSchemaMethod(schema)) return schema.toJsonSchema();
|
|
20518
|
+
throw new Error(
|
|
20519
|
+
"normalizeSchema: unsupported schema. Supported: Zod (default), JSON Schema, ArkType (.toJsonSchema()), Valibot (with @valibot/to-json-schema)."
|
|
20520
|
+
);
|
|
20521
|
+
}
|
|
20522
|
+
|
|
20127
20523
|
// src/security.ts
|
|
20128
20524
|
init_security();
|
|
20129
20525
|
var Security = class {
|
|
@@ -20176,6 +20572,96 @@ var Security = class {
|
|
|
20176
20572
|
}
|
|
20177
20573
|
};
|
|
20178
20574
|
|
|
20575
|
+
// src/session-manager.ts
|
|
20576
|
+
var SUMMARY_PREVIEW_MAX = 80;
|
|
20577
|
+
function createSessionManager(storage2) {
|
|
20578
|
+
return {
|
|
20579
|
+
async listSessions(opts) {
|
|
20580
|
+
if (typeof storage2.listConversationIds !== "function") {
|
|
20581
|
+
return {
|
|
20582
|
+
supported: false,
|
|
20583
|
+
reason: "storage adapter does not support listing conversations (listConversationIds)"
|
|
20584
|
+
};
|
|
20585
|
+
}
|
|
20586
|
+
const ids = await storage2.listConversationIds();
|
|
20587
|
+
if (ids === void 0) {
|
|
20588
|
+
return {
|
|
20589
|
+
supported: false,
|
|
20590
|
+
reason: "storage adapter reported listing as unsupported (listConversationIds \u2192 undefined)"
|
|
20591
|
+
};
|
|
20592
|
+
}
|
|
20593
|
+
const windowed = windowIds(ids, opts);
|
|
20594
|
+
const summaries = [];
|
|
20595
|
+
for (const id of windowed) {
|
|
20596
|
+
summaries.push(await buildSummary(storage2, id));
|
|
20597
|
+
}
|
|
20598
|
+
return { supported: true, value: summaries };
|
|
20599
|
+
},
|
|
20600
|
+
getSessionMessages(id, opts) {
|
|
20601
|
+
return storage2.getMessages(id, opts);
|
|
20602
|
+
},
|
|
20603
|
+
async renameSession(id, title) {
|
|
20604
|
+
if (typeof storage2.setSessionMeta !== "function") {
|
|
20605
|
+
return unsupportedWrite();
|
|
20606
|
+
}
|
|
20607
|
+
await storage2.setSessionMeta(id, { title });
|
|
20608
|
+
return { supported: true, value: void 0 };
|
|
20609
|
+
},
|
|
20610
|
+
async tagSession(id, tag) {
|
|
20611
|
+
if (typeof storage2.setSessionMeta !== "function") {
|
|
20612
|
+
return unsupportedWrite();
|
|
20613
|
+
}
|
|
20614
|
+
await storage2.setSessionMeta(id, { tag });
|
|
20615
|
+
return { supported: true, value: void 0 };
|
|
20616
|
+
}
|
|
20617
|
+
};
|
|
20618
|
+
}
|
|
20619
|
+
function unsupportedWrite() {
|
|
20620
|
+
return {
|
|
20621
|
+
supported: false,
|
|
20622
|
+
reason: "storage adapter does not support writing session metadata (setSessionMeta)"
|
|
20623
|
+
};
|
|
20624
|
+
}
|
|
20625
|
+
function windowIds(ids, opts) {
|
|
20626
|
+
const start = opts?.offset !== void 0 && opts.offset > 0 ? opts.offset : 0;
|
|
20627
|
+
const rawLimit = opts?.limit;
|
|
20628
|
+
if (rawLimit !== void 0 && rawLimit <= 0) return [];
|
|
20629
|
+
const end = rawLimit !== void 0 ? start + rawLimit : void 0;
|
|
20630
|
+
return ids.slice(start, end);
|
|
20631
|
+
}
|
|
20632
|
+
async function buildSummary(storage2, id) {
|
|
20633
|
+
const messages = await storage2.getMessages(id);
|
|
20634
|
+
const firstUser = messages.find((m) => m.role === "user")?.content;
|
|
20635
|
+
const firstPrompt = firstUser !== void 0 && firstUser.length > 0 ? firstUser : void 0;
|
|
20636
|
+
const lastModified = deriveLastModified(messages);
|
|
20637
|
+
const meta = typeof storage2.getSessionMeta === "function" ? await storage2.getSessionMeta(id) : void 0;
|
|
20638
|
+
const title = meta?.title;
|
|
20639
|
+
const tag = meta?.tag;
|
|
20640
|
+
const summary = title ?? previewOf(firstPrompt);
|
|
20641
|
+
return {
|
|
20642
|
+
id,
|
|
20643
|
+
messageCount: messages.length,
|
|
20644
|
+
...firstPrompt !== void 0 ? { firstPrompt } : {},
|
|
20645
|
+
...lastModified !== void 0 ? { lastModified } : {},
|
|
20646
|
+
...title !== void 0 ? { title } : {},
|
|
20647
|
+
...tag !== void 0 ? { tag } : {},
|
|
20648
|
+
...summary !== void 0 ? { summary } : {}
|
|
20649
|
+
};
|
|
20650
|
+
}
|
|
20651
|
+
function deriveLastModified(messages) {
|
|
20652
|
+
let last;
|
|
20653
|
+
for (const m of messages) {
|
|
20654
|
+
if (m.at !== void 0 && (last === void 0 || m.at > last)) last = m.at;
|
|
20655
|
+
}
|
|
20656
|
+
return last;
|
|
20657
|
+
}
|
|
20658
|
+
function previewOf(text) {
|
|
20659
|
+
if (text === void 0) return void 0;
|
|
20660
|
+
const oneLine = text.replace(/\s+/g, " ").trim();
|
|
20661
|
+
if (oneLine.length === 0) return void 0;
|
|
20662
|
+
return oneLine.length > SUMMARY_PREVIEW_MAX ? `${oneLine.slice(0, SUMMARY_PREVIEW_MAX - 1)}\u2026` : oneLine;
|
|
20663
|
+
}
|
|
20664
|
+
|
|
20179
20665
|
// src/session-scope.ts
|
|
20180
20666
|
function scopedConversationId(scope, id) {
|
|
20181
20667
|
return `${scope}__${id}`;
|
|
@@ -20196,7 +20682,7 @@ var PersistenceSchema = z.object({
|
|
|
20196
20682
|
// src/workflow.ts
|
|
20197
20683
|
init_path_guard();
|
|
20198
20684
|
init_workflow();
|
|
20199
|
-
z.object({
|
|
20685
|
+
var RetryPolicySchema = z.object({
|
|
20200
20686
|
// EC-3 absorbed: maxAttempts MUST be a finite int in [1, 20].
|
|
20201
20687
|
maxAttempts: z.number().int("retry.maxAttempts must be integer").min(1, "retry.maxAttempts must be >= 1").max(20, "retry.maxAttempts must be <= 20"),
|
|
20202
20688
|
initialBackoffMs: z.number().int().min(0).optional(),
|
|
@@ -20394,12 +20880,15 @@ var Workflow = class {
|
|
|
20394
20880
|
};
|
|
20395
20881
|
function agentStep(id, agent, promptTemplate, opts) {
|
|
20396
20882
|
validateStepId(id);
|
|
20883
|
+
if (opts?.retry !== void 0) RetryPolicySchema.parse(opts.retry);
|
|
20397
20884
|
return {
|
|
20398
20885
|
kind: "agent",
|
|
20399
20886
|
id,
|
|
20400
20887
|
agent,
|
|
20401
20888
|
promptTemplate,
|
|
20402
|
-
...{}
|
|
20889
|
+
...opts?.retry !== void 0 ? { retry: opts.retry } : {},
|
|
20890
|
+
// SE3 — carry the turn's provenance down to `agent.send()` (metadata-only).
|
|
20891
|
+
...opts?.origin !== void 0 ? { origin: opts.origin } : {}
|
|
20403
20892
|
};
|
|
20404
20893
|
}
|
|
20405
20894
|
function validateStepId(id) {
|
|
@@ -20447,7 +20936,8 @@ function createSquad(options) {
|
|
|
20447
20936
|
for (let i = 0; i < agents2.length; i++) {
|
|
20448
20937
|
const agent = agents2[i];
|
|
20449
20938
|
if (agent === void 0) continue;
|
|
20450
|
-
|
|
20939
|
+
const opts = i > 0 ? { origin: { kind: "peer", from: `agent-${i - 1}` } } : void 0;
|
|
20940
|
+
builder = builder.then(agentStep(`agent-${i}`, agent, (prev) => String(prev), opts));
|
|
20451
20941
|
}
|
|
20452
20942
|
const run = await builder.commit().run(input);
|
|
20453
20943
|
return { result: run.output, status: run.status, steps: run.stepResults };
|
|
@@ -20901,6 +21391,6 @@ function safeStringify2(v) {
|
|
|
20901
21391
|
}
|
|
20902
21392
|
}
|
|
20903
21393
|
|
|
20904
|
-
export { Agent, AgentBuilder, AgentDisposedError, AgentRunError, AuthenticationError, Budget, BudgetExceededError, ConfigurationError, Cron, EventBus, FileSystemConversationStorage, GenerateObjectError, InMemoryConversationStorage, IntegrationNotConnectedError, InvalidTaskIdError, JobQueue, Memory, MemoryAdapterError, NetworkError, PermissionEngine, RateLimitError, Security, StreamObjectError, Task, TaskNotFoundError, Theokit, TheokitAgentError, UnknownAgentError, UnsupportedBudgetOperationError, UnsupportedRunOperationError, UnsupportedTaskOperationError, UsageAccumulator, buildReplayHistory, chargeAndCheckThresholds, computeCost, createAgentFactory, createCounterBudgetTracker, createNoopMemoryProvider, createPermissionPlugin, createSquad, definePlugin, defineProvider, defineTool, extractRawId, getPricingEntry, inferApiMode, isTransientError, migrateSqliteToLance2 as migrateSqliteToLance, mkMemoryId, normalizeUsage, preflightCheck, scopedConversationId, sessionScopePrefix, toShareGptTrajectory, withCwdMutex };
|
|
21394
|
+
export { Agent, AgentBuilder, AgentDisposedError, AgentRunError, AuthenticationError, Budget, BudgetExceededError, ConfigurationError, Cron, EventBus, FileSystemConversationStorage, GenerateObjectError, InMemoryConversationStorage, IntegrationNotConnectedError, InvalidTaskIdError, JobQueue, Memory, MemoryAdapterError, NetworkError, PermissionEngine, RateLimitError, Security, StreamObjectError, Task, TaskNotFoundError, Theokit, TheokitAgentError, ToolError, UnknownAgentError, UnsupportedBudgetOperationError, UnsupportedRunOperationError, UnsupportedTaskOperationError, UsageAccumulator, applyMode, buildReplayHistory, chargeAndCheckThresholds, computeCost, createAgentFactory, createCounterBudgetTracker, createNoopMemoryProvider, createPermissionPlugin, createSessionManager, createSkill, createSquad, definePlugin, defineProvider, defineTool, emitRunEvent, extractRawId, getPricingEntry, inferApiMode, isTransientError, migrateSqliteToLance2 as migrateSqliteToLance, mkMemoryId, normalizeSchema, normalizeUsage, preflightCheck, scopedConversationId, sessionScopePrefix, toShareGptTrajectory, withCwdMutex };
|
|
20905
21395
|
//# sourceMappingURL=index.js.map
|
|
20906
21396
|
//# sourceMappingURL=index.js.map
|