@buoy-gg/agent-core 7.0.40 → 7.0.42

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 (202) hide show
  1. package/lib/commonjs/blocks/receipts.js +1 -761
  2. package/lib/commonjs/blocks/runId.js +1 -31
  3. package/lib/commonjs/blocks/types.js +1 -140
  4. package/lib/commonjs/blocks/uiTool.js +6 -1405
  5. package/lib/commonjs/catalog/catalog.g.js +5 -4207
  6. package/lib/commonjs/catalog/catalog.source.json +656 -12
  7. package/lib/commonjs/catalog/catalog.types.g.js +1 -44
  8. package/lib/commonjs/catalog/normalizeParams.js +2 -332
  9. package/lib/commonjs/catalog/signature.js +1 -68
  10. package/lib/commonjs/catalog/snapshotReads.js +1 -263
  11. package/lib/commonjs/catalog/toProviderTools.js +2 -145
  12. package/lib/commonjs/catalog/validateParams.js +1 -129
  13. package/lib/commonjs/context/buildContextPack.js +1 -489
  14. package/lib/commonjs/effects/digest.js +1 -34
  15. package/lib/commonjs/effects/ledger.js +1 -325
  16. package/lib/commonjs/engine/askGate.js +1 -287
  17. package/lib/commonjs/engine/effectFor.js +1 -176
  18. package/lib/commonjs/engine/evidence.js +3 -111
  19. package/lib/commonjs/engine/historyBudget.js +1 -363
  20. package/lib/commonjs/engine/retrieve.js +1 -214
  21. package/lib/commonjs/engine/runAgentTurn.js +8 -1803
  22. package/lib/commonjs/engine/systemPrompt.js +54 -163
  23. package/lib/commonjs/engine/textToolCalls.js +1 -276
  24. package/lib/commonjs/engine/tokenCalibration.js +1 -81
  25. package/lib/commonjs/engine/verify.js +4 -297
  26. package/lib/commonjs/index.js +1 -384
  27. package/lib/commonjs/policy/labels.js +1 -319
  28. package/lib/commonjs/policy/policy.js +1 -148
  29. package/lib/commonjs/policy/redact.js +1 -172
  30. package/lib/commonjs/providers/anthropic.js +3 -445
  31. package/lib/commonjs/providers/openai.js +4 -324
  32. package/lib/commonjs/providers/problem.js +1 -98
  33. package/lib/commonjs/providers/sse.js +1 -240
  34. package/lib/commonjs/providers/streamTimer.js +1 -123
  35. package/lib/commonjs/providers/transport.js +1 -123
  36. package/lib/commonjs/providers/types.js +1 -6
  37. package/lib/commonjs/providers/xhrStream.js +1 -212
  38. package/lib/commonjs/realNow.js +1 -0
  39. package/lib/commonjs/session.js +1 -393
  40. package/lib/commonjs/types.js +0 -1
  41. package/lib/module/blocks/receipts.js +1 -755
  42. package/lib/module/blocks/runId.js +1 -26
  43. package/lib/module/blocks/types.js +1 -134
  44. package/lib/module/blocks/uiTool.js +6 -1396
  45. package/lib/module/catalog/catalog.g.js +5 -4203
  46. package/lib/module/catalog/catalog.source.json +656 -12
  47. package/lib/module/catalog/catalog.types.g.js +1 -40
  48. package/lib/module/catalog/normalizeParams.js +2 -326
  49. package/lib/module/catalog/signature.js +1 -63
  50. package/lib/module/catalog/snapshotReads.js +1 -259
  51. package/lib/module/catalog/toProviderTools.js +2 -139
  52. package/lib/module/catalog/validateParams.js +1 -124
  53. package/lib/module/context/buildContextPack.js +1 -485
  54. package/lib/module/effects/digest.js +1 -29
  55. package/lib/module/effects/ledger.js +1 -319
  56. package/lib/module/engine/askGate.js +1 -280
  57. package/lib/module/engine/effectFor.js +1 -173
  58. package/lib/module/engine/evidence.js +3 -105
  59. package/lib/module/engine/historyBudget.js +1 -355
  60. package/lib/module/engine/retrieve.js +1 -210
  61. package/lib/module/engine/runAgentTurn.js +8 -1794
  62. package/lib/module/engine/systemPrompt.js +54 -157
  63. package/lib/module/engine/textToolCalls.js +1 -270
  64. package/lib/module/engine/tokenCalibration.js +1 -75
  65. package/lib/module/engine/verify.js +4 -289
  66. package/lib/module/index.js +1 -35
  67. package/lib/module/policy/labels.js +1 -312
  68. package/lib/module/policy/policy.js +1 -142
  69. package/lib/module/policy/redact.js +1 -165
  70. package/lib/module/providers/anthropic.js +3 -441
  71. package/lib/module/providers/openai.js +4 -320
  72. package/lib/module/providers/problem.js +1 -92
  73. package/lib/module/providers/sse.js +1 -231
  74. package/lib/module/providers/streamTimer.js +1 -118
  75. package/lib/module/providers/transport.js +1 -119
  76. package/lib/module/providers/types.js +1 -4
  77. package/lib/module/providers/xhrStream.js +1 -207
  78. package/lib/module/realNow.js +1 -0
  79. package/lib/module/session.js +1 -369
  80. package/lib/module/types.js +0 -1
  81. package/lib/typescript/catalog/catalog.g.d.ts +3 -3
  82. package/lib/typescript/catalog/catalog.types.g.d.ts +7 -4
  83. package/lib/typescript/effects/ledger.d.ts +16 -1
  84. package/lib/typescript/providers/problem.d.ts +0 -20
  85. package/lib/typescript/providers/streamTimer.d.ts +0 -24
  86. package/lib/typescript/realNow.d.ts +18 -0
  87. package/lib/web/index.mjs +152 -0
  88. package/package.json +24 -3
  89. package/lib/commonjs/blocks/receipts.js.map +0 -1
  90. package/lib/commonjs/blocks/runId.js.map +0 -1
  91. package/lib/commonjs/blocks/types.js.map +0 -1
  92. package/lib/commonjs/blocks/uiTool.js.map +0 -1
  93. package/lib/commonjs/catalog/catalog.g.js.map +0 -1
  94. package/lib/commonjs/catalog/catalog.types.g.js.map +0 -1
  95. package/lib/commonjs/catalog/normalizeParams.js.map +0 -1
  96. package/lib/commonjs/catalog/signature.js.map +0 -1
  97. package/lib/commonjs/catalog/snapshotReads.js.map +0 -1
  98. package/lib/commonjs/catalog/toProviderTools.js.map +0 -1
  99. package/lib/commonjs/catalog/validateParams.js.map +0 -1
  100. package/lib/commonjs/context/buildContextPack.js.map +0 -1
  101. package/lib/commonjs/effects/digest.js.map +0 -1
  102. package/lib/commonjs/effects/ledger.js.map +0 -1
  103. package/lib/commonjs/engine/askGate.js.map +0 -1
  104. package/lib/commonjs/engine/effectFor.js.map +0 -1
  105. package/lib/commonjs/engine/evidence.js.map +0 -1
  106. package/lib/commonjs/engine/historyBudget.js.map +0 -1
  107. package/lib/commonjs/engine/retrieve.js.map +0 -1
  108. package/lib/commonjs/engine/runAgentTurn.js.map +0 -1
  109. package/lib/commonjs/engine/systemPrompt.js.map +0 -1
  110. package/lib/commonjs/engine/textToolCalls.js.map +0 -1
  111. package/lib/commonjs/engine/tokenCalibration.js.map +0 -1
  112. package/lib/commonjs/engine/verify.js.map +0 -1
  113. package/lib/commonjs/index.js.map +0 -1
  114. package/lib/commonjs/policy/labels.js.map +0 -1
  115. package/lib/commonjs/policy/policy.js.map +0 -1
  116. package/lib/commonjs/policy/redact.js.map +0 -1
  117. package/lib/commonjs/providers/anthropic.js.map +0 -1
  118. package/lib/commonjs/providers/openai.js.map +0 -1
  119. package/lib/commonjs/providers/problem.js.map +0 -1
  120. package/lib/commonjs/providers/sse.js.map +0 -1
  121. package/lib/commonjs/providers/streamTimer.js.map +0 -1
  122. package/lib/commonjs/providers/transport.js.map +0 -1
  123. package/lib/commonjs/providers/types.js.map +0 -1
  124. package/lib/commonjs/providers/xhrStream.js.map +0 -1
  125. package/lib/commonjs/session.js.map +0 -1
  126. package/lib/commonjs/types.js.map +0 -1
  127. package/lib/module/blocks/receipts.js.map +0 -1
  128. package/lib/module/blocks/runId.js.map +0 -1
  129. package/lib/module/blocks/types.js.map +0 -1
  130. package/lib/module/blocks/uiTool.js.map +0 -1
  131. package/lib/module/catalog/catalog.g.js.map +0 -1
  132. package/lib/module/catalog/catalog.types.g.js.map +0 -1
  133. package/lib/module/catalog/normalizeParams.js.map +0 -1
  134. package/lib/module/catalog/signature.js.map +0 -1
  135. package/lib/module/catalog/snapshotReads.js.map +0 -1
  136. package/lib/module/catalog/toProviderTools.js.map +0 -1
  137. package/lib/module/catalog/validateParams.js.map +0 -1
  138. package/lib/module/context/buildContextPack.js.map +0 -1
  139. package/lib/module/effects/digest.js.map +0 -1
  140. package/lib/module/effects/ledger.js.map +0 -1
  141. package/lib/module/engine/askGate.js.map +0 -1
  142. package/lib/module/engine/effectFor.js.map +0 -1
  143. package/lib/module/engine/evidence.js.map +0 -1
  144. package/lib/module/engine/historyBudget.js.map +0 -1
  145. package/lib/module/engine/retrieve.js.map +0 -1
  146. package/lib/module/engine/runAgentTurn.js.map +0 -1
  147. package/lib/module/engine/systemPrompt.js.map +0 -1
  148. package/lib/module/engine/textToolCalls.js.map +0 -1
  149. package/lib/module/engine/tokenCalibration.js.map +0 -1
  150. package/lib/module/engine/verify.js.map +0 -1
  151. package/lib/module/index.js.map +0 -1
  152. package/lib/module/policy/labels.js.map +0 -1
  153. package/lib/module/policy/policy.js.map +0 -1
  154. package/lib/module/policy/redact.js.map +0 -1
  155. package/lib/module/providers/anthropic.js.map +0 -1
  156. package/lib/module/providers/openai.js.map +0 -1
  157. package/lib/module/providers/problem.js.map +0 -1
  158. package/lib/module/providers/sse.js.map +0 -1
  159. package/lib/module/providers/streamTimer.js.map +0 -1
  160. package/lib/module/providers/transport.js.map +0 -1
  161. package/lib/module/providers/types.js.map +0 -1
  162. package/lib/module/providers/xhrStream.js.map +0 -1
  163. package/lib/module/session.js.map +0 -1
  164. package/lib/module/types.js.map +0 -1
  165. package/lib/typescript/blocks/receipts.d.ts.map +0 -1
  166. package/lib/typescript/blocks/runId.d.ts.map +0 -1
  167. package/lib/typescript/blocks/types.d.ts.map +0 -1
  168. package/lib/typescript/blocks/uiTool.d.ts.map +0 -1
  169. package/lib/typescript/catalog/catalog.g.d.ts.map +0 -1
  170. package/lib/typescript/catalog/catalog.types.g.d.ts.map +0 -1
  171. package/lib/typescript/catalog/normalizeParams.d.ts.map +0 -1
  172. package/lib/typescript/catalog/signature.d.ts.map +0 -1
  173. package/lib/typescript/catalog/snapshotReads.d.ts.map +0 -1
  174. package/lib/typescript/catalog/toProviderTools.d.ts.map +0 -1
  175. package/lib/typescript/catalog/validateParams.d.ts.map +0 -1
  176. package/lib/typescript/context/buildContextPack.d.ts.map +0 -1
  177. package/lib/typescript/effects/digest.d.ts.map +0 -1
  178. package/lib/typescript/effects/ledger.d.ts.map +0 -1
  179. package/lib/typescript/engine/askGate.d.ts.map +0 -1
  180. package/lib/typescript/engine/effectFor.d.ts.map +0 -1
  181. package/lib/typescript/engine/evidence.d.ts.map +0 -1
  182. package/lib/typescript/engine/historyBudget.d.ts.map +0 -1
  183. package/lib/typescript/engine/retrieve.d.ts.map +0 -1
  184. package/lib/typescript/engine/runAgentTurn.d.ts.map +0 -1
  185. package/lib/typescript/engine/systemPrompt.d.ts.map +0 -1
  186. package/lib/typescript/engine/textToolCalls.d.ts.map +0 -1
  187. package/lib/typescript/engine/tokenCalibration.d.ts.map +0 -1
  188. package/lib/typescript/engine/verify.d.ts.map +0 -1
  189. package/lib/typescript/index.d.ts.map +0 -1
  190. package/lib/typescript/policy/labels.d.ts.map +0 -1
  191. package/lib/typescript/policy/policy.d.ts.map +0 -1
  192. package/lib/typescript/policy/redact.d.ts.map +0 -1
  193. package/lib/typescript/providers/anthropic.d.ts.map +0 -1
  194. package/lib/typescript/providers/openai.d.ts.map +0 -1
  195. package/lib/typescript/providers/problem.d.ts.map +0 -1
  196. package/lib/typescript/providers/sse.d.ts.map +0 -1
  197. package/lib/typescript/providers/streamTimer.d.ts.map +0 -1
  198. package/lib/typescript/providers/transport.d.ts.map +0 -1
  199. package/lib/typescript/providers/types.d.ts.map +0 -1
  200. package/lib/typescript/providers/xhrStream.d.ts.map +0 -1
  201. package/lib/typescript/session.d.ts.map +0 -1
  202. package/lib/typescript/types.d.ts.map +0 -1
@@ -1,81 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.TokenCalibration = exports.DEFAULT_CHARS_PER_TOKEN = void 0;
7
- exports.promptTokensOf = promptTokensOf;
8
- /**
9
- * How many characters make a token — measured, not assumed.
10
- *
11
- * Every budget in this engine is kept in characters because that is what a
12
- * string has, but every LIMIT that matters is in tokens: the provider's
13
- * context window, the reply room, the cost. The conversion was a constant
14
- * (4) everywhere. English prose does run near 4; the tool results this agent
15
- * actually sends are JSON, which tokenizes nearer 3 — so a request the budget
16
- * called 100k tokens could be 130k, on a gateway whose window is 128k. The
17
- * proactive budget was optimistic in exactly the sessions it exists for.
18
- *
19
- * The provider tells us the truth after every request: its usage report
20
- * carries the prompt's token count, and the engine knows how many characters
21
- * it sent. One division gives the ratio for THIS conversation on THIS
22
- * tokenizer; an exponential average smooths a single odd request (a round
23
- * that was all prose, or all ids). Strands' design 0008 does the same in
24
- * reverse — a known token baseline plus an estimate of the delta — and its
25
- * decision record says why: public limits should be in LLM-native units.
26
- *
27
- * Clamped, because a wrong sample must not be able to blow the budget wide
28
- * open (a gateway that reports nonsense usage) or shrink it to nothing.
29
- */
30
-
31
- const DEFAULT_CHARS_PER_TOKEN = exports.DEFAULT_CHARS_PER_TOKEN = 4;
32
- const MIN_CHARS_PER_TOKEN = 2.5;
33
- const MAX_CHARS_PER_TOKEN = 5;
34
- /** Weight of the newest sample once there is history. The first sample replaces the default outright. */
35
- const EMA_ALPHA = 0.3;
36
- /** Below this many prompt tokens a sample says more about rounding than about the tokenizer. */
37
- const MIN_SAMPLE_TOKENS = 500;
38
- class TokenCalibration {
39
- ratio = DEFAULT_CHARS_PER_TOKEN;
40
- samples = 0;
41
-
42
- /** Characters per token, as currently believed. */
43
- get charsPerToken() {
44
- return this.ratio;
45
- }
46
- get sampleCount() {
47
- return this.samples;
48
- }
49
-
50
- /** Fold in one request: what was sent, and what the provider counted. */
51
- observe(requestChars, promptTokens) {
52
- if (!(requestChars > 0) || !(promptTokens >= MIN_SAMPLE_TOKENS)) return;
53
- const sample = Math.min(MAX_CHARS_PER_TOKEN, Math.max(MIN_CHARS_PER_TOKEN, requestChars / promptTokens));
54
- this.ratio = this.samples === 0 ? sample : this.ratio + EMA_ALPHA * (sample - this.ratio);
55
- this.samples += 1;
56
- }
57
-
58
- /** Characters a token budget allows, at the believed ratio. */
59
- chars(tokens) {
60
- return Math.floor(tokens * this.ratio);
61
- }
62
- reset() {
63
- this.ratio = DEFAULT_CHARS_PER_TOKEN;
64
- this.samples = 0;
65
- }
66
- }
67
-
68
- /**
69
- * The whole prompt's token count from a usage report.
70
- *
71
- * Anthropic reports the cached and freshly-written prefix SEPARATELY from
72
- * `input`; OpenAI-shaped providers fold `cached_tokens` INTO `prompt_tokens`.
73
- * See TokenUsage. Adding on the wrong protocol double-counts the cache and
74
- * halves the believed ratio.
75
- */
76
- exports.TokenCalibration = TokenCalibration;
77
- function promptTokensOf(usage, protocol) {
78
- if (protocol === "anthropic") return usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
79
- return usage.input;
80
- }
81
- //# sourceMappingURL=tokenCalibration.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.TokenCalibration=exports.DEFAULT_CHARS_PER_TOKEN=void 0;exports.promptTokensOf=promptTokensOf;const DEFAULT_CHARS_PER_TOKEN=exports.DEFAULT_CHARS_PER_TOKEN=4;const MIN_CHARS_PER_TOKEN=2.5;const MAX_CHARS_PER_TOKEN=5;const EMA_ALPHA=.3;const MIN_SAMPLE_TOKENS=500;class TokenCalibration{ratio=DEFAULT_CHARS_PER_TOKEN;samples=0;get charsPerToken(){return this.ratio}get sampleCount(){return this.samples}observe(t,r){if(!(t>0)||!(r>=MIN_SAMPLE_TOKENS))return;const s=Math.min(MAX_CHARS_PER_TOKEN,Math.max(MIN_CHARS_PER_TOKEN,t/r));this.ratio=this.samples===0?s:this.ratio+EMA_ALPHA*(s-this.ratio);this.samples+=1}chars(t){return Math.floor(t*this.ratio)}reset(){this.ratio=DEFAULT_CHARS_PER_TOKEN;this.samples=0}}exports.TokenCalibration=TokenCalibration;function promptTokensOf(e,t){if(t==="anthropic")return e.input+(e.cacheRead??0)+(e.cacheWrite??0);return e.input}
@@ -1,300 +1,7 @@
1
- "use strict";
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.VERIFIERS=void 0;exports.atPath=atPath;exports.isSubset=isSubset;exports.verificationTrailer=verificationTrailer;exports.verifyOutcome=verifyOutcome;var _realNow=require("../realNow");const rec=e=>e&&typeof e==="object"&&!Array.isArray(e)?e:void 0;function sleep(e,i){return new Promise(n=>{if(i?.aborted)return n();const t=(0,_realNow.realSetTimeout)(r,e);function r(){(0,_realNow.realClearTimeout)(t);i?.removeEventListener("abort",r);n()}i?.addEventListener("abort",r,{once:true})})}async function poll(e,i,n,t,r){const s=(0,_realNow.realNow)()+n;for(;;){const a=await e();if(i(a))return{value:a,satisfied:true};if(r?.aborted||(0,_realNow.realNow)()+t>s)return{value:a,satisfied:false};await sleep(t,r)}}function isSubset(e,i){if(e===null||typeof e!=="object"||Array.isArray(e))return JSON.stringify(e)===JSON.stringify(i);const n=rec(i);if(!n)return false;for(const[t,r]of Object.entries(e)){if(!(t in n))return false;if(!isSubset(r,n[t]))return false}return true}function atPath(e,i){const n=i.replace(/^\/+/,"").match(/\[[^\]]*\]|[^.[\]/]+/g)??[];let t=e;for(const r of n){if(t===null||typeof t!=="object")return void 0;if(r.startsWith("[")){const s=r.slice(1,-1).trim();if(!Array.isArray(t))return void 0;const a=s.indexOf("=");if(a<0){t=t[Number(s)]}else{const o=s.slice(0,a).trim();const d=s.slice(a+1).trim().replace(/^["']|["']$/g,"");t=t.find(u=>u&&typeof u==="object"&&String(u[o])===d)}}else{t=t[r]}}return t}const brief=e=>{const i=JSON.stringify(e);return i===void 0?"undefined":i.length>80?`${i.slice(0,77)}\u2026`:i};const storageSetItem=async({params:e,dispatch:i})=>{if(typeof e.key!=="string")return void 0;const n=await i("storage","async.getItem",{key:e.key});const t=typeof n==="string"?n:rec(n)?.value;const r=typeof e.value==="string"?e.value:JSON.stringify(e.value);if(t===r)return{status:"verified",detail:`Read back: "${e.key}" now holds the written value.`};return{status:"failed",detail:`Read back after the write: "${e.key}" holds ${brief(t)}, not what was written. The write did not take.`}};const zustandSetState=async({params:e,dispatch:i,after:n})=>{if(typeof e.storeName!=="string")return void 0;const t=rec(n!==void 0?n:await i("zustand","getStoreState",{storeName:e.storeName}));if(!t||t.found===false)return{status:"failed",detail:`Read back: store "${e.storeName}" could not be read after the write.`};const r=t.currentState;if(typeof e.path==="string"){const o=atPath(r,e.path);if(JSON.stringify(o)===JSON.stringify(e.value))return{status:"verified",detail:`Read back: ${e.storeName}.${e.path} is now ${brief(o)}.`};return{status:"failed",detail:`Read back: ${e.storeName}.${e.path} is ${brief(o)}, not ${brief(e.value)}. The store did not take the write.`}}const s=rec(e.state);if(!s)return void 0;if(isSubset(s,r))return{status:"verified",detail:`Read back: "${e.storeName}" now holds the written fields (${Object.keys(s).join(", ")}).`};const a=Object.keys(s).filter(o=>!isSubset(s[o],rec(r)?.[o]));return{status:"failed",detail:`Read back: "${e.storeName}" does not hold the written value for ${a.join(", ")}. The store did not take the write \u2014 read it before deciding what to do.`}};const querySetQueryData=async({params:e,dispatch:i,after:n})=>{const t=e.queryHash!==void 0?{queryHash:e.queryHash}:e.queryKey!==void 0?{queryKey:e.queryKey}:void 0;if(!t)return void 0;const r=rec(n!==void 0?n:await i("query","getQueryData",t));if(!r||r.found===false)return{status:"failed",detail:"Read back: the query could not be read after the write."};const s=r.data;if(typeof e.path==="string"){const a=atPath(s,e.path);if(JSON.stringify(a)===JSON.stringify(e.value))return{status:"verified",detail:`Read back: the cached ${e.path} is now ${brief(a)}.`};return{status:"failed",detail:`Read back: the cached ${e.path} is ${brief(a)}, not ${brief(e.value)}. The cache did not take the write \u2014 the app may have refetched over it.`}}if(e.data===void 0)return void 0;if(isSubset(e.data,s))return{status:"verified",detail:"Read back: the cache now holds the written data."};return{status:"failed",detail:"Read back: the cache does not hold the written data \u2014 the app may have refetched over it, or the shape differed."}};const navigate=async({params:e,dispatch:i,signal:n})=>{if(typeof e.path!=="string")return void 0;const t=e.path.split("?")[0];const{value:r,satisfied:s}=await poll(async()=>rec(await i("route-events","getCurrentRoute",{})),o=>typeof o?.path==="string"&&(o.path===t||o.path.split("?")[0]===t),2e3,250,n);if(s)return{status:"verified",detail:`The app is now on ${t}.`};const a=typeof r?.path==="string"?r.path:"an unknown route";return{status:"failed",detail:`Two seconds after navigating, the app is on ${a}, not ${t}. Do not navigate again blindly \u2014 check the route exists (the sitemap) and whether something redirected.`}};const upsertOverrideRule=async({params:e,result:i,dispatch:n,signal:t})=>{const r=rec(rec(i)?.rule)?.id??rec(e.rule)?.id;if(typeof r!=="string")return void 0;const s=async()=>{const d=rec(await n("network","listOverrideRules",{}));const u=Array.isArray(d?.rules)?d.rules:[];return u.map(rec).find(f=>f?.id===r)};const{value:a,satisfied:o}=await poll(s,d=>typeof d?.hits==="number"&&d.hits>0,3e3,500,t);if(!a)return{status:"failed",detail:"The rule is not in the override list after the write. It did not install."};if(a.enabled===false)return{status:"failed",detail:"The rule is installed but disabled, so it will not fire."};if(o)return{status:"verified",detail:`The rule has matched ${a.hits} request${a.hits===1?"":"s"} \u2014 the app has already received the overridden response.`};return{status:"unverified",detail:"The rule is installed, but no request has matched it yet \u2014 the app is still showing whatever it loaded before. A refetch or a visit to the screen that fetches this will exercise it; until then, do not say the screen shows the override."}};const VERIFIERS=exports.VERIFIERS={"storage.async.setItem":storageSetItem,"zustand.setState":zustandSetState,"query.setQueryData":querySetQueryData,"route-events.navigate":navigate,"network.upsertOverrideRule":upsertOverrideRule};async function verifyOutcome(e){const i=VERIFIERS[`${e.toolId}.${e.action}`];if(!i)return void 0;try{return await i(e)}catch{return void 0}}function verificationTrailer(e){switch(e.status){case"verified":return`
2
2
 
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.VERIFIERS = void 0;
7
- exports.atPath = atPath;
8
- exports.isSubset = isSubset;
9
- exports.verificationTrailer = verificationTrailer;
10
- exports.verifyOutcome = verifyOutcome;
11
- /**
12
- * Outcome verification: after a write lands, check that what the user asked
13
- * for actually happened — not just that the adapter said ok.
14
- *
15
- * "Install override → `{ok:true}`" was reported as done. But installed ≠ a
16
- * request has used it ≠ the cart shows it, and each step can succeed while
17
- * the outcome fails: the app had the old response cached, the screen kept
18
- * saying In Stock, and the reply said "the item is now sold out". Strands'
19
- * GoalLoop frames this as a completion criterion with bounded correction; the
20
- * criterion borrowed here is DETERMINISTIC — a read-back the engine performs
21
- * with the same tools the model has — not a second model judging the reply.
22
- *
23
- * Three outcomes, each honest about what it is:
24
- *
25
- * - `verified` — the read-back shows the requested state.
26
- * - `unverified` — the write landed but the read-back cannot yet show the
27
- * outcome (an override is installed but no request has
28
- * matched it). Reported as exactly that, never as proof.
29
- * - `failed` — the read-back contradicts the write. The model is told
30
- * what was found and asked for ONE correction through the
31
- * same policy and ledger path; never to repeat the write.
32
- *
33
- * Bounded by construction: each verifier makes a few reads, polls for at most
34
- * `waitMs` (small, per action), and stops on the turn's abort signal. It never
35
- * dispatches a write, and its reads are not stashed as evidence. Undefined
36
- * means "no opinion" — nothing is appended, which is what every action
37
- * without a verifier gets.
38
- */
3
+ [Buoy] Verified: ${e.detail}`;case"unverified":return`
39
4
 
40
- const rec = v => v && typeof v === "object" && !Array.isArray(v) ? v : undefined;
41
- function sleep(ms, signal) {
42
- return new Promise(resolve => {
43
- if (signal?.aborted) return resolve();
44
- const t = setTimeout(done, ms);
45
- function done() {
46
- clearTimeout(t);
47
- signal?.removeEventListener("abort", done);
48
- resolve();
49
- }
50
- signal?.addEventListener("abort", done, {
51
- once: true
52
- });
53
- });
54
- }
5
+ [Buoy] Unverified: ${e.detail}`;case"failed":return`
55
6
 
56
- /** Poll `read` every `everyMs` until `until` says so or `waitMs` is spent. Returns the last read. */
57
- async function poll(read, until, waitMs, everyMs, signal) {
58
- const deadline = Date.now() + waitMs;
59
- for (;;) {
60
- const value = await read();
61
- if (until(value)) return {
62
- value,
63
- satisfied: true
64
- };
65
- if (signal?.aborted || Date.now() + everyMs > deadline) return {
66
- value,
67
- satisfied: false
68
- };
69
- await sleep(everyMs, signal);
70
- }
71
- }
72
-
73
- /** Every key in `want` present in `have` with an equal (deep) value. Arrays compare whole. */
74
- function isSubset(want, have) {
75
- if (want === null || typeof want !== "object" || Array.isArray(want)) return JSON.stringify(want) === JSON.stringify(have);
76
- const h = rec(have);
77
- if (!h) return false;
78
- for (const [k, v] of Object.entries(want)) {
79
- if (!(k in h)) return false;
80
- if (!isSubset(v, h[k])) return false;
81
- }
82
- return true;
83
- }
84
-
85
- /**
86
- * The adapters' path grammar — dotted keys, `[0]`, and the id-addressed
87
- * `[field=value]` the prompt recommends for list edits ("lines[lineId=seed-1].qty").
88
- * A mirror of shared/sync/valuePath.ts, kept here because agent-core imports
89
- * nothing. The first live run wrote exactly that form and this resolver, then
90
- * dotted-only, reported a landed edit as "did not take".
91
- */
92
- function atPath(root, path) {
93
- const segs = path.replace(/^\/+/, "").match(/\[[^\]]*\]|[^.[\]/]+/g) ?? [];
94
- let cur = root;
95
- for (const seg of segs) {
96
- if (cur === null || typeof cur !== "object") return undefined;
97
- if (seg.startsWith("[")) {
98
- const inner = seg.slice(1, -1).trim();
99
- if (!Array.isArray(cur)) return undefined;
100
- const eq = inner.indexOf("=");
101
- if (eq < 0) {
102
- cur = cur[Number(inner)];
103
- } else {
104
- const field = inner.slice(0, eq).trim();
105
- const value = inner.slice(eq + 1).trim().replace(/^["']|["']$/g, "");
106
- cur = cur.find(el => el && typeof el === "object" && String(el[field]) === value);
107
- }
108
- } else {
109
- cur = cur[seg];
110
- }
111
- }
112
- return cur;
113
- }
114
- const brief = v => {
115
- const s = JSON.stringify(v);
116
- return s === undefined ? "undefined" : s.length > 80 ? `${s.slice(0, 77)}…` : s;
117
- };
118
-
119
- // ── the verifiers ────────────────────────────────────────────────────────────
120
-
121
- const storageSetItem = async ({
122
- params,
123
- dispatch
124
- }) => {
125
- if (typeof params.key !== "string") return undefined;
126
- const back = await dispatch("storage", "async.getItem", {
127
- key: params.key
128
- });
129
- const value = typeof back === "string" ? back : rec(back)?.value;
130
- const wanted = typeof params.value === "string" ? params.value : JSON.stringify(params.value);
131
- if (value === wanted) return {
132
- status: "verified",
133
- detail: `Read back: "${params.key}" now holds the written value.`
134
- };
135
- return {
136
- status: "failed",
137
- detail: `Read back after the write: "${params.key}" holds ${brief(value)}, not what was written. The write did not take.`
138
- };
139
- };
140
- const zustandSetState = async ({
141
- params,
142
- dispatch,
143
- after
144
- }) => {
145
- if (typeof params.storeName !== "string") return undefined;
146
- const back = rec(after !== undefined ? after : await dispatch("zustand", "getStoreState", {
147
- storeName: params.storeName
148
- }));
149
- if (!back || back.found === false) return {
150
- status: "failed",
151
- detail: `Read back: store "${params.storeName}" could not be read after the write.`
152
- };
153
- const current = back.currentState;
154
- if (typeof params.path === "string") {
155
- const got = atPath(current, params.path);
156
- if (JSON.stringify(got) === JSON.stringify(params.value)) return {
157
- status: "verified",
158
- detail: `Read back: ${params.storeName}.${params.path} is now ${brief(got)}.`
159
- };
160
- return {
161
- status: "failed",
162
- detail: `Read back: ${params.storeName}.${params.path} is ${brief(got)}, not ${brief(params.value)}. The store did not take the write.`
163
- };
164
- }
165
- const want = rec(params.state);
166
- if (!want) return undefined;
167
- if (isSubset(want, current)) return {
168
- status: "verified",
169
- detail: `Read back: "${params.storeName}" now holds the written fields (${Object.keys(want).join(", ")}).`
170
- };
171
- const wrong = Object.keys(want).filter(k => !isSubset(want[k], rec(current)?.[k]));
172
- return {
173
- status: "failed",
174
- detail: `Read back: "${params.storeName}" does not hold the written value for ${wrong.join(", ")}. The store did not take the write — read it before deciding what to do.`
175
- };
176
- };
177
- const querySetQueryData = async ({
178
- params,
179
- dispatch,
180
- after
181
- }) => {
182
- const key = params.queryHash !== undefined ? {
183
- queryHash: params.queryHash
184
- } : params.queryKey !== undefined ? {
185
- queryKey: params.queryKey
186
- } : undefined;
187
- if (!key) return undefined;
188
- const back = rec(after !== undefined ? after : await dispatch("query", "getQueryData", key));
189
- if (!back || back.found === false) return {
190
- status: "failed",
191
- detail: "Read back: the query could not be read after the write."
192
- };
193
- const data = back.data;
194
- if (typeof params.path === "string") {
195
- const got = atPath(data, params.path);
196
- if (JSON.stringify(got) === JSON.stringify(params.value)) return {
197
- status: "verified",
198
- detail: `Read back: the cached ${params.path} is now ${brief(got)}.`
199
- };
200
- return {
201
- status: "failed",
202
- detail: `Read back: the cached ${params.path} is ${brief(got)}, not ${brief(params.value)}. The cache did not take the write — the app may have refetched over it.`
203
- };
204
- }
205
- if (params.data === undefined) return undefined;
206
- if (isSubset(params.data, data)) return {
207
- status: "verified",
208
- detail: "Read back: the cache now holds the written data."
209
- };
210
- return {
211
- status: "failed",
212
- detail: "Read back: the cache does not hold the written data — the app may have refetched over it, or the shape differed."
213
- };
214
- };
215
- const navigate = async ({
216
- params,
217
- dispatch,
218
- signal
219
- }) => {
220
- if (typeof params.path !== "string") return undefined;
221
- const wanted = params.path.split("?")[0];
222
- const {
223
- value,
224
- satisfied
225
- } = await poll(async () => rec(await dispatch("route-events", "getCurrentRoute", {})), r => typeof r?.path === "string" && (r.path === wanted || r.path.split("?")[0] === wanted), 2_000, 250, signal);
226
- if (satisfied) return {
227
- status: "verified",
228
- detail: `The app is now on ${wanted}.`
229
- };
230
- const at = typeof value?.path === "string" ? value.path : "an unknown route";
231
- return {
232
- status: "failed",
233
- detail: `Two seconds after navigating, the app is on ${at}, not ${wanted}. Do not navigate again blindly — check the route exists (the sitemap) and whether something redirected.`
234
- };
235
- };
236
- const upsertOverrideRule = async ({
237
- params,
238
- result,
239
- dispatch,
240
- signal
241
- }) => {
242
- const id = rec(rec(result)?.rule)?.id ?? rec(params.rule)?.id;
243
- if (typeof id !== "string") return undefined;
244
- const find = async () => {
245
- const list = rec(await dispatch("network", "listOverrideRules", {}));
246
- const rules = Array.isArray(list?.rules) ? list.rules : [];
247
- return rules.map(rec).find(r => r?.id === id);
248
- };
249
- const {
250
- value,
251
- satisfied
252
- } = await poll(find, r => typeof r?.hits === "number" && r.hits > 0, 3_000, 500, signal);
253
- if (!value) return {
254
- status: "failed",
255
- detail: "The rule is not in the override list after the write. It did not install."
256
- };
257
- if (value.enabled === false) return {
258
- status: "failed",
259
- detail: "The rule is installed but disabled, so it will not fire."
260
- };
261
- if (satisfied) return {
262
- status: "verified",
263
- detail: `The rule has matched ${value.hits} request${value.hits === 1 ? "" : "s"} — the app has already received the overridden response.`
264
- };
265
- return {
266
- status: "unverified",
267
- detail: "The rule is installed, but no request has matched it yet — the app is still showing whatever it loaded before. A refetch or a visit to the screen that fetches this will exercise it; until then, do not say the screen shows the override."
268
- };
269
- };
270
- const VERIFIERS = exports.VERIFIERS = {
271
- "storage.async.setItem": storageSetItem,
272
- "zustand.setState": zustandSetState,
273
- "query.setQueryData": querySetQueryData,
274
- "route-events.navigate": navigate,
275
- "network.upsertOverrideRule": upsertOverrideRule
276
- };
277
-
278
- /** Run the verifier for this action, if there is one. Never throws: a read that blows up is "no opinion". */
279
- async function verifyOutcome(input) {
280
- const verifier = VERIFIERS[`${input.toolId}.${input.action}`];
281
- if (!verifier) return undefined;
282
- try {
283
- return await verifier(input);
284
- } catch {
285
- return undefined;
286
- }
287
- }
288
-
289
- /** The trailer the model reads. Kept in the `[Buoy] ` trailer form the bench's parser splits on. */
290
- function verificationTrailer(v) {
291
- switch (v.status) {
292
- case "verified":
293
- return `\n\n[Buoy] Verified: ${v.detail}`;
294
- case "unverified":
295
- return `\n\n[Buoy] Unverified: ${v.detail}`;
296
- case "failed":
297
- return `\n\n[Buoy] Check FAILED: ${v.detail} You may correct this ONCE — read the current state first, then make a different, targeted change; never repeat the same write and never claim the outcome happened.`;
298
- }
299
- }
300
- //# sourceMappingURL=verify.js.map
7
+ [Buoy] Check FAILED: ${e.detail} You may correct this ONCE \u2014 read the current state first, then make a different, targeted change; never repeat the same write and never claim the outcome happened.`}}