@tangle-network/agent-runtime 0.105.0 → 0.106.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.
Files changed (218) hide show
  1. package/README.md +2 -2
  2. package/dist/activation-CRjVfOiy.js +203 -0
  3. package/dist/activation-CRjVfOiy.js.map +1 -0
  4. package/dist/activation-DyWB0K6E.d.ts +98 -0
  5. package/dist/agent.d.ts +216 -234
  6. package/dist/agent.js +615 -547
  7. package/dist/agent.js.map +1 -1
  8. package/dist/analyst-loop-DGdtVENg.js +517 -0
  9. package/dist/analyst-loop-DGdtVENg.js.map +1 -0
  10. package/dist/analyst-loop.d.ts +10 -43
  11. package/dist/analyst-loop.js +2 -11
  12. package/dist/backends-Dy8NujB4.js +713 -0
  13. package/dist/backends-Dy8NujB4.js.map +1 -0
  14. package/dist/candidate-execution/index.d.ts +4 -192
  15. package/dist/candidate-execution/index.js +5 -66
  16. package/dist/candidate-execution-DqMbv1rU.js +488 -0
  17. package/dist/candidate-execution-DqMbv1rU.js.map +1 -0
  18. package/dist/coder-yhVWbdWc.js +40 -0
  19. package/dist/coder-yhVWbdWc.js.map +1 -0
  20. package/dist/conversation-XucG_K3l.js +1265 -0
  21. package/dist/conversation-XucG_K3l.js.map +1 -0
  22. package/dist/conversation.d.ts +2 -804
  23. package/dist/conversation.js +2 -55
  24. package/dist/environment-provider-CfLUmKmf.js +1168 -0
  25. package/dist/environment-provider-CfLUmKmf.js.map +1 -0
  26. package/dist/environment-provider-IUGU3epE.d.ts +964 -0
  27. package/dist/environment-provider.d.ts +2 -78
  28. package/dist/environment-provider.js +2 -18
  29. package/dist/errors-DEAvWQPy.js +111 -0
  30. package/dist/errors-DEAvWQPy.js.map +1 -0
  31. package/dist/improvement-adapter-Cr5TBSji.d.ts +166 -0
  32. package/dist/improvement-cycle-C095kS_g.js +2624 -0
  33. package/dist/improvement-cycle-C095kS_g.js.map +1 -0
  34. package/dist/index-BGdxAwfO.d.ts +838 -0
  35. package/dist/index-C-FYUuFG.d.ts +193 -0
  36. package/dist/index-CbNM40xG.d.ts +140 -0
  37. package/dist/index-DruSKs3Z.d.ts +7224 -0
  38. package/dist/index-Efjb3nrQ.d.ts +671 -0
  39. package/dist/index.d.ts +14 -1058
  40. package/dist/index.js +2106 -2082
  41. package/dist/index.js.map +1 -1
  42. package/dist/intelligence.d.ts +768 -889
  43. package/dist/intelligence.js +1466 -1367
  44. package/dist/intelligence.js.map +1 -1
  45. package/dist/{kb-gate-CwHO0vz6.d.ts → kb-gate-C8z2juK8.d.ts} +33 -31
  46. package/dist/kb-gate-DpaSwXVx.js +80 -0
  47. package/dist/kb-gate-DpaSwXVx.js.map +1 -0
  48. package/dist/knowledge-Ku-mPP4f.js +433 -0
  49. package/dist/knowledge-Ku-mPP4f.js.map +1 -0
  50. package/dist/knowledge.d.ts +2 -150
  51. package/dist/knowledge.js +2 -40
  52. package/dist/local-harness-Dh8PJ0ot.d.ts +455 -0
  53. package/dist/loop-runner-bin-BXsFEUcf.d.ts +162 -0
  54. package/dist/loop-runner-bin-BwjQ1NfH.js +268 -0
  55. package/dist/loop-runner-bin-BwjQ1NfH.js.map +1 -0
  56. package/dist/loop-runner-bin.d.ts +2 -15
  57. package/dist/loop-runner-bin.js +2 -24
  58. package/dist/loops.d.ts +5 -4164
  59. package/dist/loops.js +8 -419
  60. package/dist/mcp/bin.d.ts +1 -1
  61. package/dist/mcp/bin.js +116 -146
  62. package/dist/mcp/bin.js.map +1 -1
  63. package/dist/mcp/index.d.ts +295 -436
  64. package/dist/mcp/index.js +1242 -1177
  65. package/dist/mcp/index.js.map +1 -1
  66. package/dist/mcp/memory-bin.d.ts +1 -1
  67. package/dist/mcp/memory-bin.js +37 -16
  68. package/dist/mcp/memory-bin.js.map +1 -1
  69. package/dist/memory-server-DL6cE2Ag.js +234 -0
  70. package/dist/memory-server-DL6cE2Ag.js.map +1 -0
  71. package/dist/model-resolution-Btd9iIKV.js +98 -0
  72. package/dist/model-resolution-Btd9iIKV.js.map +1 -0
  73. package/dist/openai-tools-B68JaOCx.d.ts +24 -0
  74. package/dist/openai-tools-CKLy1C7M.js +44 -0
  75. package/dist/openai-tools-CKLy1C7M.js.map +1 -0
  76. package/dist/otel-export-D34IQW1C.js +843 -0
  77. package/dist/otel-export-D34IQW1C.js.map +1 -0
  78. package/dist/platform.d.ts +188 -185
  79. package/dist/platform.js +185 -218
  80. package/dist/platform.js.map +1 -1
  81. package/dist/prepare-B53sPV7M.js +4292 -0
  82. package/dist/prepare-B53sPV7M.js.map +1 -0
  83. package/dist/primeintellect/index.d.ts +149 -145
  84. package/dist/primeintellect/index.js +626 -1003
  85. package/dist/primeintellect/index.js.map +1 -1
  86. package/dist/profiles.d.ts +296 -490
  87. package/dist/profiles.js +722 -749
  88. package/dist/profiles.js.map +1 -1
  89. package/dist/protected-model-port-BLPH5VVv.js +722 -0
  90. package/dist/protected-model-port-BLPH5VVv.js.map +1 -0
  91. package/dist/protected-model-port-BP6Z4eau.d.ts +283 -0
  92. package/dist/protected-redaction--F3v1oo8.js +200 -0
  93. package/dist/protected-redaction--F3v1oo8.js.map +1 -0
  94. package/dist/redact-D-u-rrcn.js +82 -0
  95. package/dist/redact-D-u-rrcn.js.map +1 -0
  96. package/dist/redact-kbIOjfjM.d.ts +452 -0
  97. package/dist/researcher-CoVqNhfI.js +433 -0
  98. package/dist/researcher-CoVqNhfI.js.map +1 -0
  99. package/dist/runtime-BG0BziaP.js +5408 -0
  100. package/dist/runtime-BG0BziaP.js.map +1 -0
  101. package/dist/sandbox-events-DeI5xX8P.js +316 -0
  102. package/dist/sandbox-events-DeI5xX8P.js.map +1 -0
  103. package/dist/spawn-journal-CwPvKUTa.js +456 -0
  104. package/dist/spawn-journal-CwPvKUTa.js.map +1 -0
  105. package/dist/structural-rollout-IXUEplky.js +1445 -0
  106. package/dist/structural-rollout-IXUEplky.js.map +1 -0
  107. package/dist/substrate-B0TYNrXn.js +27 -0
  108. package/dist/substrate-B0TYNrXn.js.map +1 -0
  109. package/dist/{substrate-Dyiqmd3o.d.ts → substrate-BcnuSHXm.d.ts} +57 -54
  110. package/dist/supervise-BiRutHS9.js +7321 -0
  111. package/dist/supervise-BiRutHS9.js.map +1 -0
  112. package/dist/supervisor-DTKhF-RV.js +3826 -0
  113. package/dist/supervisor-DTKhF-RV.js.map +1 -0
  114. package/dist/testing.d.ts +4 -3
  115. package/dist/testing.js +2478 -2637
  116. package/dist/testing.js.map +1 -1
  117. package/dist/tool-server-RcWgLIsL.js +141 -0
  118. package/dist/tool-server-RcWgLIsL.js.map +1 -0
  119. package/dist/trace-propagation-CJJC7SVB.js +57 -0
  120. package/dist/trace-propagation-CJJC7SVB.js.map +1 -0
  121. package/dist/types-BaIpb0XT.d.ts +492 -0
  122. package/dist/types-BevOjfTY.d.ts +765 -0
  123. package/dist/types-C9j4qg6l.d.ts +500 -0
  124. package/dist/types-Cja5OTGh.d.ts +190 -0
  125. package/dist/util-MVgdwuIS.js +145 -0
  126. package/dist/util-MVgdwuIS.js.map +1 -0
  127. package/dist/workspace-archive-BosQiotA.js +575 -0
  128. package/dist/workspace-archive-BosQiotA.js.map +1 -0
  129. package/package.json +43 -56
  130. package/skills/build-with-agent-runtime/SKILL.md +1 -0
  131. package/dist/activation-Cm-9MMX1.d.ts +0 -69
  132. package/dist/analyst-loop.js.map +0 -1
  133. package/dist/backends-BO4Jqoe2.d.ts +0 -134
  134. package/dist/candidate-execution/index.js.map +0 -1
  135. package/dist/chunk-2KGAN2HM.js +0 -1256
  136. package/dist/chunk-2KGAN2HM.js.map +0 -1
  137. package/dist/chunk-2VZYRB55.js +0 -834
  138. package/dist/chunk-2VZYRB55.js.map +0 -1
  139. package/dist/chunk-3MDZX7YU.js +0 -125
  140. package/dist/chunk-3MDZX7YU.js.map +0 -1
  141. package/dist/chunk-5IBQAPVB.js +0 -29
  142. package/dist/chunk-5IBQAPVB.js.map +0 -1
  143. package/dist/chunk-5QOB7H74.js +0 -387
  144. package/dist/chunk-5QOB7H74.js.map +0 -1
  145. package/dist/chunk-C5RTIBNZ.js +0 -48
  146. package/dist/chunk-C5RTIBNZ.js.map +0 -1
  147. package/dist/chunk-CTRA64LY.js +0 -680
  148. package/dist/chunk-CTRA64LY.js.map +0 -1
  149. package/dist/chunk-DPEUKJRO.js +0 -27
  150. package/dist/chunk-DPEUKJRO.js.map +0 -1
  151. package/dist/chunk-FD2MBMOH.js +0 -494
  152. package/dist/chunk-FD2MBMOH.js.map +0 -1
  153. package/dist/chunk-H5QPIZNX.js +0 -907
  154. package/dist/chunk-H5QPIZNX.js.map +0 -1
  155. package/dist/chunk-HLKC4UYB.js +0 -3514
  156. package/dist/chunk-HLKC4UYB.js.map +0 -1
  157. package/dist/chunk-HNP72PNU.js +0 -192
  158. package/dist/chunk-HNP72PNU.js.map +0 -1
  159. package/dist/chunk-ISPWRSEC.js +0 -408
  160. package/dist/chunk-ISPWRSEC.js.map +0 -1
  161. package/dist/chunk-KRBFHMV6.js +0 -1228
  162. package/dist/chunk-KRBFHMV6.js.map +0 -1
  163. package/dist/chunk-M22PL4GH.js +0 -171
  164. package/dist/chunk-M22PL4GH.js.map +0 -1
  165. package/dist/chunk-NURIQBJQ.js +0 -72
  166. package/dist/chunk-NURIQBJQ.js.map +0 -1
  167. package/dist/chunk-OPVWXJ2H.js +0 -75
  168. package/dist/chunk-OPVWXJ2H.js.map +0 -1
  169. package/dist/chunk-PZZKQVQV.js +0 -52
  170. package/dist/chunk-PZZKQVQV.js.map +0 -1
  171. package/dist/chunk-Q2JSAVQ3.js +0 -671
  172. package/dist/chunk-Q2JSAVQ3.js.map +0 -1
  173. package/dist/chunk-RDOAVVHY.js +0 -699
  174. package/dist/chunk-RDOAVVHY.js.map +0 -1
  175. package/dist/chunk-SGKPNBXE.js +0 -60
  176. package/dist/chunk-SGKPNBXE.js.map +0 -1
  177. package/dist/chunk-SMQXZGLZ.js +0 -351
  178. package/dist/chunk-SMQXZGLZ.js.map +0 -1
  179. package/dist/chunk-UHEZW5BU.js +0 -2918
  180. package/dist/chunk-UHEZW5BU.js.map +0 -1
  181. package/dist/chunk-UPWGXKXB.js +0 -254
  182. package/dist/chunk-UPWGXKXB.js.map +0 -1
  183. package/dist/chunk-VISA6CI3.js +0 -200
  184. package/dist/chunk-VISA6CI3.js.map +0 -1
  185. package/dist/chunk-WMTCUOQL.js +0 -474
  186. package/dist/chunk-WMTCUOQL.js.map +0 -1
  187. package/dist/chunk-WRTOVNN4.js +0 -4728
  188. package/dist/chunk-WRTOVNN4.js.map +0 -1
  189. package/dist/chunk-WSTRQZYQ.js +0 -5576
  190. package/dist/chunk-WSTRQZYQ.js.map +0 -1
  191. package/dist/chunk-XBG2W2VW.js +0 -6434
  192. package/dist/chunk-XBG2W2VW.js.map +0 -1
  193. package/dist/chunk-YEJR7IXO.js +0 -68
  194. package/dist/chunk-YEJR7IXO.js.map +0 -1
  195. package/dist/chunk-YJZA2BIK.js +0 -1338
  196. package/dist/chunk-YJZA2BIK.js.map +0 -1
  197. package/dist/completion-gate-BMy5LGoP.d.ts +0 -256
  198. package/dist/conversation.js.map +0 -1
  199. package/dist/coordination-BZZSVYpZ.d.ts +0 -2570
  200. package/dist/environment-provider.js.map +0 -1
  201. package/dist/improvement-adapter-HAZz-7vK.d.ts +0 -203
  202. package/dist/knowledge.js.map +0 -1
  203. package/dist/local-harness-BDNcl6jI.d.ts +0 -175
  204. package/dist/loop-runner-bin-68aoM9-7.d.ts +0 -199
  205. package/dist/loop-runner-bin.js.map +0 -1
  206. package/dist/loops.js.map +0 -1
  207. package/dist/openai-tools-fnj6SRVg.d.ts +0 -46
  208. package/dist/protected-model-port-B4t-OQjL.d.ts +0 -271
  209. package/dist/redact-BuFjxBUJ.d.ts +0 -481
  210. package/dist/sanitize-DEbPNtyI.d.ts +0 -328
  211. package/dist/structural-rollout-DEh6CEsa.d.ts +0 -446
  212. package/dist/supervise-4_48wwvy.d.ts +0 -379
  213. package/dist/types-BCoemcXU.d.ts +0 -802
  214. package/dist/types-BwoZWq-i.d.ts +0 -510
  215. package/dist/types-Cbp72qyu.d.ts +0 -491
  216. package/dist/types-CmYCMbFT.d.ts +0 -203
  217. package/dist/types-CvNwMzQt.d.ts +0 -957
  218. package/dist/worktree-fanout-DxhAWr5Z.d.ts +0 -999
@@ -1,1338 +0,0 @@
1
- import {
2
- createSupervisor,
3
- routerToolLoop,
4
- withDriverExecutor
5
- } from "./chunk-HLKC4UYB.js";
6
- import {
7
- InMemoryResultBlobStore,
8
- InMemorySpawnJournal
9
- } from "./chunk-ISPWRSEC.js";
10
-
11
- // src/improvement/optimizer-prompt.ts
12
- var optimizerMethod = [
13
- "THE METHOD \u2014 you are a senior engineer-scientist improving a measured system, not a code",
14
- "generator. Your change is an experiment: it exists to move a real, externally graded number,",
15
- "and it will be measured against a baseline on held-out tasks you cannot see. Work in this order:",
16
- "",
17
- "1. DIAGNOSE FIRST. Read every finding before touching anything \u2014 findings are ranked evidence",
18
- " from real failed runs. Name the DOMINANT failure mode (the single mechanism behind the",
19
- " largest share of failures) in one sentence. Attack that first; leave long-tail noise until",
20
- " the dominant mode is closed. A fix aimed at the wrong mechanism measures zero however clean",
21
- " the code is.",
22
- '2. STATE A HYPOTHESIS WITH A PREDICTED LIFT. Before designing, write down: "failures like X',
23
- " happen because MECHANISM; this change interrupts that mechanism; I predict it addresses",
24
- ' roughly N of the M findings shown." A change you cannot connect to a mechanism is a guess,',
25
- " not an experiment.",
26
- "3. DECOMPOSE INTO SUB-GOALS. Break the work into steps that are each independently checkable",
27
- " (it compiles, a test passes, the server answers). Sequence them so the riskiest assumption",
28
- " is tested first \u2014 if the hypothesis is wrong, find out on step 1, not step 5.",
29
- "4. DESIGN TO ISOLATE THE MECHANISM. Make the smallest COHERENT change that fully tests the",
30
- " hypothesis: small enough that a measured lift is attributable to this change alone, complete",
31
- " enough that it actually fires on the real execution path (a lever that exists but never",
32
- " fires measures zero). No drive-by refactors, no unrelated cleanup, no speculative scope \u2014",
33
- " anything changed alongside confounds the measurement.",
34
- "5. GENERALIZE, NEVER MEMORIZE. Fix the failure CLASS, not the shown instances: encode rules and",
35
- " logic that transfer to unseen tasks. A patch memorized to the quoted examples will not",
36
- " survive the held-out measurement \u2014 that is overfitting, and the gate will catch it.",
37
- "6. PRESERVE WHAT WORKS. The baseline already passes tasks; do not delete or weaken the behavior",
38
- " those passes depend on. A fix that trades one failure class for a new one measures as noise.",
39
- "7. VERIFY FOR REAL, THEN REFLECT. Run the verification you were given and make it genuinely",
40
- " pass \u2014 never weaken a check, stub the thing it exercises, or special-case its inputs; a",
41
- " gamed check delivers nothing because promotion is decided by a separate measurement you",
42
- " never see. Then record briefly: what you predicted, what the verifier actually showed, and",
43
- " what you would try next if the measured lift comes back null."
44
- ].join("\n");
45
- var buildDriverSystem = [
46
- "You are the DRIVER of a build loop: a senior engineering lead steering a coding WORKER inside",
47
- "an isolated git worktree toward a verified artifact. You never edit files yourself \u2014 your only",
48
- "levers are the tools below. Your intelligence goes into three places: how you AUTHOR each",
49
- "worker instruction, how you OBSERVE and RATE what a session actually produced, and what you",
50
- "DECIDE next.",
51
- "",
52
- "TOOLS",
53
- "- run_worker{instruction}: one full coding-harness session in the worktree, with your",
54
- " instruction as its entire goal. Sessions are expensive and capped \u2014 author each one well.",
55
- " The worktree PERSISTS between sessions: a later worker resumes on top of earlier edits.",
56
- "- inspect_worktree{}: current git status + diff \u2014 what has actually changed so far.",
57
- "- read_file{path,maxBytes?}: read one file from the worktree (new untracked files do not show",
58
- " in the diff \u2014 read them to rate the work).",
59
- "- run_verifier{}: the intrinsic check of the surface (compile+tests for a tool, boot-and-probe",
60
- " for an MCP server). Its exit decides what counts as delivered \u2014 your opinion does not.",
61
- "",
62
- "AUTHOR RICHLY. A worker handed a one-line label will flail. Each instruction must carry: the",
63
- "outcome in concrete terms; the hypothesis and sub-goal it serves; what already exists in the",
64
- "tree that it must build on, not duplicate; where the deliverable must land; and the exact check",
65
- "it will be held to. The worker sees NOTHING you were given (no findings, no method, no prior",
66
- "session context) unless you fold it into the instruction.",
67
- "",
68
- "THE LOOP \u2014 every turn: observe, rate, decide.",
69
- "- OBSERVE: after each session, inspect the worktree and run the verifier. Read WHAT failed and",
70
- ' WHY \u2014 "it failed" alone tells you nothing.',
71
- "- RATE: judge with a reason. Verified and complete \u2192 stop. Close, one correctable fault \u2192",
72
- ' REFINE: author "continue from the current tree; the check fails because X; fix X" (depth,',
73
- " not a fresh start \u2014 never let a worker revert its own near-miss). Empty tree, or it solved a",
74
- " different problem \u2192 RE-SCOPE: re-author narrower and more concrete; a second identical",
75
- " instruction fails identically. Too big for one session \u2192 DECOMPOSE: author the first",
76
- " self-contained slice, verify it, then author the next on top.",
77
- "- DECIDE: exactly one move per turn, with the reason stated in one line.",
78
- "",
79
- "STOP when the verifier passes \u2014 reply with no tool call and a short reflection: what you",
80
- "predicted, what the verifier showed, what you would try next if the measured lift comes back",
81
- "null. If the session budget runs out first, say plainly what remains and why. An honest",
82
- "no-winner is a real result; a claimed success is not \u2014 the final keep/discard decision is made",
83
- "by code from the verifier exit and the tree state, never from your words."
84
- ].join("\n");
85
- var researchDriverNote = [
86
- "RESEARCH \u2014 ADOPT BEFORE BUILD. A research{query} tool is provisioned for this run. Before",
87
- "authoring a from-scratch build, spend one turn researching whether an EXISTING external MCP",
88
- "server already provides the missing capability \u2014 registries and vendor docs list maintained",
89
- "servers for most common gaps (web search, fetch, GitHub, filesystems, databases).",
90
- "- If a maintained server fits, ADOPT it: report in your final reflection its endpoint or",
91
- " launch command and the API key it needs BY NAME (e.g. EXA_API_KEY) \u2014 never a key value \u2014",
92
- " so the dispatch can emit a connection candidate with provisioned secrets. Adopting a fit",
93
- " server beats rebuilding it: less code to verify, maintained upstream, same measured gate.",
94
- "- If nothing fits (unmaintained, wrong tool surface, heavier than the gap), build \u2014 and state",
95
- " in one line why adoption lost."
96
- ].join("\n");
97
- var strategyAuthorMethod = [
98
- "Work as a senior researcher, in this order:",
99
- "1. DIAGNOSE: read the per-task losses above and name the DOMINANT failure mode in one sentence",
100
- " \u2014 the single mechanism behind the largest share of lost score (e.g. first attempts near-miss",
101
- " and never get corrected; fresh retries discard progress; one persona plateaus).",
102
- '2. HYPOTHESIS + PREDICTED LIFT: state "these losses happen because MECHANISM; the composition',
103
- ' below interrupts it; I predict roughly +N on this environment at the same budget."',
104
- "3. DESIGN TO ISOLATE THE MECHANISM: change ONE coordination mechanism relative to the baselines",
105
- " (carry vs fresh, where the critique lands, a persona split, a tool restriction) so any",
106
- " measured lift is attributable to it. Do not stack three clever ideas \u2014 a tangled win teaches",
107
- " nothing and a tangled loss cannot be debugged.",
108
- "4. DECOMPOSE THE BUDGET: plan how the shots divide across explore / attempt / critique / repair",
109
- " before writing code, and spend the whole budget \u2014 an early stop on a mid score is a loss.",
110
- "5. GENERALIZE: the strategy runs on unseen tasks from this environment. Read tools via",
111
- " listTools(handle), never hardcode task specifics from the losses shown.",
112
- "6. PREDICT, THEN REFLECT: put the hypothesis, the mechanism, and the predicted lift in a",
113
- " comment at the top of the module \u2014 the holdout verdict will be read against it."
114
- ].join("\n");
115
-
116
- // src/runtime/observe.ts
117
- import { makeFinding } from "@tangle-network/agent-eval";
118
- var observerId = "observe/trace";
119
- 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.";
120
- function summarizeTrace(trace, maxLines) {
121
- const lines = [];
122
- for (const ev of trace) {
123
- const e = ev;
124
- const t = (e.type ?? "").toLowerCase();
125
- const d = e.data ?? {};
126
- const part = d.part ?? {};
127
- if (part.type === "tool")
128
- lines.push(`tool:${part.tool}${part.state?.status ? `(${part.state.status})` : ""}`);
129
- else if (t.includes("error"))
130
- lines.push(`ERROR: ${String(d.message ?? d.detail ?? "").slice(0, 200)}`);
131
- else if (t === "status" && typeof d.status === "string") lines.push(`status:${d.status}`);
132
- else if (t.includes("tool")) lines.push(`tool-event:${t}`);
133
- }
134
- const out = [];
135
- for (const ln of lines) {
136
- const prev = out[out.length - 1];
137
- const m = prev?.match(/^(.*?)(?: x(\d+))?$/);
138
- if (m && m[1] === ln) out[out.length - 1] = `${ln} x${(Number(m[2]) || 1) + 1}`;
139
- else out.push(ln);
140
- }
141
- return out.slice(0, maxLines).join("\n") || "(no tool/error events in trace)";
142
- }
143
- var findingsSchema = {
144
- name: "observer_findings",
145
- schema: {
146
- type: "object",
147
- additionalProperties: false,
148
- properties: {
149
- findings: {
150
- type: "array",
151
- items: {
152
- type: "object",
153
- additionalProperties: false,
154
- properties: {
155
- area: {
156
- type: "string",
157
- description: "tool-use | cost | verification | process | failure | latency"
158
- },
159
- severity: { type: "string", enum: ["critical", "high", "medium", "low", "info"] },
160
- claim: {
161
- type: "string",
162
- description: "what you OBSERVED in the trace (a fact, with the evidence)"
163
- },
164
- recommended_action: {
165
- type: "string",
166
- description: "the concrete change for the agent or operator"
167
- },
168
- audience: {
169
- type: "string",
170
- enum: ["agent", "operator"],
171
- description: "who should act on this"
172
- },
173
- confidence: { type: "number" }
174
- },
175
- required: ["area", "severity", "claim", "recommended_action", "audience", "confidence"]
176
- }
177
- }
178
- },
179
- required: ["findings"]
180
- }
181
- };
182
- async function observe(input, opts) {
183
- const traceSummary = summarizeTrace(input.trace, opts.maxTraceLines ?? 80);
184
- const res = await opts.chat.chat(
185
- {
186
- ...opts.model ? { model: opts.model } : {},
187
- jsonSchema: findingsSchema,
188
- messages: [
189
- {
190
- role: "system",
191
- content: opts.analystInstruction ?? defaultAnalystInstruction
192
- },
193
- {
194
- role: "user",
195
- content: `TASK: ${input.task}
196
-
197
- OUTCOME: ${input.outcome ?? "unknown"}
198
-
199
- FINAL OUTPUT (truncated):
200
- ${input.output.slice(0, 1200)}
201
-
202
- TRACE (in order; "xN" = repeated):
203
- ${traceSummary}`
204
- }
205
- ]
206
- },
207
- { ...opts.signal ? { signal: opts.signal } : {} }
208
- );
209
- const parsed = parseFindings(res.content);
210
- const producedAt = input.runId ? `${input.runId}` : observerId;
211
- const findings = parsed.map(
212
- (f) => makeFinding({
213
- analyst_id: observerId,
214
- area: `${f.area}`,
215
- severity: f.severity,
216
- claim: f.claim,
217
- recommended_action: f.recommended_action,
218
- confidence: typeof f.confidence === "number" ? f.confidence : 0.5,
219
- evidence_refs: [],
220
- // The observer reads BEHAVIOR, never the judge verdict — firewall provenance.
221
- derived_from_judge: false,
222
- metadata: { audience: f.audience },
223
- ...input.runId ? { subject: input.runId } : {}
224
- })
225
- );
226
- const learned = [];
227
- if (opts.corpus) {
228
- for (const f of findings) {
229
- const record = {
230
- schemaVersion: "1.0.0",
231
- id: f.finding_id,
232
- runId: input.runId ?? observerId,
233
- producedAt: f.produced_at ?? producedAt,
234
- area: f.area,
235
- claim: f.recommended_action ?? f.claim,
236
- ...f.claim ? { rationale: f.claim } : {},
237
- tags: [...opts.tags ?? [], `audience:${f.metadata?.audience ?? "agent"}`],
238
- confidence: f.confidence,
239
- evidence: [{ kind: "finding", uri: f.finding_id }]
240
- };
241
- const r = await opts.corpus.append(record);
242
- if (r.succeeded) learned.push(record);
243
- }
244
- }
245
- return { findings, learned, report: renderReport(findings) };
246
- }
247
- function parseFindings(content) {
248
- let obj;
249
- try {
250
- obj = JSON.parse(content);
251
- } catch {
252
- const m = content.match(/\{[\s\S]*\}/);
253
- obj = m ? JSON.parse(m[0]) : { findings: [] };
254
- }
255
- const arr = obj.findings;
256
- return Array.isArray(arr) ? arr : [];
257
- }
258
- function renderReport(findings) {
259
- if (findings.length === 0) return "\u2713 clean run \u2014 the observer found nothing to change.";
260
- const audience = (f) => f.metadata?.audience ?? "agent";
261
- const forAgent = findings.filter((f) => audience(f) === "agent");
262
- const forOperator = findings.filter((f) => audience(f) === "operator");
263
- const block = (title, fs) => fs.length === 0 ? "" : `**${title}**
264
- ${fs.map((f) => `- [${f.severity}] ${f.claim}
265
- \u2192 ${f.recommended_action ?? ""}`).join("\n")}
266
- `;
267
- return [
268
- block("For the agent (fix skills / prompt / tools)", forAgent),
269
- block("For you (the operator)", forOperator)
270
- ].filter(Boolean).join("\n");
271
- }
272
-
273
- // src/runtime/strategy.ts
274
- import { createChatClient, estimateCost, isModelPriced } from "@tangle-network/agent-eval";
275
- 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.";
276
- async function runShot(surface, _task, handle, tools, messages, opts, modelOverride) {
277
- let toolErrors = 0;
278
- const execute = async (name, args) => {
279
- try {
280
- const out = await surface.call(handle, name, args);
281
- if (out.startsWith("ERROR:")) toolErrors += 1;
282
- return out;
283
- } catch (e) {
284
- toolErrors += 1;
285
- return `ERROR: ${e instanceof Error ? e.message : String(e)}`;
286
- }
287
- };
288
- const r = await routerToolLoop(
289
- {
290
- routerBaseUrl: opts.routerBaseUrl,
291
- routerKey: opts.routerKey,
292
- model: modelOverride ?? opts.model,
293
- ...opts.complete ? { complete: opts.complete } : {}
294
- },
295
- "",
296
- "",
297
- tools,
298
- execute,
299
- {
300
- maxTurns: opts.innerTurns ?? 4,
301
- temperature: opts.temperature ?? 0.7,
302
- initialMessages: messages,
303
- ...opts.maxTokens ? { maxTokens: opts.maxTokens } : {}
304
- }
305
- );
306
- return {
307
- messages: r.messages,
308
- completions: r.turns,
309
- toolCalls: r.toolCalls,
310
- toolErrors,
311
- tokens: r.usage
312
- };
313
- }
314
- function compactTrajectory(messages) {
315
- return messages.filter((m) => m.role === "assistant" || m.role === "tool").map((m) => {
316
- if (m.role === "tool") return `RESULT ${String(m.content).slice(0, 280)}`;
317
- const calls = m.tool_calls?.map((c) => `${c.function.name}(${c.function.arguments})`).join(", ");
318
- return calls ? `CALL ${calls}` : `SAY ${String(m.content).slice(0, 200)}`;
319
- }).join("\n").slice(0, 7e3);
320
- }
321
- function analystChat(opts, defaultModel) {
322
- if (!opts.complete) {
323
- return createChatClient({
324
- transport: "router",
325
- apiKey: opts.routerKey,
326
- baseUrl: opts.routerBaseUrl,
327
- defaultModel
328
- });
329
- }
330
- const complete = opts.complete;
331
- return createChatClient({
332
- transport: "mock",
333
- defaultModel,
334
- handler: async (req) => {
335
- const raw = await complete({
336
- model: req.model ?? defaultModel,
337
- messages: req.messages,
338
- ...req.temperature !== void 0 ? { temperature: req.temperature } : {},
339
- ...req.maxTokens !== void 0 ? { max_tokens: req.maxTokens } : {}
340
- });
341
- const content = raw.choices?.[0]?.message?.content ?? "";
342
- const promptTokens = raw.usage?.prompt_tokens ?? 0;
343
- const completionTokens = raw.usage?.completion_tokens ?? 0;
344
- return {
345
- content,
346
- usage: {
347
- promptTokens,
348
- completionTokens,
349
- totalTokens: promptTokens + completionTokens
350
- },
351
- costUsd: null,
352
- model: req.model ?? defaultModel,
353
- durationMs: 0,
354
- finishReason: raw.choices?.[0]?.finish_reason ?? null,
355
- contentEmpty: content.trim().length === 0,
356
- raw
357
- };
358
- }
359
- });
360
- }
361
- async function consultAnalyst(task, messages, instruction, opts) {
362
- const trajectory = compactTrajectory(messages);
363
- const analystModel = opts.analystModel ?? opts.model;
364
- const chat = analystChat(opts, analystModel);
365
- const consultMessages = trajectory ? [
366
- { role: "system", content: instruction },
367
- {
368
- role: "user",
369
- content: `TASK: ${task.userPrompt.slice(0, 1500)}
370
-
371
- TRAJECTORY:
372
- ${trajectory}`
373
- }
374
- ] : [
375
- {
376
- role: "user",
377
- content: `${instruction}
378
-
379
- TASK:
380
- ${task.userPrompt.slice(0, 1500)}`
381
- }
382
- ];
383
- const res = await chat.chat({
384
- model: analystModel,
385
- temperature: 0.2,
386
- maxTokens: 1024,
387
- messages: consultMessages
388
- });
389
- const usage = res.usage;
390
- return {
391
- steer: res.content.trim(),
392
- tokens: {
393
- input: usage?.promptTokens ?? usage?.prompt_tokens ?? 0,
394
- output: usage?.completionTokens ?? usage?.completion_tokens ?? 0
395
- }
396
- };
397
- }
398
- async function analyze(task, messages, opts) {
399
- const trajectory = compactTrajectory(messages);
400
- const analystModel = opts.analystModel ?? opts.model;
401
- const inner = analystChat(opts, analystModel);
402
- const tokens = { input: 0, output: 0 };
403
- const chat = {
404
- ...inner,
405
- chat: async (req, callOpts) => {
406
- const res = await inner.chat(req, callOpts);
407
- const u = res.usage;
408
- if (u) {
409
- tokens.input += u.promptTokens ?? u.prompt_tokens ?? 0;
410
- tokens.output += u.completionTokens ?? u.completion_tokens ?? 0;
411
- }
412
- return res;
413
- }
414
- };
415
- const obs = await observe(
416
- {
417
- task: task.userPrompt,
418
- output: trajectory,
419
- trace: messages,
420
- outcome: "failed",
421
- runId: task.id
422
- },
423
- {
424
- chat,
425
- model: analystModel,
426
- ...opts.analystInstruction ? { analystInstruction: opts.analystInstruction } : {},
427
- ...opts.corpus ? { corpus: opts.corpus, tags: opts.corpusTags ?? [] } : {}
428
- }
429
- );
430
- const steer = obs.findings.map((f) => f.recommended_action).filter((a) => typeof a === "string" && a.trim().length > 0).join("\n").trim();
431
- return { steer: steer || "COMPLETE", tokens };
432
- }
433
- async function renderCorpusReadback(opts) {
434
- if (!opts.corpus || !opts.corpusReadback) return "";
435
- const maxFacts = opts.corpusReadback.maxFacts ?? 3;
436
- if (!Number.isInteger(maxFacts) || maxFacts < 0) {
437
- throw new Error(`corpusReadback.maxFacts must be a non-negative integer, got ${maxFacts}`);
438
- }
439
- if (maxFacts === 0) return "";
440
- const tags = [
441
- ...opts.corpusTags ?? [],
442
- ...opts.corpusReadback.tags ?? [],
443
- ...opts.corpusReadback.includeOperatorFacts ? [] : ["audience:agent"]
444
- ];
445
- const facts = await opts.corpus.query({
446
- ...tags.length > 0 ? { tags } : {},
447
- minConfidence: opts.corpusReadback.minConfidence ?? 0.7,
448
- limit: maxFacts
449
- });
450
- if (facts.length === 0) return "";
451
- const rendered = facts.map(
452
- (fact) => fact.rationale ? `- ${fact.claim} (${fact.rationale})` : `- ${fact.claim}`
453
- );
454
- return `Relevant learned facts from prior attempts:
455
- ${rendered.join("\n")}`;
456
- }
457
- function shotExecutor(surface, opts) {
458
- let artifact;
459
- return {
460
- runtime: "agentic-shot",
461
- async execute(task) {
462
- const t = task;
463
- const own = !t.handle;
464
- const handle = t.handle ?? await surface.open(t.task);
465
- try {
466
- const allTools = await surface.tools(t.task, handle);
467
- let tools = allTools;
468
- if (t.tools) {
469
- const known = new Set(allTools.map((tool) => tool.function.name));
470
- const unknown = t.tools.filter((name) => !known.has(name));
471
- if (unknown.length > 0) {
472
- throw new Error(
473
- `shot tools: unknown tool name(s) ${unknown.join(", ")} \u2014 domain offers: ${[...known].join(", ")}`
474
- );
475
- }
476
- const want = new Set(t.tools);
477
- tools = allTools.filter((tool) => want.has(tool.function.name));
478
- }
479
- const messages = t.messages?.length ? t.messages : [
480
- { role: "system", content: t.persona?.systemPrompt ?? t.task.systemPrompt },
481
- { role: "user", content: `${t.task.userPrompt}
482
-
483
- ${taskNudge}` }
484
- ];
485
- if (t.messages?.length && t.persona?.systemPrompt) {
486
- messages.push({
487
- role: "user",
488
- content: `[hand-off] You are now acting as: ${t.persona.systemPrompt}`
489
- });
490
- }
491
- if (t.steer) messages.push({ role: "user", content: t.steer });
492
- const shot = await runShot(surface, t.task, handle, tools, messages, opts, t.persona?.model);
493
- const s = await surface.score(t.task, handle);
494
- const score = s.total > 0 ? s.passes / s.total : 0;
495
- const out = {
496
- messages: shot.messages,
497
- score,
498
- passes: s.passes,
499
- total: s.total,
500
- completions: shot.completions,
501
- toolErrors: shot.toolErrors
502
- };
503
- artifact = {
504
- outRef: `shot:${handle.id}:${shot.completions}:${s.passes}/${s.total}`,
505
- out,
506
- verdict: { valid: s.total > 0 && s.passes === s.total, score },
507
- // Real usage to the conserved pool: tokens from the router responses; usd only
508
- // when the model is in the price table (never a fabricated number).
509
- spent: {
510
- iterations: shot.completions,
511
- tokens: shot.tokens,
512
- usd: isModelPriced(opts.model) ? estimateCost(shot.tokens.input, shot.tokens.output, opts.model) : 0,
513
- ms: 0
514
- }
515
- };
516
- return artifact;
517
- } finally {
518
- if (own) await surface.close(handle);
519
- }
520
- },
521
- teardown: () => Promise.resolve({ destroyed: true }),
522
- resultArtifact() {
523
- if (!artifact) throw new Error("shotExecutor: resultArtifact before execute");
524
- return artifact;
525
- }
526
- };
527
- }
528
- function analystExecutor(opts) {
529
- let artifact;
530
- return {
531
- runtime: "agentic-analyst",
532
- async execute(task) {
533
- const t = task;
534
- const { steer, tokens } = t.rawInstruction ? await consultAnalyst(t.task, t.messages, t.rawInstruction, opts) : await analyze(t.task, t.messages, opts);
535
- const analystModel = opts.analystModel ?? opts.model;
536
- artifact = {
537
- outRef: `analyst:${steer.length}`,
538
- out: steer,
539
- spent: {
540
- iterations: 1,
541
- tokens,
542
- usd: isModelPriced(analystModel) ? estimateCost(tokens.input, tokens.output, analystModel) : 0,
543
- ms: 0
544
- }
545
- };
546
- return artifact;
547
- },
548
- teardown: () => Promise.resolve({ destroyed: true }),
549
- resultArtifact() {
550
- if (!artifact) throw new Error("analystExecutor: resultArtifact before execute");
551
- return artifact;
552
- }
553
- };
554
- }
555
- function agenticRegistry(surface, opts) {
556
- const leaves = {
557
- register() {
558
- throw new Error("agenticRegistry: register unsupported");
559
- },
560
- resolve(spec) {
561
- const role = spec.profile.metadata?.role;
562
- const factory = (_s, _ctx) => role === "analyst" ? analystExecutor(opts) : shotExecutor(surface, opts);
563
- return { succeeded: true, value: factory };
564
- }
565
- };
566
- return withDriverExecutor(leaves);
567
- }
568
- function leaf(name, role) {
569
- const agent = {
570
- name,
571
- executorSpec: { profile: { name, metadata: { role } }, harness: null },
572
- act() {
573
- throw new Error(`agentic: spawned child "${name}" was run directly (the executor drives it)`);
574
- }
575
- };
576
- return agent;
577
- }
578
- async function drainOne(scope) {
579
- const s = await scope.next();
580
- if (!s) throw new Error("agentic: spawned child never settled");
581
- return s;
582
- }
583
- var perChild = (innerTurns) => ({
584
- maxIterations: innerTurns + 1,
585
- maxTokens: 1e6
586
- });
587
- function depthStrategy(surface, task, opts, cfg) {
588
- const innerTurns = opts.innerTurns ?? 4;
589
- let pendingSteer;
590
- return {
591
- name: "depth",
592
- async act(_t, scope) {
593
- const handle = await surface.open(task);
594
- const progression = [];
595
- let messages;
596
- let completions = 0;
597
- let shots = 0;
598
- try {
599
- for (shots = 0; shots < cfg.maxShots; shots += 1) {
600
- const child = leaf(`shot:${shots}`, "shot");
601
- const memorySteer = await renderCorpusReadback(opts);
602
- const steer = [shots === 0 ? void 0 : pendingSteer, memorySteer].filter((part) => typeof part === "string" && part.trim().length > 0).join("\n\n");
603
- const res = scope.spawn(child, { task, handle, messages, steer }, {
604
- budget: perChild(innerTurns),
605
- label: `shot:${shots}`
606
- });
607
- if (!res.ok) break;
608
- const settled = await drainOne(scope);
609
- if (settled.kind === "down") break;
610
- const out = settled.out;
611
- messages = out.messages;
612
- completions += out.completions;
613
- progression.push(out.score);
614
- if (out.score >= 1 || shots === cfg.maxShots - 1) break;
615
- const aChild = leaf(`analyst:${shots}`, "analyst");
616
- const aRes = scope.spawn(
617
- aChild,
618
- { task, messages },
619
- { budget: perChild(1), label: `analyst:${shots}` }
620
- );
621
- if (!aRes.ok) break;
622
- const aSettled = await drainOne(scope);
623
- completions += 1;
624
- if (aSettled.kind === "down") break;
625
- const findings = aSettled.out;
626
- if (/^\s*COMPLETE\b/i.test(findings)) break;
627
- pendingSteer = `A reviewer flagged unfinished items:
628
- ${findings}
629
-
630
- Address each with the tools, verify they took, then continue.`;
631
- }
632
- const final = await surface.score(task, handle);
633
- const score = final.total > 0 ? final.passes / final.total : 0;
634
- return {
635
- kind: "done",
636
- deliverable: {
637
- mode: "depth",
638
- score,
639
- resolved: final.total > 0 && final.passes === final.total,
640
- completions,
641
- progression,
642
- shots: shots + 1
643
- }
644
- };
645
- } finally {
646
- await surface.close(handle);
647
- }
648
- }
649
- };
650
- }
651
- function breadthStrategy(_surface, task, opts, cfg) {
652
- const innerTurns = opts.innerTurns ?? 4;
653
- return {
654
- name: "breadth",
655
- async act(_t, scope) {
656
- let opened = 0;
657
- for (let k = 0; k < cfg.width; k += 1) {
658
- const res = scope.spawn(leaf(`rollout:${k}`, "shot"), { task }, {
659
- budget: perChild(innerTurns),
660
- label: `rollout:${k}`
661
- });
662
- if (res.ok) opened += 1;
663
- }
664
- if (opened === 0) return { kind: "blocked", blockers: ["breadth: pool admitted no rollout"] };
665
- let best = -1;
666
- let bestResolved = false;
667
- let completions = 0;
668
- const progression = [];
669
- for (let s = await scope.next(); s !== null; s = await scope.next()) {
670
- if (s.kind === "down") continue;
671
- const out = s.out;
672
- completions += out.completions;
673
- if (out.score > best) best = out.score;
674
- if (out.total > 0 && out.passes === out.total) bestResolved = true;
675
- progression.push(best);
676
- }
677
- if (best < 0) return { kind: "blocked", blockers: ["breadth: every rollout went down"] };
678
- return {
679
- kind: "done",
680
- deliverable: {
681
- mode: "breadth",
682
- score: best,
683
- resolved: bestResolved,
684
- completions,
685
- progression,
686
- shots: opened
687
- }
688
- };
689
- }
690
- };
691
- }
692
- var sample = {
693
- name: "sample",
694
- driver: (surface, task, opts, budget) => breadthStrategy(surface, task, opts, { width: budget })
695
- };
696
- var refine = {
697
- name: "refine",
698
- driver: (surface, task, opts, budget) => depthStrategy(surface, task, opts, { maxShots: budget })
699
- };
700
- function defineStrategy(name, run) {
701
- return {
702
- name,
703
- driver: (surface, task, opts, budget) => ({
704
- name,
705
- async act(_t, scope) {
706
- let seq = 0;
707
- const innerTurns = opts.innerTurns ?? 4;
708
- let verifiedBest = 0;
709
- let verifiedResolved = false;
710
- const openHandles = /* @__PURE__ */ new Set();
711
- const ctx = {
712
- // Narrowed to open/close — the body gets no raw call()/score() access.
713
- surface: {
714
- name: surface.name,
715
- open: async (t) => {
716
- const h = await surface.open(t);
717
- openHandles.add(h.id);
718
- return h;
719
- },
720
- close: async (h) => {
721
- if (!h || !openHandles.has(h.id)) return;
722
- openHandles.delete(h.id);
723
- await surface.close(h);
724
- }
725
- },
726
- task,
727
- opts,
728
- budget,
729
- scope,
730
- async shot(spec) {
731
- const child = leaf(`shot:${seq}`, "shot");
732
- seq += 1;
733
- const res = scope.spawn(
734
- child,
735
- {
736
- task,
737
- handle: spec?.handle,
738
- messages: spec?.messages,
739
- steer: spec?.steer,
740
- persona: spec?.persona,
741
- tools: spec?.tools
742
- },
743
- { budget: perChild(innerTurns), label: child.name }
744
- );
745
- if (!res.ok) return null;
746
- const settled = await drainOne(scope);
747
- if (settled.kind === "down") return null;
748
- const out = settled.out;
749
- if (out.score > verifiedBest) verifiedBest = out.score;
750
- if (out.total > 0 && out.passes === out.total) verifiedResolved = true;
751
- return out;
752
- },
753
- async listTools(handle) {
754
- const tools = await surface.tools(task, handle);
755
- return tools.map((t) => ({
756
- name: t.function.name,
757
- ...t.function.description ? { description: t.function.description } : {}
758
- }));
759
- },
760
- async critique(messages) {
761
- const child = leaf(`analyst:${seq}`, "analyst");
762
- seq += 1;
763
- const res = scope.spawn(
764
- child,
765
- { task, messages },
766
- { budget: perChild(1), label: child.name }
767
- );
768
- if (!res.ok) return null;
769
- const settled = await drainOne(scope);
770
- if (settled.kind === "down") return null;
771
- const findings = settled.out;
772
- return /^\s*COMPLETE\b/i.test(findings) ? null : findings;
773
- },
774
- async consult(messages, instruction) {
775
- const child = leaf(`analyst:${seq}`, "analyst");
776
- seq += 1;
777
- const res = scope.spawn(
778
- child,
779
- { task, messages, rawInstruction: instruction },
780
- { budget: perChild(1), label: child.name }
781
- );
782
- if (!res.ok) return null;
783
- const settled = await drainOne(scope);
784
- if (settled.kind === "down") return null;
785
- return settled.out;
786
- }
787
- };
788
- const r = await run(ctx);
789
- return {
790
- kind: "done",
791
- deliverable: {
792
- mode: name,
793
- ...r,
794
- progression: Array.isArray(r.progression) ? r.progression : [],
795
- completions: typeof r.completions === "number" ? r.completions : 0,
796
- shots: typeof r.shots === "number" ? r.shots : 0,
797
- score: verifiedBest,
798
- resolved: verifiedResolved
799
- }
800
- };
801
- }
802
- })
803
- };
804
- }
805
- var adaptiveRefine = defineStrategy(
806
- "adaptiveRefine",
807
- async ({ surface, task, budget, shot, critique }) => {
808
- let handle = await surface.open(task);
809
- const progression = [];
810
- let messages;
811
- let steer;
812
- let completions = 0;
813
- let best = -1;
814
- let shots = 0;
815
- try {
816
- for (shots = 0; shots < budget; shots += 1) {
817
- const out = await shot({ handle, messages, steer });
818
- if (!out) break;
819
- completions += out.completions;
820
- progression.push(out.score);
821
- if (out.score >= 1) break;
822
- if (out.score <= best) {
823
- await surface.close(handle);
824
- handle = await surface.open(task);
825
- messages = void 0;
826
- steer = void 0;
827
- continue;
828
- }
829
- best = out.score;
830
- messages = out.messages;
831
- const findings = await critique(out.messages);
832
- completions += 1;
833
- if (!findings) break;
834
- steer = `A reviewer flagged unfinished items:
835
- ${findings}
836
-
837
- Address each with the tools, verify they took, then continue.`;
838
- }
839
- const score = progression.length ? Math.max(...progression) : 0;
840
- return { score, resolved: score >= 1, completions, progression, shots };
841
- } finally {
842
- await surface.close(handle);
843
- }
844
- }
845
- );
846
- var sampleThenRefine = defineStrategy(
847
- "sampleThenRefine",
848
- async ({ surface, task, budget, shot, critique }) => {
849
- const explore = Math.max(1, Math.ceil(budget / 2));
850
- const open = /* @__PURE__ */ new Set();
851
- const progression = [];
852
- let completions = 0;
853
- let shots = 0;
854
- try {
855
- let best;
856
- for (let i = 0; i < explore; i += 1) {
857
- const handle = await surface.open(task);
858
- open.add(handle);
859
- const out = await shot({ handle });
860
- if (!out) continue;
861
- shots += 1;
862
- completions += out.completions;
863
- progression.push(out.score);
864
- if (!best || out.score > best.out.score) best = { handle, out };
865
- if (out.score >= 1) break;
866
- }
867
- if (!best) return { score: 0, resolved: false, completions, progression, shots };
868
- for (const h of [...open]) {
869
- if (h !== best.handle) {
870
- await surface.close(h);
871
- open.delete(h);
872
- }
873
- }
874
- let messages = best.out.messages;
875
- let topScore = best.out.score;
876
- for (let i = explore; i < budget && topScore < 1; i += 1) {
877
- const findings = await critique(messages);
878
- completions += 1;
879
- if (!findings) break;
880
- const out = await shot({
881
- handle: best.handle,
882
- messages,
883
- steer: `A reviewer flagged unfinished items:
884
- ${findings}
885
-
886
- Address each with the tools, verify they took, then continue.`
887
- });
888
- if (!out) break;
889
- shots += 1;
890
- completions += out.completions;
891
- progression.push(out.score);
892
- messages = out.messages;
893
- if (out.score > topScore) topScore = out.score;
894
- }
895
- const score = progression.length ? Math.max(...progression) : 0;
896
- return { score, resolved: score >= 1, completions, progression, shots };
897
- } finally {
898
- for (const h of open) await surface.close(h);
899
- }
900
- }
901
- );
902
- async function runAgentic(opts) {
903
- const strategy = opts.strategy ?? (opts.mode === "breadth" ? sample : refine);
904
- const driver = strategy.driver(opts.surface, opts.task, opts, opts.budget);
905
- const supervisor = createSupervisor();
906
- const root = opts.rootBudget ?? {
907
- maxIterations: opts.budget * ((opts.innerTurns ?? 4) + 2),
908
- maxTokens: 1e9
909
- };
910
- const started = Date.now();
911
- const result = await supervisor.run(driver, void 0, {
912
- budget: root,
913
- runId: `agentic:${strategy.name}:${opts.task.id}`,
914
- journal: new InMemorySpawnJournal(),
915
- blobs: new InMemoryResultBlobStore(),
916
- executors: agenticRegistry(opts.surface, opts),
917
- maxDepth: 3,
918
- ...opts.hooks ? { hooks: opts.hooks } : {}
919
- });
920
- if (result.kind !== "winner" || result.out.kind !== "done") {
921
- const reason = result.kind === "winner" ? `blocked: ${result.out.blockers?.join("; ")}` : `no-winner: ${result.reason}`;
922
- throw new Error(`runAgentic(${strategy.name}) produced no result \u2014 ${reason}`);
923
- }
924
- const core = result.out.deliverable;
925
- return {
926
- ...core,
927
- usd: result.spentTotal.usd,
928
- tokens: result.spentTotal.tokens,
929
- ms: Date.now() - started
930
- };
931
- }
932
-
933
- // src/runtime/structural-rollout.ts
934
- import { randomBytes } from "crypto";
935
- var defaultStructuralRolloutPolicy = {
936
- k: 5,
937
- repairRounds: 2,
938
- testgen: 6
939
- };
940
- function resolvePolicy(overrides) {
941
- const policy = { ...defaultStructuralRolloutPolicy, ...overrides };
942
- if (!Number.isInteger(policy.k) || policy.k < 1) {
943
- throw new Error(`structuralRollout: policy.k must be an integer >= 1, got ${policy.k}`);
944
- }
945
- if (!Number.isInteger(policy.repairRounds) || policy.repairRounds < 0) {
946
- throw new Error(
947
- `structuralRollout: policy.repairRounds must be an integer >= 0, got ${policy.repairRounds}`
948
- );
949
- }
950
- if (!Number.isInteger(policy.testgen) || policy.testgen < 0) {
951
- throw new Error(
952
- `structuralRollout: policy.testgen must be an integer >= 0, got ${policy.testgen}`
953
- );
954
- }
955
- return policy;
956
- }
957
- 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.`;
958
- function filterAuthoredAsserts(reply, entrySymbol, count) {
959
- const fences = [...reply.matchAll(/```(?:python|py)?\s*\n([\s\S]*?)```/gi)].map(
960
- (m) => (m[1] ?? "").trim()
961
- );
962
- const block = fences.length > 0 ? fences.join("\n") : reply;
963
- const balanced = (s) => {
964
- let d = 0;
965
- for (const ch of s) {
966
- if (ch === "(" || ch === "[" || ch === "{") d += 1;
967
- else if (ch === ")" || ch === "]" || ch === "}") d -= 1;
968
- if (d < 0) return false;
969
- }
970
- return d === 0;
971
- };
972
- return block.split("\n").map((l) => l.trim()).filter((l) => l.startsWith("assert ") && l.includes(entrySymbol) && balanced(l)).slice(0, count);
973
- }
974
- function modelAuthoredChecks(overrides = {}) {
975
- return {
976
- async generate(_task, ctx) {
977
- const count = overrides.count ?? ctx.count;
978
- if (count <= 0 || !ctx.entrySymbol) return [];
979
- const entry = ctx.entrySymbol;
980
- const reply = await ctx.consult(authorInstruction(count, entry));
981
- if (!reply) return [];
982
- return filterAuthoredAsserts(reply, entry, count).map((code) => ({
983
- code,
984
- kind: "authored"
985
- }));
986
- }
987
- };
988
- }
989
- function officialChecksFromMeta(key = "visibleChecks") {
990
- return {
991
- async generate(task) {
992
- const raw = task.meta?.[key];
993
- if (!Array.isArray(raw)) return [];
994
- return raw.filter((c) => typeof c === "string" && c.trim().length > 0).map((code) => ({ code, kind: "official" }));
995
- }
996
- };
997
- }
998
- function composeCheckSources(...sources) {
999
- return {
1000
- async generate(task, ctx) {
1001
- const all = [];
1002
- for (const source of sources) all.push(...await source.generate(task, ctx));
1003
- return all;
1004
- }
1005
- };
1006
- }
1007
- function resolveEntrySymbol(task) {
1008
- const meta = task.meta?.entryPoint;
1009
- if (typeof meta === "string" && meta.trim().length > 0) return meta.trim();
1010
- const defs = [...task.userPrompt.matchAll(/(?:^|\n)\s*def\s+([A-Za-z_]\w*)\s*\(/g)];
1011
- const last = defs[defs.length - 1];
1012
- return last?.[1];
1013
- }
1014
- function buildCheckProgram(candidate, official, authored, nonce) {
1015
- const officialB64 = Buffer.from(JSON.stringify(official), "utf8").toString("base64");
1016
- const authoredB64 = Buffer.from(JSON.stringify(authored), "utf8").toString("base64");
1017
- return `${candidate}
1018
-
1019
- import base64 as _b64, json as _json, sys as _sys
1020
- _official = _json.loads(_b64.b64decode("${officialB64}").decode("utf8"))
1021
- _authored = _json.loads(_b64.b64decode("${authoredB64}").decode("utf8"))
1022
- _lines = []
1023
- def _run(_tests):
1024
- _att, _fail = 0, 0
1025
- for _t in _tests:
1026
- _att += 1
1027
- try:
1028
- exec(_t, dict(globals()))
1029
- except Exception as _e:
1030
- _fail += 1
1031
- _lines.append("CHECK FAILED: %s -> %s: %s" % (_t.strip()[:200], type(_e).__name__, str(_e)[:200]))
1032
- return _att, _fail
1033
- _o_att, _o_fail = _run(_official)
1034
- _a_att, _a_fail = _run(_authored)
1035
- print("SRCK-${nonce} official=%d/%d authored=%d/%d" % (_o_att - _o_fail, _o_att, _a_att - _a_fail, _a_att))
1036
- _sys.stdout.write("\\n".join(_lines)[-1500:])
1037
- _sys.exit(0 if (_o_fail + _a_fail) == 0 and (_o_att + _a_att) > 0 else 1)
1038
- `;
1039
- }
1040
- function sandboxCheckRunner(options = {}) {
1041
- const python = options.python ?? "python3";
1042
- const timeoutMs = options.timeoutMs ?? 2e4;
1043
- return {
1044
- async run(candidate, checks, ctx) {
1045
- if (checks.length === 0) {
1046
- return {
1047
- passedOfficial: 0,
1048
- totalOfficial: 0,
1049
- passedAuthored: 0,
1050
- totalAuthored: 0,
1051
- failureOutput: ""
1052
- };
1053
- }
1054
- const box = ctx.box ?? options.box;
1055
- if (!box) {
1056
- throw new Error(
1057
- "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."
1058
- );
1059
- }
1060
- const nonce = randomBytes(8).toString("hex");
1061
- const official = checks.filter((c) => c.kind === "official").map((c) => c.code);
1062
- const authored = checks.filter((c) => c.kind === "authored").map((c) => c.code);
1063
- const program = buildCheckProgram(candidate, official, authored, nonce);
1064
- const b64 = Buffer.from(program, "utf8").toString("base64");
1065
- const r = await box.exec(`printf '%s' '${b64}' | base64 -d | ${python} -`, { timeoutMs });
1066
- const summary = new RegExp(
1067
- `SRCK-${nonce} official=(\\d+)/(\\d+) authored=(\\d+)/(\\d+)`
1068
- ).exec(r.stdout);
1069
- if (!summary) {
1070
- const detail = (r.stderr || r.stdout).slice(-1500) || "no output (crashed or timed out before the checks could run)";
1071
- return {
1072
- passedOfficial: 0,
1073
- totalOfficial: 0,
1074
- passedAuthored: 0,
1075
- totalAuthored: 0,
1076
- failureOutput: detail,
1077
- crashed: true
1078
- };
1079
- }
1080
- const failureOutput = r.stdout.replace(summary[0], "").slice(-1500).trim();
1081
- return {
1082
- passedOfficial: Number(summary[1]),
1083
- totalOfficial: Number(summary[2]),
1084
- passedAuthored: Number(summary[3]),
1085
- totalAuthored: Number(summary[4]),
1086
- failureOutput
1087
- };
1088
- }
1089
- };
1090
- }
1091
- var frac = (passed, total) => total > 0 ? passed / total : 0;
1092
- function compareCheckOutcomes(a, b) {
1093
- const aCrashed = a.crashed === true;
1094
- const bCrashed = b.crashed === true;
1095
- if (aCrashed !== bCrashed) return aCrashed ? -1 : 1;
1096
- if (aCrashed) return 0;
1097
- const official = frac(a.passedOfficial, a.totalOfficial) - frac(b.passedOfficial, b.totalOfficial);
1098
- if (official !== 0) return official;
1099
- return frac(a.passedAuthored, a.totalAuthored) - frac(b.passedAuthored, b.totalAuthored);
1100
- }
1101
- function visibleCheckScore(o) {
1102
- if (o.crashed) return -1;
1103
- return frac(o.passedOfficial, o.totalOfficial) + 1e-3 * frac(o.passedAuthored, o.totalAuthored);
1104
- }
1105
- function selectBestIndex(outcomes) {
1106
- let best = 0;
1107
- for (let i = 1; i < outcomes.length; i += 1) {
1108
- if (compareCheckOutcomes(outcomes[i], outcomes[best]) > 0) {
1109
- best = i;
1110
- }
1111
- }
1112
- return best;
1113
- }
1114
- function canDisplace(challenger, incumbent) {
1115
- if (challenger.crashed === true) return false;
1116
- if (challenger.passedOfficial < incumbent.passedOfficial) return false;
1117
- return compareCheckOutcomes(challenger, incumbent) > 0;
1118
- }
1119
- var totalChecks = (o) => o.totalOfficial + o.totalAuthored;
1120
- var passesAllChecks = (o) => o.crashed !== true && totalChecks(o) > 0 && o.passedOfficial === o.totalOfficial && o.passedAuthored === o.totalAuthored;
1121
- function defaultExtractCandidate(messages) {
1122
- for (let i = messages.length - 1; i >= 0; i -= 1) {
1123
- const calls = messages[i]?.tool_calls;
1124
- if (!calls) continue;
1125
- for (let j = calls.length - 1; j >= 0; j -= 1) {
1126
- const call = calls[j];
1127
- if (call?.function?.name !== "submit_answer") continue;
1128
- try {
1129
- const args = JSON.parse(call.function.arguments ?? "{}");
1130
- if (typeof args.answer === "string" && args.answer.trim()) return args.answer.trim();
1131
- } catch {
1132
- }
1133
- }
1134
- }
1135
- const contents = [];
1136
- for (const m of messages) {
1137
- if (m.role === "assistant" && typeof m.content === "string" && m.content.trim()) {
1138
- contents.push(m.content);
1139
- }
1140
- }
1141
- const fencesOf = (text) => [...text.matchAll(/```(?:python|py)?\s*\n([\s\S]*?)```/gi)].map((m) => (m[1] ?? "").trim());
1142
- for (let i = contents.length - 1; i >= 0; i -= 1) {
1143
- const fences = fencesOf(contents[i]);
1144
- for (let j = fences.length - 1; j >= 0; j -= 1) {
1145
- if (/(^|\n)\s*def\s+\w+/.test(fences[j])) return fences[j];
1146
- }
1147
- }
1148
- for (let i = contents.length - 1; i >= 0; i -= 1) {
1149
- const fences = fencesOf(contents[i]);
1150
- if (fences.length > 0) return fences[fences.length - 1];
1151
- }
1152
- return (contents[contents.length - 1] ?? "").trim();
1153
- }
1154
- var DIVERSE_LENSES = [
1155
- "Answer directly and decisively from what you already know. State the single best answer without hedging.",
1156
- "Decompose the question into the sub-facts it depends on. Establish each sub-fact explicitly, then compose them into the answer.",
1157
- "Reason from first principles. Ignore the most obvious or popular guess; derive the answer from underlying facts and relationships.",
1158
- "Name the most plausible WRONG answer and the trap that makes it tempting. Rule it out, then commit to the answer that survives."
1159
- ];
1160
- function slotLens(slot) {
1161
- const lens = DIVERSE_LENSES[slot % DIVERSE_LENSES.length];
1162
- const tag = slot < DIVERSE_LENSES.length ? "" : ` (variant ${Math.floor(slot / DIVERSE_LENSES.length) + 1})`;
1163
- return `${lens}${tag}`;
1164
- }
1165
- function repairSteer(outcome) {
1166
- return [
1167
- "Your latest solution failed some of the task-visible checks.",
1168
- "Result of running the visible checks against it:",
1169
- "```",
1170
- outcome.failureOutput.trim() || "(the code crashed before the checks could run)",
1171
- "```",
1172
- "Fix the solution so the visible checks pass. Provide the COMPLETE corrected solution the",
1173
- "same way you provided the original (same tool or format) \u2014 not a fragment or a diff."
1174
- ].join("\n");
1175
- }
1176
- function describeOutcome(label, o) {
1177
- if (o.crashed) return `${label}: crashed before the checks could run`;
1178
- return `${label}: official ${o.passedOfficial}/${o.totalOfficial}, authored ${o.passedAuthored}/${o.totalAuthored}`;
1179
- }
1180
- function structuralRollout(config = {}) {
1181
- const policy = resolvePolicy(config.policy);
1182
- const checkSource = config.checkSource ?? composeCheckSources(officialChecksFromMeta(), modelAuthoredChecks());
1183
- const checkRunner = config.checkRunner ?? sandboxCheckRunner();
1184
- const extract = config.extractCandidate ?? defaultExtractCandidate;
1185
- const inner = defineStrategy(
1186
- "structuralRollout",
1187
- async (ctx) => {
1188
- const { task, shot } = ctx;
1189
- const progression = [];
1190
- const receipts = [];
1191
- let completions = 0;
1192
- let shots = 0;
1193
- const consult = async (instruction) => {
1194
- const reply = await ctx.consult([], instruction);
1195
- completions += 1;
1196
- return reply;
1197
- };
1198
- const entrySymbol = resolveEntrySymbol(task);
1199
- const checks = await checkSource.generate(task, {
1200
- count: policy.testgen,
1201
- ...entrySymbol ? { entrySymbol } : {},
1202
- consult
1203
- });
1204
- const officialChecks = checks.filter((c) => c.kind === "official").length;
1205
- const authoredChecks = checks.length - officialChecks;
1206
- const runCtx = { task, ...config.box ? { box: config.box } : {} };
1207
- const candidates = [];
1208
- for (let i = 0; i < policy.k; i += 1) {
1209
- const out = await shot(policy.diverse ? { steer: slotLens(i) } : void 0);
1210
- if (!out) break;
1211
- shots += 1;
1212
- completions += out.completions;
1213
- progression.push(out.score);
1214
- const outcome = await checkRunner.run(extract(out.messages), checks, runCtx);
1215
- candidates.push({
1216
- index: candidates.length,
1217
- messages: out.messages,
1218
- outcome,
1219
- shotScore: out.score,
1220
- shotResolved: out.total > 0 && out.passes === out.total
1221
- });
1222
- }
1223
- if (candidates.length === 0) {
1224
- return {
1225
- score: 0,
1226
- resolved: false,
1227
- completions,
1228
- progression,
1229
- shots,
1230
- selection: receipts,
1231
- repairStop: "no-candidates",
1232
- officialChecks,
1233
- authoredChecks
1234
- };
1235
- }
1236
- let best = candidates[selectBestIndex(candidates.map((c) => c.outcome))];
1237
- for (const c of candidates) {
1238
- receipts.push({
1239
- candidateIndex: c.index,
1240
- selected: false,
1241
- score: visibleCheckScore(c.outcome),
1242
- reason: describeOutcome("sample", c.outcome),
1243
- selector: "driver"
1244
- });
1245
- }
1246
- let seq = candidates.length;
1247
- let repairStop = "already-passing";
1248
- if (!passesAllChecks(best.outcome)) {
1249
- if (best.outcome.crashed !== true && totalChecks(best.outcome) === 0) {
1250
- repairStop = "no-signal";
1251
- } else {
1252
- repairStop = "rounds-exhausted";
1253
- for (let r = 0; r < policy.repairRounds; r += 1) {
1254
- const out = await shot({ messages: best.messages, steer: repairSteer(best.outcome) });
1255
- if (!out) break;
1256
- shots += 1;
1257
- completions += out.completions;
1258
- progression.push(out.score);
1259
- const outcome = await checkRunner.run(extract(out.messages), checks, runCtx);
1260
- const displaced = canDisplace(outcome, best.outcome);
1261
- 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)";
1262
- receipts.push({
1263
- candidateIndex: seq,
1264
- selected: false,
1265
- score: visibleCheckScore(outcome),
1266
- reason: describeOutcome(label, outcome),
1267
- selector: "driver"
1268
- });
1269
- if (displaced) {
1270
- best = {
1271
- index: seq,
1272
- messages: out.messages,
1273
- outcome,
1274
- shotScore: out.score,
1275
- shotResolved: out.total > 0 && out.passes === out.total
1276
- };
1277
- }
1278
- seq += 1;
1279
- if (passesAllChecks(best.outcome)) {
1280
- repairStop = "repaired-pass";
1281
- break;
1282
- }
1283
- }
1284
- }
1285
- }
1286
- const winner = receipts.find((r) => r.candidateIndex === best.index);
1287
- if (winner) winner.selected = true;
1288
- return {
1289
- score: best.shotScore,
1290
- resolved: best.shotResolved,
1291
- completions,
1292
- progression,
1293
- shots,
1294
- selection: receipts,
1295
- repairStop,
1296
- officialChecks,
1297
- authoredChecks
1298
- };
1299
- }
1300
- );
1301
- if (policy.temperature === void 0) return inner;
1302
- return {
1303
- name: inner.name,
1304
- driver: (surface, task, opts, budget) => inner.driver(surface, task, { ...opts, temperature: policy.temperature }, budget)
1305
- };
1306
- }
1307
-
1308
- export {
1309
- optimizerMethod,
1310
- buildDriverSystem,
1311
- researchDriverNote,
1312
- strategyAuthorMethod,
1313
- defaultAnalystInstruction,
1314
- observe,
1315
- renderReport,
1316
- depthStrategy,
1317
- breadthStrategy,
1318
- sample,
1319
- refine,
1320
- defineStrategy,
1321
- adaptiveRefine,
1322
- sampleThenRefine,
1323
- runAgentic,
1324
- defaultStructuralRolloutPolicy,
1325
- filterAuthoredAsserts,
1326
- modelAuthoredChecks,
1327
- officialChecksFromMeta,
1328
- composeCheckSources,
1329
- resolveEntrySymbol,
1330
- sandboxCheckRunner,
1331
- compareCheckOutcomes,
1332
- visibleCheckScore,
1333
- selectBestIndex,
1334
- canDisplace,
1335
- defaultExtractCandidate,
1336
- structuralRollout
1337
- };
1338
- //# sourceMappingURL=chunk-YJZA2BIK.js.map