@tangle-network/agent-runtime 0.102.0 → 0.102.2

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.
Files changed (77) hide show
  1. package/dist/agent.d.ts +1 -1
  2. package/dist/agent.js +5 -3
  3. package/dist/agent.js.map +1 -1
  4. package/dist/analyst-loop.d.ts +1 -1
  5. package/dist/candidate-execution/index.js +5 -4
  6. package/dist/{chunk-SPCD4IQQ.js → chunk-377GOJHJ.js} +2 -2
  7. package/dist/{chunk-LKKIM5QD.js → chunk-3DW5DEKQ.js} +3 -3
  8. package/dist/{chunk-4AMAFNUD.js → chunk-7FJJUC73.js} +311 -40
  9. package/dist/chunk-7FJJUC73.js.map +1 -0
  10. package/dist/{chunk-DA7YL6I4.js → chunk-CK76OZPM.js} +3 -3
  11. package/dist/{chunk-KSBUSEUA.js → chunk-EKUMRQNR.js} +2 -2
  12. package/dist/{chunk-23Z7N5IG.js → chunk-J6V6DWWS.js} +5 -5
  13. package/dist/{chunk-AIBIRAJ6.js → chunk-KSM6GFHP.js} +2 -2
  14. package/dist/chunk-L5DST3QC.js +351 -0
  15. package/dist/chunk-L5DST3QC.js.map +1 -0
  16. package/dist/{chunk-TGDHHHH4.js → chunk-LJLG734E.js} +12 -253
  17. package/dist/chunk-LJLG734E.js.map +1 -0
  18. package/dist/{chunk-MAONWP4R.js → chunk-QCXD7NHM.js} +611 -1419
  19. package/dist/chunk-QCXD7NHM.js.map +1 -0
  20. package/dist/chunk-ROILMKDL.js +1338 -0
  21. package/dist/chunk-ROILMKDL.js.map +1 -0
  22. package/dist/{chunk-N2CEE5Q3.js → chunk-SCOHHMKU.js} +3 -3
  23. package/dist/chunk-SQ3ZJH3Y.js +3082 -0
  24. package/dist/chunk-SQ3ZJH3Y.js.map +1 -0
  25. package/dist/chunk-UPWGXKXB.js +254 -0
  26. package/dist/chunk-UPWGXKXB.js.map +1 -0
  27. package/dist/{chunk-KVJQV342.js → chunk-ZUCUAFVF.js} +26 -1778
  28. package/dist/chunk-ZUCUAFVF.js.map +1 -0
  29. package/dist/{completion-gate-C80jiRfN.d.ts → completion-gate-C6dhVN-N.d.ts} +2 -2
  30. package/dist/{coordination-BFE3Den7.d.ts → coordination-D9l_YmwW.d.ts} +6 -6
  31. package/dist/environment-provider.d.ts +2 -2
  32. package/dist/{improve-CIml6hT3.d.ts → improve-B40dRu0X.d.ts} +40 -19
  33. package/dist/index.d.ts +329 -21
  34. package/dist/index.js +541 -137
  35. package/dist/index.js.map +1 -1
  36. package/dist/intelligence.d.ts +5 -5
  37. package/dist/intelligence.js +7 -5
  38. package/dist/intelligence.js.map +1 -1
  39. package/dist/knowledge.d.ts +8 -8
  40. package/dist/knowledge.js +9 -7
  41. package/dist/{local-harness-ZqCx51u7.d.ts → local-harness-CtK9dSny.d.ts} +14 -2
  42. package/dist/{loop-runner-bin-Cn1N2rRo.d.ts → loop-runner-bin-PnWslIw4.d.ts} +2 -2
  43. package/dist/loop-runner-bin.d.ts +6 -6
  44. package/dist/loop-runner-bin.js +6 -4
  45. package/dist/loops.d.ts +231 -460
  46. package/dist/loops.js +58 -37
  47. package/dist/mcp/bin.js +2 -2
  48. package/dist/mcp/index.d.ts +184 -12
  49. package/dist/mcp/index.js +31 -9
  50. package/dist/mcp/index.js.map +1 -1
  51. package/dist/mcp/memory-bin.d.ts +1 -0
  52. package/dist/mcp/memory-bin.js +22 -0
  53. package/dist/mcp/memory-bin.js.map +1 -0
  54. package/dist/profiles.d.ts +3 -3
  55. package/dist/structural-rollout-D7xik9XR.d.ts +446 -0
  56. package/dist/{substrate-DO2GHNg2.d.ts → substrate-Dyiqmd3o.d.ts} +1 -1
  57. package/dist/{supervise-BLPI50-w.d.ts → supervise-BQdNAXtK.d.ts} +4 -4
  58. package/dist/testing.js +10 -8
  59. package/dist/testing.js.map +1 -1
  60. package/dist/{types-B3vAW0Oq.d.ts → types-CLat4bT9.d.ts} +1 -1
  61. package/dist/{types-CmnA2iL3.d.ts → types-D870JlH0.d.ts} +2 -2
  62. package/dist/{worktree-fanout-DCA3G4bO.d.ts → worktree-fanout-DsIR4d6w.d.ts} +234 -234
  63. package/package.json +4 -3
  64. package/dist/chunk-4AMAFNUD.js.map +0 -1
  65. package/dist/chunk-IKGCKPDX.js +0 -1115
  66. package/dist/chunk-IKGCKPDX.js.map +0 -1
  67. package/dist/chunk-KVJQV342.js.map +0 -1
  68. package/dist/chunk-MAONWP4R.js.map +0 -1
  69. package/dist/chunk-TGDHHHH4.js.map +0 -1
  70. package/dist/{chunk-SPCD4IQQ.js.map → chunk-377GOJHJ.js.map} +0 -0
  71. package/dist/{chunk-LKKIM5QD.js.map → chunk-3DW5DEKQ.js.map} +0 -0
  72. package/dist/{chunk-DA7YL6I4.js.map → chunk-CK76OZPM.js.map} +0 -0
  73. package/dist/{chunk-KSBUSEUA.js.map → chunk-EKUMRQNR.js.map} +0 -0
  74. package/dist/{chunk-23Z7N5IG.js.map → chunk-J6V6DWWS.js.map} +0 -0
  75. package/dist/{chunk-AIBIRAJ6.js.map → chunk-KSM6GFHP.js.map} +0 -0
  76. package/dist/{chunk-N2CEE5Q3.js.map → chunk-SCOHHMKU.js.map} +0 -0
  77. package/dist/{sanitize-BTSsdBXw.d.ts → sanitize-DEbPNtyI.d.ts} +58 -58
@@ -7,18 +7,33 @@ import {
7
7
  createExecutor,
8
8
  createExecutorRegistry,
9
9
  createSandboxLineage,
10
- createSupervisor,
11
10
  createWorktreeCliExecutor,
12
11
  defaultSelectWinner,
13
12
  gateOnDeliverable,
14
- notifyRuntimeHookEvent,
15
13
  probeSandboxCapabilities,
16
- routerToolLoop,
17
14
  runLoop,
15
+ supervise
16
+ } from "./chunk-ZUCUAFVF.js";
17
+ import {
18
+ observe,
19
+ refine,
20
+ runAgentic,
21
+ sample,
22
+ sampleThenRefine,
23
+ strategyAuthorMethod
24
+ } from "./chunk-ROILMKDL.js";
25
+ import {
26
+ redactProtectedReason,
27
+ redactProtectedValue
28
+ } from "./chunk-UPWGXKXB.js";
29
+ import {
30
+ createSupervisor,
31
+ notifyRuntimeHookEvent,
32
+ routerBrain,
33
+ runBrainLoop,
18
34
  settledToIteration,
19
- supervise,
20
35
  withDriverExecutor
21
- } from "./chunk-KVJQV342.js";
36
+ } from "./chunk-SQ3ZJH3Y.js";
22
37
  import {
23
38
  InMemoryResultBlobStore,
24
39
  InMemorySpawnJournal
@@ -44,7 +59,7 @@ import {
44
59
  } from "./chunk-YEJR7IXO.js";
45
60
 
46
61
  // src/runtime/index.ts
47
- import { computeFindingId, makeFinding as makeFinding2 } from "@tangle-network/agent-eval";
62
+ import { computeFindingId, makeFinding } from "@tangle-network/agent-eval";
48
63
 
49
64
  // src/runtime/anytime.ts
50
65
  var median = (xs) => {
@@ -769,6 +784,472 @@ function inlineSandboxClient(factory) {
769
784
  };
770
785
  }
771
786
 
787
+ // src/runtime/local-sandbox-client.ts
788
+ import {
789
+ canonicalCandidateDigest
790
+ } from "@tangle-network/agent-interface";
791
+
792
+ // src/runtime/stdio-mcp-client.ts
793
+ import { spawn } from "child_process";
794
+ import { createInterface } from "readline";
795
+ import {
796
+ validateAgentProfileSecurity
797
+ } from "@tangle-network/agent-interface";
798
+
799
+ // src/runtime/key-provider.ts
800
+ function envKeyProvider(env = process.env) {
801
+ return {
802
+ async get(name) {
803
+ const value = env[name];
804
+ return value !== void 0 && value.trim().length > 0 ? value : void 0;
805
+ }
806
+ };
807
+ }
808
+ var mcpSecretEnvMetadataKey = "secretEnv";
809
+ function secretEnvOfMcpServer(server) {
810
+ const raw = server.metadata?.[mcpSecretEnvMetadataKey];
811
+ if (raw === void 0 || raw === null) return void 0;
812
+ if (typeof raw !== "object" || Array.isArray(raw)) {
813
+ throw new ValidationError(
814
+ `secretEnvOfMcpServer: metadata.${mcpSecretEnvMetadataKey} must be an object mapping env var name -> key name`
815
+ );
816
+ }
817
+ const entries = Object.entries(raw);
818
+ if (entries.length === 0) return void 0;
819
+ for (const [envName, keyName] of entries) {
820
+ if (!envName.trim() || typeof keyName !== "string" || !keyName.trim()) {
821
+ throw new ValidationError(
822
+ `secretEnvOfMcpServer: metadata.${mcpSecretEnvMetadataKey}['${envName}'] must name a non-empty provider key`
823
+ );
824
+ }
825
+ }
826
+ return raw;
827
+ }
828
+ async function resolveSecretEnv(secretEnv, keys, label) {
829
+ const entries = Object.entries(secretEnv);
830
+ if (entries.length === 0) return {};
831
+ if (!keys) {
832
+ throw new ValidationError(
833
+ `${label} declares secret env (${entries.map(([e]) => e).join(", ")}) but no KeyProvider was supplied \u2014 refusing to boot an external server keyless`
834
+ );
835
+ }
836
+ const resolved = {};
837
+ for (const [envName, keyName] of entries) {
838
+ const value = await keys.get(keyName);
839
+ if (value === void 0) {
840
+ throw new ValidationError(
841
+ `${label}: the KeyProvider holds no value for '${keyName}' (wanted for env ${envName}) \u2014 provision the key or drop the grant`
842
+ );
843
+ }
844
+ resolved[envName] = value;
845
+ }
846
+ return resolved;
847
+ }
848
+
849
+ // src/runtime/mcp-environment.ts
850
+ async function rpc(endpoint, body) {
851
+ let lastErr;
852
+ for (let attempt = 0; attempt < 4; attempt += 1) {
853
+ try {
854
+ const r = await fetch(endpoint.url, {
855
+ method: "POST",
856
+ headers: { "content-type": "application/json", ...endpoint.headers ?? {} },
857
+ body: JSON.stringify(body)
858
+ });
859
+ const text = await r.text();
860
+ const dataLines = text.split("\n").filter((l) => l.startsWith("data:")).map((l) => l.slice(5).trim());
861
+ const payload = dataLines.length ? dataLines[dataLines.length - 1] : text;
862
+ try {
863
+ return { status: r.status, json: JSON.parse(payload ?? "null") };
864
+ } catch {
865
+ return { status: r.status, json: text };
866
+ }
867
+ } catch (err) {
868
+ lastErr = err;
869
+ await new Promise((res) => setTimeout(res, 1e3 * (attempt + 1)));
870
+ }
871
+ }
872
+ throw new Error(
873
+ `mcp rpc ${endpoint.url} failed after 4 attempts: ${lastErr instanceof Error ? lastErr.message : String(lastErr)}`
874
+ );
875
+ }
876
+ function sanitizeMcpToolSchema(s) {
877
+ const o = s && typeof s === "object" ? s : {};
878
+ const banned = o.oneOf || o.anyOf || o.allOf || o.not || o.enum;
879
+ if (o.type === "object" && !banned && o.properties && typeof o.properties === "object") {
880
+ return {
881
+ type: "object",
882
+ properties: o.properties,
883
+ ...Array.isArray(o.required) ? { required: o.required } : {}
884
+ };
885
+ }
886
+ return { type: "object", properties: {} };
887
+ }
888
+ function createMcpEnvironment(opts) {
889
+ const endpoints = /* @__PURE__ */ new Map();
890
+ const maxChars = opts.maxResultChars ?? 1500;
891
+ return {
892
+ name: opts.name,
893
+ async open(task) {
894
+ const { handle, endpoint } = await opts.open(task);
895
+ endpoints.set(handle.id, endpoint);
896
+ return handle;
897
+ },
898
+ async tools(task, handle) {
899
+ const endpoint = endpoints.get(handle.id);
900
+ if (!endpoint) throw new Error(`${opts.name}: tools() before open() for ${handle.id}`);
901
+ const { json } = await rpc(endpoint, {
902
+ jsonrpc: "2.0",
903
+ id: 1,
904
+ method: "tools/list",
905
+ params: {}
906
+ });
907
+ const all = (json.result?.tools ?? []).map(
908
+ (t) => ({
909
+ type: "function",
910
+ function: {
911
+ name: t.name,
912
+ description: (t.description ?? "").slice(0, 1e3),
913
+ parameters: sanitizeMcpToolSchema(t.inputSchema)
914
+ }
915
+ })
916
+ );
917
+ return opts.selectTools ? opts.selectTools(task, all) : all;
918
+ },
919
+ async call(handle, name, args) {
920
+ const endpoint = endpoints.get(handle.id);
921
+ if (!endpoint) return "ERROR: workspace closed";
922
+ const { json } = await rpc(endpoint, {
923
+ jsonrpc: "2.0",
924
+ id: 2,
925
+ method: "tools/call",
926
+ params: { name, arguments: args }
927
+ });
928
+ const result = json ?? {};
929
+ if (result.error) return `ERROR: ${JSON.stringify(result.error).slice(0, 300)}`;
930
+ const text = result.result?.content?.map((c) => c.text ?? "").join("\n") ?? JSON.stringify(result.result ?? json);
931
+ return text.slice(0, maxChars);
932
+ },
933
+ score: (task, handle) => opts.score(task, handle),
934
+ async close(handle) {
935
+ endpoints.delete(handle.id);
936
+ await opts.close?.(handle);
937
+ }
938
+ };
939
+ }
940
+
941
+ // src/runtime/stdio-mcp-client.ts
942
+ var PROTOCOL_VERSION = "2024-11-05";
943
+ var SAFE_INHERITED_ENV_NAMES = [
944
+ "PATH",
945
+ "LANG",
946
+ "LC_ALL",
947
+ "LC_CTYPE",
948
+ "TZ",
949
+ "SYSTEMROOT",
950
+ "WINDIR",
951
+ "COMSPEC",
952
+ "PATHEXT"
953
+ ];
954
+ function inheritedStdioEnv(source = process.env) {
955
+ const env = {};
956
+ for (const name of SAFE_INHERITED_ENV_NAMES) {
957
+ const value = source[name];
958
+ if (value !== void 0) env[name] = value;
959
+ }
960
+ return env;
961
+ }
962
+ var McpSpawnFault = class extends Error {
963
+ };
964
+ async function connectStdioMcp(spec) {
965
+ const timeoutMs = spec.timeoutMs ?? 3e4;
966
+ const protectedValues = Object.values(spec.protectedEnv ?? {});
967
+ const redactReason = (value) => redactProtectedReason(value, protectedValues);
968
+ const child = spawn(spec.command, spec.args ?? [], {
969
+ ...spec.cwd ? { cwd: spec.cwd } : {},
970
+ stdio: ["pipe", "pipe", "pipe"],
971
+ env: { ...inheritedStdioEnv(), ...spec.env, ...spec.protectedEnv }
972
+ });
973
+ const stderr = [];
974
+ child.stderr.on("data", (d) => stderr.push(String(d)));
975
+ const stderrTail = () => stderr.length > 0 ? `
976
+ stderr:
977
+ ${redactReason(stderr.join("")).slice(-2e3)}` : "";
978
+ let nextId = 1;
979
+ let spawnFault;
980
+ let closed = false;
981
+ const pending = /* @__PURE__ */ new Map();
982
+ const failAllPending = (err) => {
983
+ for (const p of pending.values()) {
984
+ clearTimeout(p.timer);
985
+ p.reject(err);
986
+ }
987
+ pending.clear();
988
+ };
989
+ child.on("error", (err) => {
990
+ const code = err.code;
991
+ spawnFault = code === "ENOENT" ? new McpSpawnFault(
992
+ `'${spec.command}' not found in PATH (setup bug, not a failed candidate)`
993
+ ) : new McpSpawnFault(`'${spec.command}' failed to spawn: ${err.message}`);
994
+ failAllPending(spawnFault);
995
+ });
996
+ child.stdin.on("error", (err) => {
997
+ failAllPending(
998
+ new Error(redactReason(`writing to MCP server stdin failed: ${err.message}${stderrTail()}`))
999
+ );
1000
+ });
1001
+ child.on("close", (code, signal) => {
1002
+ failAllPending(
1003
+ spawnFault ?? new Error(
1004
+ redactReason(
1005
+ `MCP server exited (code ${code}, signal ${signal}) before serving${stderrTail()}`
1006
+ )
1007
+ )
1008
+ );
1009
+ });
1010
+ const rl = createInterface({ input: child.stdout });
1011
+ rl.on("line", (line) => {
1012
+ let msg;
1013
+ try {
1014
+ msg = JSON.parse(line);
1015
+ } catch {
1016
+ return;
1017
+ }
1018
+ if (!msg || typeof msg !== "object" || typeof msg.id !== "number") return;
1019
+ const p = pending.get(msg.id);
1020
+ if (!p) return;
1021
+ pending.delete(msg.id);
1022
+ clearTimeout(p.timer);
1023
+ p.resolve(msg);
1024
+ });
1025
+ const send = (msg) => {
1026
+ child.stdin.write(`${JSON.stringify(msg)}
1027
+ `);
1028
+ };
1029
+ const request = (method, params, timeoutMessage = `MCP server did not answer '${method}' within ${timeoutMs}ms`) => new Promise((resolve, reject) => {
1030
+ if (spawnFault) return reject(spawnFault);
1031
+ if (closed) return reject(new Error("MCP connection closed"));
1032
+ const id = nextId++;
1033
+ const timer = setTimeout(() => {
1034
+ pending.delete(id);
1035
+ reject(new Error(redactReason(`${timeoutMessage}${stderrTail()}`)));
1036
+ }, timeoutMs);
1037
+ pending.set(id, { resolve, reject, timer });
1038
+ try {
1039
+ send({ jsonrpc: "2.0", id, method, ...params ? { params } : {} });
1040
+ } catch (err) {
1041
+ pending.delete(id);
1042
+ clearTimeout(timer);
1043
+ reject(
1044
+ new Error(
1045
+ redactReason(
1046
+ `writing to MCP server stdin failed: ${err instanceof Error ? err.message : String(err)}${stderrTail()}`
1047
+ )
1048
+ )
1049
+ );
1050
+ }
1051
+ });
1052
+ const close = async () => {
1053
+ if (closed) return;
1054
+ closed = true;
1055
+ rl.close();
1056
+ failAllPending(new Error("MCP connection closed"));
1057
+ child.kill("SIGKILL");
1058
+ };
1059
+ const handshakeTimeout = `MCP server did not complete the handshake within ${timeoutMs}ms`;
1060
+ try {
1061
+ const init = await request(
1062
+ "initialize",
1063
+ {
1064
+ protocolVersion: PROTOCOL_VERSION,
1065
+ capabilities: {},
1066
+ clientInfo: { name: "agent-runtime-local-mcp", version: "0" }
1067
+ },
1068
+ handshakeTimeout
1069
+ );
1070
+ if (init.error)
1071
+ throw new Error(
1072
+ redactReason(`initialize errored: ${JSON.stringify(init.error)}${stderrTail()}`)
1073
+ );
1074
+ send({ jsonrpc: "2.0", method: "notifications/initialized" });
1075
+ const list = await request("tools/list", void 0, handshakeTimeout);
1076
+ if (list.error)
1077
+ throw new Error(
1078
+ redactReason(`tools/list errored: ${JSON.stringify(list.error)}${stderrTail()}`)
1079
+ );
1080
+ const rawTools = list.result?.tools;
1081
+ if (!Array.isArray(rawTools))
1082
+ throw new Error(`tools/list result has no tools array${stderrTail()}`);
1083
+ const tools = redactProtectedValue(rawTools, protectedValues).value;
1084
+ const callTool = async (name, args) => {
1085
+ const res = await request("tools/call", { name, arguments: args });
1086
+ if (res.error) return `ERROR: ${redactReason(JSON.stringify(res.error)).slice(0, 300)}`;
1087
+ const result = res.result;
1088
+ const chunks = result?.content?.map((c) => c.text ?? "");
1089
+ const joined = chunks?.join("\n") ?? JSON.stringify(result ?? null);
1090
+ const collapsed = chunks?.join("");
1091
+ let text = joined;
1092
+ if (collapsed !== void 0) {
1093
+ const collapsedRedacted = redactReason(collapsed);
1094
+ if (collapsedRedacted !== collapsed) text = collapsedRedacted;
1095
+ }
1096
+ return redactReason(result?.isError ? `ERROR: ${text}` : text);
1097
+ };
1098
+ return { tools, callTool, close };
1099
+ } catch (err) {
1100
+ await close();
1101
+ throw err;
1102
+ }
1103
+ }
1104
+ async function materializeLocalMcp(profile, opts = {}) {
1105
+ const security = validateAgentProfileSecurity(profile, opts.profileSecurityPolicy);
1106
+ if (!security.ok) {
1107
+ const reasons = security.issues.filter((issue) => issue.level === "error").map((issue) => issue.message).join("; ");
1108
+ throw new ValidationError(`materializeLocalMcp: profile host execution refused: ${reasons}`);
1109
+ }
1110
+ const maxResultChars = opts.maxResultChars ?? 2e3;
1111
+ const connections = [];
1112
+ const routes = /* @__PURE__ */ new Map();
1113
+ const tools = [];
1114
+ const close = async () => {
1115
+ await Promise.all(connections.map((c) => c.close()));
1116
+ };
1117
+ try {
1118
+ for (const [key, server] of Object.entries(profile.mcp ?? {})) {
1119
+ if (server.enabled === false) continue;
1120
+ const transport = server.transport ?? "stdio";
1121
+ if (transport !== "stdio") {
1122
+ throw new ValidationError(
1123
+ `materializeLocalMcp: profile.mcp['${key}'] has transport '${transport}' \u2014 the same-host client only spawns stdio servers; a remote (http/sse) server needs an http MCP client (not yet built here) or the sandbox backend. Failing loud: scoring this profile without its declared server would fake the with/without ablation`
1124
+ );
1125
+ }
1126
+ if (!server.command || server.command.trim().length === 0) {
1127
+ throw new ValidationError(
1128
+ `materializeLocalMcp: profile.mcp['${key}'] declares a stdio server with no command`
1129
+ );
1130
+ }
1131
+ const secretRefs = secretEnvOfMcpServer(server);
1132
+ const provisioned = secretRefs ? await resolveSecretEnv(
1133
+ secretRefs,
1134
+ opts.keys,
1135
+ `materializeLocalMcp: profile.mcp['${key}']`
1136
+ ) : void 0;
1137
+ const conn = await connectStdioMcp({
1138
+ command: server.command,
1139
+ ...server.args ? { args: server.args } : {},
1140
+ ...server.cwd ? { cwd: server.cwd } : {},
1141
+ ...server.env ? { env: server.env } : {},
1142
+ ...provisioned ? { protectedEnv: provisioned } : {},
1143
+ ...opts.timeoutMs !== void 0 ? { timeoutMs: opts.timeoutMs } : {}
1144
+ });
1145
+ connections.push(conn);
1146
+ const prefix = key.replace(/[^a-zA-Z0-9_-]/g, "_");
1147
+ for (const t of conn.tools) {
1148
+ const name = `${prefix}__${t.name.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
1149
+ if (routes.has(name)) {
1150
+ throw new ValidationError(
1151
+ `materializeLocalMcp: namespaced tool '${name}' collides across servers \u2014 rename the profile.mcp keys`
1152
+ );
1153
+ }
1154
+ routes.set(name, { conn, tool: t.name });
1155
+ tools.push({
1156
+ type: "function",
1157
+ function: {
1158
+ name,
1159
+ description: (t.description ?? "").slice(0, 1e3),
1160
+ parameters: sanitizeMcpToolSchema(t.inputSchema)
1161
+ }
1162
+ });
1163
+ }
1164
+ }
1165
+ } catch (err) {
1166
+ await close();
1167
+ throw err;
1168
+ }
1169
+ return {
1170
+ tools,
1171
+ owns: (name) => routes.has(name),
1172
+ call: async (name, args) => {
1173
+ const route = routes.get(name);
1174
+ if (!route) throw new Error(`materializeLocalMcp: unknown tool '${name}'`);
1175
+ const out = await route.conn.callTool(route.tool, args);
1176
+ return out.length > maxResultChars ? out.slice(0, maxResultChars) : out;
1177
+ },
1178
+ close
1179
+ };
1180
+ }
1181
+
1182
+ // src/runtime/local-sandbox-client.ts
1183
+ function localSandboxClient(opts) {
1184
+ if (opts.profileSecurityPolicy?.allowLocalMcp && opts.profile === void 0) {
1185
+ throw new ValidationError(
1186
+ "localSandboxClient: allowLocalMcp requires a fixed author-controlled profile; dynamic profiles need a real sandbox"
1187
+ );
1188
+ }
1189
+ const trustedProfileDigest = opts.profileSecurityPolicy?.allowLocalMcp && opts.profile !== void 0 ? canonicalCandidateDigest(opts.profile) : void 0;
1190
+ const maxTurns = opts.maxTurns ?? 8;
1191
+ let seq = 0;
1192
+ return {
1193
+ async create(options) {
1194
+ const profile = options?.backend?.profile ?? opts.profile ?? {};
1195
+ const policyApplies = opts.profileSecurityPolicy !== void 0 && (!opts.profileSecurityPolicy.allowLocalMcp || trustedProfileDigest !== void 0 && canonicalCandidateDigest(profile) === trustedProfileDigest);
1196
+ const mcp = await materializeLocalMcp(profile, {
1197
+ ...opts.keys ? { keys: opts.keys } : {},
1198
+ ...policyApplies ? { profileSecurityPolicy: opts.profileSecurityPolicy } : {}
1199
+ });
1200
+ const brain = routerBrain(
1201
+ {
1202
+ routerBaseUrl: opts.router.baseUrl,
1203
+ routerKey: opts.router.key,
1204
+ model: opts.router.model
1205
+ },
1206
+ opts.temperature !== void 0 ? { temperature: opts.temperature } : {}
1207
+ );
1208
+ const system = [profile.prompt?.systemPrompt, ...profile.prompt?.instructions ?? []].filter((s) => typeof s === "string" && s.trim().length > 0).join("\n\n");
1209
+ const id = `local-${seq++}`;
1210
+ return {
1211
+ id,
1212
+ async *streamPrompt(message, popts) {
1213
+ let costUsd = 0;
1214
+ const chat = async (messages, tools) => {
1215
+ const r2 = await brain(messages, tools);
1216
+ if (r2.costUsd) costUsd += r2.costUsd;
1217
+ return r2;
1218
+ };
1219
+ const r = await runBrainLoop({
1220
+ chat,
1221
+ tools: mcp.tools,
1222
+ execute: (name, args) => mcp.call(name, args),
1223
+ initialMessages: [
1224
+ ...system ? [{ role: "system", content: system }] : [],
1225
+ { role: "user", content: message }
1226
+ ],
1227
+ maxTurns,
1228
+ hooks: { stopBefore: () => popts?.signal?.aborted === true }
1229
+ });
1230
+ if (r.usage.input || r.usage.output || costUsd) {
1231
+ yield {
1232
+ type: "llm_call",
1233
+ data: { tokensIn: r.usage.input, tokensOut: r.usage.output, costUsd }
1234
+ };
1235
+ }
1236
+ yield {
1237
+ type: "result",
1238
+ data: {
1239
+ finalText: r.final,
1240
+ tokenUsage: { inputTokens: r.usage.input, outputTokens: r.usage.output },
1241
+ costUsd
1242
+ }
1243
+ };
1244
+ },
1245
+ async delete() {
1246
+ await mcp.close();
1247
+ }
1248
+ };
1249
+ }
1250
+ };
1251
+ }
1252
+
772
1253
  // src/runtime/resolve-sandbox-client.ts
773
1254
  function resolveSandboxClient(opts) {
774
1255
  switch (opts.backend) {
@@ -811,6 +1292,15 @@ function resolveSandboxClient(opts) {
811
1292
  })
812
1293
  );
813
1294
  }
1295
+ case "local": {
1296
+ const local = opts.local;
1297
+ if (!local?.router?.baseUrl || !local.router.key || !local.router.model) {
1298
+ throw new Error(
1299
+ "resolveSandboxClient: backend 'local' requires local.router.baseUrl, local.router.key and local.router.model"
1300
+ );
1301
+ }
1302
+ return localSandboxClient(local);
1303
+ }
814
1304
  }
815
1305
  }
816
1306
 
@@ -1159,163 +1649,6 @@ function defineLeaderboard(spec) {
1159
1649
  return { run, toBenchmarkAdapter };
1160
1650
  }
1161
1651
 
1162
- // src/runtime/observe.ts
1163
- import { makeFinding } from "@tangle-network/agent-eval";
1164
- var observerId = "observe/trace";
1165
- var defaultAnalystInstruction = "You are a third-person OBSERVER watching an AI agent work. You see its TRACE (what it did), not its grader. From the trace, name SPECIFIC, behavior-grounded findings: wasted/duplicated tool calls, thrash/retries, token/cost waste, missing verification, failure patterns. For each, a concrete recommended_action, and whether the AGENT (fix its skills/prompt/tools) or the OPERATOR (fix framing/decomposition/config) should act. Only claim what the trace shows. No findings if the run was clean.";
1166
- function summarizeTrace(trace, maxLines) {
1167
- const lines = [];
1168
- for (const ev of trace) {
1169
- const e = ev;
1170
- const t = (e.type ?? "").toLowerCase();
1171
- const d = e.data ?? {};
1172
- const part = d.part ?? {};
1173
- if (part.type === "tool")
1174
- lines.push(`tool:${part.tool}${part.state?.status ? `(${part.state.status})` : ""}`);
1175
- else if (t.includes("error"))
1176
- lines.push(`ERROR: ${String(d.message ?? d.detail ?? "").slice(0, 200)}`);
1177
- else if (t === "status" && typeof d.status === "string") lines.push(`status:${d.status}`);
1178
- else if (t.includes("tool")) lines.push(`tool-event:${t}`);
1179
- }
1180
- const out = [];
1181
- for (const ln of lines) {
1182
- const prev = out[out.length - 1];
1183
- const m = prev?.match(/^(.*?)(?: x(\d+))?$/);
1184
- if (m && m[1] === ln) out[out.length - 1] = `${ln} x${(Number(m[2]) || 1) + 1}`;
1185
- else out.push(ln);
1186
- }
1187
- return out.slice(0, maxLines).join("\n") || "(no tool/error events in trace)";
1188
- }
1189
- var findingsSchema = {
1190
- name: "observer_findings",
1191
- schema: {
1192
- type: "object",
1193
- additionalProperties: false,
1194
- properties: {
1195
- findings: {
1196
- type: "array",
1197
- items: {
1198
- type: "object",
1199
- additionalProperties: false,
1200
- properties: {
1201
- area: {
1202
- type: "string",
1203
- description: "tool-use | cost | verification | process | failure | latency"
1204
- },
1205
- severity: { type: "string", enum: ["critical", "high", "medium", "low", "info"] },
1206
- claim: {
1207
- type: "string",
1208
- description: "what you OBSERVED in the trace (a fact, with the evidence)"
1209
- },
1210
- recommended_action: {
1211
- type: "string",
1212
- description: "the concrete change for the agent or operator"
1213
- },
1214
- audience: {
1215
- type: "string",
1216
- enum: ["agent", "operator"],
1217
- description: "who should act on this"
1218
- },
1219
- confidence: { type: "number" }
1220
- },
1221
- required: ["area", "severity", "claim", "recommended_action", "audience", "confidence"]
1222
- }
1223
- }
1224
- },
1225
- required: ["findings"]
1226
- }
1227
- };
1228
- async function observe(input, opts) {
1229
- const traceSummary = summarizeTrace(input.trace, opts.maxTraceLines ?? 80);
1230
- const res = await opts.chat.chat(
1231
- {
1232
- ...opts.model ? { model: opts.model } : {},
1233
- jsonSchema: findingsSchema,
1234
- messages: [
1235
- {
1236
- role: "system",
1237
- content: opts.analystInstruction ?? defaultAnalystInstruction
1238
- },
1239
- {
1240
- role: "user",
1241
- content: `TASK: ${input.task}
1242
-
1243
- OUTCOME: ${input.outcome ?? "unknown"}
1244
-
1245
- FINAL OUTPUT (truncated):
1246
- ${input.output.slice(0, 1200)}
1247
-
1248
- TRACE (in order; "xN" = repeated):
1249
- ${traceSummary}`
1250
- }
1251
- ]
1252
- },
1253
- { ...opts.signal ? { signal: opts.signal } : {} }
1254
- );
1255
- const parsed = parseFindings(res.content);
1256
- const producedAt = input.runId ? `${input.runId}` : observerId;
1257
- const findings = parsed.map(
1258
- (f) => makeFinding({
1259
- analyst_id: observerId,
1260
- area: `${f.area}`,
1261
- severity: f.severity,
1262
- claim: f.claim,
1263
- recommended_action: f.recommended_action,
1264
- confidence: typeof f.confidence === "number" ? f.confidence : 0.5,
1265
- evidence_refs: [],
1266
- // The observer reads BEHAVIOR, never the judge verdict — firewall provenance.
1267
- derived_from_judge: false,
1268
- metadata: { audience: f.audience },
1269
- ...input.runId ? { subject: input.runId } : {}
1270
- })
1271
- );
1272
- const learned = [];
1273
- if (opts.corpus) {
1274
- for (const f of findings) {
1275
- const record = {
1276
- schemaVersion: "1.0.0",
1277
- id: f.finding_id,
1278
- runId: input.runId ?? observerId,
1279
- producedAt: f.produced_at ?? producedAt,
1280
- area: f.area,
1281
- claim: f.recommended_action ?? f.claim,
1282
- ...f.claim ? { rationale: f.claim } : {},
1283
- tags: [...opts.tags ?? [], `audience:${f.metadata?.audience ?? "agent"}`],
1284
- confidence: f.confidence,
1285
- evidence: [{ kind: "finding", uri: f.finding_id }]
1286
- };
1287
- const r = await opts.corpus.append(record);
1288
- if (r.succeeded) learned.push(record);
1289
- }
1290
- }
1291
- return { findings, learned, report: renderReport(findings) };
1292
- }
1293
- function parseFindings(content) {
1294
- let obj2;
1295
- try {
1296
- obj2 = JSON.parse(content);
1297
- } catch {
1298
- const m = content.match(/\{[\s\S]*\}/);
1299
- obj2 = m ? JSON.parse(m[0]) : { findings: [] };
1300
- }
1301
- const arr = obj2.findings;
1302
- return Array.isArray(arr) ? arr : [];
1303
- }
1304
- function renderReport(findings) {
1305
- if (findings.length === 0) return "\u2713 clean run \u2014 the observer found nothing to change.";
1306
- const audience = (f) => f.metadata?.audience ?? "agent";
1307
- const forAgent = findings.filter((f) => audience(f) === "agent");
1308
- const forOperator = findings.filter((f) => audience(f) === "operator");
1309
- const block = (title, fs) => fs.length === 0 ? "" : `**${title}**
1310
- ${fs.map((f) => `- [${f.severity}] ${f.claim}
1311
- \u2192 ${f.recommended_action ?? ""}`).join("\n")}
1312
- `;
1313
- return [
1314
- block("For the agent (fix skills / prompt / tools)", forAgent),
1315
- block("For you (the operator)", forOperator)
1316
- ].filter(Boolean).join("\n");
1317
- }
1318
-
1319
1652
  // src/runtime/harvest-corpus.ts
1320
1653
  async function harvestCorpus(opts) {
1321
1654
  const concurrency = Math.max(1, opts.concurrency ?? 4);
@@ -1454,98 +1787,6 @@ function inProcessSandboxClient(options) {
1454
1787
  };
1455
1788
  }
1456
1789
 
1457
- // src/runtime/mcp-environment.ts
1458
- async function rpc(endpoint, body) {
1459
- let lastErr;
1460
- for (let attempt = 0; attempt < 4; attempt += 1) {
1461
- try {
1462
- const r = await fetch(endpoint.url, {
1463
- method: "POST",
1464
- headers: { "content-type": "application/json", ...endpoint.headers ?? {} },
1465
- body: JSON.stringify(body)
1466
- });
1467
- const text = await r.text();
1468
- const dataLines = text.split("\n").filter((l) => l.startsWith("data:")).map((l) => l.slice(5).trim());
1469
- const payload = dataLines.length ? dataLines[dataLines.length - 1] : text;
1470
- try {
1471
- return { status: r.status, json: JSON.parse(payload ?? "null") };
1472
- } catch {
1473
- return { status: r.status, json: text };
1474
- }
1475
- } catch (err) {
1476
- lastErr = err;
1477
- await new Promise((res) => setTimeout(res, 1e3 * (attempt + 1)));
1478
- }
1479
- }
1480
- throw new Error(
1481
- `mcp rpc ${endpoint.url} failed after 4 attempts: ${lastErr instanceof Error ? lastErr.message : String(lastErr)}`
1482
- );
1483
- }
1484
- function sanitizeSchema(s) {
1485
- const o = s && typeof s === "object" ? s : {};
1486
- const banned = o.oneOf || o.anyOf || o.allOf || o.not || o.enum;
1487
- if (o.type === "object" && !banned && o.properties && typeof o.properties === "object") {
1488
- return {
1489
- type: "object",
1490
- properties: o.properties,
1491
- ...Array.isArray(o.required) ? { required: o.required } : {}
1492
- };
1493
- }
1494
- return { type: "object", properties: {} };
1495
- }
1496
- function createMcpEnvironment(opts) {
1497
- const endpoints = /* @__PURE__ */ new Map();
1498
- const maxChars = opts.maxResultChars ?? 1500;
1499
- return {
1500
- name: opts.name,
1501
- async open(task) {
1502
- const { handle, endpoint } = await opts.open(task);
1503
- endpoints.set(handle.id, endpoint);
1504
- return handle;
1505
- },
1506
- async tools(task, handle) {
1507
- const endpoint = endpoints.get(handle.id);
1508
- if (!endpoint) throw new Error(`${opts.name}: tools() before open() for ${handle.id}`);
1509
- const { json } = await rpc(endpoint, {
1510
- jsonrpc: "2.0",
1511
- id: 1,
1512
- method: "tools/list",
1513
- params: {}
1514
- });
1515
- const all = (json.result?.tools ?? []).map(
1516
- (t) => ({
1517
- type: "function",
1518
- function: {
1519
- name: t.name,
1520
- description: (t.description ?? "").slice(0, 1e3),
1521
- parameters: sanitizeSchema(t.inputSchema)
1522
- }
1523
- })
1524
- );
1525
- return opts.selectTools ? opts.selectTools(task, all) : all;
1526
- },
1527
- async call(handle, name, args) {
1528
- const endpoint = endpoints.get(handle.id);
1529
- if (!endpoint) return "ERROR: workspace closed";
1530
- const { json } = await rpc(endpoint, {
1531
- jsonrpc: "2.0",
1532
- id: 2,
1533
- method: "tools/call",
1534
- params: { name, arguments: args }
1535
- });
1536
- const result = json ?? {};
1537
- if (result.error) return `ERROR: ${JSON.stringify(result.error).slice(0, 300)}`;
1538
- const text = result.result?.content?.map((c) => c.text ?? "").join("\n") ?? JSON.stringify(result.result ?? json);
1539
- return text.slice(0, maxChars);
1540
- },
1541
- score: (task, handle) => opts.score(task, handle),
1542
- async close(handle) {
1543
- endpoints.delete(handle.id);
1544
- await opts.close?.(handle);
1545
- }
1546
- };
1547
- }
1548
-
1549
1790
  // src/runtime/personify/analyst.ts
1550
1791
  var judgeEvidenceUri = /^(verdict|judge|score)\b/i;
1551
1792
  var assertTraceDerivedFindings = (findings) => {
@@ -2302,13 +2543,13 @@ function shapeName(shape, _resolved) {
2302
2543
  }
2303
2544
  function resolveShapeBudget(root, over) {
2304
2545
  const fanout2 = over?.fanout ?? defaultFanout;
2305
- const perChild2 = over?.perChild ?? {
2546
+ const perChild = over?.perChild ?? {
2306
2547
  maxIterations: Math.max(1, Math.floor(root.maxIterations / fanout2)),
2307
2548
  maxTokens: Math.max(1, Math.floor(root.maxTokens / fanout2)),
2308
2549
  ...root.maxUsd !== void 0 ? { maxUsd: root.maxUsd / fanout2 } : {},
2309
2550
  ...root.deadlineMs !== void 0 ? { deadlineMs: root.deadlineMs } : {}
2310
2551
  };
2311
- return { perChild: perChild2, fanout: fanout2 };
2552
+ return { perChild, fanout: fanout2 };
2312
2553
  }
2313
2554
  var defaultFanout = 3;
2314
2555
  function personaRegistry(persona) {
@@ -2594,777 +2835,115 @@ function promotionGate(opts) {
2594
2835
  candMs.push(cand.ms);
2595
2836
  cellIds.push(row.taskId);
2596
2837
  }
2597
- if (before.length === 0) {
2598
- throw new Error(
2599
- `promotionGate: no holdout task carried cells for both "${opts.incumbent}" and "${opts.candidate}" \u2014 the report must come from a run that included both strategies`
2600
- );
2601
- }
2602
- const sig = heldoutSignificance(
2603
- { before, after, cellIds },
2604
- {
2605
- deltaThreshold: opts.deltaThreshold ?? 0,
2606
- minProductiveRuns: opts.minPairedTasks ?? 6,
2607
- statistic: opts.statistic ?? "mean",
2608
- ...opts.seed !== void 0 ? { seed: opts.seed } : {},
2609
- ...opts.resamples !== void 0 ? { resamples: opts.resamples } : {}
2610
- }
2611
- );
2612
- const lift = {
2613
- mean: sig.bootstrap.mean,
2614
- median: sig.bootstrap.median,
2615
- low: sig.bootstrap.low,
2616
- high: sig.bootstrap.high
2617
- };
2618
- const latSig = heldoutSignificance(
2619
- { before: incMs, after: candMs, cellIds },
2620
- {
2621
- deltaThreshold: 0,
2622
- minProductiveRuns: 1,
2623
- statistic: opts.statistic ?? "mean",
2624
- ...opts.seed !== void 0 ? { seed: opts.seed } : {},
2625
- ...opts.resamples !== void 0 ? { resamples: opts.resamples } : {}
2626
- }
2627
- );
2628
- const latency = {
2629
- mean: latSig.bootstrap.mean,
2630
- median: latSig.bootstrap.median,
2631
- low: latSig.bootstrap.low,
2632
- high: latSig.bootstrap.high
2633
- };
2634
- if (mode === "superiority") {
2635
- if (sig.fewRuns) return { promoted: false, reason: "few-tasks", mode, n: sig.n, lift, latency };
2636
- return sig.significant ? { promoted: true, reason: "significant", mode, n: sig.n, lift, latency } : { promoted: false, reason: "no-margin", mode, n: sig.n, lift, latency };
2637
- }
2638
- const tolerance = opts.scoreTolerance ?? 0.05;
2639
- const scoreSig = heldoutSignificance(
2640
- { before, after, cellIds },
2641
- {
2642
- deltaThreshold: -tolerance,
2643
- minProductiveRuns: opts.minPairedTasks ?? 6,
2644
- statistic: opts.statistic ?? "mean",
2645
- ...opts.seed !== void 0 ? { seed: opts.seed } : {},
2646
- ...opts.resamples !== void 0 ? { resamples: opts.resamples } : {}
2647
- }
2648
- );
2649
- const costSig = heldoutSignificance(
2650
- { before: candUsd, after: incUsd, cellIds },
2651
- {
2652
- deltaThreshold: 0,
2653
- minProductiveRuns: opts.minPairedTasks ?? 6,
2654
- statistic: opts.statistic ?? "mean",
2655
- ...opts.seed !== void 0 ? { seed: opts.seed } : {},
2656
- ...opts.resamples !== void 0 ? { resamples: opts.resamples } : {}
2657
- }
2658
- );
2659
- const costSavings = {
2660
- mean: costSig.bootstrap.mean,
2661
- median: costSig.bootstrap.median,
2662
- low: costSig.bootstrap.low,
2663
- high: costSig.bootstrap.high
2664
- };
2665
- if (scoreSig.fewRuns)
2666
- return { promoted: false, reason: "few-tasks", mode, n: scoreSig.n, lift, costSavings, latency };
2667
- if (!scoreSig.significant)
2668
- return {
2669
- promoted: false,
2670
- reason: "non-inferiority-unproven",
2671
- mode,
2672
- n: scoreSig.n,
2673
- lift,
2674
- costSavings,
2675
- latency
2676
- };
2677
- if (!costSig.significant)
2678
- return {
2679
- promoted: false,
2680
- reason: "not-cheaper",
2681
- mode,
2682
- n: scoreSig.n,
2683
- lift,
2684
- costSavings,
2685
- latency
2686
- };
2687
- return {
2688
- promoted: true,
2689
- reason: "non-inferior-and-cheaper",
2690
- mode,
2691
- n: scoreSig.n,
2692
- lift,
2693
- costSavings,
2694
- latency
2695
- };
2696
- }
2697
-
2698
- // src/runtime/report-usage.ts
2699
- function reportLoopUsage(cost, result, source = "loop") {
2700
- cost.observe(result.costUsd, source);
2701
- cost.observeTokens(result.tokenUsage);
2702
- }
2703
-
2704
- // src/runtime/run-benchmark.ts
2705
- import { pairedBootstrap as pairedBootstrap2, paretoFrontier } from "@tangle-network/agent-eval";
2706
-
2707
- // src/runtime/strategy.ts
2708
- import { createChatClient, estimateCost, isModelPriced } from "@tangle-network/agent-eval";
2709
- var taskNudge = "Use the available tools to bring the artifact to the required final state. Address EVERY distinct change the request implies. After each tool result, check what remains and continue. Re-read the values you set to confirm they took. Reply DONE only once every required change is made and verified.";
2710
- async function runShot(surface, _task, handle, tools, messages, opts, modelOverride) {
2711
- let toolErrors = 0;
2712
- const execute = async (name, args) => {
2713
- try {
2714
- const out = await surface.call(handle, name, args);
2715
- if (out.startsWith("ERROR:")) toolErrors += 1;
2716
- return out;
2717
- } catch (e) {
2718
- toolErrors += 1;
2719
- return `ERROR: ${e instanceof Error ? e.message : String(e)}`;
2720
- }
2721
- };
2722
- const r = await routerToolLoop(
2723
- {
2724
- routerBaseUrl: opts.routerBaseUrl,
2725
- routerKey: opts.routerKey,
2726
- model: modelOverride ?? opts.model,
2727
- ...opts.complete ? { complete: opts.complete } : {}
2728
- },
2729
- "",
2730
- "",
2731
- tools,
2732
- execute,
2733
- {
2734
- maxTurns: opts.innerTurns ?? 4,
2735
- temperature: opts.temperature ?? 0.7,
2736
- initialMessages: messages,
2737
- ...opts.maxTokens ? { maxTokens: opts.maxTokens } : {}
2738
- }
2739
- );
2740
- return {
2741
- messages: r.messages,
2742
- completions: r.turns,
2743
- toolCalls: r.toolCalls,
2744
- toolErrors,
2745
- tokens: r.usage
2746
- };
2747
- }
2748
- function compactTrajectory(messages) {
2749
- return messages.filter((m) => m.role === "assistant" || m.role === "tool").map((m) => {
2750
- if (m.role === "tool") return `RESULT ${String(m.content).slice(0, 280)}`;
2751
- const calls = m.tool_calls?.map((c) => `${c.function.name}(${c.function.arguments})`).join(", ");
2752
- return calls ? `CALL ${calls}` : `SAY ${String(m.content).slice(0, 200)}`;
2753
- }).join("\n").slice(0, 7e3);
2754
- }
2755
- function analystChat(opts, defaultModel) {
2756
- if (!opts.complete) {
2757
- return createChatClient({
2758
- transport: "router",
2759
- apiKey: opts.routerKey,
2760
- baseUrl: opts.routerBaseUrl,
2761
- defaultModel
2762
- });
2763
- }
2764
- const complete = opts.complete;
2765
- return createChatClient({
2766
- transport: "mock",
2767
- defaultModel,
2768
- handler: async (req) => {
2769
- const raw = await complete({
2770
- model: req.model ?? defaultModel,
2771
- messages: req.messages,
2772
- ...req.temperature !== void 0 ? { temperature: req.temperature } : {},
2773
- ...req.maxTokens !== void 0 ? { max_tokens: req.maxTokens } : {}
2774
- });
2775
- const content = raw.choices?.[0]?.message?.content ?? "";
2776
- const promptTokens = raw.usage?.prompt_tokens ?? 0;
2777
- const completionTokens = raw.usage?.completion_tokens ?? 0;
2778
- return {
2779
- content,
2780
- usage: {
2781
- promptTokens,
2782
- completionTokens,
2783
- totalTokens: promptTokens + completionTokens
2784
- },
2785
- costUsd: null,
2786
- model: req.model ?? defaultModel,
2787
- durationMs: 0,
2788
- finishReason: raw.choices?.[0]?.finish_reason ?? null,
2789
- contentEmpty: content.trim().length === 0,
2790
- raw
2791
- };
2792
- }
2793
- });
2794
- }
2795
- async function consultAnalyst(task, messages, instruction, opts) {
2796
- const trajectory = compactTrajectory(messages);
2797
- const analystModel = opts.analystModel ?? opts.model;
2798
- const chat = analystChat(opts, analystModel);
2799
- const consultMessages = trajectory ? [
2800
- { role: "system", content: instruction },
2801
- {
2802
- role: "user",
2803
- content: `TASK: ${task.userPrompt.slice(0, 1500)}
2804
-
2805
- TRAJECTORY:
2806
- ${trajectory}`
2807
- }
2808
- ] : [
2809
- {
2810
- role: "user",
2811
- content: `${instruction}
2812
-
2813
- TASK:
2814
- ${task.userPrompt.slice(0, 1500)}`
2815
- }
2816
- ];
2817
- const res = await chat.chat({
2818
- model: analystModel,
2819
- temperature: 0.2,
2820
- maxTokens: 1024,
2821
- messages: consultMessages
2822
- });
2823
- const usage = res.usage;
2824
- return {
2825
- steer: res.content.trim(),
2826
- tokens: {
2827
- input: usage?.promptTokens ?? usage?.prompt_tokens ?? 0,
2828
- output: usage?.completionTokens ?? usage?.completion_tokens ?? 0
2829
- }
2830
- };
2831
- }
2832
- async function analyze(task, messages, opts) {
2833
- const trajectory = compactTrajectory(messages);
2834
- const analystModel = opts.analystModel ?? opts.model;
2835
- const inner = analystChat(opts, analystModel);
2836
- const tokens = { input: 0, output: 0 };
2837
- const chat = {
2838
- ...inner,
2839
- chat: async (req, callOpts) => {
2840
- const res = await inner.chat(req, callOpts);
2841
- const u = res.usage;
2842
- if (u) {
2843
- tokens.input += u.promptTokens ?? u.prompt_tokens ?? 0;
2844
- tokens.output += u.completionTokens ?? u.completion_tokens ?? 0;
2845
- }
2846
- return res;
2847
- }
2848
- };
2849
- const obs = await observe(
2850
- {
2851
- task: task.userPrompt,
2852
- output: trajectory,
2853
- trace: messages,
2854
- outcome: "failed",
2855
- runId: task.id
2856
- },
2857
- {
2858
- chat,
2859
- model: analystModel,
2860
- ...opts.analystInstruction ? { analystInstruction: opts.analystInstruction } : {},
2861
- ...opts.corpus ? { corpus: opts.corpus, tags: opts.corpusTags ?? [] } : {}
2862
- }
2863
- );
2864
- const steer = obs.findings.map((f) => f.recommended_action).filter((a) => typeof a === "string" && a.trim().length > 0).join("\n").trim();
2865
- return { steer: steer || "COMPLETE", tokens };
2866
- }
2867
- async function renderCorpusReadback(opts) {
2868
- if (!opts.corpus || !opts.corpusReadback) return "";
2869
- const maxFacts = opts.corpusReadback.maxFacts ?? 3;
2870
- if (!Number.isInteger(maxFacts) || maxFacts < 0) {
2871
- throw new Error(`corpusReadback.maxFacts must be a non-negative integer, got ${maxFacts}`);
2872
- }
2873
- if (maxFacts === 0) return "";
2874
- const tags = [
2875
- ...opts.corpusTags ?? [],
2876
- ...opts.corpusReadback.tags ?? [],
2877
- ...opts.corpusReadback.includeOperatorFacts ? [] : ["audience:agent"]
2878
- ];
2879
- const facts = await opts.corpus.query({
2880
- ...tags.length > 0 ? { tags } : {},
2881
- minConfidence: opts.corpusReadback.minConfidence ?? 0.7,
2882
- limit: maxFacts
2883
- });
2884
- if (facts.length === 0) return "";
2885
- const rendered = facts.map(
2886
- (fact) => fact.rationale ? `- ${fact.claim} (${fact.rationale})` : `- ${fact.claim}`
2887
- );
2888
- return `Relevant learned facts from prior attempts:
2889
- ${rendered.join("\n")}`;
2890
- }
2891
- function shotExecutor(surface, opts) {
2892
- let artifact;
2893
- return {
2894
- runtime: "agentic-shot",
2895
- async execute(task) {
2896
- const t = task;
2897
- const own = !t.handle;
2898
- const handle = t.handle ?? await surface.open(t.task);
2899
- try {
2900
- const allTools = await surface.tools(t.task, handle);
2901
- let tools = allTools;
2902
- if (t.tools) {
2903
- const known = new Set(allTools.map((tool) => tool.function.name));
2904
- const unknown = t.tools.filter((name) => !known.has(name));
2905
- if (unknown.length > 0) {
2906
- throw new Error(
2907
- `shot tools: unknown tool name(s) ${unknown.join(", ")} \u2014 domain offers: ${[...known].join(", ")}`
2908
- );
2909
- }
2910
- const want = new Set(t.tools);
2911
- tools = allTools.filter((tool) => want.has(tool.function.name));
2912
- }
2913
- const messages = t.messages?.length ? t.messages : [
2914
- { role: "system", content: t.persona?.systemPrompt ?? t.task.systemPrompt },
2915
- { role: "user", content: `${t.task.userPrompt}
2916
-
2917
- ${taskNudge}` }
2918
- ];
2919
- if (t.messages?.length && t.persona?.systemPrompt) {
2920
- messages.push({
2921
- role: "user",
2922
- content: `[hand-off] You are now acting as: ${t.persona.systemPrompt}`
2923
- });
2924
- }
2925
- if (t.steer) messages.push({ role: "user", content: t.steer });
2926
- const shot = await runShot(surface, t.task, handle, tools, messages, opts, t.persona?.model);
2927
- const s = await surface.score(t.task, handle);
2928
- const score = s.total > 0 ? s.passes / s.total : 0;
2929
- const out = {
2930
- messages: shot.messages,
2931
- score,
2932
- passes: s.passes,
2933
- total: s.total,
2934
- completions: shot.completions,
2935
- toolErrors: shot.toolErrors
2936
- };
2937
- artifact = {
2938
- outRef: `shot:${handle.id}:${shot.completions}:${s.passes}/${s.total}`,
2939
- out,
2940
- verdict: { valid: s.total > 0 && s.passes === s.total, score },
2941
- // Real usage to the conserved pool: tokens from the router responses; usd only
2942
- // when the model is in the price table (never a fabricated number).
2943
- spent: {
2944
- iterations: shot.completions,
2945
- tokens: shot.tokens,
2946
- usd: isModelPriced(opts.model) ? estimateCost(shot.tokens.input, shot.tokens.output, opts.model) : 0,
2947
- ms: 0
2948
- }
2949
- };
2950
- return artifact;
2951
- } finally {
2952
- if (own) await surface.close(handle);
2953
- }
2954
- },
2955
- teardown: () => Promise.resolve({ destroyed: true }),
2956
- resultArtifact() {
2957
- if (!artifact) throw new Error("shotExecutor: resultArtifact before execute");
2958
- return artifact;
2959
- }
2960
- };
2961
- }
2962
- function analystExecutor(opts) {
2963
- let artifact;
2964
- return {
2965
- runtime: "agentic-analyst",
2966
- async execute(task) {
2967
- const t = task;
2968
- const { steer, tokens } = t.rawInstruction ? await consultAnalyst(t.task, t.messages, t.rawInstruction, opts) : await analyze(t.task, t.messages, opts);
2969
- const analystModel = opts.analystModel ?? opts.model;
2970
- artifact = {
2971
- outRef: `analyst:${steer.length}`,
2972
- out: steer,
2973
- spent: {
2974
- iterations: 1,
2975
- tokens,
2976
- usd: isModelPriced(analystModel) ? estimateCost(tokens.input, tokens.output, analystModel) : 0,
2977
- ms: 0
2978
- }
2979
- };
2980
- return artifact;
2981
- },
2982
- teardown: () => Promise.resolve({ destroyed: true }),
2983
- resultArtifact() {
2984
- if (!artifact) throw new Error("analystExecutor: resultArtifact before execute");
2985
- return artifact;
2986
- }
2987
- };
2988
- }
2989
- function agenticRegistry(surface, opts) {
2990
- const leaves = {
2991
- register() {
2992
- throw new Error("agenticRegistry: register unsupported");
2993
- },
2994
- resolve(spec) {
2995
- const role = spec.profile.metadata?.role;
2996
- const factory = (_s, _ctx) => role === "analyst" ? analystExecutor(opts) : shotExecutor(surface, opts);
2997
- return { succeeded: true, value: factory };
2838
+ if (before.length === 0) {
2839
+ throw new Error(
2840
+ `promotionGate: no holdout task carried cells for both "${opts.incumbent}" and "${opts.candidate}" \u2014 the report must come from a run that included both strategies`
2841
+ );
2842
+ }
2843
+ const sig = heldoutSignificance(
2844
+ { before, after, cellIds },
2845
+ {
2846
+ deltaThreshold: opts.deltaThreshold ?? 0,
2847
+ minProductiveRuns: opts.minPairedTasks ?? 6,
2848
+ statistic: opts.statistic ?? "mean",
2849
+ ...opts.seed !== void 0 ? { seed: opts.seed } : {},
2850
+ ...opts.resamples !== void 0 ? { resamples: opts.resamples } : {}
2998
2851
  }
2852
+ );
2853
+ const lift = {
2854
+ mean: sig.bootstrap.mean,
2855
+ median: sig.bootstrap.median,
2856
+ low: sig.bootstrap.low,
2857
+ high: sig.bootstrap.high
2999
2858
  };
3000
- return withDriverExecutor(leaves);
3001
- }
3002
- function leaf(name, role) {
3003
- const agent = {
3004
- name,
3005
- executorSpec: { profile: { name, metadata: { role } }, harness: null },
3006
- act() {
3007
- throw new Error(`agentic: spawned child "${name}" was run directly (the executor drives it)`);
2859
+ const latSig = heldoutSignificance(
2860
+ { before: incMs, after: candMs, cellIds },
2861
+ {
2862
+ deltaThreshold: 0,
2863
+ minProductiveRuns: 1,
2864
+ statistic: opts.statistic ?? "mean",
2865
+ ...opts.seed !== void 0 ? { seed: opts.seed } : {},
2866
+ ...opts.resamples !== void 0 ? { resamples: opts.resamples } : {}
3008
2867
  }
2868
+ );
2869
+ const latency = {
2870
+ mean: latSig.bootstrap.mean,
2871
+ median: latSig.bootstrap.median,
2872
+ low: latSig.bootstrap.low,
2873
+ high: latSig.bootstrap.high
3009
2874
  };
3010
- return agent;
3011
- }
3012
- async function drainOne2(scope) {
3013
- const s = await scope.next();
3014
- if (!s) throw new Error("agentic: spawned child never settled");
3015
- return s;
3016
- }
3017
- var perChild = (innerTurns) => ({
3018
- maxIterations: innerTurns + 1,
3019
- maxTokens: 1e6
3020
- });
3021
- function depthStrategy(surface, task, opts, cfg) {
3022
- const innerTurns = opts.innerTurns ?? 4;
3023
- let pendingSteer;
3024
- return {
3025
- name: "depth",
3026
- async act(_t, scope) {
3027
- const handle = await surface.open(task);
3028
- const progression = [];
3029
- let messages;
3030
- let completions = 0;
3031
- let shots = 0;
3032
- try {
3033
- for (shots = 0; shots < cfg.maxShots; shots += 1) {
3034
- const child = leaf(`shot:${shots}`, "shot");
3035
- const memorySteer = await renderCorpusReadback(opts);
3036
- const steer = [shots === 0 ? void 0 : pendingSteer, memorySteer].filter((part) => typeof part === "string" && part.trim().length > 0).join("\n\n");
3037
- const res = scope.spawn(child, { task, handle, messages, steer }, {
3038
- budget: perChild(innerTurns),
3039
- label: `shot:${shots}`
3040
- });
3041
- if (!res.ok) break;
3042
- const settled = await drainOne2(scope);
3043
- if (settled.kind === "down") break;
3044
- const out = settled.out;
3045
- messages = out.messages;
3046
- completions += out.completions;
3047
- progression.push(out.score);
3048
- if (out.score >= 1 || shots === cfg.maxShots - 1) break;
3049
- const aChild = leaf(`analyst:${shots}`, "analyst");
3050
- const aRes = scope.spawn(
3051
- aChild,
3052
- { task, messages },
3053
- { budget: perChild(1), label: `analyst:${shots}` }
3054
- );
3055
- if (!aRes.ok) break;
3056
- const aSettled = await drainOne2(scope);
3057
- completions += 1;
3058
- if (aSettled.kind === "down") break;
3059
- const findings = aSettled.out;
3060
- if (/^\s*COMPLETE\b/i.test(findings)) break;
3061
- pendingSteer = `A reviewer flagged unfinished items:
3062
- ${findings}
3063
-
3064
- Address each with the tools, verify they took, then continue.`;
3065
- }
3066
- const final = await surface.score(task, handle);
3067
- const score = final.total > 0 ? final.passes / final.total : 0;
3068
- return {
3069
- kind: "done",
3070
- deliverable: {
3071
- mode: "depth",
3072
- score,
3073
- resolved: final.total > 0 && final.passes === final.total,
3074
- completions,
3075
- progression,
3076
- shots: shots + 1
3077
- }
3078
- };
3079
- } finally {
3080
- await surface.close(handle);
3081
- }
2875
+ if (mode === "superiority") {
2876
+ if (sig.fewRuns) return { promoted: false, reason: "few-tasks", mode, n: sig.n, lift, latency };
2877
+ return sig.significant ? { promoted: true, reason: "significant", mode, n: sig.n, lift, latency } : { promoted: false, reason: "no-margin", mode, n: sig.n, lift, latency };
2878
+ }
2879
+ const tolerance = opts.scoreTolerance ?? 0.05;
2880
+ const scoreSig = heldoutSignificance(
2881
+ { before, after, cellIds },
2882
+ {
2883
+ deltaThreshold: -tolerance,
2884
+ minProductiveRuns: opts.minPairedTasks ?? 6,
2885
+ statistic: opts.statistic ?? "mean",
2886
+ ...opts.seed !== void 0 ? { seed: opts.seed } : {},
2887
+ ...opts.resamples !== void 0 ? { resamples: opts.resamples } : {}
3082
2888
  }
3083
- };
3084
- }
3085
- function breadthStrategy(_surface, task, opts, cfg) {
3086
- const innerTurns = opts.innerTurns ?? 4;
3087
- return {
3088
- name: "breadth",
3089
- async act(_t, scope) {
3090
- let opened = 0;
3091
- for (let k = 0; k < cfg.width; k += 1) {
3092
- const res = scope.spawn(leaf(`rollout:${k}`, "shot"), { task }, {
3093
- budget: perChild(innerTurns),
3094
- label: `rollout:${k}`
3095
- });
3096
- if (res.ok) opened += 1;
3097
- }
3098
- if (opened === 0) return { kind: "blocked", blockers: ["breadth: pool admitted no rollout"] };
3099
- let best = -1;
3100
- let bestResolved = false;
3101
- let completions = 0;
3102
- const progression = [];
3103
- for (let s = await scope.next(); s !== null; s = await scope.next()) {
3104
- if (s.kind === "down") continue;
3105
- const out = s.out;
3106
- completions += out.completions;
3107
- if (out.score > best) best = out.score;
3108
- if (out.total > 0 && out.passes === out.total) bestResolved = true;
3109
- progression.push(best);
3110
- }
3111
- if (best < 0) return { kind: "blocked", blockers: ["breadth: every rollout went down"] };
3112
- return {
3113
- kind: "done",
3114
- deliverable: {
3115
- mode: "breadth",
3116
- score: best,
3117
- resolved: bestResolved,
3118
- completions,
3119
- progression,
3120
- shots: opened
3121
- }
3122
- };
2889
+ );
2890
+ const costSig = heldoutSignificance(
2891
+ { before: candUsd, after: incUsd, cellIds },
2892
+ {
2893
+ deltaThreshold: 0,
2894
+ minProductiveRuns: opts.minPairedTasks ?? 6,
2895
+ statistic: opts.statistic ?? "mean",
2896
+ ...opts.seed !== void 0 ? { seed: opts.seed } : {},
2897
+ ...opts.resamples !== void 0 ? { resamples: opts.resamples } : {}
3123
2898
  }
2899
+ );
2900
+ const costSavings = {
2901
+ mean: costSig.bootstrap.mean,
2902
+ median: costSig.bootstrap.median,
2903
+ low: costSig.bootstrap.low,
2904
+ high: costSig.bootstrap.high
3124
2905
  };
3125
- }
3126
- var sample = {
3127
- name: "sample",
3128
- driver: (surface, task, opts, budget) => breadthStrategy(surface, task, opts, { width: budget })
3129
- };
3130
- var refine = {
3131
- name: "refine",
3132
- driver: (surface, task, opts, budget) => depthStrategy(surface, task, opts, { maxShots: budget })
3133
- };
3134
- function defineStrategy(name, run) {
2906
+ if (scoreSig.fewRuns)
2907
+ return { promoted: false, reason: "few-tasks", mode, n: scoreSig.n, lift, costSavings, latency };
2908
+ if (!scoreSig.significant)
2909
+ return {
2910
+ promoted: false,
2911
+ reason: "non-inferiority-unproven",
2912
+ mode,
2913
+ n: scoreSig.n,
2914
+ lift,
2915
+ costSavings,
2916
+ latency
2917
+ };
2918
+ if (!costSig.significant)
2919
+ return {
2920
+ promoted: false,
2921
+ reason: "not-cheaper",
2922
+ mode,
2923
+ n: scoreSig.n,
2924
+ lift,
2925
+ costSavings,
2926
+ latency
2927
+ };
3135
2928
  return {
3136
- name,
3137
- driver: (surface, task, opts, budget) => ({
3138
- name,
3139
- async act(_t, scope) {
3140
- let seq = 0;
3141
- const innerTurns = opts.innerTurns ?? 4;
3142
- let verifiedBest = 0;
3143
- let verifiedResolved = false;
3144
- const openHandles = /* @__PURE__ */ new Set();
3145
- const ctx = {
3146
- // Narrowed to open/close — the body gets no raw call()/score() access.
3147
- surface: {
3148
- name: surface.name,
3149
- open: async (t) => {
3150
- const h = await surface.open(t);
3151
- openHandles.add(h.id);
3152
- return h;
3153
- },
3154
- close: async (h) => {
3155
- if (!h || !openHandles.has(h.id)) return;
3156
- openHandles.delete(h.id);
3157
- await surface.close(h);
3158
- }
3159
- },
3160
- task,
3161
- opts,
3162
- budget,
3163
- scope,
3164
- async shot(spec) {
3165
- const child = leaf(`shot:${seq}`, "shot");
3166
- seq += 1;
3167
- const res = scope.spawn(
3168
- child,
3169
- {
3170
- task,
3171
- handle: spec?.handle,
3172
- messages: spec?.messages,
3173
- steer: spec?.steer,
3174
- persona: spec?.persona,
3175
- tools: spec?.tools
3176
- },
3177
- { budget: perChild(innerTurns), label: child.name }
3178
- );
3179
- if (!res.ok) return null;
3180
- const settled = await drainOne2(scope);
3181
- if (settled.kind === "down") return null;
3182
- const out = settled.out;
3183
- if (out.score > verifiedBest) verifiedBest = out.score;
3184
- if (out.total > 0 && out.passes === out.total) verifiedResolved = true;
3185
- return out;
3186
- },
3187
- async listTools(handle) {
3188
- const tools = await surface.tools(task, handle);
3189
- return tools.map((t) => ({
3190
- name: t.function.name,
3191
- ...t.function.description ? { description: t.function.description } : {}
3192
- }));
3193
- },
3194
- async critique(messages) {
3195
- const child = leaf(`analyst:${seq}`, "analyst");
3196
- seq += 1;
3197
- const res = scope.spawn(
3198
- child,
3199
- { task, messages },
3200
- { budget: perChild(1), label: child.name }
3201
- );
3202
- if (!res.ok) return null;
3203
- const settled = await drainOne2(scope);
3204
- if (settled.kind === "down") return null;
3205
- const findings = settled.out;
3206
- return /^\s*COMPLETE\b/i.test(findings) ? null : findings;
3207
- },
3208
- async consult(messages, instruction) {
3209
- const child = leaf(`analyst:${seq}`, "analyst");
3210
- seq += 1;
3211
- const res = scope.spawn(
3212
- child,
3213
- { task, messages, rawInstruction: instruction },
3214
- { budget: perChild(1), label: child.name }
3215
- );
3216
- if (!res.ok) return null;
3217
- const settled = await drainOne2(scope);
3218
- if (settled.kind === "down") return null;
3219
- return settled.out;
3220
- }
3221
- };
3222
- const r = await run(ctx);
3223
- return {
3224
- kind: "done",
3225
- deliverable: {
3226
- mode: name,
3227
- ...r,
3228
- progression: Array.isArray(r.progression) ? r.progression : [],
3229
- completions: typeof r.completions === "number" ? r.completions : 0,
3230
- shots: typeof r.shots === "number" ? r.shots : 0,
3231
- score: verifiedBest,
3232
- resolved: verifiedResolved
3233
- }
3234
- };
3235
- }
3236
- })
2929
+ promoted: true,
2930
+ reason: "non-inferior-and-cheaper",
2931
+ mode,
2932
+ n: scoreSig.n,
2933
+ lift,
2934
+ costSavings,
2935
+ latency
3237
2936
  };
3238
2937
  }
3239
- var adaptiveRefine = defineStrategy(
3240
- "adaptiveRefine",
3241
- async ({ surface, task, budget, shot, critique }) => {
3242
- let handle = await surface.open(task);
3243
- const progression = [];
3244
- let messages;
3245
- let steer;
3246
- let completions = 0;
3247
- let best = -1;
3248
- let shots = 0;
3249
- try {
3250
- for (shots = 0; shots < budget; shots += 1) {
3251
- const out = await shot({ handle, messages, steer });
3252
- if (!out) break;
3253
- completions += out.completions;
3254
- progression.push(out.score);
3255
- if (out.score >= 1) break;
3256
- if (out.score <= best) {
3257
- await surface.close(handle);
3258
- handle = await surface.open(task);
3259
- messages = void 0;
3260
- steer = void 0;
3261
- continue;
3262
- }
3263
- best = out.score;
3264
- messages = out.messages;
3265
- const findings = await critique(out.messages);
3266
- completions += 1;
3267
- if (!findings) break;
3268
- steer = `A reviewer flagged unfinished items:
3269
- ${findings}
3270
-
3271
- Address each with the tools, verify they took, then continue.`;
3272
- }
3273
- const score = progression.length ? Math.max(...progression) : 0;
3274
- return { score, resolved: score >= 1, completions, progression, shots };
3275
- } finally {
3276
- await surface.close(handle);
3277
- }
3278
- }
3279
- );
3280
- var sampleThenRefine = defineStrategy(
3281
- "sampleThenRefine",
3282
- async ({ surface, task, budget, shot, critique }) => {
3283
- const explore = Math.max(1, Math.ceil(budget / 2));
3284
- const open = /* @__PURE__ */ new Set();
3285
- const progression = [];
3286
- let completions = 0;
3287
- let shots = 0;
3288
- try {
3289
- let best;
3290
- for (let i = 0; i < explore; i += 1) {
3291
- const handle = await surface.open(task);
3292
- open.add(handle);
3293
- const out = await shot({ handle });
3294
- if (!out) continue;
3295
- shots += 1;
3296
- completions += out.completions;
3297
- progression.push(out.score);
3298
- if (!best || out.score > best.out.score) best = { handle, out };
3299
- if (out.score >= 1) break;
3300
- }
3301
- if (!best) return { score: 0, resolved: false, completions, progression, shots };
3302
- for (const h of [...open]) {
3303
- if (h !== best.handle) {
3304
- await surface.close(h);
3305
- open.delete(h);
3306
- }
3307
- }
3308
- let messages = best.out.messages;
3309
- let topScore = best.out.score;
3310
- for (let i = explore; i < budget && topScore < 1; i += 1) {
3311
- const findings = await critique(messages);
3312
- completions += 1;
3313
- if (!findings) break;
3314
- const out = await shot({
3315
- handle: best.handle,
3316
- messages,
3317
- steer: `A reviewer flagged unfinished items:
3318
- ${findings}
3319
2938
 
3320
- Address each with the tools, verify they took, then continue.`
3321
- });
3322
- if (!out) break;
3323
- shots += 1;
3324
- completions += out.completions;
3325
- progression.push(out.score);
3326
- messages = out.messages;
3327
- if (out.score > topScore) topScore = out.score;
3328
- }
3329
- const score = progression.length ? Math.max(...progression) : 0;
3330
- return { score, resolved: score >= 1, completions, progression, shots };
3331
- } finally {
3332
- for (const h of open) await surface.close(h);
3333
- }
3334
- }
3335
- );
3336
- async function runAgentic(opts) {
3337
- const strategy = opts.strategy ?? (opts.mode === "breadth" ? sample : refine);
3338
- const driver = strategy.driver(opts.surface, opts.task, opts, opts.budget);
3339
- const supervisor = createSupervisor();
3340
- const root = opts.rootBudget ?? {
3341
- maxIterations: opts.budget * ((opts.innerTurns ?? 4) + 2),
3342
- maxTokens: 1e9
3343
- };
3344
- const started = Date.now();
3345
- const result = await supervisor.run(driver, void 0, {
3346
- budget: root,
3347
- runId: `agentic:${strategy.name}:${opts.task.id}`,
3348
- journal: new InMemorySpawnJournal(),
3349
- blobs: new InMemoryResultBlobStore(),
3350
- executors: agenticRegistry(opts.surface, opts),
3351
- maxDepth: 3,
3352
- ...opts.hooks ? { hooks: opts.hooks } : {}
3353
- });
3354
- if (result.kind !== "winner" || result.out.kind !== "done") {
3355
- const reason = result.kind === "winner" ? `blocked: ${result.out.blockers?.join("; ")}` : `no-winner: ${result.reason}`;
3356
- throw new Error(`runAgentic(${strategy.name}) produced no result \u2014 ${reason}`);
3357
- }
3358
- const core = result.out.deliverable;
3359
- return {
3360
- ...core,
3361
- usd: result.spentTotal.usd,
3362
- tokens: result.spentTotal.tokens,
3363
- ms: Date.now() - started
3364
- };
2939
+ // src/runtime/report-usage.ts
2940
+ function reportLoopUsage(cost, result, source = "loop") {
2941
+ cost.observe(result.costUsd, source);
2942
+ cost.observeTokens(result.tokenUsage);
3365
2943
  }
3366
2944
 
3367
2945
  // src/runtime/run-benchmark.ts
2946
+ import { pairedBootstrap as pairedBootstrap2, paretoFrontier } from "@tangle-network/agent-eval";
3368
2947
  async function pool(items, limit, fn) {
3369
2948
  const out = new Array(items.length);
3370
2949
  let next = 0;
@@ -3831,16 +3410,19 @@ async function requestAuthoredCode(opts, model) {
3831
3410
  messages: [
3832
3411
  {
3833
3412
  role: "system",
3834
- content: "You are a senior engineer authoring optimization strategies for agent loops. Output exactly one fenced ```ts code block and nothing else."
3413
+ content: "You are a senior researcher authoring optimization strategies for agent loops: you read per-task losses like experimental data, form a mechanism-level hypothesis, and author the one composition that tests it. Output exactly one fenced ```ts code block and nothing else."
3835
3414
  },
3836
3415
  {
3837
3416
  role: "user",
3838
3417
  content: `${opts.contract ?? strategyAuthorContract}
3839
3418
 
3840
- BASELINE RESULTS on the "${opts.environmentName}" environment (budget=${opts.budget}):
3419
+ BASELINE RESULTS on the "${opts.environmentName}" environment (budget=${opts.budget}) \u2014 the per-task losses are your gradient:
3841
3420
  ${opts.lossesJson}
3842
3421
 
3843
- Author ONE new strategy that you expect to beat the baselines on THIS environment at the same budget. Use the losses to target the observed failure mode. Output only the module code block.`
3422
+ Author ONE new strategy that you expect to beat the baselines on THIS environment at the same budget.
3423
+ ${strategyAuthorMethod}
3424
+
3425
+ Output only the module code block.`
3844
3426
  }
3845
3427
  ]
3846
3428
  },
@@ -4470,381 +4052,6 @@ function deriveTurnSignal(callerSignal, timeoutMs) {
4470
4052
  };
4471
4053
  }
4472
4054
 
4473
- // src/runtime/structural-rollout.ts
4474
- import { randomBytes } from "crypto";
4475
- var defaultStructuralRolloutPolicy = {
4476
- k: 5,
4477
- repairRounds: 2,
4478
- testgen: 6
4479
- };
4480
- function resolvePolicy(overrides) {
4481
- const policy = { ...defaultStructuralRolloutPolicy, ...overrides };
4482
- if (!Number.isInteger(policy.k) || policy.k < 1) {
4483
- throw new Error(`structuralRollout: policy.k must be an integer >= 1, got ${policy.k}`);
4484
- }
4485
- if (!Number.isInteger(policy.repairRounds) || policy.repairRounds < 0) {
4486
- throw new Error(
4487
- `structuralRollout: policy.repairRounds must be an integer >= 0, got ${policy.repairRounds}`
4488
- );
4489
- }
4490
- if (!Number.isInteger(policy.testgen) || policy.testgen < 0) {
4491
- throw new Error(
4492
- `structuralRollout: policy.testgen must be an integer >= 0, got ${policy.testgen}`
4493
- );
4494
- }
4495
- return policy;
4496
- }
4497
- var authorInstruction = (count, entry) => `Read the task below. Write exactly ${count} single-line assert statements that test the function \`${entry}\`, based ONLY on the behavior the task itself describes. Each assert must be one physical line of the form \`assert ${entry}(...) == expected\` (or a True/False check). Do NOT implement the function. Do NOT copy shown examples verbatim if you can test other cases too. Output ONLY the assert lines inside a single \`\`\`python code block.`;
4498
- function filterAuthoredAsserts(reply, entrySymbol, count) {
4499
- const fences = [...reply.matchAll(/```(?:python|py)?\s*\n([\s\S]*?)```/gi)].map(
4500
- (m) => (m[1] ?? "").trim()
4501
- );
4502
- const block = fences.length > 0 ? fences.join("\n") : reply;
4503
- const balanced = (s) => {
4504
- let d = 0;
4505
- for (const ch of s) {
4506
- if (ch === "(" || ch === "[" || ch === "{") d += 1;
4507
- else if (ch === ")" || ch === "]" || ch === "}") d -= 1;
4508
- if (d < 0) return false;
4509
- }
4510
- return d === 0;
4511
- };
4512
- return block.split("\n").map((l) => l.trim()).filter((l) => l.startsWith("assert ") && l.includes(entrySymbol) && balanced(l)).slice(0, count);
4513
- }
4514
- function modelAuthoredChecks(overrides = {}) {
4515
- return {
4516
- async generate(_task, ctx) {
4517
- const count = overrides.count ?? ctx.count;
4518
- if (count <= 0 || !ctx.entrySymbol) return [];
4519
- const entry = ctx.entrySymbol;
4520
- const reply = await ctx.consult(authorInstruction(count, entry));
4521
- if (!reply) return [];
4522
- return filterAuthoredAsserts(reply, entry, count).map((code) => ({
4523
- code,
4524
- kind: "authored"
4525
- }));
4526
- }
4527
- };
4528
- }
4529
- function officialChecksFromMeta(key = "visibleChecks") {
4530
- return {
4531
- async generate(task) {
4532
- const raw = task.meta?.[key];
4533
- if (!Array.isArray(raw)) return [];
4534
- return raw.filter((c) => typeof c === "string" && c.trim().length > 0).map((code) => ({ code, kind: "official" }));
4535
- }
4536
- };
4537
- }
4538
- function composeCheckSources(...sources) {
4539
- return {
4540
- async generate(task, ctx) {
4541
- const all = [];
4542
- for (const source of sources) all.push(...await source.generate(task, ctx));
4543
- return all;
4544
- }
4545
- };
4546
- }
4547
- function resolveEntrySymbol(task) {
4548
- const meta = task.meta?.entryPoint;
4549
- if (typeof meta === "string" && meta.trim().length > 0) return meta.trim();
4550
- const defs = [...task.userPrompt.matchAll(/(?:^|\n)\s*def\s+([A-Za-z_]\w*)\s*\(/g)];
4551
- const last = defs[defs.length - 1];
4552
- return last?.[1];
4553
- }
4554
- function buildCheckProgram(candidate, official, authored, nonce) {
4555
- const officialB64 = Buffer.from(JSON.stringify(official), "utf8").toString("base64");
4556
- const authoredB64 = Buffer.from(JSON.stringify(authored), "utf8").toString("base64");
4557
- return `${candidate}
4558
-
4559
- import base64 as _b64, json as _json, sys as _sys
4560
- _official = _json.loads(_b64.b64decode("${officialB64}").decode("utf8"))
4561
- _authored = _json.loads(_b64.b64decode("${authoredB64}").decode("utf8"))
4562
- _lines = []
4563
- def _run(_tests):
4564
- _att, _fail = 0, 0
4565
- for _t in _tests:
4566
- _att += 1
4567
- try:
4568
- exec(_t, dict(globals()))
4569
- except Exception as _e:
4570
- _fail += 1
4571
- _lines.append("CHECK FAILED: %s -> %s: %s" % (_t.strip()[:200], type(_e).__name__, str(_e)[:200]))
4572
- return _att, _fail
4573
- _o_att, _o_fail = _run(_official)
4574
- _a_att, _a_fail = _run(_authored)
4575
- print("SRCK-${nonce} official=%d/%d authored=%d/%d" % (_o_att - _o_fail, _o_att, _a_att - _a_fail, _a_att))
4576
- _sys.stdout.write("\\n".join(_lines)[-1500:])
4577
- _sys.exit(0 if (_o_fail + _a_fail) == 0 and (_o_att + _a_att) > 0 else 1)
4578
- `;
4579
- }
4580
- function sandboxCheckRunner(options = {}) {
4581
- const python = options.python ?? "python3";
4582
- const timeoutMs = options.timeoutMs ?? 2e4;
4583
- return {
4584
- async run(candidate, checks, ctx) {
4585
- if (checks.length === 0) {
4586
- return {
4587
- passedOfficial: 0,
4588
- totalOfficial: 0,
4589
- passedAuthored: 0,
4590
- totalAuthored: 0,
4591
- failureOutput: ""
4592
- };
4593
- }
4594
- const box = ctx.box ?? options.box;
4595
- if (!box) {
4596
- throw new Error(
4597
- "sandboxCheckRunner: no execution channel \u2014 bind one via sandboxCheckRunner({ box }) or CheckRunContext.box (ValidationCtx.box / a sandbox instance). Refusing to score without executing: a silent 0 would poison selection."
4598
- );
4599
- }
4600
- const nonce = randomBytes(8).toString("hex");
4601
- const official = checks.filter((c) => c.kind === "official").map((c) => c.code);
4602
- const authored = checks.filter((c) => c.kind === "authored").map((c) => c.code);
4603
- const program = buildCheckProgram(candidate, official, authored, nonce);
4604
- const b64 = Buffer.from(program, "utf8").toString("base64");
4605
- const r = await box.exec(`printf '%s' '${b64}' | base64 -d | ${python} -`, { timeoutMs });
4606
- const summary = new RegExp(
4607
- `SRCK-${nonce} official=(\\d+)/(\\d+) authored=(\\d+)/(\\d+)`
4608
- ).exec(r.stdout);
4609
- if (!summary) {
4610
- const detail = (r.stderr || r.stdout).slice(-1500) || "no output (crashed or timed out before the checks could run)";
4611
- return {
4612
- passedOfficial: 0,
4613
- totalOfficial: 0,
4614
- passedAuthored: 0,
4615
- totalAuthored: 0,
4616
- failureOutput: detail,
4617
- crashed: true
4618
- };
4619
- }
4620
- const failureOutput = r.stdout.replace(summary[0], "").slice(-1500).trim();
4621
- return {
4622
- passedOfficial: Number(summary[1]),
4623
- totalOfficial: Number(summary[2]),
4624
- passedAuthored: Number(summary[3]),
4625
- totalAuthored: Number(summary[4]),
4626
- failureOutput
4627
- };
4628
- }
4629
- };
4630
- }
4631
- var frac = (passed, total) => total > 0 ? passed / total : 0;
4632
- function compareCheckOutcomes(a, b) {
4633
- const aCrashed = a.crashed === true;
4634
- const bCrashed = b.crashed === true;
4635
- if (aCrashed !== bCrashed) return aCrashed ? -1 : 1;
4636
- if (aCrashed) return 0;
4637
- const official = frac(a.passedOfficial, a.totalOfficial) - frac(b.passedOfficial, b.totalOfficial);
4638
- if (official !== 0) return official;
4639
- return frac(a.passedAuthored, a.totalAuthored) - frac(b.passedAuthored, b.totalAuthored);
4640
- }
4641
- function visibleCheckScore(o) {
4642
- if (o.crashed) return -1;
4643
- return frac(o.passedOfficial, o.totalOfficial) + 1e-3 * frac(o.passedAuthored, o.totalAuthored);
4644
- }
4645
- function selectBestIndex(outcomes) {
4646
- let best = 0;
4647
- for (let i = 1; i < outcomes.length; i += 1) {
4648
- if (compareCheckOutcomes(outcomes[i], outcomes[best]) > 0) {
4649
- best = i;
4650
- }
4651
- }
4652
- return best;
4653
- }
4654
- function canDisplace(challenger, incumbent) {
4655
- if (challenger.crashed === true) return false;
4656
- if (challenger.passedOfficial < incumbent.passedOfficial) return false;
4657
- return compareCheckOutcomes(challenger, incumbent) > 0;
4658
- }
4659
- var totalChecks = (o) => o.totalOfficial + o.totalAuthored;
4660
- var passesAllChecks = (o) => o.crashed !== true && totalChecks(o) > 0 && o.passedOfficial === o.totalOfficial && o.passedAuthored === o.totalAuthored;
4661
- function defaultExtractCandidate(messages) {
4662
- for (let i = messages.length - 1; i >= 0; i -= 1) {
4663
- const calls = messages[i]?.tool_calls;
4664
- if (!calls) continue;
4665
- for (let j = calls.length - 1; j >= 0; j -= 1) {
4666
- const call = calls[j];
4667
- if (call?.function?.name !== "submit_answer") continue;
4668
- try {
4669
- const args = JSON.parse(call.function.arguments ?? "{}");
4670
- if (typeof args.answer === "string" && args.answer.trim()) return args.answer.trim();
4671
- } catch {
4672
- }
4673
- }
4674
- }
4675
- const contents = [];
4676
- for (const m of messages) {
4677
- if (m.role === "assistant" && typeof m.content === "string" && m.content.trim()) {
4678
- contents.push(m.content);
4679
- }
4680
- }
4681
- const fencesOf = (text) => [...text.matchAll(/```(?:python|py)?\s*\n([\s\S]*?)```/gi)].map((m) => (m[1] ?? "").trim());
4682
- for (let i = contents.length - 1; i >= 0; i -= 1) {
4683
- const fences = fencesOf(contents[i]);
4684
- for (let j = fences.length - 1; j >= 0; j -= 1) {
4685
- if (/(^|\n)\s*def\s+\w+/.test(fences[j])) return fences[j];
4686
- }
4687
- }
4688
- for (let i = contents.length - 1; i >= 0; i -= 1) {
4689
- const fences = fencesOf(contents[i]);
4690
- if (fences.length > 0) return fences[fences.length - 1];
4691
- }
4692
- return (contents[contents.length - 1] ?? "").trim();
4693
- }
4694
- var DIVERSE_LENSES = [
4695
- "Answer directly and decisively from what you already know. State the single best answer without hedging.",
4696
- "Decompose the question into the sub-facts it depends on. Establish each sub-fact explicitly, then compose them into the answer.",
4697
- "Reason from first principles. Ignore the most obvious or popular guess; derive the answer from underlying facts and relationships.",
4698
- "Name the most plausible WRONG answer and the trap that makes it tempting. Rule it out, then commit to the answer that survives."
4699
- ];
4700
- function slotLens(slot) {
4701
- const lens = DIVERSE_LENSES[slot % DIVERSE_LENSES.length];
4702
- const tag = slot < DIVERSE_LENSES.length ? "" : ` (variant ${Math.floor(slot / DIVERSE_LENSES.length) + 1})`;
4703
- return `${lens}${tag}`;
4704
- }
4705
- function repairSteer(outcome) {
4706
- return [
4707
- "Your latest solution failed some of the task-visible checks.",
4708
- "Result of running the visible checks against it:",
4709
- "```",
4710
- outcome.failureOutput.trim() || "(the code crashed before the checks could run)",
4711
- "```",
4712
- "Fix the solution so the visible checks pass. Provide the COMPLETE corrected solution the",
4713
- "same way you provided the original (same tool or format) \u2014 not a fragment or a diff."
4714
- ].join("\n");
4715
- }
4716
- function describeOutcome(label, o) {
4717
- if (o.crashed) return `${label}: crashed before the checks could run`;
4718
- return `${label}: official ${o.passedOfficial}/${o.totalOfficial}, authored ${o.passedAuthored}/${o.totalAuthored}`;
4719
- }
4720
- function structuralRollout(config = {}) {
4721
- const policy = resolvePolicy(config.policy);
4722
- const checkSource = config.checkSource ?? composeCheckSources(officialChecksFromMeta(), modelAuthoredChecks());
4723
- const checkRunner = config.checkRunner ?? sandboxCheckRunner();
4724
- const extract = config.extractCandidate ?? defaultExtractCandidate;
4725
- const inner = defineStrategy(
4726
- "structuralRollout",
4727
- async (ctx) => {
4728
- const { task, shot } = ctx;
4729
- const progression = [];
4730
- const receipts = [];
4731
- let completions = 0;
4732
- let shots = 0;
4733
- const consult = async (instruction) => {
4734
- const reply = await ctx.consult([], instruction);
4735
- completions += 1;
4736
- return reply;
4737
- };
4738
- const entrySymbol = resolveEntrySymbol(task);
4739
- const checks = await checkSource.generate(task, {
4740
- count: policy.testgen,
4741
- ...entrySymbol ? { entrySymbol } : {},
4742
- consult
4743
- });
4744
- const officialChecks = checks.filter((c) => c.kind === "official").length;
4745
- const authoredChecks = checks.length - officialChecks;
4746
- const runCtx = { task, ...config.box ? { box: config.box } : {} };
4747
- const candidates = [];
4748
- for (let i = 0; i < policy.k; i += 1) {
4749
- const out = await shot(policy.diverse ? { steer: slotLens(i) } : void 0);
4750
- if (!out) break;
4751
- shots += 1;
4752
- completions += out.completions;
4753
- progression.push(out.score);
4754
- const outcome = await checkRunner.run(extract(out.messages), checks, runCtx);
4755
- candidates.push({
4756
- index: candidates.length,
4757
- messages: out.messages,
4758
- outcome,
4759
- shotScore: out.score,
4760
- shotResolved: out.total > 0 && out.passes === out.total
4761
- });
4762
- }
4763
- if (candidates.length === 0) {
4764
- return {
4765
- score: 0,
4766
- resolved: false,
4767
- completions,
4768
- progression,
4769
- shots,
4770
- selection: receipts,
4771
- repairStop: "no-candidates",
4772
- officialChecks,
4773
- authoredChecks
4774
- };
4775
- }
4776
- let best = candidates[selectBestIndex(candidates.map((c) => c.outcome))];
4777
- for (const c of candidates) {
4778
- receipts.push({
4779
- candidateIndex: c.index,
4780
- selected: false,
4781
- score: visibleCheckScore(c.outcome),
4782
- reason: describeOutcome("sample", c.outcome),
4783
- selector: "driver"
4784
- });
4785
- }
4786
- let seq = candidates.length;
4787
- let repairStop = "already-passing";
4788
- if (!passesAllChecks(best.outcome)) {
4789
- if (best.outcome.crashed !== true && totalChecks(best.outcome) === 0) {
4790
- repairStop = "no-signal";
4791
- } else {
4792
- repairStop = "rounds-exhausted";
4793
- for (let r = 0; r < policy.repairRounds; r += 1) {
4794
- const out = await shot({ messages: best.messages, steer: repairSteer(best.outcome) });
4795
- if (!out) break;
4796
- shots += 1;
4797
- completions += out.completions;
4798
- progression.push(out.score);
4799
- const outcome = await checkRunner.run(extract(out.messages), checks, runCtx);
4800
- const displaced = canDisplace(outcome, best.outcome);
4801
- const label = displaced ? "repair (displaced the incumbent)" : outcome.crashed !== true && outcome.passedOfficial < best.outcome.passedOfficial ? "repair (held out: passes fewer official checks than the incumbent)" : "repair (held out: no improvement)";
4802
- receipts.push({
4803
- candidateIndex: seq,
4804
- selected: false,
4805
- score: visibleCheckScore(outcome),
4806
- reason: describeOutcome(label, outcome),
4807
- selector: "driver"
4808
- });
4809
- if (displaced) {
4810
- best = {
4811
- index: seq,
4812
- messages: out.messages,
4813
- outcome,
4814
- shotScore: out.score,
4815
- shotResolved: out.total > 0 && out.passes === out.total
4816
- };
4817
- }
4818
- seq += 1;
4819
- if (passesAllChecks(best.outcome)) {
4820
- repairStop = "repaired-pass";
4821
- break;
4822
- }
4823
- }
4824
- }
4825
- }
4826
- const winner = receipts.find((r) => r.candidateIndex === best.index);
4827
- if (winner) winner.selected = true;
4828
- return {
4829
- score: best.shotScore,
4830
- resolved: best.shotResolved,
4831
- completions,
4832
- progression,
4833
- shots,
4834
- selection: receipts,
4835
- repairStop,
4836
- officialChecks,
4837
- authoredChecks
4838
- };
4839
- }
4840
- );
4841
- if (policy.temperature === void 0) return inner;
4842
- return {
4843
- name: inner.name,
4844
- driver: (surface, task, opts, budget) => inner.driver(surface, task, { ...opts, temperature: policy.temperature }, budget)
4845
- };
4846
- }
4847
-
4848
4055
  // src/runtime/supervise/detector-monitor.ts
4849
4056
  import {
4850
4057
  argHash,
@@ -5683,6 +4890,15 @@ function tail(s) {
5683
4890
  }
5684
4891
 
5685
4892
  export {
4893
+ envKeyProvider,
4894
+ mcpSecretEnvMetadataKey,
4895
+ secretEnvOfMcpServer,
4896
+ resolveSecretEnv,
4897
+ sanitizeMcpToolSchema,
4898
+ createMcpEnvironment,
4899
+ McpSpawnFault,
4900
+ connectStdioMcp,
4901
+ materializeLocalMcp,
5686
4902
  anytimeReport,
5687
4903
  renderAnytimeTable,
5688
4904
  defaultAuditorInstruction,
@@ -5700,16 +4916,13 @@ export {
5700
4916
  loopCampaignDispatch,
5701
4917
  loopDispatch,
5702
4918
  inlineSandboxClient,
4919
+ localSandboxClient,
5703
4920
  resolveSandboxClient,
5704
4921
  naiveDriver,
5705
4922
  dumbDriver,
5706
4923
  defineLeaderboard,
5707
- defaultAnalystInstruction,
5708
- observe,
5709
- renderReport,
5710
4924
  harvestCorpus,
5711
4925
  inProcessSandboxClient,
5712
- createMcpEnvironment,
5713
4926
  assertTraceDerivedFindings,
5714
4927
  createScopeAnalyst,
5715
4928
  registryScopeAnalyst,
@@ -5734,14 +4947,6 @@ export {
5734
4947
  equalKOnCost,
5735
4948
  promotionGate,
5736
4949
  reportLoopUsage,
5737
- depthStrategy,
5738
- breadthStrategy,
5739
- sample,
5740
- refine,
5741
- defineStrategy,
5742
- adaptiveRefine,
5743
- sampleThenRefine,
5744
- runAgentic,
5745
4950
  runBenchmark,
5746
4951
  printBenchmarkReport,
5747
4952
  SandboxRunAbortError,
@@ -5755,19 +4960,6 @@ export {
5755
4960
  runStrategyEvolution,
5756
4961
  streamAgentTurn,
5757
4962
  collectAgentTurn,
5758
- defaultStructuralRolloutPolicy,
5759
- filterAuthoredAsserts,
5760
- modelAuthoredChecks,
5761
- officialChecksFromMeta,
5762
- composeCheckSources,
5763
- resolveEntrySymbol,
5764
- sandboxCheckRunner,
5765
- compareCheckOutcomes,
5766
- visibleCheckScore,
5767
- selectBestIndex,
5768
- canDisplace,
5769
- defaultExtractCandidate,
5770
- structuralRollout,
5771
4963
  defaultToolDetectors,
5772
4964
  watchTrace,
5773
4965
  runCoderChecks,
@@ -5786,6 +4978,6 @@ export {
5786
4978
  jjWorkspace,
5787
4979
  runInWorkspace,
5788
4980
  computeFindingId,
5789
- makeFinding2 as makeFinding
4981
+ makeFinding
5790
4982
  };
5791
- //# sourceMappingURL=chunk-MAONWP4R.js.map
4983
+ //# sourceMappingURL=chunk-QCXD7NHM.js.map