@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,331 @@
1
+ /**
2
+ * The tool-loop chassis (RFC0001, layer 4): everything an AI SDK step
3
+ * executor needs except its tool vocabulary. `createAgent` is this chassis
4
+ * plus the grammar toolset; a device or API executor brings different
5
+ * tools and inherits the whole discipline unchanged:
6
+ *
7
+ * - the `complete_step` verdict tool and the closed blocked-code policy;
8
+ * - hard-stop handling (budget/timeout/cancel end the loop, never the model);
9
+ * - loop guards (repeated calls and short cycles warn, then force a verdict);
10
+ * - the wind-down notice and forced conclusion on the final turns;
11
+ * - model-call accounting and a step transcript for `--debug`.
12
+ */
13
+ import { z } from 'zod';
14
+ import { asSdkLanguageModel } from '../config/agent.js';
15
+ import { loadAiSdk } from './ai-sdk.js';
16
+ import { readCost } from './model/sdk.js';
17
+ import { AgentError, isAgentError } from './error.js';
18
+ import { BLOCKABLE_CODES, RUNTIME_CODES, } from './executor.js';
19
+ import { checkLoopGuards, extractGuardCalls } from './loop-guards.js';
20
+ /** Codes the model may pick when concluding; runtime codes are runtime-assigned. */
21
+ const MODEL_ERROR_CODES = [
22
+ 'ACTION_FAILED',
23
+ 'AUTOMATION_UNSUPPORTED',
24
+ 'ASSERTION_FAILED',
25
+ 'AUTHENTICATION_FAILED',
26
+ 'AUTH_CREDENTIAL_UNAVAILABLE',
27
+ 'AUTH_CREDENTIAL_INVALID',
28
+ 'ENVIRONMENT_UNAVAILABLE',
29
+ 'SEED_DATA_MISSING',
30
+ 'TEST_SETUP_FAILED',
31
+ 'APP_UNREACHABLE',
32
+ 'APP_NOT_OPEN',
33
+ 'POLICY_DENIED',
34
+ ];
35
+ /** The model-pickable codes a blocked verdict accepts; derived, never restated. */
36
+ const MODEL_BLOCKABLE_CODES = MODEL_ERROR_CODES.filter((code) => BLOCKABLE_CODES.has(code));
37
+ const VERDICT_RULES = `Verdict rules:
38
+ - When the step's goal is achieved, or you are certain it cannot be, call complete_step exactly once.
39
+ - Verify outcomes with your tools before concluding; never guess success.
40
+ - "passed" means the application behaved as the step required. "failed" means it did not. "blocked" means credentials, the environment, or test setup prevented a product verdict — blocked says nothing about the product and requires an errorCode.`;
41
+ /** Turns remaining when the loop warns the model to wrap up. */
42
+ const WIND_DOWN_TURNS = 5;
43
+ /**
44
+ * Ceiling on the remaining step time under which the loop takes the verdict it
45
+ * can get. A slow provider turn runs tens of seconds; concluding with the
46
+ * model's own summary beats a verdict-less STEP_TIMEOUT every time. The
47
+ * effective window is a quarter of the step's budget, capped here, so a short
48
+ * step keeps most of its clock for work instead of losing half of it to the
49
+ * wind-down.
50
+ */
51
+ const CLOCK_WIND_DOWN_MS = 60_000;
52
+ const CLOCK_WIND_DOWN_FRACTION = 4;
53
+ /** Transcript ceiling per step; enough for every turn without unbounded logs. */
54
+ const MAX_TRANSCRIPT_CHARS = 262_144;
55
+ /** Builds a step executor from a tool vocabulary and the shared loop chassis. */
56
+ export function createToolLoopExecutor(options) {
57
+ return {
58
+ name: options.name,
59
+ ...(options.version === undefined ? {} : { version: options.version }),
60
+ async runStep(context) {
61
+ // The AI SDK is an optional peer; load it before anything touches it —
62
+ // including the context's gateway-model getter below.
63
+ const ai = await loadAiSdk();
64
+ // The context's model getter resolves the configured model on read, so
65
+ // an executor that brought its own never touches (or fails on) it.
66
+ const model = options.model ??
67
+ (context.model === undefined ? undefined : asSdkLanguageModel(context.model));
68
+ if (model === undefined) {
69
+ throw new AgentError('MODEL_UNAVAILABLE', `the "${options.name}" executor requires a model: set agent.model, E2E_MODEL, or pass one to the executor`);
70
+ }
71
+ const loop = new LoopRun(ai, options, context, model);
72
+ return loop.run();
73
+ },
74
+ };
75
+ }
76
+ /** One step's loop state and wiring; constructed fresh per runStep. */
77
+ class LoopRun {
78
+ ai;
79
+ options;
80
+ context;
81
+ model;
82
+ verdict;
83
+ hardStop;
84
+ guardStop;
85
+ noticedGuardReason;
86
+ noticedLowClock = false;
87
+ transcript = [];
88
+ maxTurns;
89
+ windDownMs;
90
+ constructor(ai, options, context, model) {
91
+ this.ai = ai;
92
+ this.options = options;
93
+ this.context = context;
94
+ this.model = model;
95
+ // Capped, never raised: the harness budget is the ceiling for any turns
96
+ // setting, so the loop cannot spend past what the step was given.
97
+ this.maxTurns = Math.min(options.maxTurns ?? context.budgets.maxModelCalls, context.budgets.maxModelCalls);
98
+ this.windDownMs = Math.min(CLOCK_WIND_DOWN_MS, Math.floor(context.budgets.remainingMs() / CLOCK_WIND_DOWN_FRACTION));
99
+ }
100
+ async run() {
101
+ const helpers = this.helpers();
102
+ const tools = {
103
+ ...this.options.tools(this.context, helpers),
104
+ complete_step: this.concludeTool(),
105
+ };
106
+ const loop = new this.ai.ToolLoopAgent({
107
+ model: this.model,
108
+ instructions: this.instructions(),
109
+ tools,
110
+ toolChoice: 'required',
111
+ stopWhen: [
112
+ () => this.verdict !== undefined || this.hardStop !== undefined,
113
+ this.ai.stepCountIs(this.maxTurns),
114
+ ],
115
+ prepareStep: ({ messages, stepNumber }) => this.prepareTurn(messages, stepNumber),
116
+ });
117
+ const identity = this.model;
118
+ const prompt = await this.options.buildPrompt(this.context);
119
+ let turnStartedMs = Date.now();
120
+ try {
121
+ await loop.generate({
122
+ prompt,
123
+ abortSignal: this.context.signal,
124
+ onStepStart: () => {
125
+ turnStartedMs = Date.now();
126
+ },
127
+ onStepEnd: (step) => {
128
+ this.recordTurn(step);
129
+ const estimatedCostUsd = readCost(step.providerMetadata);
130
+ this.context.budgets.recordModelCall({
131
+ ...(step.usage.inputTokens === undefined
132
+ ? {}
133
+ : { inputTokens: step.usage.inputTokens }),
134
+ ...(step.usage.outputTokens === undefined
135
+ ? {}
136
+ : { outputTokens: step.usage.outputTokens }),
137
+ durationMs: Date.now() - turnStartedMs,
138
+ ...(typeof identity.provider === 'string' ? { provider: identity.provider } : {}),
139
+ ...(typeof identity.modelId === 'string' ? { modelId: identity.modelId } : {}),
140
+ ...(estimatedCostUsd === undefined ? {} : { estimatedCostUsd }),
141
+ });
142
+ },
143
+ });
144
+ }
145
+ catch (cause) {
146
+ this.attachTranscript();
147
+ if (this.context.signal.aborted) {
148
+ throw new AgentError('CANCELLED', 'the step was cancelled', { cause });
149
+ }
150
+ if (this.hardStop !== undefined)
151
+ throw this.hardStop;
152
+ if (isAgentError(cause))
153
+ throw cause;
154
+ throw new AgentError('MODEL_PROVIDER_FAILED', `the model provider failed: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
155
+ }
156
+ this.attachTranscript();
157
+ if (this.verdict !== undefined)
158
+ return this.verdict;
159
+ if (this.hardStop !== undefined) {
160
+ if (this.hardStop.code === 'CANCELLED')
161
+ throw this.hardStop;
162
+ return { status: 'blocked', summary: this.hardStop.message, errorCode: this.hardStop.code };
163
+ }
164
+ return {
165
+ status: 'failed',
166
+ summary: `the agent used ${this.maxTurns} turn(s) without calling complete_step`,
167
+ errorCode: 'STEP_NO_CONCLUSION',
168
+ };
169
+ }
170
+ helpers() {
171
+ return {
172
+ concluding: () => this.verdict !== undefined || this.hardStop !== undefined,
173
+ reportHardStop: (error) => {
174
+ this.hardStop ??= error;
175
+ },
176
+ guard: async (body) => {
177
+ if (this.verdict !== undefined || this.hardStop !== undefined) {
178
+ return 'The step is already concluding; no further actions run.';
179
+ }
180
+ try {
181
+ return await body();
182
+ }
183
+ catch (cause) {
184
+ if (isAgentError(cause) && RUNTIME_CODES.has(cause.code)) {
185
+ this.hardStop ??= cause;
186
+ return `HARD STOP (${cause.code}): ${cause.message}`;
187
+ }
188
+ const message = cause instanceof Error ? cause.message : String(cause);
189
+ return `Action failed: ${message}`;
190
+ }
191
+ },
192
+ };
193
+ }
194
+ /**
195
+ * Per-turn policy, in order: compact history, evaluate the loop guards,
196
+ * inject the wind-down notice, and — near the budget or after a guard stop —
197
+ * offer only the conclusion tool. Two forced turns, not one, so a rejected
198
+ * verdict (blocked without a code) can be repaired.
199
+ */
200
+ prepareTurn(messages, stepNumber) {
201
+ let prepared = this.options.compactMessages?.(messages) ?? messages;
202
+ const turnsLeft = this.maxTurns - stepNumber;
203
+ // Never on the very first turn: a deliberately short step timeout still
204
+ // deserves one working turn before the clock takes the verdict.
205
+ const lowClock = stepNumber > 0 && this.context.budgets.remainingMs() < this.windDownMs;
206
+ if (lowClock && this.noticedLowClock !== true) {
207
+ this.noticedLowClock = true;
208
+ prepared = appendNotice(prepared, '[SYSTEM] The step is nearly out of time. Call complete_step now with your best ' +
209
+ 'verdict: passed only if you verified the goal, failed if the application ' +
210
+ 'misbehaved, blocked (with errorCode) if something outside the application ' +
211
+ 'stopped you.');
212
+ }
213
+ if (this.guardStop === undefined) {
214
+ const guard = checkLoopGuards(extractGuardCalls(prepared, 'complete_step'));
215
+ if (guard.kind === 'stop') {
216
+ this.guardStop = guard.reason;
217
+ }
218
+ else if (guard.kind === 'warn' && guard.reason !== this.noticedGuardReason) {
219
+ this.noticedGuardReason = guard.reason;
220
+ prepared = appendNotice(prepared, `[SYSTEM NOTICE] You appear to be going in circles: ${guard.reason}. ` +
221
+ 'Change approach, or call complete_step with your best verdict.');
222
+ }
223
+ }
224
+ if (this.guardStop !== undefined && this.guardStop !== this.noticedGuardReason) {
225
+ this.noticedGuardReason = this.guardStop;
226
+ prepared = appendNotice(prepared, `[SYSTEM] Loop guard: ${this.guardStop}. Repeating it further will not make progress. ` +
227
+ 'Call complete_step now with your best verdict: failed if the application misbehaved, ' +
228
+ 'blocked (with errorCode) if something outside the application stopped you.');
229
+ }
230
+ if (turnsLeft === WIND_DOWN_TURNS && this.guardStop === undefined) {
231
+ prepared = appendNotice(prepared, `[SYSTEM NOTICE] Only ${turnsLeft} turns remain for this step. ` +
232
+ 'Finish the remaining work now, or call complete_step with your best verdict: ' +
233
+ 'failed if the application misbehaved, blocked (with errorCode) if something ' +
234
+ 'outside the application stopped you.');
235
+ }
236
+ const forced = turnsLeft <= 2 || this.guardStop !== undefined || lowClock;
237
+ return {
238
+ ...(prepared === messages ? {} : { messages: prepared }),
239
+ ...(forced
240
+ ? {
241
+ activeTools: ['complete_step'],
242
+ toolChoice: { type: 'tool', toolName: 'complete_step' },
243
+ }
244
+ : {}),
245
+ };
246
+ }
247
+ concludeTool() {
248
+ const { tool } = this.ai;
249
+ return tool({
250
+ description: 'Conclude the step with the final verdict. passed = the application behaved as required and you verified it. failed = the application did not behave as required. blocked = credentials, environment, or test setup prevented a product verdict; blocked requires errorCode.',
251
+ inputSchema: z.object({
252
+ status: z.enum(['passed', 'failed', 'blocked']),
253
+ summary: z
254
+ .string()
255
+ .min(1)
256
+ .max(500)
257
+ .describe('What you did and what you saw, in plain language'),
258
+ errorCode: z.enum(MODEL_ERROR_CODES).optional(),
259
+ }),
260
+ execute: async (input) => {
261
+ if (this.verdict !== undefined)
262
+ return 'The step already concluded.';
263
+ if (input.status === 'blocked' &&
264
+ (input.errorCode === undefined ||
265
+ !MODEL_BLOCKABLE_CODES.includes(input.errorCode))) {
266
+ return ('Rejected: a blocked verdict requires errorCode naming what blocked you ' +
267
+ `(one of ${MODEL_BLOCKABLE_CODES.join(', ')}). ` +
268
+ 'If the application itself misbehaved, use status "failed" instead.');
269
+ }
270
+ this.verdict = {
271
+ status: input.status,
272
+ summary: input.summary,
273
+ // A passed verdict never carries a code; a redundant one from the
274
+ // model is dropped rather than failing the step.
275
+ ...(input.errorCode === undefined || input.status === 'passed'
276
+ ? {}
277
+ : { errorCode: input.errorCode }),
278
+ };
279
+ return 'Step concluded.';
280
+ },
281
+ });
282
+ }
283
+ instructions() {
284
+ const parts = [];
285
+ if (this.options.system !== undefined && this.options.system.trim() !== '') {
286
+ parts.push(this.options.system);
287
+ }
288
+ const project = this.context.agentContext;
289
+ if (project !== undefined && project.trim() !== '') {
290
+ parts.push(`Project context:\n${project}`);
291
+ }
292
+ parts.push(VERDICT_RULES);
293
+ return parts.join('\n\n');
294
+ }
295
+ /** Serializes one turn into the step transcript. */
296
+ recordTurn(step) {
297
+ const turn = this.transcript.length + 1;
298
+ const lines = [`--- turn ${turn} ---`];
299
+ if (step.text.trim() !== '')
300
+ lines.push(`assistant: ${truncate(step.text, 1_000)}`);
301
+ for (const call of step.toolCalls) {
302
+ lines.push(`tool call: ${call.toolName}(${truncate(safeJson(call.input), 400)})`);
303
+ }
304
+ for (const result of step.toolResults) {
305
+ lines.push(`tool result [${result.toolName}]: ${truncate(safeJson(result.output), 600)}`);
306
+ }
307
+ this.transcript.push(lines.join('\n'));
308
+ }
309
+ attachTranscript() {
310
+ if (this.transcript.length === 0)
311
+ return;
312
+ this.context.attachTranscript(truncate(this.transcript.join('\n'), MAX_TRANSCRIPT_CHARS));
313
+ }
314
+ }
315
+ function appendNotice(messages, content) {
316
+ return [...messages, { role: 'user', content }];
317
+ }
318
+ function truncate(text, max) {
319
+ return text.length <= max ? text : `${text.slice(0, max)}…[truncated]`;
320
+ }
321
+ function safeJson(value) {
322
+ if (typeof value === 'string')
323
+ return value;
324
+ try {
325
+ return JSON.stringify(value) ?? String(value);
326
+ }
327
+ catch {
328
+ return String(value);
329
+ }
330
+ }
331
+ //# sourceMappingURL=tool-loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-loop.js","sourceRoot":"","sources":["../../src/agent/tool-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAyB,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAc,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EACL,eAAe,EACf,aAAa,GAId,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEtE,oFAAoF;AACpF,MAAM,iBAAiB,GAAG;IACxB,eAAe;IACf,wBAAwB;IACxB,kBAAkB;IAClB,uBAAuB;IACvB,6BAA6B;IAC7B,yBAAyB;IACzB,yBAAyB;IACzB,mBAAmB;IACnB,mBAAmB;IACnB,iBAAiB;IACjB,cAAc;IACd,eAAe;CACP,CAAC;AAEX,mFAAmF;AACnF,MAAM,qBAAqB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AAE5F,MAAM,aAAa,GAAG;;;sPAGgO,CAAC;AAEvP,gEAAgE;AAChE,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B;;;;;;;GAOG;AACH,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAEnC,iFAAiF;AACjF,MAAM,oBAAoB,GAAG,OAAO,CAAC;AAoCrC,iFAAiF;AACjF,MAAM,UAAU,sBAAsB,CAAC,OAAgC;IACrE,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;QACtE,KAAK,CAAC,OAAO,CAAC,OAA4B;YACxC,uEAAuE;YACvE,sDAAsD;YACtD,MAAM,EAAE,GAAG,MAAM,SAAS,EAAE,CAAC;YAC7B,uEAAuE;YACvE,mEAAmE;YACnE,MAAM,KAAK,GACT,OAAO,CAAC,KAAK;gBACb,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YAChF,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,IAAI,UAAU,CAClB,mBAAmB,EACnB,QAAQ,OAAO,CAAC,IAAI,sFAAsF,CAC3G,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YACtD,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,MAAM,OAAO;IAWQ,EAAE;IACF,OAAO;IACP,OAAO;IACP,KAAK;IAbhB,OAAO,CAA0B;IACjC,QAAQ,CAAyB;IACjC,SAAS,CAAqB;IAC9B,kBAAkB,CAAqB;IACvC,eAAe,GAAG,KAAK,CAAC;IACf,UAAU,GAAa,EAAE,CAAC;IAC1B,QAAQ,CAAS;IACjB,UAAU,CAAS;IAEpC,YACmB,EAAS,EACT,OAAgC,EAChC,OAA4B,EAC5B,KAAoB;kBAHpB,EAAE;uBACF,OAAO;uBACP,OAAO;qBACP,KAAK;QAEtB,wEAAwE;QACxE,kEAAkE;QAClE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,CACtB,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,aAAa,EACjD,OAAO,CAAC,OAAO,CAAC,aAAa,CAC9B,CAAC;QACF,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CACxB,kBAAkB,EAClB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,wBAAwB,CAAC,CACrE,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,GAAG;QACP,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAY;YACrB,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC;YAC5C,aAAa,EAAE,IAAI,CAAC,YAAY,EAAE;SACnC,CAAC;QACF,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE;YACjC,KAAK;YACL,UAAU,EAAE,UAAU;YACtB,QAAQ,EAAE;gBACR,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAC/D,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC;aACnC;YACD,WAAW,EAAE,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC;SAClF,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAgD,CAAC;QACvE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5D,IAAI,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC;gBAClB,MAAM;gBACN,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;gBAChC,WAAW,EAAE,GAAG,EAAE;oBAChB,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC7B,CAAC;gBACD,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;oBAClB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;oBACtB,MAAM,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;oBACzD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC;wBACnC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS;4BACtC,CAAC,CAAC,EAAE;4BACJ,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;wBAC5C,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS;4BACvC,CAAC,CAAC,EAAE;4BACJ,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;wBAC9C,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa;wBACtC,GAAG,CAAC,OAAO,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACjF,GAAG,CAAC,OAAO,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC9E,GAAG,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC;qBAChE,CAAC,CAAC;gBACL,CAAC;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAChC,MAAM,IAAI,UAAU,CAAC,WAAW,EAAE,wBAAwB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YACzE,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAAE,MAAM,IAAI,CAAC,QAAQ,CAAC;YACrD,IAAI,YAAY,CAAC,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAC;YACrC,MAAM,IAAI,UAAU,CAClB,uBAAuB,EACvB,8BAA8B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EACtF,EAAE,KAAK,EAAE,CACV,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC;QACpD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,WAAW;gBAAE,MAAM,IAAI,CAAC,QAAQ,CAAC;YAC5D,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC9F,CAAC;QACD,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,kBAAkB,IAAI,CAAC,QAAQ,wCAAwC;YAChF,SAAS,EAAE,oBAAoB;SAChC,CAAC;IACJ,CAAC;IAEO,OAAO;QACb,OAAO;YACL,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;YAC3E,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE;gBACxB,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAC;YAC1B,CAAC;YACD,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACpB,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;oBAC9D,OAAO,yDAAyD,CAAC;gBACnE,CAAC;gBACD,IAAI,CAAC;oBACH,OAAO,MAAM,IAAI,EAAE,CAAC;gBACtB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;wBACzD,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAC;wBACxB,OAAO,cAAc,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;oBACvD,CAAC;oBACD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBACvE,OAAO,kBAAkB,OAAO,EAAE,CAAC;gBACrC,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACK,WAAW,CACjB,QAAwB,EACxB,UAAkB;QAMlB,IAAI,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC;QACpE,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC;QAC7C,wEAAwE;QACxE,gEAAgE;QAChE,MAAM,QAAQ,GAAG,UAAU,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC;QACxF,IAAI,QAAQ,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI,EAAE,CAAC;YAC9C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC5B,QAAQ,GAAG,YAAY,CACrB,QAAQ,EACR,iFAAiF;gBAC/E,2EAA2E;gBAC3E,4EAA4E;gBAC5E,cAAc,CACjB,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,eAAe,CAAC,iBAAiB,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;YAC5E,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC;YAChC,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC7E,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC,MAAM,CAAC;gBACvC,QAAQ,GAAG,YAAY,CACrB,QAAQ,EACR,sDAAsD,KAAK,CAAC,MAAM,IAAI;oBACpE,gEAAgE,CACnE,CAAC;YACJ,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC/E,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,SAAS,CAAC;YACzC,QAAQ,GAAG,YAAY,CACrB,QAAQ,EACR,wBAAwB,IAAI,CAAC,SAAS,iDAAiD;gBACrF,uFAAuF;gBACvF,4EAA4E,CAC/E,CAAC;QACJ,CAAC;QACD,IAAI,SAAS,KAAK,eAAe,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAClE,QAAQ,GAAG,YAAY,CACrB,QAAQ,EACR,wBAAwB,SAAS,+BAA+B;gBAC9D,+EAA+E;gBAC/E,8EAA8E;gBAC9E,sCAAsC,CACzC,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,QAAQ,CAAC;QAC1E,OAAO;YACL,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;YACxD,GAAG,CAAC,MAAM;gBACR,CAAC,CAAC;oBACE,WAAW,EAAE,CAAC,eAAe,CAAC;oBAC9B,UAAU,EAAE,EAAE,IAAI,EAAE,MAAe,EAAE,QAAQ,EAAE,eAAe,EAAE;iBACjE;gBACH,CAAC,CAAC,EAAE,CAAC;SACR,CAAC;IACJ,CAAC;IAEO,YAAY;QAClB,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;YACV,WAAW,EACT,6QAA6Q;YAC/Q,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;gBACpB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;gBAC/C,OAAO,EAAE,CAAC;qBACP,MAAM,EAAE;qBACR,GAAG,CAAC,CAAC,CAAC;qBACN,GAAG,CAAC,GAAG,CAAC;qBACR,QAAQ,CAAC,kDAAkD,CAAC;gBAC/D,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE;aAChD,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAmB,EAAE;gBACxC,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;oBAAE,OAAO,6BAA6B,CAAC;gBACrE,IACE,KAAK,CAAC,MAAM,KAAK,SAAS;oBAC1B,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS;wBAC5B,CAAC,qBAAqB,CAAC,QAAQ,CAC7B,KAAK,CAAC,SAAmD,CAC1D,CAAC,EACJ,CAAC;oBACD,OAAO,CACL,yEAAyE;wBACzE,WAAW,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;wBAChD,oEAAoE,CACrE,CAAC;gBACJ,CAAC;gBACD,IAAI,CAAC,OAAO,GAAG;oBACb,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,kEAAkE;oBAClE,iDAAiD;oBACjD,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ;wBAC5D,CAAC,CAAC,EAAE;wBACJ,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;iBACpC,CAAC;gBACF,OAAO,iBAAiB,CAAC;YAC3B,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAEO,YAAY;QAClB,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3E,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;QAC1C,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACnD,KAAK,CAAC,IAAI,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,oDAAoD;IAC5C,UAAU,CAAC,IAAyB;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QACxC,MAAM,KAAK,GAAa,CAAC,YAAY,IAAI,MAAM,CAAC,CAAC;QACjD,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,cAAc,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QACpF,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACpF,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,QAAQ,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5F,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACzC,CAAC;IAEO,gBAAgB;QACtB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACzC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAC5F,CAAC;CACF;AAED,SAAS,YAAY,CAAC,QAAwB,EAAE,OAAe;IAC7D,OAAO,CAAC,GAAG,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,GAAW;IACzC,OAAO,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC;AACzE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * `defineTool` (RFC0001, layer 2): an AI SDK tool plus the required semantic
3
+ * annotation. The annotation is what lets the harness treat a project tool as
4
+ * a first-class capability — replay eligibility, mutation tracking, and secret
5
+ * gating are declared, never inferred. A tool without declared semantics is
6
+ * excluded from caching and untrusted by default, which in v0 (no cache)
7
+ * reduces to: the annotation is required and recorded.
8
+ */
9
+ import type { Tool } from 'ai';
10
+ import type { Platform } from '../types.ts';
11
+ export interface ToolAnnotations {
12
+ /**
13
+ * `'deterministic'` — same input, same effect; a future cache may replay it.
14
+ * `'none'` — never replayed; always re-executed by a live executor.
15
+ */
16
+ readonly replay: 'deterministic' | 'none';
17
+ /** Whether executing the tool can change application state. */
18
+ readonly mutates: boolean;
19
+ /** Whether the tool handles secret material. */
20
+ readonly secrets: boolean;
21
+ /**
22
+ * Platforms this tool is offered on; absent means every platform. A suite
23
+ * that mixes targets of different platforms keeps a gesture tool off the
24
+ * platforms that cannot honor it by declaring this, not by splitting
25
+ * configs.
26
+ */
27
+ readonly platforms?: readonly Platform[];
28
+ }
29
+ export interface DefinedTool {
30
+ readonly tool: Tool;
31
+ readonly annotations: ToolAnnotations;
32
+ }
33
+ /** Attaches required semantics to an AI SDK tool. */
34
+ export declare function defineTool(tool: Tool, annotations: ToolAnnotations): DefinedTool;
35
+ /** True when a defined tool is offered on the given platform. */
36
+ export declare function toolAppliesTo(defined: DefinedTool, platform: Platform): boolean;
37
+ /** True when a value came through `defineTool`, from this or another realm. */
38
+ export declare function isDefinedTool(value: unknown): value is DefinedTool;
39
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/agent/tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAK5C,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAAC;IAC1C,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC;CACvC;AAED,qDAAqD;AACrD,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,eAAe,GAAG,WAAW,CAmChF;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAE/E;AAED,+EAA+E;AAC/E,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAElE"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * `defineTool` (RFC0001, layer 2): an AI SDK tool plus the required semantic
3
+ * annotation. The annotation is what lets the harness treat a project tool as
4
+ * a first-class capability — replay eligibility, mutation tracking, and secret
5
+ * gating are declared, never inferred. A tool without declared semantics is
6
+ * excluded from caching and untrusted by default, which in v0 (no cache)
7
+ * reduces to: the annotation is required and recorded.
8
+ */
9
+ import { TestError } from '../internal/errors.js';
10
+ /** Cross-realm identity marker for defined tools. */
11
+ const DEFINED_TOOL_MARKER = Symbol.for('e2e.defined-tool.v1');
12
+ /** Attaches required semantics to an AI SDK tool. */
13
+ export function defineTool(tool, annotations) {
14
+ if (typeof tool !== 'object' || tool === null || typeof tool.execute !== 'function') {
15
+ throw new TestError('INVALID_ARGUMENT', 'defineTool requires an AI SDK tool with an execute function');
16
+ }
17
+ if (annotations === undefined || typeof annotations !== 'object') {
18
+ throw new TestError('INVALID_ARGUMENT', 'defineTool requires annotations: { replay, mutates, secrets }');
19
+ }
20
+ if (annotations.replay !== 'deterministic' && annotations.replay !== 'none') {
21
+ throw new TestError('INVALID_ARGUMENT', "annotations.replay must be 'deterministic' or 'none'");
22
+ }
23
+ if (typeof annotations.mutates !== 'boolean' || typeof annotations.secrets !== 'boolean') {
24
+ throw new TestError('INVALID_ARGUMENT', 'annotations.mutates and annotations.secrets must be booleans');
25
+ }
26
+ if (annotations.platforms !== undefined &&
27
+ (!Array.isArray(annotations.platforms) ||
28
+ annotations.platforms.length === 0 ||
29
+ annotations.platforms.some((platform) => typeof platform !== 'string' || platform === ''))) {
30
+ throw new TestError('INVALID_ARGUMENT', 'annotations.platforms must be a non-empty array of platform names when present');
31
+ }
32
+ const defined = {
33
+ tool,
34
+ annotations: {
35
+ replay: annotations.replay,
36
+ mutates: annotations.mutates,
37
+ secrets: annotations.secrets,
38
+ ...(annotations.platforms === undefined ? {} : { platforms: [...annotations.platforms] }),
39
+ },
40
+ };
41
+ Object.defineProperty(defined, DEFINED_TOOL_MARKER, { value: true });
42
+ return Object.freeze(defined);
43
+ }
44
+ /** True when a defined tool is offered on the given platform. */
45
+ export function toolAppliesTo(defined, platform) {
46
+ return defined.annotations.platforms === undefined || defined.annotations.platforms.includes(platform);
47
+ }
48
+ /** True when a value came through `defineTool`, from this or another realm. */
49
+ export function isDefinedTool(value) {
50
+ return typeof value === 'object' && value !== null && DEFINED_TOOL_MARKER in value;
51
+ }
52
+ //# sourceMappingURL=tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../src/agent/tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlD,qDAAqD;AACrD,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;AA0B9D,qDAAqD;AACrD,MAAM,UAAU,UAAU,CAAC,IAAU,EAAE,WAA4B;IACjE,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QACpF,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,6DAA6D,CAAC,CAAC;IACzG,CAAC;IACD,IAAI,WAAW,KAAK,SAAS,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACjE,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,+DAA+D,CAAC,CAAC;IAC3G,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,KAAK,eAAe,IAAI,WAAW,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC5E,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,sDAAsD,CAAC,CAAC;IAClG,CAAC;IACD,IAAI,OAAO,WAAW,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,WAAW,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACzF,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,8DAA8D,CAAC,CAAC;IAC1G,CAAC;IACD,IACE,WAAW,CAAC,SAAS,KAAK,SAAS;QACnC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC;YACpC,WAAW,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;YAClC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,EAAE,CAAC,CAAC,EAC5F,CAAC;QACD,MAAM,IAAI,SAAS,CACjB,kBAAkB,EAClB,gFAAgF,CACjF,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAgB;QAC3B,IAAI;QACJ,WAAW,EAAE;YACX,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,GAAG,CAAC,WAAW,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;SAC1F;KACF,CAAC;IACF,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,mBAAmB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,aAAa,CAAC,OAAoB,EAAE,QAAkB;IACpE,OAAO,OAAO,CAAC,WAAW,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACzG,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,mBAAmB,IAAI,KAAK,CAAC;AACrF,CAAC"}
@@ -0,0 +1,186 @@
1
+ /**
2
+ * The backend contract vocabulary (RFC0002): the platform-neutral types every
3
+ * backend speaks and the harness consumes. A backend imports these from
4
+ * `@e2edev/e2e/backend`; core never imports anything from a backend.
5
+ *
6
+ * Everything here is capability vocabulary - semantic nodes, locator
7
+ * expressions, action kinds, the error contract - never a platform noun. A
8
+ * document platform, a simulator, and a desktop shell describe themselves with the same
9
+ * words, which is what lets `screen`, `expect`, and the agent work identically
10
+ * on all of them.
11
+ */
12
+ import type { Momentum, ScrollDirection, SelectOption } from '../types.ts';
13
+ /** The backend contract version this runner speaks. */
14
+ export declare const BACKEND_SPI_VERSION = 1;
15
+ export type BackendSpiVersion = typeof BACKEND_SPI_VERSION;
16
+ export interface OperationContext {
17
+ readonly signal: AbortSignal;
18
+ /** Remaining operation budget when the call starts. */
19
+ readonly timeoutMs: number;
20
+ readonly runId: string;
21
+ readonly attemptId: string;
22
+ }
23
+ export type TextPattern = {
24
+ readonly kind: 'string';
25
+ readonly value: string;
26
+ readonly exact: boolean;
27
+ } | {
28
+ readonly kind: 'regexp';
29
+ readonly source: string;
30
+ readonly flags: string;
31
+ };
32
+ export type QueryKind = 'role' | 'label' | 'placeholder' | 'text' | 'displayValue' | 'testId';
33
+ export interface SemanticQuery {
34
+ readonly kind: QueryKind;
35
+ readonly value: TextPattern;
36
+ readonly name?: TextPattern;
37
+ readonly states?: Readonly<Partial<Record<'checked' | 'disabled' | 'selected' | 'expanded' | 'hidden', boolean>>>;
38
+ }
39
+ /**
40
+ * The location capability's query language. `selector` is a platform-native
41
+ * selector string (CSS or XPath on a document platform, a predicate on a
42
+ * device platform); `frame` scopes a query inside one nested document.
43
+ */
44
+ export type LocatorExpression = {
45
+ readonly kind: 'query';
46
+ readonly query: SemanticQuery;
47
+ readonly scope?: LocatorExpression;
48
+ } | {
49
+ readonly kind: 'filter';
50
+ readonly source: LocatorExpression;
51
+ readonly hasText?: TextPattern;
52
+ readonly has?: LocatorExpression;
53
+ } | {
54
+ readonly kind: 'index';
55
+ readonly source: LocatorExpression;
56
+ readonly index: number | 'first' | 'last';
57
+ } | {
58
+ readonly kind: 'selector';
59
+ readonly selector: string;
60
+ } | {
61
+ readonly kind: 'frame';
62
+ readonly selector: string;
63
+ readonly source: LocatorExpression;
64
+ };
65
+ export interface NodeRef {
66
+ readonly id: string;
67
+ readonly revision: string;
68
+ }
69
+ /**
70
+ * Per-field bounds a backend applies to observation-tree nodes. A `name` or
71
+ * `text` whose length reaches its limit was cut at exactly that limit, so
72
+ * "length >= limit" is a precise truncation signal; every shorter value is
73
+ * complete. Single-node reads are unbounded and always carry the full value.
74
+ */
75
+ export declare const OBSERVED_NAME_LIMIT = 256;
76
+ export declare const OBSERVED_TEXT_LIMIT = 512;
77
+ export interface SemanticNode {
78
+ readonly ref: NodeRef;
79
+ readonly role?: string;
80
+ readonly name?: string;
81
+ readonly text?: string;
82
+ readonly value?: string;
83
+ readonly inputPurpose?: 'username' | 'password' | 'one-time-code' | 'generic-secret' | 'none';
84
+ readonly states?: Readonly<Partial<Record<'checked' | 'disabled' | 'selected' | 'expanded' | 'focused' | 'hidden' | 'secure', boolean>>>;
85
+ readonly attributes?: Readonly<Record<string, string>>;
86
+ readonly rect?: {
87
+ readonly x: number;
88
+ readonly y: number;
89
+ readonly width: number;
90
+ readonly height: number;
91
+ };
92
+ /**
93
+ * Platform selector that addresses this node within its own document, when
94
+ * the platform has one. It is structural, not semantic: it survives the
95
+ * content changes that rename a node, and a runner may store it to re-find
96
+ * the node cheaply on a later run. It is never part of the node's identity,
97
+ * so whatever it resolves to is still checked before it is used.
98
+ *
99
+ * It SHOULD be anchored on an attribute naming the node or one of its
100
+ * ancestors, and SHOULD be absent rather than positional all the way to the
101
+ * document root: such a path is shifted by anything inserted above the node,
102
+ * so it does not survive to the later run it exists for (10-determinism.md).
103
+ */
104
+ readonly selector?: string;
105
+ /**
106
+ * Enclosing nested-document chain as selectors of each boundary node,
107
+ * outermost first. Absent for nodes in the main document.
108
+ */
109
+ readonly framePath?: readonly string[];
110
+ readonly children?: readonly SemanticNode[];
111
+ }
112
+ /**
113
+ * Viewport point in CSS pixels, origin at the top-left of the viewport.
114
+ * Reserved for coordinate-addressed actions; no runner surface consumes it yet.
115
+ */
116
+ export interface ViewportPoint {
117
+ readonly x: number;
118
+ readonly y: number;
119
+ }
120
+ /**
121
+ * Masked viewport pixels captured for one observation revision.
122
+ *
123
+ * `width` and `height` MUST be the true dimensions of `data`, because they are
124
+ * the space every coordinate read off the image refers to. `scale` relates that
125
+ * space to the CSS pixels of `SemanticNode.rect`, which is the space actions
126
+ * dispatch in: one image pixel is `1 / scale` CSS pixels.
127
+ */
128
+ export interface ObservationPixels {
129
+ readonly data: Uint8Array;
130
+ readonly mediaType: 'image/png';
131
+ readonly width: number;
132
+ readonly height: number;
133
+ /** Image pixels per CSS pixel; 1 for a CSS-scale capture. */
134
+ readonly scale: number;
135
+ }
136
+ /** One deterministic action the location tier performs on a located node. */
137
+ export type LocatorAction = {
138
+ readonly kind: 'tap' | 'doubleTap' | 'check' | 'uncheck' | 'clear' | 'focus' | 'hover' | 'scrollIntoView';
139
+ } | {
140
+ readonly kind: 'longPress';
141
+ readonly durationMs?: number;
142
+ } | {
143
+ readonly kind: 'fill';
144
+ readonly value: string;
145
+ readonly sensitive: boolean;
146
+ } | {
147
+ readonly kind: 'press';
148
+ readonly key: string;
149
+ } | {
150
+ readonly kind: 'selectOption';
151
+ readonly value: SelectOption;
152
+ } | {
153
+ readonly kind: 'setInputFiles';
154
+ readonly paths: readonly string[];
155
+ } | {
156
+ readonly kind: 'dragTo';
157
+ readonly target: NodeRef;
158
+ } | {
159
+ readonly kind: 'swipe';
160
+ readonly direction: ScrollDirection;
161
+ readonly momentum?: Momentum;
162
+ };
163
+ /** The closed backend error code set; the type is derived from it, so the two cannot drift. */
164
+ export declare const BACKEND_ERROR_CODES: readonly ['NODE_STALE', 'FRAME_NOT_FOUND', 'FRAME_AMBIGUOUS', 'NOT_ACTIONABLE', 'ACTION_MAY_HAVE_COMMITTED', 'OPERATION_TIMEOUT', 'CANCELLED', 'UNSUPPORTED_CAPABILITY', 'INVALID_STATE', 'BACKEND_FAILURE'];
165
+ export type BackendErrorCode = (typeof BACKEND_ERROR_CODES)[number];
166
+ /**
167
+ * The only codes that may be retryable: both describe a repeatable read. Any
168
+ * other retryable claim, from this module's class or a foreign copy of it, is
169
+ * coerced to a non-retryable `BACKEND_FAILURE`.
170
+ */
171
+ export declare const RETRYABLE_BACKEND_ERROR_CODES: ReadonlySet<BackendErrorCode>;
172
+ /**
173
+ * The error contract a backend throws across the seam. Retryability is closed
174
+ * to `RETRYABLE_BACKEND_ERROR_CODES`; any other retryable claim is coerced to
175
+ * a non-retryable `BACKEND_FAILURE` so a backend can never talk the harness
176
+ * into repeating an action that may have committed.
177
+ */
178
+ export declare class BackendError extends Error {
179
+ readonly code: BackendErrorCode;
180
+ readonly retryable: boolean;
181
+ constructor(code: BackendErrorCode, message: string, options: {
182
+ retryable: boolean;
183
+ cause?: unknown;
184
+ });
185
+ }
186
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/backend/contract.ts"],"names":[],"mappings":"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"}