@e2edev/e2e 0.2.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 (399) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +104 -0
  3. package/dist/agent/act-validation.d.ts +27 -0
  4. package/dist/agent/act-validation.d.ts.map +1 -0
  5. package/dist/agent/act-validation.js +121 -0
  6. package/dist/agent/act-validation.js.map +1 -0
  7. package/dist/agent/act.d.ts +27 -0
  8. package/dist/agent/act.d.ts.map +1 -0
  9. package/dist/agent/act.js +775 -0
  10. package/dist/agent/act.js.map +1 -0
  11. package/dist/agent/actions.d.ts +66 -0
  12. package/dist/agent/actions.d.ts.map +1 -0
  13. package/dist/agent/actions.js +82 -0
  14. package/dist/agent/actions.js.map +1 -0
  15. package/dist/agent/ai-sdk.d.ts +16 -0
  16. package/dist/agent/ai-sdk.d.ts.map +1 -0
  17. package/dist/agent/ai-sdk.js +59 -0
  18. package/dist/agent/ai-sdk.js.map +1 -0
  19. package/dist/agent/call-options.d.ts +10 -0
  20. package/dist/agent/call-options.d.ts.map +1 -0
  21. package/dist/agent/call-options.js +28 -0
  22. package/dist/agent/call-options.js.map +1 -0
  23. package/dist/agent/default-agent.d.ts +22 -0
  24. package/dist/agent/default-agent.d.ts.map +1 -0
  25. package/dist/agent/default-agent.js +354 -0
  26. package/dist/agent/default-agent.js.map +1 -0
  27. package/dist/agent/error.d.ts +53 -0
  28. package/dist/agent/error.d.ts.map +1 -0
  29. package/dist/agent/error.js +94 -0
  30. package/dist/agent/error.js.map +1 -0
  31. package/dist/agent/executor.d.ts +238 -0
  32. package/dist/agent/executor.d.ts.map +1 -0
  33. package/dist/agent/executor.js +56 -0
  34. package/dist/agent/executor.js.map +1 -0
  35. package/dist/agent/index.d.ts +15 -0
  36. package/dist/agent/index.d.ts.map +1 -0
  37. package/dist/agent/index.js +304 -0
  38. package/dist/agent/index.js.map +1 -0
  39. package/dist/agent/invocation.d.ts +194 -0
  40. package/dist/agent/invocation.d.ts.map +1 -0
  41. package/dist/agent/invocation.js +389 -0
  42. package/dist/agent/invocation.js.map +1 -0
  43. package/dist/agent/ledger.d.ts +24 -0
  44. package/dist/agent/ledger.d.ts.map +1 -0
  45. package/dist/agent/ledger.js +48 -0
  46. package/dist/agent/ledger.js.map +1 -0
  47. package/dist/agent/loop-guards.d.ts +35 -0
  48. package/dist/agent/loop-guards.d.ts.map +1 -0
  49. package/dist/agent/loop-guards.js +110 -0
  50. package/dist/agent/loop-guards.js.map +1 -0
  51. package/dist/agent/model/adapter.d.ts +97 -0
  52. package/dist/agent/model/adapter.d.ts.map +1 -0
  53. package/dist/agent/model/adapter.js +40 -0
  54. package/dist/agent/model/adapter.js.map +1 -0
  55. package/dist/agent/model/router.d.ts +36 -0
  56. package/dist/agent/model/router.d.ts.map +1 -0
  57. package/dist/agent/model/router.js +45 -0
  58. package/dist/agent/model/router.js.map +1 -0
  59. package/dist/agent/model/schema.d.ts +16 -0
  60. package/dist/agent/model/schema.d.ts.map +1 -0
  61. package/dist/agent/model/schema.js +37 -0
  62. package/dist/agent/model/schema.js.map +1 -0
  63. package/dist/agent/model/sdk.d.ts +28 -0
  64. package/dist/agent/model/sdk.d.ts.map +1 -0
  65. package/dist/agent/model/sdk.js +258 -0
  66. package/dist/agent/model/sdk.js.map +1 -0
  67. package/dist/agent/observation.d.ts +70 -0
  68. package/dist/agent/observation.d.ts.map +1 -0
  69. package/dist/agent/observation.js +174 -0
  70. package/dist/agent/observation.js.map +1 -0
  71. package/dist/agent/phases.d.ts +71 -0
  72. package/dist/agent/phases.d.ts.map +1 -0
  73. package/dist/agent/phases.js +124 -0
  74. package/dist/agent/phases.js.map +1 -0
  75. package/dist/agent/prompts.d.ts +40 -0
  76. package/dist/agent/prompts.d.ts.map +1 -0
  77. package/dist/agent/prompts.js +104 -0
  78. package/dist/agent/prompts.js.map +1 -0
  79. package/dist/agent/protocol.d.ts +31 -0
  80. package/dist/agent/protocol.d.ts.map +1 -0
  81. package/dist/agent/protocol.js +67 -0
  82. package/dist/agent/protocol.js.map +1 -0
  83. package/dist/agent/public.d.ts +12 -0
  84. package/dist/agent/public.d.ts.map +1 -0
  85. package/dist/agent/public.js +12 -0
  86. package/dist/agent/public.js.map +1 -0
  87. package/dist/agent/replay.d.ts +61 -0
  88. package/dist/agent/replay.d.ts.map +1 -0
  89. package/dist/agent/replay.js +185 -0
  90. package/dist/agent/replay.js.map +1 -0
  91. package/dist/agent/secrets.d.ts +22 -0
  92. package/dist/agent/secrets.d.ts.map +1 -0
  93. package/dist/agent/secrets.js +63 -0
  94. package/dist/agent/secrets.js.map +1 -0
  95. package/dist/agent/step-cache.d.ts +156 -0
  96. package/dist/agent/step-cache.d.ts.map +1 -0
  97. package/dist/agent/step-cache.js +301 -0
  98. package/dist/agent/step-cache.js.map +1 -0
  99. package/dist/agent/tool-loop.d.ts +51 -0
  100. package/dist/agent/tool-loop.d.ts.map +1 -0
  101. package/dist/agent/tool-loop.js +331 -0
  102. package/dist/agent/tool-loop.js.map +1 -0
  103. package/dist/agent/tool.d.ts +39 -0
  104. package/dist/agent/tool.d.ts.map +1 -0
  105. package/dist/agent/tool.js +52 -0
  106. package/dist/agent/tool.js.map +1 -0
  107. package/dist/backend/contract.d.ts +186 -0
  108. package/dist/backend/contract.d.ts.map +1 -0
  109. package/dist/backend/contract.js +65 -0
  110. package/dist/backend/contract.js.map +1 -0
  111. package/dist/backend/index.d.ts +316 -0
  112. package/dist/backend/index.d.ts.map +1 -0
  113. package/dist/backend/index.js +219 -0
  114. package/dist/backend/index.js.map +1 -0
  115. package/dist/backend/session.d.ts +23 -0
  116. package/dist/backend/session.d.ts.map +1 -0
  117. package/dist/backend/session.js +213 -0
  118. package/dist/backend/session.js.map +1 -0
  119. package/dist/backend/surface.d.ts +83 -0
  120. package/dist/backend/surface.d.ts.map +1 -0
  121. package/dist/backend/surface.js +11 -0
  122. package/dist/backend/surface.js.map +1 -0
  123. package/dist/cache/anchors.d.ts +37 -0
  124. package/dist/cache/anchors.d.ts.map +1 -0
  125. package/dist/cache/anchors.js +89 -0
  126. package/dist/cache/anchors.js.map +1 -0
  127. package/dist/cache/context.d.ts +74 -0
  128. package/dist/cache/context.d.ts.map +1 -0
  129. package/dist/cache/context.js +82 -0
  130. package/dist/cache/context.js.map +1 -0
  131. package/dist/cache/decide.d.ts +42 -0
  132. package/dist/cache/decide.d.ts.map +1 -0
  133. package/dist/cache/decide.js +47 -0
  134. package/dist/cache/decide.js.map +1 -0
  135. package/dist/cache/identity.d.ts +113 -0
  136. package/dist/cache/identity.d.ts.map +1 -0
  137. package/dist/cache/identity.js +109 -0
  138. package/dist/cache/identity.js.map +1 -0
  139. package/dist/cache/recorder.d.ts +76 -0
  140. package/dist/cache/recorder.d.ts.map +1 -0
  141. package/dist/cache/recorder.js +143 -0
  142. package/dist/cache/recorder.js.map +1 -0
  143. package/dist/cache/relocate.d.ts +69 -0
  144. package/dist/cache/relocate.d.ts.map +1 -0
  145. package/dist/cache/relocate.js +125 -0
  146. package/dist/cache/relocate.js.map +1 -0
  147. package/dist/cache/store.d.ts +68 -0
  148. package/dist/cache/store.d.ts.map +1 -0
  149. package/dist/cache/store.js +106 -0
  150. package/dist/cache/store.js.map +1 -0
  151. package/dist/cache/trace.d.ts +146 -0
  152. package/dist/cache/trace.d.ts.map +1 -0
  153. package/dist/cache/trace.js +249 -0
  154. package/dist/cache/trace.js.map +1 -0
  155. package/dist/cli/bin.d.ts +3 -0
  156. package/dist/cli/bin.d.ts.map +1 -0
  157. package/dist/cli/bin.js +4 -0
  158. package/dist/cli/bin.js.map +1 -0
  159. package/dist/cli/index.d.ts +4 -0
  160. package/dist/cli/index.d.ts.map +1 -0
  161. package/dist/cli/index.js +108 -0
  162. package/dist/cli/index.js.map +1 -0
  163. package/dist/cli/init.d.ts +6 -0
  164. package/dist/cli/init.d.ts.map +1 -0
  165. package/dist/cli/init.js +101 -0
  166. package/dist/cli/init.js.map +1 -0
  167. package/dist/collect/collect.d.ts +44 -0
  168. package/dist/collect/collect.d.ts.map +1 -0
  169. package/dist/collect/collect.js +89 -0
  170. package/dist/collect/collect.js.map +1 -0
  171. package/dist/collect/registry.d.ts +47 -0
  172. package/dist/collect/registry.d.ts.map +1 -0
  173. package/dist/collect/registry.js +262 -0
  174. package/dist/collect/registry.js.map +1 -0
  175. package/dist/collect/select.d.ts +54 -0
  176. package/dist/collect/select.d.ts.map +1 -0
  177. package/dist/collect/select.js +230 -0
  178. package/dist/collect/select.js.map +1 -0
  179. package/dist/config/agent.d.ts +91 -0
  180. package/dist/config/agent.d.ts.map +1 -0
  181. package/dist/config/agent.js +232 -0
  182. package/dist/config/agent.js.map +1 -0
  183. package/dist/config/load.d.ts +23 -0
  184. package/dist/config/load.d.ts.map +1 -0
  185. package/dist/config/load.js +75 -0
  186. package/dist/config/load.js.map +1 -0
  187. package/dist/config/resolve.d.ts +94 -0
  188. package/dist/config/resolve.d.ts.map +1 -0
  189. package/dist/config/resolve.js +500 -0
  190. package/dist/config/resolve.js.map +1 -0
  191. package/dist/config/validate.d.ts +6 -0
  192. package/dist/config/validate.d.ts.map +1 -0
  193. package/dist/config/validate.js +21 -0
  194. package/dist/config/validate.js.map +1 -0
  195. package/dist/credentials.d.ts +7 -0
  196. package/dist/credentials.d.ts.map +1 -0
  197. package/dist/credentials.js +42 -0
  198. package/dist/credentials.js.map +1 -0
  199. package/dist/expect/async.d.ts +5 -0
  200. package/dist/expect/async.d.ts.map +1 -0
  201. package/dist/expect/async.js +186 -0
  202. package/dist/expect/async.js.map +1 -0
  203. package/dist/expect/index.d.ts +7 -0
  204. package/dist/expect/index.d.ts.map +1 -0
  205. package/dist/expect/index.js +23 -0
  206. package/dist/expect/index.js.map +1 -0
  207. package/dist/expect/values.d.ts +4 -0
  208. package/dist/expect/values.d.ts.map +1 -0
  209. package/dist/expect/values.js +108 -0
  210. package/dist/expect/values.js.map +1 -0
  211. package/dist/index.d.ts +13 -0
  212. package/dist/index.d.ts.map +1 -0
  213. package/dist/index.js +15 -0
  214. package/dist/index.js.map +1 -0
  215. package/dist/internal/ai-trace.d.ts +151 -0
  216. package/dist/internal/ai-trace.d.ts.map +1 -0
  217. package/dist/internal/ai-trace.js +360 -0
  218. package/dist/internal/ai-trace.js.map +1 -0
  219. package/dist/internal/brands.d.ts +9 -0
  220. package/dist/internal/brands.d.ts.map +1 -0
  221. package/dist/internal/brands.js +9 -0
  222. package/dist/internal/brands.js.map +1 -0
  223. package/dist/internal/debug.d.ts +43 -0
  224. package/dist/internal/debug.d.ts.map +1 -0
  225. package/dist/internal/debug.js +102 -0
  226. package/dist/internal/debug.js.map +1 -0
  227. package/dist/internal/errors.d.ts +98 -0
  228. package/dist/internal/errors.d.ts.map +1 -0
  229. package/dist/internal/errors.js +212 -0
  230. package/dist/internal/errors.js.map +1 -0
  231. package/dist/internal/globs.d.ts +29 -0
  232. package/dist/internal/globs.d.ts.map +1 -0
  233. package/dist/internal/globs.js +126 -0
  234. package/dist/internal/globs.js.map +1 -0
  235. package/dist/internal/ids.d.ts +32 -0
  236. package/dist/internal/ids.d.ts.map +1 -0
  237. package/dist/internal/ids.js +124 -0
  238. package/dist/internal/ids.js.map +1 -0
  239. package/dist/internal/json-value.d.ts +15 -0
  240. package/dist/internal/json-value.d.ts.map +1 -0
  241. package/dist/internal/json-value.js +61 -0
  242. package/dist/internal/json-value.js.map +1 -0
  243. package/dist/internal/package-version.d.ts +6 -0
  244. package/dist/internal/package-version.d.ts.map +1 -0
  245. package/dist/internal/package-version.js +14 -0
  246. package/dist/internal/package-version.js.map +1 -0
  247. package/dist/internal/realm-slot.d.ts +13 -0
  248. package/dist/internal/realm-slot.d.ts.map +1 -0
  249. package/dist/internal/realm-slot.js +23 -0
  250. package/dist/internal/realm-slot.js.map +1 -0
  251. package/dist/internal/redact.d.ts +33 -0
  252. package/dist/internal/redact.d.ts.map +1 -0
  253. package/dist/internal/redact.js +56 -0
  254. package/dist/internal/redact.js.map +1 -0
  255. package/dist/internal/regexp.d.ts +10 -0
  256. package/dist/internal/regexp.d.ts.map +1 -0
  257. package/dist/internal/regexp.js +27 -0
  258. package/dist/internal/regexp.js.map +1 -0
  259. package/dist/internal/text.d.ts +39 -0
  260. package/dist/internal/text.d.ts.map +1 -0
  261. package/dist/internal/text.js +66 -0
  262. package/dist/internal/text.js.map +1 -0
  263. package/dist/internal/time.d.ts +37 -0
  264. package/dist/internal/time.d.ts.map +1 -0
  265. package/dist/internal/time.js +91 -0
  266. package/dist/internal/time.js.map +1 -0
  267. package/dist/internal/trace.d.ts +18 -0
  268. package/dist/internal/trace.d.ts.map +1 -0
  269. package/dist/internal/trace.js +46 -0
  270. package/dist/internal/trace.js.map +1 -0
  271. package/dist/internal/urls.d.ts +31 -0
  272. package/dist/internal/urls.d.ts.map +1 -0
  273. package/dist/internal/urls.js +95 -0
  274. package/dist/internal/urls.js.map +1 -0
  275. package/dist/locator/engine.d.ts +65 -0
  276. package/dist/locator/engine.d.ts.map +1 -0
  277. package/dist/locator/engine.js +164 -0
  278. package/dist/locator/engine.js.map +1 -0
  279. package/dist/locator/expression.d.ts +19 -0
  280. package/dist/locator/expression.d.ts.map +1 -0
  281. package/dist/locator/expression.js +85 -0
  282. package/dist/locator/expression.js.map +1 -0
  283. package/dist/locator/screen.d.ts +36 -0
  284. package/dist/locator/screen.d.ts.map +1 -0
  285. package/dist/locator/screen.js +281 -0
  286. package/dist/locator/screen.js.map +1 -0
  287. package/dist/report/build.d.ts +214 -0
  288. package/dist/report/build.d.ts.map +1 -0
  289. package/dist/report/build.js +346 -0
  290. package/dist/report/build.js.map +1 -0
  291. package/dist/report/code-frame.d.ts +20 -0
  292. package/dist/report/code-frame.d.ts.map +1 -0
  293. package/dist/report/code-frame.js +73 -0
  294. package/dist/report/code-frame.js.map +1 -0
  295. package/dist/report/debug-steps.d.ts +14 -0
  296. package/dist/report/debug-steps.d.ts.map +1 -0
  297. package/dist/report/debug-steps.js +85 -0
  298. package/dist/report/debug-steps.js.map +1 -0
  299. package/dist/report/list.d.ts +80 -0
  300. package/dist/report/list.d.ts.map +1 -0
  301. package/dist/report/list.js +372 -0
  302. package/dist/report/list.js.map +1 -0
  303. package/dist/report/live-status.d.ts +51 -0
  304. package/dist/report/live-status.d.ts.map +1 -0
  305. package/dist/report/live-status.js +162 -0
  306. package/dist/report/live-status.js.map +1 -0
  307. package/dist/report/write.d.ts +4 -0
  308. package/dist/report/write.d.ts.map +1 -0
  309. package/dist/report/write.js +13 -0
  310. package/dist/report/write.js.map +1 -0
  311. package/dist/run/app-process.d.ts +18 -0
  312. package/dist/run/app-process.d.ts.map +1 -0
  313. package/dist/run/app-process.js +112 -0
  314. package/dist/run/app-process.js.map +1 -0
  315. package/dist/run/artifacts.d.ts +51 -0
  316. package/dist/run/artifacts.d.ts.map +1 -0
  317. package/dist/run/artifacts.js +114 -0
  318. package/dist/run/artifacts.js.map +1 -0
  319. package/dist/run/events.d.ts +100 -0
  320. package/dist/run/events.d.ts.map +1 -0
  321. package/dist/run/events.js +59 -0
  322. package/dist/run/events.js.map +1 -0
  323. package/dist/run/execute.d.ts +119 -0
  324. package/dist/run/execute.d.ts.map +1 -0
  325. package/dist/run/execute.js +555 -0
  326. package/dist/run/execute.js.map +1 -0
  327. package/dist/run/fixtures.d.ts +40 -0
  328. package/dist/run/fixtures.d.ts.map +1 -0
  329. package/dist/run/fixtures.js +408 -0
  330. package/dist/run/fixtures.js.map +1 -0
  331. package/dist/run/in-process.d.ts +24 -0
  332. package/dist/run/in-process.d.ts.map +1 -0
  333. package/dist/run/in-process.js +120 -0
  334. package/dist/run/in-process.js.map +1 -0
  335. package/dist/run/public.d.ts +19 -0
  336. package/dist/run/public.d.ts.map +1 -0
  337. package/dist/run/public.js +11 -0
  338. package/dist/run/public.js.map +1 -0
  339. package/dist/run/realm.d.ts +52 -0
  340. package/dist/run/realm.d.ts.map +1 -0
  341. package/dist/run/realm.js +101 -0
  342. package/dist/run/realm.js.map +1 -0
  343. package/dist/run/records.d.ts +87 -0
  344. package/dist/run/records.d.ts.map +1 -0
  345. package/dist/run/records.js +3 -0
  346. package/dist/run/records.js.map +1 -0
  347. package/dist/run/retry.d.ts +18 -0
  348. package/dist/run/retry.d.ts.map +1 -0
  349. package/dist/run/retry.js +33 -0
  350. package/dist/run/retry.js.map +1 -0
  351. package/dist/run/runner.d.ts +49 -0
  352. package/dist/run/runner.d.ts.map +1 -0
  353. package/dist/run/runner.js +375 -0
  354. package/dist/run/runner.js.map +1 -0
  355. package/dist/run/scheduler.d.ts +45 -0
  356. package/dist/run/scheduler.d.ts.map +1 -0
  357. package/dist/run/scheduler.js +512 -0
  358. package/dist/run/scheduler.js.map +1 -0
  359. package/dist/run/serial.d.ts +52 -0
  360. package/dist/run/serial.d.ts.map +1 -0
  361. package/dist/run/serial.js +247 -0
  362. package/dist/run/serial.js.map +1 -0
  363. package/dist/run/sessions.d.ts +54 -0
  364. package/dist/run/sessions.d.ts.map +1 -0
  365. package/dist/run/sessions.js +221 -0
  366. package/dist/run/sessions.js.map +1 -0
  367. package/dist/run/steps.d.ts +196 -0
  368. package/dist/run/steps.d.ts.map +1 -0
  369. package/dist/run/steps.js +151 -0
  370. package/dist/run/steps.js.map +1 -0
  371. package/dist/run/unit-runner.d.ts +30 -0
  372. package/dist/run/unit-runner.d.ts.map +1 -0
  373. package/dist/run/unit-runner.js +11 -0
  374. package/dist/run/unit-runner.js.map +1 -0
  375. package/dist/run/units.d.ts +50 -0
  376. package/dist/run/units.d.ts.map +1 -0
  377. package/dist/run/units.js +103 -0
  378. package/dist/run/units.js.map +1 -0
  379. package/dist/run/worker/entry.d.ts +8 -0
  380. package/dist/run/worker/entry.d.ts.map +1 -0
  381. package/dist/run/worker/entry.js +137 -0
  382. package/dist/run/worker/entry.js.map +1 -0
  383. package/dist/run/worker/handle.d.ts +10 -0
  384. package/dist/run/worker/handle.d.ts.map +1 -0
  385. package/dist/run/worker/handle.js +74 -0
  386. package/dist/run/worker/handle.js.map +1 -0
  387. package/dist/run/worker/protocol.d.ts +129 -0
  388. package/dist/run/worker/protocol.d.ts.map +1 -0
  389. package/dist/run/worker/protocol.js +18 -0
  390. package/dist/run/worker/protocol.js.map +1 -0
  391. package/dist/run/worker/session.d.ts +69 -0
  392. package/dist/run/worker/session.d.ts.map +1 -0
  393. package/dist/run/worker/session.js +123 -0
  394. package/dist/run/worker/session.js.map +1 -0
  395. package/dist/types.d.ts +630 -0
  396. package/dist/types.d.ts.map +1 -0
  397. package/dist/types.js +6 -0
  398. package/dist/types.js.map +1 -0
  399. package/package.json +91 -0
@@ -0,0 +1,258 @@
1
+ /**
2
+ * AI SDK adapter (spec 05-config.md). One implementation serves every
3
+ * provider: a `provider/model-id` reference resolves through the AI Gateway,
4
+ * and a caller-supplied AI SDK model instance (`openai('gpt-4o')`, a local
5
+ * provider, a scripted test model) is used directly. Everything after model
6
+ * construction — bounded requests, closed-grammar validation, usage and error
7
+ * translation — is provider-independent.
8
+ */
9
+ import { GATEWAY_API_KEY_ENV, } from '../../config/agent.js';
10
+ import { aiSdk, loadAiSdk } from '../ai-sdk.js';
11
+ import { packageVersion } from '../../internal/package-version.js';
12
+ import { AgentError } from '../error.js';
13
+ import { imageTokenUpperBound, ModelOutputInvalidError, tokenUpperBound, } from './adapter.js';
14
+ /** Default AI Gateway base URL used when no endpoint override is configured. */
15
+ const DEFAULT_GATEWAY_ENDPOINT = 'https://ai-gateway.vercel.sh/v4/ai';
16
+ const PROVIDER_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
17
+ /**
18
+ * Provider transport retries; distinct from runner-owned model-call budget.
19
+ *
20
+ * Rate limits and 5xx bursts are the dominant cause of spurious agent-step
21
+ * failures, and the SDK only retries errors the provider marked retryable,
22
+ * honoring `retry-after` before its own exponential backoff. Raising the SDK
23
+ * default of 2 costs nothing on a healthy provider: `timeout` below is merged
24
+ * into the signal the retry loop waits on, so the step deadline — not the
25
+ * attempt count — bounds the whole chain.
26
+ */
27
+ const TRANSPORT_RETRIES = 5;
28
+ /** Creates the adapter for one resolved model, or fails with MODEL_UNAVAILABLE. */
29
+ export function createModelAdapter(model) {
30
+ if (model === undefined) {
31
+ throw new AgentError('MODEL_UNAVAILABLE', 'the agent fixture requires model configuration: set agent.model or E2E_MODEL');
32
+ }
33
+ const { endpoint, flavor } = validateModel(model);
34
+ const adapterVersion = packageVersion(import.meta.url, '../../../package.json', '0.0.0');
35
+ // The AI SDK is an optional peer: the language model is constructed on the
36
+ // first call, after the loader has resolved (or clearly refused) it.
37
+ let languageModel;
38
+ return {
39
+ provenance: {
40
+ provider: model.provider,
41
+ model: model.id,
42
+ endpoint,
43
+ adapterVersion: `${flavor}/${adapterVersion}`,
44
+ },
45
+ async generate(call) {
46
+ const { generateText, jsonSchema, Output } = await loadAiSdk();
47
+ languageModel ??= instantiate(model).languageModel;
48
+ const images = call.images ?? [];
49
+ const inputBound = tokenUpperBound(call.system) +
50
+ tokenUpperBound(call.prompt) +
51
+ images.reduce((total, image) => total + imageTokenUpperBound(image), 0);
52
+ if (inputBound > call.maxInputTokens) {
53
+ throw new AgentError('STEP_BUDGET_EXHAUSTED', `model input upper bound ${inputBound} exceeds limits.maxModelTokensPerCall ${call.maxInputTokens}`);
54
+ }
55
+ let issue;
56
+ const schema = call.schema;
57
+ const settings = {
58
+ model: languageModel,
59
+ system: call.system,
60
+ // Text-only calls keep the plain prompt form; images require the
61
+ // multi-part message form, and both must carry the same instruction
62
+ // text in the same position relative to the system policy.
63
+ ...(images.length === 0
64
+ ? { prompt: call.prompt }
65
+ : { messages: [userMessage(call.prompt, images)] }),
66
+ maxOutputTokens: call.maxOutputTokens,
67
+ temperature: 0,
68
+ maxRetries: TRANSPORT_RETRIES,
69
+ abortSignal: call.signal,
70
+ timeout: call.timeoutMs,
71
+ };
72
+ try {
73
+ if (schema === undefined) {
74
+ const result = await generateText(settings);
75
+ const parsed = parseJsonObject(result.text);
76
+ const validation = call.validate(parsed);
77
+ if (!validation.ok) {
78
+ throw new ModelOutputInvalidError(validation.issue, { rawText: result.text });
79
+ }
80
+ return { value: validation.value, usage: readUsage(result, inputBound) };
81
+ }
82
+ const result = await generateText({
83
+ ...settings,
84
+ output: Output.object({
85
+ schema: jsonSchema(schema, {
86
+ validate: (value) => {
87
+ const validation = call.validate(value);
88
+ if (validation.ok)
89
+ return { success: true, value: validation.value };
90
+ issue = validation.issue;
91
+ return { success: false, error: new Error(validation.issue) };
92
+ },
93
+ }),
94
+ name: call.schemaName,
95
+ }),
96
+ });
97
+ const output = result.output;
98
+ if (output === undefined) {
99
+ throw new ModelOutputInvalidError('provider returned no structured output');
100
+ }
101
+ return { value: output, usage: readUsage(result, inputBound) };
102
+ }
103
+ catch (cause) {
104
+ throw translateModelError(cause, issue, call.signal);
105
+ }
106
+ },
107
+ };
108
+ }
109
+ /**
110
+ * Builds the one user message of a vision call: instruction text first, then
111
+ * the image parts it refers to, so the text framing the pixels as data is read
112
+ * before them.
113
+ */
114
+ function userMessage(prompt, images) {
115
+ return {
116
+ role: 'user',
117
+ content: [
118
+ { type: 'text', text: prompt },
119
+ // A file part with an image media type, not the deprecated `image` part.
120
+ ...images.map((image) => ({
121
+ type: 'file',
122
+ data: image.data,
123
+ mediaType: image.mediaType,
124
+ })),
125
+ ],
126
+ };
127
+ }
128
+ /**
129
+ * Builds the bare AI SDK language model for one resolved model reference, for
130
+ * callers that drive the SDK directly (the default step executor) rather than
131
+ * through the adapter. Fails with MODEL_UNAVAILABLE exactly like the adapter.
132
+ * Gateway references require the AI SDK to be loaded (loadAiSdk) first; model
133
+ * instances never touch it.
134
+ */
135
+ export function instantiateLanguageModel(model) {
136
+ return instantiate(model).languageModel;
137
+ }
138
+ /**
139
+ * Validates one resolved model and derives its report provenance without
140
+ * touching the AI SDK, so an adapter can be constructed — and refuse clearly —
141
+ * before the optional peer dependency is ever loaded.
142
+ */
143
+ function validateModel(model) {
144
+ if (model.kind === 'instance') {
145
+ // The instance owns its transport; the report records that the endpoint is
146
+ // whatever the provider package defaults to.
147
+ return { endpoint: 'provider-default', flavor: 'ai-sdk' };
148
+ }
149
+ if (!PROVIDER_PATTERN.test(model.provider)) {
150
+ throw new AgentError('MODEL_UNAVAILABLE', `unknown model provider "${model.provider}"; expected a gateway provider ID or an AI SDK model instance`);
151
+ }
152
+ if (model.apiKey === undefined) {
153
+ throw new AgentError('MODEL_UNAVAILABLE', `no model credential: set ${model.apiKeyEnv} or ${GATEWAY_API_KEY_ENV}`);
154
+ }
155
+ return { endpoint: model.endpoint ?? DEFAULT_GATEWAY_ENDPOINT, flavor: 'ai-gateway' };
156
+ }
157
+ /** Builds the AI SDK language model for one validated resolved model. */
158
+ function instantiate(model) {
159
+ if (model.kind === 'instance')
160
+ return { languageModel: model.model };
161
+ const { endpoint } = validateModel(model);
162
+ const gateway = aiSdk().createGateway({ apiKey: model.apiKey, baseURL: endpoint });
163
+ return { languageModel: gateway.languageModel(`${model.provider}/${model.id}`) };
164
+ }
165
+ function readUsage(result, inputBound) {
166
+ const inputTokens = result.usage?.inputTokens;
167
+ const outputTokens = result.usage?.outputTokens;
168
+ const estimatedCostUsd = readCost(result.providerMetadata);
169
+ if (typeof inputTokens === 'number' && typeof outputTokens === 'number') {
170
+ return { inputTokens, outputTokens, accounting: 'provider', estimatedCostUsd };
171
+ }
172
+ return {
173
+ inputTokens: inputBound,
174
+ outputTokens: tokenUpperBound(result.text ?? ''),
175
+ accounting: 'adapter-upper-bound',
176
+ estimatedCostUsd,
177
+ };
178
+ }
179
+ /**
180
+ * Parses exactly one JSON object from response text, tolerating a code fence.
181
+ * Model text is never evaluated as code.
182
+ */
183
+ function parseJsonObject(text) {
184
+ const trimmed = text.trim();
185
+ const fenced = /^```(?:json)?\s*([\s\S]*?)```$/.exec(trimmed);
186
+ const body = (fenced?.[1] ?? trimmed).trim();
187
+ try {
188
+ return JSON.parse(body);
189
+ }
190
+ catch (cause) {
191
+ throw new ModelOutputInvalidError('response text is not a single JSON value', {
192
+ rawText: text,
193
+ cause,
194
+ });
195
+ }
196
+ }
197
+ /**
198
+ * The AI Gateway reports per-request cost in provider metadata when available;
199
+ * other providers simply lack the key. `cost` is what the gateway bills; BYOK
200
+ * routes bill the provider key directly and report `cost: "0"`, so fall back
201
+ * to `marketCost`, the list-price estimate of the same request.
202
+ */
203
+ export function readCost(metadata) {
204
+ const billed = parseCost(metadata?.['gateway']?.['cost']);
205
+ if (billed !== undefined && billed > 0)
206
+ return billed;
207
+ return parseCost(metadata?.['gateway']?.['marketCost']) ?? billed;
208
+ }
209
+ function parseCost(raw) {
210
+ const cost = typeof raw === 'string' ? Number(raw) : raw;
211
+ return typeof cost === 'number' && Number.isFinite(cost) && cost >= 0 ? cost : undefined;
212
+ }
213
+ /**
214
+ * Maps adapter and provider failures onto the closed agent error set. Runs
215
+ * only after `generate` loaded the SDK, so the cached module is available for
216
+ * the error-class checks.
217
+ */
218
+ function translateModelError(rawCause, issue, signal) {
219
+ const { APICallError, NoObjectGeneratedError } = aiSdk();
220
+ const cause = unwrapRetry(rawCause);
221
+ if (cause instanceof AgentError)
222
+ return cause;
223
+ // Only an aborted attempt is a cancellation. A request that exceeded the
224
+ // remaining step budget is a timeout, which is a test failure (06-cli.md).
225
+ if (signal.aborted) {
226
+ return new AgentError('CANCELLED', 'model call cancelled', { cause });
227
+ }
228
+ if (isAbort(cause)) {
229
+ return new AgentError('STEP_TIMEOUT', 'model call exceeded the remaining step timeout', { cause });
230
+ }
231
+ if (NoObjectGeneratedError.isInstance(cause)) {
232
+ return new ModelOutputInvalidError(issue ?? 'provider response did not match the closed response grammar', { ...(cause.text !== undefined ? { rawText: cause.text } : {}), cause });
233
+ }
234
+ if (APICallError.isInstance(cause)) {
235
+ return new AgentError('MODEL_PROVIDER_FAILED', `model provider failed: ${cause.message}`, {
236
+ cause,
237
+ });
238
+ }
239
+ return new AgentError('MODEL_PROVIDER_FAILED', `model provider failed: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
240
+ }
241
+ /**
242
+ * Unwraps a spent transport retry chain to the attempt that actually failed,
243
+ * because the wrapper's message names the retry reason rather than the failure.
244
+ * A chain cut short by the deadline stays wrapped so it classifies as an abort.
245
+ */
246
+ function unwrapRetry(cause) {
247
+ const { RetryError } = aiSdk();
248
+ if (!RetryError.isInstance(cause) || cause.reason === 'abort')
249
+ return cause;
250
+ return cause.lastError ?? cause;
251
+ }
252
+ function isAbort(cause) {
253
+ const { RetryError } = aiSdk();
254
+ if (RetryError.isInstance(cause) && cause.reason === 'abort')
255
+ return true;
256
+ return cause instanceof Error && (cause.name === 'AbortError' || cause.name === 'TimeoutError');
257
+ }
258
+ //# sourceMappingURL=sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../../src/agent/model/sdk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /** Observation capture, redaction, and model serialization (spec 09-drivers.md, 14-security.md). */
2
+ import type { Observation, ObservationPixels, SemanticNode } from '../backend/surface.ts';
3
+ /** Why pixels the caller asked for are not part of this observation. */
4
+ type PixelsWithheld = 'MASKING_UNPROVEN';
5
+ /** Masked pixel evidence cleared for model input. */
6
+ export interface AgentPixels extends ObservationPixels {
7
+ readonly maskedRegionCount: number;
8
+ readonly bytes: number;
9
+ }
10
+ export interface AgentObservation {
11
+ readonly revision: string;
12
+ /** Redacted, size-bounded serialization sent to the model. */
13
+ readonly text: string;
14
+ readonly bytes: number;
15
+ readonly nodes: ReadonlyMap<string, SemanticNode>;
16
+ readonly viewport: {
17
+ readonly width: number;
18
+ readonly height: number;
19
+ readonly scale: number;
20
+ };
21
+ readonly truncated: boolean;
22
+ /** Present only when the backend captured pixels and masking checks out. */
23
+ readonly pixels?: AgentPixels | undefined;
24
+ /** Set when captured pixels were dropped instead of being sent. */
25
+ readonly pixelsWithheld?: PixelsWithheld | undefined;
26
+ }
27
+ /**
28
+ * Turns one raw backend observation into redacted model input.
29
+ *
30
+ * Pixels whose masking the backend cannot prove (fewer masked regions than
31
+ * secure nodes) are withheld before they reach a model or disk; the semantic
32
+ * tree never carries secure values. Registered secret values are additionally
33
+ * replaced by their stable secret name.
34
+ */
35
+ export declare function prepareObservation(observation: Observation, options: {
36
+ redact: (text: string) => string;
37
+ maxBytes: number;
38
+ testIdAttribute: string;
39
+ }): AgentObservation;
40
+ /**
41
+ * What the screen looks like, independent of which observation looked at it.
42
+ *
43
+ * Two things are dropped. Node ids, because they are minted per observation, so
44
+ * two looks at a screen that has not moved would never render identically. And
45
+ * the focus state, because focus moves on its own — the platform settling it
46
+ * after load, a script claiming it, a widget stealing it — without the screen
47
+ * having changed in any way a judgment could answer differently about. Leaving
48
+ * it in meant a genuinely static screen could still spend a second model call.
49
+ *
50
+ * Lives next to `formatNode` so the line grammar keeps one owner.
51
+ */
52
+ export declare function observationShape(observation: AgentObservation): string;
53
+ /** What a settle loop needs from its step: the remaining clock and cancellation. */
54
+ interface SettleClock {
55
+ remainingMs(): number;
56
+ readonly signal: AbortSignal;
57
+ }
58
+ /**
59
+ * Captures until the screen shape holds still, bounded by a short ceiling and
60
+ * the step clock. An observation taken right after an action can be a
61
+ * snapshot the app is still reacting to — a fetch-backed mutation re-renders
62
+ * long after the action resolves — and acting or judging on it repeats
63
+ * actions and passes steps on pre-render state. The executor-facing observe
64
+ * (act.ts) settles through this loop, and replay's pre-action looks and the
65
+ * cache session's probes reach it through that same observe, so the pacing
66
+ * can never drift between them.
67
+ */
68
+ export declare function settleObservation<T>(capture: () => Promise<T>, shapeOf: (value: T) => string, clock: SettleClock): Promise<T>;
69
+ export {};
70
+ //# sourceMappingURL=observation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../../src/agent/observation.ts"],"names":[],"mappings":"AAAA,oGAAoG;AAEpG,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAO1F,wEAAwE;AACxE,KAAK,cAAc,GAAG,kBAAkB,CAAC;AAEzC,qDAAqD;AACrD,MAAM,WAAW,WAAY,SAAQ,iBAAiB;IACpD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAClD,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/F,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC1C,mEAAmE;IACnE,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;CACtD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE;IACP,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;CACzB,GACA,gBAAgB,CA6ClB;AAiED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,gBAAgB,GAAG,MAAM,CAOtE;AAMD,oFAAoF;AACpF,UAAU,WAAW;IACnB,WAAW,IAAI,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,EAC7B,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,CAAC,CAAC,CAaZ"}
@@ -0,0 +1,174 @@
1
+ /** Observation capture, redaction, and model serialization (spec 09-drivers.md, 14-security.md). */
2
+ import { collapseText } from '../internal/text.js';
3
+ import { sleep } from '../internal/time.js';
4
+ /** Appended when the node walk stopped at the observation byte budget. */
5
+ const TRUNCATION_MARKER = '[observation truncated at the resolved observation byte limit]';
6
+ /**
7
+ * Turns one raw backend observation into redacted model input.
8
+ *
9
+ * Pixels whose masking the backend cannot prove (fewer masked regions than
10
+ * secure nodes) are withheld before they reach a model or disk; the semantic
11
+ * tree never carries secure values. Registered secret values are additionally
12
+ * replaced by their stable secret name.
13
+ */
14
+ export function prepareObservation(observation, options) {
15
+ const nodes = new Map();
16
+ indexNodes(observation.tree, nodes);
17
+ const redact = options.redact;
18
+ const lines = [];
19
+ const encoder = new TextEncoder();
20
+ // The marker is reserved up front so a truncated observation still fits the
21
+ // budget; the budget is what keeps the request under the token ceiling.
22
+ const markerBytes = encoder.encode(`${TRUNCATION_MARKER}\n`).byteLength;
23
+ const budget = Math.max(0, options.maxBytes - markerBytes);
24
+ let bytes = 0;
25
+ let truncated = false;
26
+ const emit = (node, depth) => {
27
+ if (truncated)
28
+ return;
29
+ const line = formatNode(node, depth, redact, options.testIdAttribute);
30
+ const size = encoder.encode(`${line}\n`).byteLength;
31
+ if (lines.length > 0 && bytes + size > budget) {
32
+ truncated = true;
33
+ return;
34
+ }
35
+ bytes += size;
36
+ lines.push(line);
37
+ for (const child of node.children ?? [])
38
+ emit(child, depth + 1);
39
+ };
40
+ emit(observation.tree, 0);
41
+ if (truncated)
42
+ lines.push(TRUNCATION_MARKER);
43
+ const text = lines.join('\n');
44
+ // Every emitted line was measured with its newline; the join has one fewer
45
+ // and the marker was measured up front, so the size is known without a
46
+ // second pass over the whole tree text.
47
+ const textBytes = Math.max(0, bytes + (truncated ? markerBytes : 0) - 1);
48
+ const pixels = clearPixels(observation);
49
+ return {
50
+ revision: observation.revision,
51
+ text,
52
+ bytes: textBytes,
53
+ nodes,
54
+ viewport: observation.viewport,
55
+ truncated,
56
+ ...(pixels.cleared === undefined ? {} : { pixels: pixels.cleared }),
57
+ ...(pixels.withheld === undefined ? {} : { pixelsWithheld: pixels.withheld }),
58
+ };
59
+ }
60
+ /**
61
+ * Clears captured pixels for model input, or withholds them.
62
+ *
63
+ * Every secure node the backend observed must be covered by a masked region.
64
+ * When it is not, the backend masked less than it saw and the image cannot be
65
+ * proven redacted, so it is dropped exactly like an incompletely redacted
66
+ * artifact (14-security.md) — the semantic tree still goes out.
67
+ */
68
+ function clearPixels(observation) {
69
+ const pixels = observation.pixels;
70
+ if (pixels === undefined)
71
+ return {};
72
+ const { secureNodeCount, maskedRegionCount } = observation.redaction;
73
+ if (maskedRegionCount < secureNodeCount)
74
+ return { withheld: 'MASKING_UNPROVEN' };
75
+ return { cleared: { ...pixels, maskedRegionCount, bytes: pixels.data.byteLength } };
76
+ }
77
+ /** Depth beyond this renders flat; deep chrome must not buy tokens with spaces. */
78
+ const MAX_INDENT_DEPTH = 10;
79
+ /**
80
+ * Renders one node as `#id role "name" text="..." [states]`. Role-less text
81
+ * holders omit the role token entirely: on a large screen they are half the
82
+ * lines, and the model needs their text, not a filler word.
83
+ */
84
+ function formatNode(node, depth, redact, testIdAttribute) {
85
+ const parts = [`#${node.ref.id}`];
86
+ if (node.role !== undefined && node.role !== '')
87
+ parts.push(node.role);
88
+ if (node.name !== undefined && node.name !== '')
89
+ parts.push(JSON.stringify(redact(node.name)));
90
+ const text = node.text === undefined ? '' : collapseText(node.text);
91
+ if (text !== '' && text !== node.name)
92
+ parts.push(`text=${JSON.stringify(redact(text))}`);
93
+ // Disambiguators the model needs when role and name repeat. The backend has
94
+ // already reduced href to origin and path.
95
+ const testId = node.attributes?.[testIdAttribute];
96
+ if (testId !== undefined && testId !== '')
97
+ parts.push(`testid=${JSON.stringify(testId)}`);
98
+ const href = node.attributes?.['href'];
99
+ if (href !== undefined && href !== '')
100
+ parts.push(`href=${JSON.stringify(redact(href))}`);
101
+ const placeholder = node.attributes?.['placeholder'];
102
+ if (placeholder !== undefined && placeholder !== '' && (node.name ?? '') === '') {
103
+ parts.push(`placeholder=${JSON.stringify(redact(placeholder))}`);
104
+ }
105
+ if (node.states?.secure === true) {
106
+ parts.push('value=<secure>');
107
+ }
108
+ else if (node.value !== undefined && node.value !== '') {
109
+ parts.push(`value=${JSON.stringify(redact(node.value))}`);
110
+ }
111
+ if (node.inputPurpose !== undefined && node.inputPurpose !== 'none') {
112
+ parts.push(`purpose=${node.inputPurpose}`);
113
+ }
114
+ const states = Object.entries(node.states ?? {})
115
+ .filter(([, value]) => value === true)
116
+ .map(([key]) => key);
117
+ if (states.length > 0)
118
+ parts.push(`[${states.join(' ')}]`);
119
+ return `${' '.repeat(Math.min(depth, MAX_INDENT_DEPTH))}${parts.join(' ')}`;
120
+ }
121
+ /**
122
+ * What the screen looks like, independent of which observation looked at it.
123
+ *
124
+ * Two things are dropped. Node ids, because they are minted per observation, so
125
+ * two looks at a screen that has not moved would never render identically. And
126
+ * the focus state, because focus moves on its own — the platform settling it
127
+ * after load, a script claiming it, a widget stealing it — without the screen
128
+ * having changed in any way a judgment could answer differently about. Leaving
129
+ * it in meant a genuinely static screen could still spend a second model call.
130
+ *
131
+ * Lives next to `formatNode` so the line grammar keeps one owner.
132
+ */
133
+ export function observationShape(observation) {
134
+ return observation.text
135
+ .replaceAll(/(^|\n)(\s*)#\S+/g, '$1$2')
136
+ .replaceAll(/ \[([^\]]*)\]/g, (_match, states) => {
137
+ const stable = states.split(' ').filter((state) => state !== 'focused');
138
+ return stable.length === 0 ? '' : ` [${stable.join(' ')}]`;
139
+ });
140
+ }
141
+ /** Poll interval and ceiling for shape-stability settling. */
142
+ const SETTLE_POLL_MS = 75;
143
+ const SETTLE_TIMEOUT_MS = 1_000;
144
+ /**
145
+ * Captures until the screen shape holds still, bounded by a short ceiling and
146
+ * the step clock. An observation taken right after an action can be a
147
+ * snapshot the app is still reacting to — a fetch-backed mutation re-renders
148
+ * long after the action resolves — and acting or judging on it repeats
149
+ * actions and passes steps on pre-render state. The executor-facing observe
150
+ * (act.ts) settles through this loop, and replay's pre-action looks and the
151
+ * cache session's probes reach it through that same observe, so the pacing
152
+ * can never drift between them.
153
+ */
154
+ export async function settleObservation(capture, shapeOf, clock) {
155
+ let value = await capture();
156
+ let shape = shapeOf(value);
157
+ const deadlineMs = Date.now() + SETTLE_TIMEOUT_MS;
158
+ while (Date.now() < deadlineMs && clock.remainingMs() > SETTLE_POLL_MS) {
159
+ await sleep(SETTLE_POLL_MS, clock.signal);
160
+ value = await capture();
161
+ const next = shapeOf(value);
162
+ const stable = next === shape;
163
+ shape = next;
164
+ if (stable)
165
+ break;
166
+ }
167
+ return value;
168
+ }
169
+ function indexNodes(node, into) {
170
+ into.set(node.ref.id, node);
171
+ for (const child of node.children ?? [])
172
+ indexNodes(child, into);
173
+ }
174
+ //# sourceMappingURL=observation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observation.js","sourceRoot":"","sources":["../../src/agent/observation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Shared per-phase machinery for agent step execution. `Invocation` (the
3
+ * locate/judgment tier) and `ActDispatch` (the executor socket) both compose
4
+ * these, so event recording, `--debug` buckets, tracing, deadline semantics,
5
+ * and observation race-hardening cannot drift between the two paths.
6
+ */
7
+ import { type Observation, type OperationContext } from '../backend/surface.ts';
8
+ import type { DebugTrace } from '../internal/debug.ts';
9
+ import { type Deadline } from '../internal/time.ts';
10
+ import type { LocatorEngine } from '../locator/engine.ts';
11
+ import type { StepEvent, StepRecorder } from '../run/steps.ts';
12
+ /**
13
+ * One backend operation's budget: `actionTimeout`, capped by the step clock.
14
+ * Bounding each call independently is what keeps a single screen that never
15
+ * settles from consuming the whole step: the hang costs one action timeout and
16
+ * a clearly attributed failure, not the test budget.
17
+ */
18
+ export declare function boundedOperation(engine: LocatorEngine, actionTimeout: number, deadline: Deadline): OperationContext;
19
+ /** Records one policy decision as a child event of the current step. */
20
+ export declare function recordPolicyEvent(steps: StepRecorder, name: string, decision: 'allowed' | 'denied', code?: string): void;
21
+ /** The step recorder and optional debug trace a phase reports into. */
22
+ export interface PhaseHost {
23
+ readonly steps: StepRecorder;
24
+ readonly debug?: DebugTrace | undefined;
25
+ }
26
+ /** One instrumented phase: the event kind it records and the debug bucket it feeds. */
27
+ export interface PhaseSpec {
28
+ /** Public API name of the enclosing step, e.g. `agent.assert`. */
29
+ readonly api: string;
30
+ readonly kind: StepEvent['kind'];
31
+ readonly phase: 'agent.observe' | 'agent.model' | 'agent.action' | 'agent.cache';
32
+ readonly name?: string;
33
+ }
34
+ /**
35
+ * Runs one phase with uniform accounting: a child event on success and
36
+ * failure, one debug bucket, and translation onto the closed agent error set.
37
+ * Every observe/model/action phase of every agent step goes through here so
38
+ * the records cannot drift apart.
39
+ */
40
+ export declare function instrumentPhase<Value>(host: PhaseHost, spec: PhaseSpec, body: () => Promise<Value>, detail?: (value: Value) => Partial<StepEvent>): Promise<Value>;
41
+ /**
42
+ * Fails when the step clock has run out.
43
+ *
44
+ * `cause` carries the failure that was being handled when the clock was found
45
+ * to be out, so a step that timed out mid-operation still says what the
46
+ * operation reported.
47
+ */
48
+ export declare function checkStepClock(options: {
49
+ readonly signal: AbortSignal;
50
+ readonly deadline: Deadline;
51
+ readonly api: string;
52
+ readonly timeoutMs: number;
53
+ readonly cause?: unknown;
54
+ }): void;
55
+ /**
56
+ * Captures one raw observation, re-capturing while the backend reports a
57
+ * retryable failure and the step clock allows. A screen that navigates as it is
58
+ * read (a redirect, a hydration swap, a form submit still committing) makes
59
+ * the capture lose its document; that is a race, not a broken app, so it is
60
+ * re-read rather than surfaced as a failed call. `guard` is the caller's
61
+ * clock check, so a capture that outlives the deadline reports the step's own
62
+ * timeout rather than whichever transport error the truncated budget produced.
63
+ */
64
+ export declare function retryingObserve(options: {
65
+ readonly observe: (operation: OperationContext) => Promise<Observation>;
66
+ readonly operation: () => OperationContext;
67
+ readonly guard: (cause?: unknown) => void;
68
+ readonly signal: AbortSignal;
69
+ readonly api: string;
70
+ }): Promise<Observation>;
71
+ //# sourceMappingURL=phases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phases.d.ts","sourceRoot":"","sources":["../../src/agent/phases.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAgB,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGvD,OAAO,EAA2B,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/D;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,aAAa,EACrB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,QAAQ,GACjB,gBAAgB,CAElB;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,SAAS,GAAG,QAAQ,EAC9B,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CAUN;AAED,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACzC;AAED,uFAAuF;AACvF,MAAM,WAAW,SAAS;IACxB,kEAAkE;IAClE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,aAAa,GAAG,cAAc,GAAG,aAAa,CAAC;IACjF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,KAAK,EACzC,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,EAC1B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,SAAS,CAAC,GAC5C,OAAO,CAAC,KAAK,CAAC,CAyChB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,IAAI,CAYP;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE;IAC7C,QAAQ,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,gBAAgB,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IACxE,QAAQ,CAAC,SAAS,EAAE,MAAM,gBAAgB,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,WAAW,CAAC,CAevB"}