@full-self-browsing/lattice 1.3.0-rc.0 → 1.3.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 +2227 -1253
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6237 -130
- package/dist/index.js.map +1 -1
- package/dist/rolldown-runtime-CiIaOW0V.js +13 -0
- package/dist/run-crew-DDznbc3G.js +888 -0
- package/dist/run-crew-DDznbc3G.js.map +1 -0
- package/dist/{runtime-CfZ-sGGk.js → runtime-BTi8lr_O.js} +258 -228
- package/dist/runtime-BTi8lr_O.js.map +1 -0
- package/package.json +1 -1
- 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,15 @@ 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.2",
|
|
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 } : {},
|
|
456
447
|
usage: usageToCanonical(input.usage),
|
|
457
448
|
contractVerdict: input.contractVerdict,
|
|
458
449
|
contractHash: input.contractHash,
|
|
@@ -597,51 +588,164 @@ function extractReceiptId(envelope) {
|
|
|
597
588
|
}
|
|
598
589
|
}
|
|
599
590
|
//#endregion
|
|
600
|
-
//#region src/
|
|
591
|
+
//#region src/agent/format-tools.ts
|
|
601
592
|
/**
|
|
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.
|
|
593
|
+
* Convert a Standard Schema to a JSON Schema-shaped descriptor suitable for
|
|
594
|
+
* inclusion in an LLM tool description. Standard Schema vendors can
|
|
595
|
+
* optionally expose `toJSONSchema` on their schema objects; when absent,
|
|
596
|
+
* we fall back to a minimal structural description that lists the schema
|
|
597
|
+
* vendor + version + a placeholder. Models tolerate placeholder schemas in
|
|
598
|
+
* practice because the tool description is supplementary — what matters
|
|
599
|
+
* is the envelope contract (`{tool_call: {name, args}}`).
|
|
612
600
|
*/
|
|
613
|
-
function
|
|
614
|
-
const
|
|
615
|
-
|
|
616
|
-
|
|
601
|
+
function toolSchemaToJsonSchema(schema) {
|
|
602
|
+
const standardSchema = schema["~standard"];
|
|
603
|
+
if (typeof standardSchema === "object" && standardSchema !== null && "vendor" in standardSchema) {
|
|
604
|
+
const vendor = standardSchema;
|
|
605
|
+
const maybeToJson = schema.toJSONSchema;
|
|
606
|
+
if (typeof maybeToJson === "function") try {
|
|
607
|
+
return maybeToJson();
|
|
608
|
+
} catch {}
|
|
609
|
+
return {
|
|
610
|
+
$comment: `standard-schema vendor: ${vendor.vendor}; toJSONSchema not available`,
|
|
611
|
+
type: "object"
|
|
612
|
+
};
|
|
613
|
+
}
|
|
617
614
|
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
|
-
|
|
615
|
+
$comment: "non-standard-schema input",
|
|
616
|
+
type: "object"
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* Builds the prompt-reencoded tool-use protocol handle for any provider.
|
|
621
|
+
*
|
|
622
|
+
* Phase 19 ships a uniform implementation across all 7 logical providers
|
|
623
|
+
* (openai, openai-compat, anthropic, gemini, xai, openrouter, lm-studio).
|
|
624
|
+
* The `providerName` argument is accepted for forward compatibility but
|
|
625
|
+
* does not branch the implementation in v1.2.
|
|
626
|
+
*/
|
|
627
|
+
function formatToolsForProvider(providerName, tools, options = {}) {
|
|
628
|
+
options.mode;
|
|
629
|
+
const system = options.system?.trim() ?? "";
|
|
630
|
+
const toolDescriptions = tools.map((tool) => {
|
|
631
|
+
const schemaDescriptor = toolSchemaToJsonSchema(tool.inputSchema);
|
|
632
|
+
const schemaJson = JSON.stringify(schemaDescriptor, null, 2);
|
|
633
|
+
const desc = tool.description?.trim() ?? "(no description)";
|
|
634
|
+
return `- name: ${tool.name}\n description: ${desc}\n args_schema: ${schemaJson}`;
|
|
635
|
+
}).join("\n");
|
|
636
|
+
const envelopeInstructions = [
|
|
637
|
+
"You are a single-agent loop. You can either:",
|
|
638
|
+
" (a) answer the user directly with a final response, OR",
|
|
639
|
+
" (b) request one or more tool calls.",
|
|
640
|
+
"",
|
|
641
|
+
"To request tool calls, respond with ONE JSON object on a line by itself:",
|
|
642
|
+
" {\"tool_calls\": [{\"id\": \"...\", \"name\": \"tool_name\", \"args\": {...}}]}",
|
|
643
|
+
"Each tool_call needs a unique id (any string). The args MUST match the tool's args_schema.",
|
|
644
|
+
"",
|
|
645
|
+
"To answer directly, respond with a final answer in natural language with NO JSON envelope.",
|
|
646
|
+
"Do not mix a final answer and a tool_calls envelope in the same response."
|
|
647
|
+
].join("\n");
|
|
648
|
+
const systemBlock = [
|
|
649
|
+
system,
|
|
650
|
+
"",
|
|
651
|
+
"Available tools:",
|
|
652
|
+
toolDescriptions || "(none)",
|
|
653
|
+
"",
|
|
654
|
+
envelopeInstructions
|
|
655
|
+
].filter((s) => s !== "" || true).join("\n").replace(/^\n+/, "").trimEnd();
|
|
656
|
+
function assembleTask(conversation, includeSystemBlock) {
|
|
657
|
+
const lines = [];
|
|
658
|
+
if (includeSystemBlock) lines.push(systemBlock);
|
|
659
|
+
lines.push("");
|
|
660
|
+
lines.push("---");
|
|
661
|
+
lines.push("");
|
|
662
|
+
for (const turn of conversation) {
|
|
663
|
+
if (turn.role === "user") lines.push(`USER:\n${turn.content}`);
|
|
664
|
+
else if (turn.role === "assistant") lines.push(`ASSISTANT:\n${turn.content}`);
|
|
665
|
+
else {
|
|
666
|
+
const idHint = turn.toolCallId !== void 0 ? ` id=${turn.toolCallId}` : "";
|
|
667
|
+
const nameHint = turn.toolName !== void 0 ? ` name=${turn.toolName}` : "";
|
|
668
|
+
lines.push(`TOOL_RESULT (${nameHint.trim() || "tool"}${idHint}):\n${turn.content}`);
|
|
669
|
+
}
|
|
670
|
+
lines.push("");
|
|
642
671
|
}
|
|
672
|
+
lines.push("ASSISTANT:");
|
|
673
|
+
return lines.join("\n");
|
|
674
|
+
}
|
|
675
|
+
function buildTask(conversation) {
|
|
676
|
+
return assembleTask(conversation, true);
|
|
677
|
+
}
|
|
678
|
+
function buildTaskBody(conversation) {
|
|
679
|
+
return assembleTask(conversation, false);
|
|
680
|
+
}
|
|
681
|
+
function describeForSystem() {
|
|
682
|
+
return systemBlock;
|
|
683
|
+
}
|
|
684
|
+
return {
|
|
685
|
+
buildTask,
|
|
686
|
+
buildTaskBody,
|
|
687
|
+
parseToolUse: parseToolUseEnvelope,
|
|
688
|
+
describeForSystem,
|
|
689
|
+
mode: "prompt-reencoded"
|
|
643
690
|
};
|
|
644
691
|
}
|
|
692
|
+
function parseToolUseEnvelope(responseText) {
|
|
693
|
+
if (typeof responseText !== "string" || responseText.length === 0) return null;
|
|
694
|
+
const candidates = extractJsonCandidates(responseText);
|
|
695
|
+
for (const candidate of candidates) {
|
|
696
|
+
const parsed = tryParseEnvelope(candidate);
|
|
697
|
+
if (parsed !== null) return parsed;
|
|
698
|
+
}
|
|
699
|
+
return null;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Extracts JSON-looking candidate substrings from a response text.
|
|
703
|
+
*
|
|
704
|
+
* Models routinely wrap JSON in markdown code fences (```json ... ```),
|
|
705
|
+
* prepend explanatory prose ("I'll call the search tool: { ... }"), or
|
|
706
|
+
* produce multiple JSON-shaped blobs. This extractor scans for plausible
|
|
707
|
+
* candidates ordered by likelihood.
|
|
708
|
+
*/
|
|
709
|
+
function extractJsonCandidates(text) {
|
|
710
|
+
const candidates = [];
|
|
711
|
+
const fenceRegex = /```(?:json)?\s*([\s\S]*?)```/g;
|
|
712
|
+
let fenceMatch;
|
|
713
|
+
while ((fenceMatch = fenceRegex.exec(text)) !== null) {
|
|
714
|
+
const inner = fenceMatch[1];
|
|
715
|
+
if (inner !== void 0) candidates.push(inner.trim());
|
|
716
|
+
}
|
|
717
|
+
const braceStart = text.indexOf("{");
|
|
718
|
+
const braceEnd = text.lastIndexOf("}");
|
|
719
|
+
if (braceStart !== -1 && braceEnd > braceStart) candidates.push(text.slice(braceStart, braceEnd + 1));
|
|
720
|
+
candidates.push(text.trim());
|
|
721
|
+
return candidates;
|
|
722
|
+
}
|
|
723
|
+
function tryParseEnvelope(jsonLike) {
|
|
724
|
+
let parsed;
|
|
725
|
+
try {
|
|
726
|
+
parsed = JSON.parse(jsonLike);
|
|
727
|
+
} catch {
|
|
728
|
+
return null;
|
|
729
|
+
}
|
|
730
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
731
|
+
const toolCalls = parsed["tool_calls"];
|
|
732
|
+
if (!Array.isArray(toolCalls) || toolCalls.length === 0) return null;
|
|
733
|
+
const requests = [];
|
|
734
|
+
for (const call of toolCalls) {
|
|
735
|
+
if (typeof call !== "object" || call === null) return null;
|
|
736
|
+
const callRecord = call;
|
|
737
|
+
const id = callRecord["id"];
|
|
738
|
+
const name = callRecord["name"];
|
|
739
|
+
const args = callRecord["args"];
|
|
740
|
+
if (typeof id !== "string" || typeof name !== "string") return null;
|
|
741
|
+
requests.push({
|
|
742
|
+
id,
|
|
743
|
+
name,
|
|
744
|
+
args
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
return requests;
|
|
748
|
+
}
|
|
645
749
|
//#endregion
|
|
646
750
|
//#region src/outputs/validate.ts
|
|
647
751
|
async function validateSchemaOutput(name, schema, value) {
|
|
@@ -771,6 +875,52 @@ function normalizePathKey(key) {
|
|
|
771
875
|
return key;
|
|
772
876
|
}
|
|
773
877
|
//#endregion
|
|
878
|
+
//#region src/runtime/survivability.ts
|
|
879
|
+
/**
|
|
880
|
+
* Reference implementation of SurvivabilityAdapter<TState>. Records
|
|
881
|
+
* eviction events but does NOT persist; serialize / deserialize round-
|
|
882
|
+
* trip via JSON.stringify / JSON.parse. Analog to createFakeProvider
|
|
883
|
+
* in the providers/ module -- gives Lattice's vitest a complete shape-
|
|
884
|
+
* conformance target before the real (FSB-side) adapter ships in
|
|
885
|
+
* Plan 05-05.
|
|
886
|
+
*
|
|
887
|
+
* Per CONTEXT.md D-11 the noop adapter ships in Lattice (not FSB)
|
|
888
|
+
* because it covers the contract surface in Lattice's own test suite;
|
|
889
|
+
* FSB's real chrome.storage.session-backed adapter is glue layer.
|
|
890
|
+
*/
|
|
891
|
+
function createNoopSurvivabilityAdapter(options = {}) {
|
|
892
|
+
const id = options.id ?? "noop-survivability";
|
|
893
|
+
const defaultPolicy = options.policy ?? "SAFE";
|
|
894
|
+
const hooks = /* @__PURE__ */ new Set();
|
|
895
|
+
return {
|
|
896
|
+
kind: "survivability-adapter",
|
|
897
|
+
id,
|
|
898
|
+
serialize(state) {
|
|
899
|
+
return {
|
|
900
|
+
kind: "survivability-snapshot",
|
|
901
|
+
version: "lattice-survivability/v1",
|
|
902
|
+
payload: JSON.stringify(state ?? null),
|
|
903
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
904
|
+
};
|
|
905
|
+
},
|
|
906
|
+
deserialize(snapshot) {
|
|
907
|
+
return JSON.parse(snapshot.payload);
|
|
908
|
+
},
|
|
909
|
+
onEviction(hook) {
|
|
910
|
+
hooks.add(hook);
|
|
911
|
+
let unsubscribed = false;
|
|
912
|
+
return () => {
|
|
913
|
+
if (unsubscribed) return;
|
|
914
|
+
unsubscribed = true;
|
|
915
|
+
hooks.delete(hook);
|
|
916
|
+
};
|
|
917
|
+
},
|
|
918
|
+
async resume(_snapshot) {
|
|
919
|
+
return defaultPolicy;
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
//#endregion
|
|
774
924
|
//#region src/tools/tools.ts
|
|
775
925
|
function defineTool(definition) {
|
|
776
926
|
return {
|
|
@@ -815,158 +965,6 @@ function createToolCallId() {
|
|
|
815
965
|
return `${Date.now()}:${Math.random().toString(16).slice(2)}`;
|
|
816
966
|
}
|
|
817
967
|
//#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
968
|
//#region src/agent/host.ts
|
|
971
969
|
/**
|
|
972
970
|
* Reference implementation suitable for Node tests + the Phase 19 default
|
|
@@ -1020,7 +1018,10 @@ var AgentDeniedError = class extends Error {
|
|
|
1020
1018
|
};
|
|
1021
1019
|
//#endregion
|
|
1022
1020
|
//#region src/agent/runtime.ts
|
|
1023
|
-
var runtime_exports = /* @__PURE__ */ __exportAll({
|
|
1021
|
+
var runtime_exports = /* @__PURE__ */ __exportAll({
|
|
1022
|
+
runAgent: () => runAgent,
|
|
1023
|
+
runAgentInternal: () => runAgentInternal
|
|
1024
|
+
});
|
|
1024
1025
|
const ZERO_USAGE = {
|
|
1025
1026
|
promptTokens: 0,
|
|
1026
1027
|
completionTokens: 0,
|
|
@@ -1033,8 +1034,20 @@ const ZERO_USAGE = {
|
|
|
1033
1034
|
* calling Promise), direct transport (provider.execute()), and in-memory
|
|
1034
1035
|
* transcript (the `conversation` array). Phase 20 promotes scheduler /
|
|
1035
1036
|
* transport / storage to the pluggable `AgentHost` adapter.
|
|
1037
|
+
*
|
|
1038
|
+
* Phase 39: `runAgent` is a thin public wrapper over `runAgentInternal`
|
|
1039
|
+
* with no internal options — the public signature and behavior are
|
|
1040
|
+
* unchanged.
|
|
1036
1041
|
*/
|
|
1037
1042
|
async function runAgent(intent, config = {}) {
|
|
1043
|
+
return runAgentInternal(intent, config);
|
|
1044
|
+
}
|
|
1045
|
+
/**
|
|
1046
|
+
* The agent-loop implementation with the internal dispatch seam (Phase 39).
|
|
1047
|
+
* In-package consumers (agent/crew/, 39-05) call this directly; it is NOT
|
|
1048
|
+
* part of the public package surface.
|
|
1049
|
+
*/
|
|
1050
|
+
async function runAgentInternal(intent, config = {}, internalOptions = {}) {
|
|
1038
1051
|
const startedAt = Date.now();
|
|
1039
1052
|
const cumulativeUsage = {
|
|
1040
1053
|
promptTokens: 0,
|
|
@@ -1169,8 +1182,12 @@ async function runAgent(intent, config = {}) {
|
|
|
1169
1182
|
const iterUsage = response.normalizedUsage ?? ZERO_USAGE;
|
|
1170
1183
|
accumulateUsage(cumulativeUsage, iterUsage);
|
|
1171
1184
|
const responseText = extractResponseText(response);
|
|
1172
|
-
const toolUseRequests =
|
|
1173
|
-
|
|
1185
|
+
const toolUseRequests = response.toolCalls !== void 0 ? response.toolCalls.map((toolCall) => ({
|
|
1186
|
+
id: toolCall.id,
|
|
1187
|
+
name: toolCall.name,
|
|
1188
|
+
args: toolCall.args
|
|
1189
|
+
})) : handle.parseToolUse(responseText);
|
|
1190
|
+
if (toolUseRequests === null || toolUseRequests.length === 0) {
|
|
1174
1191
|
const finalRecord = {
|
|
1175
1192
|
index: iterationIndex,
|
|
1176
1193
|
provider: providerName,
|
|
@@ -1208,28 +1225,41 @@ async function runAgent(intent, config = {}) {
|
|
|
1208
1225
|
});
|
|
1209
1226
|
const toolCallRecords = [];
|
|
1210
1227
|
for (const req of toolUseRequests) {
|
|
1211
|
-
|
|
1212
|
-
let toolResult = null;
|
|
1213
|
-
let resultContent;
|
|
1228
|
+
let resultContent = null;
|
|
1214
1229
|
let resultHash = "tool-not-found";
|
|
1215
|
-
if (
|
|
1216
|
-
|
|
1217
|
-
await pipeline.run("BEFORE_TOOL", {
|
|
1230
|
+
if (internalOptions.dispatchToolUse !== void 0) {
|
|
1231
|
+
const dispatched = await internalOptions.dispatchToolUse(req, {
|
|
1218
1232
|
iterationIndex,
|
|
1219
|
-
|
|
1220
|
-
|
|
1233
|
+
conversation,
|
|
1234
|
+
pipeline
|
|
1221
1235
|
});
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
});
|
|
1231
|
-
|
|
1232
|
-
|
|
1236
|
+
if (dispatched !== void 0) {
|
|
1237
|
+
resultContent = dispatched.content;
|
|
1238
|
+
resultHash = stableHash(dispatched.content);
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
if (resultContent === null) {
|
|
1242
|
+
const tool = intent.tools.find((t) => t.name === req.name);
|
|
1243
|
+
let toolResult = null;
|
|
1244
|
+
if (tool === void 0) resultContent = JSON.stringify({ error: `Unknown tool: ${req.name}` });
|
|
1245
|
+
else try {
|
|
1246
|
+
await pipeline.run("BEFORE_TOOL", {
|
|
1247
|
+
iterationIndex,
|
|
1248
|
+
toolName: req.name,
|
|
1249
|
+
args: req.args
|
|
1250
|
+
});
|
|
1251
|
+
toolResult = await runTool(tool, req.args);
|
|
1252
|
+
resultContent = stringifyArtifactValue(toolResult.artifact.value);
|
|
1253
|
+
resultHash = toolResult.callId;
|
|
1254
|
+
await pipeline.run("AFTER_TOOL", {
|
|
1255
|
+
iterationIndex,
|
|
1256
|
+
toolName: req.name,
|
|
1257
|
+
args: req.args,
|
|
1258
|
+
result: toolResult.artifact.value
|
|
1259
|
+
});
|
|
1260
|
+
} catch (error) {
|
|
1261
|
+
resultContent = JSON.stringify({ error: error instanceof Error ? error.message : "Tool execution failed" });
|
|
1262
|
+
}
|
|
1233
1263
|
}
|
|
1234
1264
|
conversation.push({
|
|
1235
1265
|
role: "tool",
|
|
@@ -1354,6 +1384,6 @@ function stableHash(input) {
|
|
|
1354
1384
|
}
|
|
1355
1385
|
}
|
|
1356
1386
|
//#endregion
|
|
1357
|
-
export {
|
|
1387
|
+
export { decodeEnvelope as C, artifact as D, createHookPipeline as E, toArtifactRef 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, 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
1388
|
|
|
1359
|
-
//# sourceMappingURL=runtime-
|
|
1389
|
+
//# sourceMappingURL=runtime-BTi8lr_O.js.map
|