@full-self-browsing/lattice 1.3.0-rc.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2502 -1241
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14280 -300
- package/dist/index.js.map +1 -1
- package/dist/rolldown-runtime-CiIaOW0V.js +13 -0
- package/dist/run-crew-CKdBjh5P.js +1010 -0
- package/dist/run-crew-CKdBjh5P.js.map +1 -0
- package/dist/{runtime-CfZ-sGGk.js → runtime-D25ehzCj.js} +261 -228
- package/dist/runtime-D25ehzCj.js.map +1 -0
- package/package.json +7 -5
- package/dist/runtime-CfZ-sGGk.js.map +0 -1
|
@@ -1,17 +1,6 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
|
|
1
2
|
import mime from "mime";
|
|
2
3
|
import canonicalize from "canonicalize";
|
|
3
|
-
//#region \0rolldown/runtime.js
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __exportAll = (all, no_symbols) => {
|
|
6
|
-
let target = {};
|
|
7
|
-
for (var name in all) __defProp(target, name, {
|
|
8
|
-
get: all[name],
|
|
9
|
-
enumerable: true
|
|
10
|
-
});
|
|
11
|
-
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
12
|
-
return target;
|
|
13
|
-
};
|
|
14
|
-
//#endregion
|
|
15
4
|
//#region src/artifacts/metadata.ts
|
|
16
5
|
const textEncoder$1 = new TextEncoder();
|
|
17
6
|
function inferMediaType(value, options) {
|
|
@@ -446,13 +435,16 @@ async function createReceipt(input, signer) {
|
|
|
446
435
|
const receiptId = input.receiptId ?? crypto.randomUUID();
|
|
447
436
|
const issuedAt = input.issuedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
448
437
|
const { body } = redactReceiptBody({
|
|
449
|
-
version: "lattice-receipt/v1.
|
|
438
|
+
version: "lattice-receipt/v1.3",
|
|
450
439
|
receiptId,
|
|
451
440
|
runId: input.runId,
|
|
452
441
|
issuedAt,
|
|
453
442
|
kid: signer.kid,
|
|
454
443
|
model: input.model,
|
|
455
444
|
route: input.route,
|
|
445
|
+
...input.modelClass !== void 0 ? { modelClass: input.modelClass } : {},
|
|
446
|
+
...input.parentReceiptCid !== void 0 ? { parentReceiptCid: input.parentReceiptCid } : {},
|
|
447
|
+
...input.lineageMerkleRoot !== void 0 ? { lineageMerkleRoot: input.lineageMerkleRoot } : {},
|
|
456
448
|
usage: usageToCanonical(input.usage),
|
|
457
449
|
contractVerdict: input.contractVerdict,
|
|
458
450
|
contractHash: input.contractHash,
|
|
@@ -597,51 +589,164 @@ function extractReceiptId(envelope) {
|
|
|
597
589
|
}
|
|
598
590
|
}
|
|
599
591
|
//#endregion
|
|
600
|
-
//#region src/
|
|
592
|
+
//#region src/agent/format-tools.ts
|
|
601
593
|
/**
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
607
|
-
*
|
|
608
|
-
*
|
|
609
|
-
* Per CONTEXT.md D-11 the noop adapter ships in Lattice (not FSB)
|
|
610
|
-
* because it covers the contract surface in Lattice's own test suite;
|
|
611
|
-
* FSB's real chrome.storage.session-backed adapter is glue layer.
|
|
594
|
+
* Convert a Standard Schema to a JSON Schema-shaped descriptor suitable for
|
|
595
|
+
* inclusion in an LLM tool description. Standard Schema vendors can
|
|
596
|
+
* optionally expose `toJSONSchema` on their schema objects; when absent,
|
|
597
|
+
* we fall back to a minimal structural description that lists the schema
|
|
598
|
+
* vendor + version + a placeholder. Models tolerate placeholder schemas in
|
|
599
|
+
* practice because the tool description is supplementary — what matters
|
|
600
|
+
* is the envelope contract (`{tool_call: {name, args}}`).
|
|
612
601
|
*/
|
|
613
|
-
function
|
|
614
|
-
const
|
|
615
|
-
|
|
616
|
-
|
|
602
|
+
function toolSchemaToJsonSchema(schema) {
|
|
603
|
+
const standardSchema = schema["~standard"];
|
|
604
|
+
if (typeof standardSchema === "object" && standardSchema !== null && "vendor" in standardSchema) {
|
|
605
|
+
const vendor = standardSchema;
|
|
606
|
+
const maybeToJson = schema.toJSONSchema;
|
|
607
|
+
if (typeof maybeToJson === "function") try {
|
|
608
|
+
return maybeToJson();
|
|
609
|
+
} catch {}
|
|
610
|
+
return {
|
|
611
|
+
$comment: `standard-schema vendor: ${vendor.vendor}; toJSONSchema not available`,
|
|
612
|
+
type: "object"
|
|
613
|
+
};
|
|
614
|
+
}
|
|
617
615
|
return {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
616
|
+
$comment: "non-standard-schema input",
|
|
617
|
+
type: "object"
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Builds the prompt-reencoded tool-use protocol handle for any provider.
|
|
622
|
+
*
|
|
623
|
+
* Phase 19 ships a uniform implementation across all 7 logical providers
|
|
624
|
+
* (openai, openai-compat, anthropic, gemini, xai, openrouter, lm-studio).
|
|
625
|
+
* The `providerName` argument is accepted for forward compatibility but
|
|
626
|
+
* does not branch the implementation in v1.2.
|
|
627
|
+
*/
|
|
628
|
+
function formatToolsForProvider(providerName, tools, options = {}) {
|
|
629
|
+
options.mode;
|
|
630
|
+
const system = options.system?.trim() ?? "";
|
|
631
|
+
const toolDescriptions = tools.map((tool) => {
|
|
632
|
+
const schemaDescriptor = toolSchemaToJsonSchema(tool.inputSchema);
|
|
633
|
+
const schemaJson = JSON.stringify(schemaDescriptor, null, 2);
|
|
634
|
+
const desc = tool.description?.trim() ?? "(no description)";
|
|
635
|
+
return `- name: ${tool.name}\n description: ${desc}\n args_schema: ${schemaJson}`;
|
|
636
|
+
}).join("\n");
|
|
637
|
+
const envelopeInstructions = [
|
|
638
|
+
"You are a single-agent loop. You can either:",
|
|
639
|
+
" (a) answer the user directly with a final response, OR",
|
|
640
|
+
" (b) request one or more tool calls.",
|
|
641
|
+
"",
|
|
642
|
+
"To request tool calls, respond with ONE JSON object on a line by itself:",
|
|
643
|
+
" {\"tool_calls\": [{\"id\": \"...\", \"name\": \"tool_name\", \"args\": {...}}]}",
|
|
644
|
+
"Each tool_call needs a unique id (any string). The args MUST match the tool's args_schema.",
|
|
645
|
+
"",
|
|
646
|
+
"To answer directly, respond with a final answer in natural language with NO JSON envelope.",
|
|
647
|
+
"Do not mix a final answer and a tool_calls envelope in the same response."
|
|
648
|
+
].join("\n");
|
|
649
|
+
const systemBlock = [
|
|
650
|
+
system,
|
|
651
|
+
"",
|
|
652
|
+
"Available tools:",
|
|
653
|
+
toolDescriptions || "(none)",
|
|
654
|
+
"",
|
|
655
|
+
envelopeInstructions
|
|
656
|
+
].filter((s) => s !== "" || true).join("\n").replace(/^\n+/, "").trimEnd();
|
|
657
|
+
function assembleTask(conversation, includeSystemBlock) {
|
|
658
|
+
const lines = [];
|
|
659
|
+
if (includeSystemBlock) lines.push(systemBlock);
|
|
660
|
+
lines.push("");
|
|
661
|
+
lines.push("---");
|
|
662
|
+
lines.push("");
|
|
663
|
+
for (const turn of conversation) {
|
|
664
|
+
if (turn.role === "user") lines.push(`USER:\n${turn.content}`);
|
|
665
|
+
else if (turn.role === "assistant") lines.push(`ASSISTANT:\n${turn.content}`);
|
|
666
|
+
else {
|
|
667
|
+
const idHint = turn.toolCallId !== void 0 ? ` id=${turn.toolCallId}` : "";
|
|
668
|
+
const nameHint = turn.toolName !== void 0 ? ` name=${turn.toolName}` : "";
|
|
669
|
+
lines.push(`TOOL_RESULT (${nameHint.trim() || "tool"}${idHint}):\n${turn.content}`);
|
|
670
|
+
}
|
|
671
|
+
lines.push("");
|
|
642
672
|
}
|
|
673
|
+
lines.push("ASSISTANT:");
|
|
674
|
+
return lines.join("\n");
|
|
675
|
+
}
|
|
676
|
+
function buildTask(conversation) {
|
|
677
|
+
return assembleTask(conversation, true);
|
|
678
|
+
}
|
|
679
|
+
function buildTaskBody(conversation) {
|
|
680
|
+
return assembleTask(conversation, false);
|
|
681
|
+
}
|
|
682
|
+
function describeForSystem() {
|
|
683
|
+
return systemBlock;
|
|
684
|
+
}
|
|
685
|
+
return {
|
|
686
|
+
buildTask,
|
|
687
|
+
buildTaskBody,
|
|
688
|
+
parseToolUse: parseToolUseEnvelope,
|
|
689
|
+
describeForSystem,
|
|
690
|
+
mode: "prompt-reencoded"
|
|
643
691
|
};
|
|
644
692
|
}
|
|
693
|
+
function parseToolUseEnvelope(responseText) {
|
|
694
|
+
if (typeof responseText !== "string" || responseText.length === 0) return null;
|
|
695
|
+
const candidates = extractJsonCandidates(responseText);
|
|
696
|
+
for (const candidate of candidates) {
|
|
697
|
+
const parsed = tryParseEnvelope(candidate);
|
|
698
|
+
if (parsed !== null) return parsed;
|
|
699
|
+
}
|
|
700
|
+
return null;
|
|
701
|
+
}
|
|
702
|
+
/**
|
|
703
|
+
* Extracts JSON-looking candidate substrings from a response text.
|
|
704
|
+
*
|
|
705
|
+
* Models routinely wrap JSON in markdown code fences (```json ... ```),
|
|
706
|
+
* prepend explanatory prose ("I'll call the search tool: { ... }"), or
|
|
707
|
+
* produce multiple JSON-shaped blobs. This extractor scans for plausible
|
|
708
|
+
* candidates ordered by likelihood.
|
|
709
|
+
*/
|
|
710
|
+
function extractJsonCandidates(text) {
|
|
711
|
+
const candidates = [];
|
|
712
|
+
const fenceRegex = /```(?:json)?\s*([\s\S]*?)```/g;
|
|
713
|
+
let fenceMatch;
|
|
714
|
+
while ((fenceMatch = fenceRegex.exec(text)) !== null) {
|
|
715
|
+
const inner = fenceMatch[1];
|
|
716
|
+
if (inner !== void 0) candidates.push(inner.trim());
|
|
717
|
+
}
|
|
718
|
+
const braceStart = text.indexOf("{");
|
|
719
|
+
const braceEnd = text.lastIndexOf("}");
|
|
720
|
+
if (braceStart !== -1 && braceEnd > braceStart) candidates.push(text.slice(braceStart, braceEnd + 1));
|
|
721
|
+
candidates.push(text.trim());
|
|
722
|
+
return candidates;
|
|
723
|
+
}
|
|
724
|
+
function tryParseEnvelope(jsonLike) {
|
|
725
|
+
let parsed;
|
|
726
|
+
try {
|
|
727
|
+
parsed = JSON.parse(jsonLike);
|
|
728
|
+
} catch {
|
|
729
|
+
return null;
|
|
730
|
+
}
|
|
731
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
732
|
+
const toolCalls = parsed["tool_calls"];
|
|
733
|
+
if (!Array.isArray(toolCalls) || toolCalls.length === 0) return null;
|
|
734
|
+
const requests = [];
|
|
735
|
+
for (const call of toolCalls) {
|
|
736
|
+
if (typeof call !== "object" || call === null) return null;
|
|
737
|
+
const callRecord = call;
|
|
738
|
+
const id = callRecord["id"];
|
|
739
|
+
const name = callRecord["name"];
|
|
740
|
+
const args = callRecord["args"];
|
|
741
|
+
if (typeof id !== "string" || typeof name !== "string") return null;
|
|
742
|
+
requests.push({
|
|
743
|
+
id,
|
|
744
|
+
name,
|
|
745
|
+
args
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
return requests;
|
|
749
|
+
}
|
|
645
750
|
//#endregion
|
|
646
751
|
//#region src/outputs/validate.ts
|
|
647
752
|
async function validateSchemaOutput(name, schema, value) {
|
|
@@ -771,6 +876,52 @@ function normalizePathKey(key) {
|
|
|
771
876
|
return key;
|
|
772
877
|
}
|
|
773
878
|
//#endregion
|
|
879
|
+
//#region src/runtime/survivability.ts
|
|
880
|
+
/**
|
|
881
|
+
* Reference implementation of SurvivabilityAdapter<TState>. Records
|
|
882
|
+
* eviction events but does NOT persist; serialize / deserialize round-
|
|
883
|
+
* trip via JSON.stringify / JSON.parse. Analog to createFakeProvider
|
|
884
|
+
* in the providers/ module -- gives Lattice's vitest a complete shape-
|
|
885
|
+
* conformance target before the real (FSB-side) adapter ships in
|
|
886
|
+
* Plan 05-05.
|
|
887
|
+
*
|
|
888
|
+
* Per CONTEXT.md D-11 the noop adapter ships in Lattice (not FSB)
|
|
889
|
+
* because it covers the contract surface in Lattice's own test suite;
|
|
890
|
+
* FSB's real chrome.storage.session-backed adapter is glue layer.
|
|
891
|
+
*/
|
|
892
|
+
function createNoopSurvivabilityAdapter(options = {}) {
|
|
893
|
+
const id = options.id ?? "noop-survivability";
|
|
894
|
+
const defaultPolicy = options.policy ?? "SAFE";
|
|
895
|
+
const hooks = /* @__PURE__ */ new Set();
|
|
896
|
+
return {
|
|
897
|
+
kind: "survivability-adapter",
|
|
898
|
+
id,
|
|
899
|
+
serialize(state) {
|
|
900
|
+
return {
|
|
901
|
+
kind: "survivability-snapshot",
|
|
902
|
+
version: "lattice-survivability/v1",
|
|
903
|
+
payload: JSON.stringify(state ?? null),
|
|
904
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
905
|
+
};
|
|
906
|
+
},
|
|
907
|
+
deserialize(snapshot) {
|
|
908
|
+
return JSON.parse(snapshot.payload);
|
|
909
|
+
},
|
|
910
|
+
onEviction(hook) {
|
|
911
|
+
hooks.add(hook);
|
|
912
|
+
let unsubscribed = false;
|
|
913
|
+
return () => {
|
|
914
|
+
if (unsubscribed) return;
|
|
915
|
+
unsubscribed = true;
|
|
916
|
+
hooks.delete(hook);
|
|
917
|
+
};
|
|
918
|
+
},
|
|
919
|
+
async resume(_snapshot) {
|
|
920
|
+
return defaultPolicy;
|
|
921
|
+
}
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
//#endregion
|
|
774
925
|
//#region src/tools/tools.ts
|
|
775
926
|
function defineTool(definition) {
|
|
776
927
|
return {
|
|
@@ -815,158 +966,6 @@ function createToolCallId() {
|
|
|
815
966
|
return `${Date.now()}:${Math.random().toString(16).slice(2)}`;
|
|
816
967
|
}
|
|
817
968
|
//#endregion
|
|
818
|
-
//#region src/agent/format-tools.ts
|
|
819
|
-
/**
|
|
820
|
-
* Convert a Standard Schema to a JSON Schema-shaped descriptor suitable for
|
|
821
|
-
* inclusion in an LLM tool description. Standard Schema vendors can
|
|
822
|
-
* optionally expose `toJSONSchema` on their schema objects; when absent,
|
|
823
|
-
* we fall back to a minimal structural description that lists the schema
|
|
824
|
-
* vendor + version + a placeholder. Models tolerate placeholder schemas in
|
|
825
|
-
* practice because the tool description is supplementary — what matters
|
|
826
|
-
* is the envelope contract (`{tool_call: {name, args}}`).
|
|
827
|
-
*/
|
|
828
|
-
function toolSchemaToJsonSchema(schema) {
|
|
829
|
-
const standardSchema = schema["~standard"];
|
|
830
|
-
if (typeof standardSchema === "object" && standardSchema !== null && "vendor" in standardSchema) {
|
|
831
|
-
const vendor = standardSchema;
|
|
832
|
-
const maybeToJson = schema.toJSONSchema;
|
|
833
|
-
if (typeof maybeToJson === "function") try {
|
|
834
|
-
return maybeToJson();
|
|
835
|
-
} catch {}
|
|
836
|
-
return {
|
|
837
|
-
$comment: `standard-schema vendor: ${vendor.vendor}; toJSONSchema not available`,
|
|
838
|
-
type: "object"
|
|
839
|
-
};
|
|
840
|
-
}
|
|
841
|
-
return {
|
|
842
|
-
$comment: "non-standard-schema input",
|
|
843
|
-
type: "object"
|
|
844
|
-
};
|
|
845
|
-
}
|
|
846
|
-
/**
|
|
847
|
-
* Builds the prompt-reencoded tool-use protocol handle for any provider.
|
|
848
|
-
*
|
|
849
|
-
* Phase 19 ships a uniform implementation across all 7 logical providers
|
|
850
|
-
* (openai, openai-compat, anthropic, gemini, xai, openrouter, lm-studio).
|
|
851
|
-
* The `providerName` argument is accepted for forward compatibility but
|
|
852
|
-
* does not branch the implementation in v1.2.
|
|
853
|
-
*/
|
|
854
|
-
function formatToolsForProvider(providerName, tools, options = {}) {
|
|
855
|
-
options.mode;
|
|
856
|
-
const system = options.system?.trim() ?? "";
|
|
857
|
-
const toolDescriptions = tools.map((tool) => {
|
|
858
|
-
const schemaDescriptor = toolSchemaToJsonSchema(tool.inputSchema);
|
|
859
|
-
const schemaJson = JSON.stringify(schemaDescriptor, null, 2);
|
|
860
|
-
const desc = tool.description?.trim() ?? "(no description)";
|
|
861
|
-
return `- name: ${tool.name}\n description: ${desc}\n args_schema: ${schemaJson}`;
|
|
862
|
-
}).join("\n");
|
|
863
|
-
const envelopeInstructions = [
|
|
864
|
-
"You are a single-agent loop. You can either:",
|
|
865
|
-
" (a) answer the user directly with a final response, OR",
|
|
866
|
-
" (b) request one or more tool calls.",
|
|
867
|
-
"",
|
|
868
|
-
"To request tool calls, respond with ONE JSON object on a line by itself:",
|
|
869
|
-
" {\"tool_calls\": [{\"id\": \"...\", \"name\": \"tool_name\", \"args\": {...}}]}",
|
|
870
|
-
"Each tool_call needs a unique id (any string). The args MUST match the tool's args_schema.",
|
|
871
|
-
"",
|
|
872
|
-
"To answer directly, respond with a final answer in natural language with NO JSON envelope.",
|
|
873
|
-
"Do not mix a final answer and a tool_calls envelope in the same response."
|
|
874
|
-
].join("\n");
|
|
875
|
-
const systemBlock = [
|
|
876
|
-
system,
|
|
877
|
-
"",
|
|
878
|
-
"Available tools:",
|
|
879
|
-
toolDescriptions || "(none)",
|
|
880
|
-
"",
|
|
881
|
-
envelopeInstructions
|
|
882
|
-
].filter((s) => s !== "" || true).join("\n").replace(/^\n+/, "").trimEnd();
|
|
883
|
-
function buildTask(conversation) {
|
|
884
|
-
const lines = [];
|
|
885
|
-
lines.push(systemBlock);
|
|
886
|
-
lines.push("");
|
|
887
|
-
lines.push("---");
|
|
888
|
-
lines.push("");
|
|
889
|
-
for (const turn of conversation) {
|
|
890
|
-
if (turn.role === "user") lines.push(`USER:\n${turn.content}`);
|
|
891
|
-
else if (turn.role === "assistant") lines.push(`ASSISTANT:\n${turn.content}`);
|
|
892
|
-
else {
|
|
893
|
-
const idHint = turn.toolCallId !== void 0 ? ` id=${turn.toolCallId}` : "";
|
|
894
|
-
const nameHint = turn.toolName !== void 0 ? ` name=${turn.toolName}` : "";
|
|
895
|
-
lines.push(`TOOL_RESULT (${nameHint.trim() || "tool"}${idHint}):\n${turn.content}`);
|
|
896
|
-
}
|
|
897
|
-
lines.push("");
|
|
898
|
-
}
|
|
899
|
-
lines.push("ASSISTANT:");
|
|
900
|
-
return lines.join("\n");
|
|
901
|
-
}
|
|
902
|
-
function parseToolUse(responseText) {
|
|
903
|
-
if (typeof responseText !== "string" || responseText.length === 0) return null;
|
|
904
|
-
const candidates = extractJsonCandidates(responseText);
|
|
905
|
-
for (const candidate of candidates) {
|
|
906
|
-
const parsed = tryParseEnvelope(candidate);
|
|
907
|
-
if (parsed !== null) return parsed;
|
|
908
|
-
}
|
|
909
|
-
return null;
|
|
910
|
-
}
|
|
911
|
-
function describeForSystem() {
|
|
912
|
-
return systemBlock;
|
|
913
|
-
}
|
|
914
|
-
return {
|
|
915
|
-
buildTask,
|
|
916
|
-
parseToolUse,
|
|
917
|
-
describeForSystem,
|
|
918
|
-
mode: "prompt-reencoded"
|
|
919
|
-
};
|
|
920
|
-
}
|
|
921
|
-
/**
|
|
922
|
-
* Extracts JSON-looking candidate substrings from a response text.
|
|
923
|
-
*
|
|
924
|
-
* Models routinely wrap JSON in markdown code fences (```json ... ```),
|
|
925
|
-
* prepend explanatory prose ("I'll call the search tool: { ... }"), or
|
|
926
|
-
* produce multiple JSON-shaped blobs. This extractor scans for plausible
|
|
927
|
-
* candidates ordered by likelihood.
|
|
928
|
-
*/
|
|
929
|
-
function extractJsonCandidates(text) {
|
|
930
|
-
const candidates = [];
|
|
931
|
-
const fenceRegex = /```(?:json)?\s*([\s\S]*?)```/g;
|
|
932
|
-
let fenceMatch;
|
|
933
|
-
while ((fenceMatch = fenceRegex.exec(text)) !== null) {
|
|
934
|
-
const inner = fenceMatch[1];
|
|
935
|
-
if (inner !== void 0) candidates.push(inner.trim());
|
|
936
|
-
}
|
|
937
|
-
const braceStart = text.indexOf("{");
|
|
938
|
-
const braceEnd = text.lastIndexOf("}");
|
|
939
|
-
if (braceStart !== -1 && braceEnd > braceStart) candidates.push(text.slice(braceStart, braceEnd + 1));
|
|
940
|
-
candidates.push(text.trim());
|
|
941
|
-
return candidates;
|
|
942
|
-
}
|
|
943
|
-
function tryParseEnvelope(jsonLike) {
|
|
944
|
-
let parsed;
|
|
945
|
-
try {
|
|
946
|
-
parsed = JSON.parse(jsonLike);
|
|
947
|
-
} catch {
|
|
948
|
-
return null;
|
|
949
|
-
}
|
|
950
|
-
if (typeof parsed !== "object" || parsed === null) return null;
|
|
951
|
-
const toolCalls = parsed["tool_calls"];
|
|
952
|
-
if (!Array.isArray(toolCalls) || toolCalls.length === 0) return null;
|
|
953
|
-
const requests = [];
|
|
954
|
-
for (const call of toolCalls) {
|
|
955
|
-
if (typeof call !== "object" || call === null) return null;
|
|
956
|
-
const callRecord = call;
|
|
957
|
-
const id = callRecord["id"];
|
|
958
|
-
const name = callRecord["name"];
|
|
959
|
-
const args = callRecord["args"];
|
|
960
|
-
if (typeof id !== "string" || typeof name !== "string") return null;
|
|
961
|
-
requests.push({
|
|
962
|
-
id,
|
|
963
|
-
name,
|
|
964
|
-
args
|
|
965
|
-
});
|
|
966
|
-
}
|
|
967
|
-
return requests;
|
|
968
|
-
}
|
|
969
|
-
//#endregion
|
|
970
969
|
//#region src/agent/host.ts
|
|
971
970
|
/**
|
|
972
971
|
* Reference implementation suitable for Node tests + the Phase 19 default
|
|
@@ -1020,7 +1019,10 @@ var AgentDeniedError = class extends Error {
|
|
|
1020
1019
|
};
|
|
1021
1020
|
//#endregion
|
|
1022
1021
|
//#region src/agent/runtime.ts
|
|
1023
|
-
var runtime_exports = /* @__PURE__ */ __exportAll({
|
|
1022
|
+
var runtime_exports = /* @__PURE__ */ __exportAll({
|
|
1023
|
+
runAgent: () => runAgent,
|
|
1024
|
+
runAgentInternal: () => runAgentInternal
|
|
1025
|
+
});
|
|
1024
1026
|
const ZERO_USAGE = {
|
|
1025
1027
|
promptTokens: 0,
|
|
1026
1028
|
completionTokens: 0,
|
|
@@ -1033,8 +1035,20 @@ const ZERO_USAGE = {
|
|
|
1033
1035
|
* calling Promise), direct transport (provider.execute()), and in-memory
|
|
1034
1036
|
* transcript (the `conversation` array). Phase 20 promotes scheduler /
|
|
1035
1037
|
* transport / storage to the pluggable `AgentHost` adapter.
|
|
1038
|
+
*
|
|
1039
|
+
* Phase 39: `runAgent` is a thin public wrapper over `runAgentInternal`
|
|
1040
|
+
* with no internal options — the public signature and behavior are
|
|
1041
|
+
* unchanged.
|
|
1036
1042
|
*/
|
|
1037
1043
|
async function runAgent(intent, config = {}) {
|
|
1044
|
+
return runAgentInternal(intent, config);
|
|
1045
|
+
}
|
|
1046
|
+
/**
|
|
1047
|
+
* The agent-loop implementation with the internal dispatch seam (Phase 39).
|
|
1048
|
+
* In-package consumers (agent/crew/, 39-05) call this directly; it is NOT
|
|
1049
|
+
* part of the public package surface.
|
|
1050
|
+
*/
|
|
1051
|
+
async function runAgentInternal(intent, config = {}, internalOptions = {}) {
|
|
1038
1052
|
const startedAt = Date.now();
|
|
1039
1053
|
const cumulativeUsage = {
|
|
1040
1054
|
promptTokens: 0,
|
|
@@ -1169,8 +1183,12 @@ async function runAgent(intent, config = {}) {
|
|
|
1169
1183
|
const iterUsage = response.normalizedUsage ?? ZERO_USAGE;
|
|
1170
1184
|
accumulateUsage(cumulativeUsage, iterUsage);
|
|
1171
1185
|
const responseText = extractResponseText(response);
|
|
1172
|
-
const toolUseRequests =
|
|
1173
|
-
|
|
1186
|
+
const toolUseRequests = response.toolCalls !== void 0 ? response.toolCalls.map((toolCall) => ({
|
|
1187
|
+
id: toolCall.id,
|
|
1188
|
+
name: toolCall.name,
|
|
1189
|
+
args: toolCall.args
|
|
1190
|
+
})) : handle.parseToolUse(responseText);
|
|
1191
|
+
if (toolUseRequests === null || toolUseRequests.length === 0) {
|
|
1174
1192
|
const finalRecord = {
|
|
1175
1193
|
index: iterationIndex,
|
|
1176
1194
|
provider: providerName,
|
|
@@ -1195,9 +1213,11 @@ async function runAgent(intent, config = {}) {
|
|
|
1195
1213
|
previousStepName: `agent-iteration-${iterationIndex}-before`
|
|
1196
1214
|
});
|
|
1197
1215
|
await host.storage?.clear();
|
|
1216
|
+
const artifactRefs = response.artifactRefs !== void 0 ? response.artifactRefs.map(toArtifactRef) : [];
|
|
1198
1217
|
return {
|
|
1199
1218
|
kind: "success",
|
|
1200
1219
|
output: { answer: responseText },
|
|
1220
|
+
...artifactRefs.length > 0 ? { artifacts: artifactRefs } : {},
|
|
1201
1221
|
usage: snapshotUsage(cumulativeUsage),
|
|
1202
1222
|
iterations: Object.freeze([...iterations])
|
|
1203
1223
|
};
|
|
@@ -1208,28 +1228,41 @@ async function runAgent(intent, config = {}) {
|
|
|
1208
1228
|
});
|
|
1209
1229
|
const toolCallRecords = [];
|
|
1210
1230
|
for (const req of toolUseRequests) {
|
|
1211
|
-
|
|
1212
|
-
let toolResult = null;
|
|
1213
|
-
let resultContent;
|
|
1231
|
+
let resultContent = null;
|
|
1214
1232
|
let resultHash = "tool-not-found";
|
|
1215
|
-
if (
|
|
1216
|
-
|
|
1217
|
-
await pipeline.run("BEFORE_TOOL", {
|
|
1233
|
+
if (internalOptions.dispatchToolUse !== void 0) {
|
|
1234
|
+
const dispatched = await internalOptions.dispatchToolUse(req, {
|
|
1218
1235
|
iterationIndex,
|
|
1219
|
-
|
|
1220
|
-
|
|
1236
|
+
conversation,
|
|
1237
|
+
pipeline
|
|
1221
1238
|
});
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
});
|
|
1231
|
-
|
|
1232
|
-
|
|
1239
|
+
if (dispatched !== void 0) {
|
|
1240
|
+
resultContent = dispatched.content;
|
|
1241
|
+
resultHash = stableHash(dispatched.content);
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
if (resultContent === null) {
|
|
1245
|
+
const tool = intent.tools.find((t) => t.name === req.name);
|
|
1246
|
+
let toolResult = null;
|
|
1247
|
+
if (tool === void 0) resultContent = JSON.stringify({ error: `Unknown tool: ${req.name}` });
|
|
1248
|
+
else try {
|
|
1249
|
+
await pipeline.run("BEFORE_TOOL", {
|
|
1250
|
+
iterationIndex,
|
|
1251
|
+
toolName: req.name,
|
|
1252
|
+
args: req.args
|
|
1253
|
+
});
|
|
1254
|
+
toolResult = await runTool(tool, req.args);
|
|
1255
|
+
resultContent = stringifyArtifactValue(toolResult.artifact.value);
|
|
1256
|
+
resultHash = toolResult.callId;
|
|
1257
|
+
await pipeline.run("AFTER_TOOL", {
|
|
1258
|
+
iterationIndex,
|
|
1259
|
+
toolName: req.name,
|
|
1260
|
+
args: req.args,
|
|
1261
|
+
result: toolResult.artifact.value
|
|
1262
|
+
});
|
|
1263
|
+
} catch (error) {
|
|
1264
|
+
resultContent = JSON.stringify({ error: error instanceof Error ? error.message : "Tool execution failed" });
|
|
1265
|
+
}
|
|
1233
1266
|
}
|
|
1234
1267
|
conversation.push({
|
|
1235
1268
|
role: "tool",
|
|
@@ -1354,6 +1387,6 @@ function stableHash(input) {
|
|
|
1354
1387
|
}
|
|
1355
1388
|
}
|
|
1356
1389
|
//#endregion
|
|
1357
|
-
export {
|
|
1390
|
+
export { decodeEnvelope as C, artifact as D, createHookPipeline as E, isArtifactRef as O, buildPae as S, BAND as T, STEP_TRANSITION_EVENT_NAME as _, createNoopAgentHost as a, PAYLOAD_TYPE as b, runTool as c, validateOutputMap as d, validateSchemaOutput as f, DEFAULT_CHECKPOINT_BAND as g, toolSchemaToJsonSchema as h, AgentDeniedError as i, toArtifactRef as k, toolArtifactRef as l, parseToolUseEnvelope as m, runAgentInternal as n, defineTool as o, formatToolsForProvider as p, runtime_exports as r, importMcpTools as s, runAgent as t, createNoopSurvivabilityAdapter as u, createCheckpointHook as v, canonicalizeReceiptBody as w, base64Encode as x, createReceipt as y };
|
|
1358
1391
|
|
|
1359
|
-
//# sourceMappingURL=runtime-
|
|
1392
|
+
//# sourceMappingURL=runtime-D25ehzCj.js.map
|