@e2edev/e2e 0.2.0 → 0.4.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 (242) hide show
  1. package/README.md +32 -3
  2. package/dist/agent/act.d.ts.map +1 -1
  3. package/dist/agent/act.js +124 -71
  4. package/dist/agent/act.js.map +1 -1
  5. package/dist/agent/actions.d.ts +15 -0
  6. package/dist/agent/actions.d.ts.map +1 -1
  7. package/dist/agent/actions.js +59 -1
  8. package/dist/agent/actions.js.map +1 -1
  9. package/dist/agent/default-agent.d.ts +34 -4
  10. package/dist/agent/default-agent.d.ts.map +1 -1
  11. package/dist/agent/default-agent.js +28 -150
  12. package/dist/agent/default-agent.js.map +1 -1
  13. package/dist/agent/derived.d.ts +17 -0
  14. package/dist/agent/derived.d.ts.map +1 -0
  15. package/dist/agent/derived.js +45 -0
  16. package/dist/agent/derived.js.map +1 -0
  17. package/dist/agent/executor.d.ts +122 -2
  18. package/dist/agent/executor.d.ts.map +1 -1
  19. package/dist/agent/executor.js.map +1 -1
  20. package/dist/agent/index.js +1 -1
  21. package/dist/agent/index.js.map +1 -1
  22. package/dist/agent/invocation.d.ts +4 -8
  23. package/dist/agent/invocation.d.ts.map +1 -1
  24. package/dist/agent/invocation.js +16 -42
  25. package/dist/agent/invocation.js.map +1 -1
  26. package/dist/agent/ledger.d.ts +14 -4
  27. package/dist/agent/ledger.d.ts.map +1 -1
  28. package/dist/agent/ledger.js +26 -5
  29. package/dist/agent/ledger.js.map +1 -1
  30. package/dist/agent/loop-guards.d.ts +14 -1
  31. package/dist/agent/loop-guards.d.ts.map +1 -1
  32. package/dist/agent/loop-guards.js +11 -8
  33. package/dist/agent/loop-guards.js.map +1 -1
  34. package/dist/agent/observation.d.ts +28 -7
  35. package/dist/agent/observation.d.ts.map +1 -1
  36. package/dist/agent/observation.js +52 -5
  37. package/dist/agent/observation.js.map +1 -1
  38. package/dist/agent/primitives.d.ts +86 -0
  39. package/dist/agent/primitives.d.ts.map +1 -0
  40. package/dist/agent/primitives.js +255 -0
  41. package/dist/agent/primitives.js.map +1 -0
  42. package/dist/agent/prompts.d.ts.map +1 -1
  43. package/dist/agent/prompts.js.map +1 -1
  44. package/dist/agent/public.d.ts +6 -3
  45. package/dist/agent/public.d.ts.map +1 -1
  46. package/dist/agent/public.js +4 -2
  47. package/dist/agent/public.js.map +1 -1
  48. package/dist/agent/replay.d.ts +1 -1
  49. package/dist/agent/replay.d.ts.map +1 -1
  50. package/dist/agent/replay.js +19 -2
  51. package/dist/agent/replay.js.map +1 -1
  52. package/dist/agent/step-cache.d.ts +5 -2
  53. package/dist/agent/step-cache.d.ts.map +1 -1
  54. package/dist/agent/step-cache.js +37 -5
  55. package/dist/agent/step-cache.js.map +1 -1
  56. package/dist/agent/tool-loop.d.ts +59 -5
  57. package/dist/agent/tool-loop.d.ts.map +1 -1
  58. package/dist/agent/tool-loop.js +77 -105
  59. package/dist/agent/tool-loop.js.map +1 -1
  60. package/dist/agent/tool.d.ts +11 -16
  61. package/dist/agent/tool.d.ts.map +1 -1
  62. package/dist/agent/tool.js +19 -13
  63. package/dist/agent/tool.js.map +1 -1
  64. package/dist/agent/usage.d.ts +27 -0
  65. package/dist/agent/usage.d.ts.map +1 -0
  66. package/dist/agent/usage.js +54 -0
  67. package/dist/agent/usage.js.map +1 -0
  68. package/dist/backend/index.d.ts +72 -6
  69. package/dist/backend/index.d.ts.map +1 -1
  70. package/dist/backend/index.js +4 -1
  71. package/dist/backend/index.js.map +1 -1
  72. package/dist/backend/session.d.ts.map +1 -1
  73. package/dist/backend/session.js +1 -0
  74. package/dist/backend/session.js.map +1 -1
  75. package/dist/backend/surface.d.ts +2 -0
  76. package/dist/backend/surface.d.ts.map +1 -1
  77. package/dist/backend/timing.d.ts +3 -0
  78. package/dist/backend/timing.d.ts.map +1 -0
  79. package/dist/backend/timing.js +8 -0
  80. package/dist/backend/timing.js.map +1 -0
  81. package/dist/cache/recorder.d.ts +2 -0
  82. package/dist/cache/recorder.d.ts.map +1 -1
  83. package/dist/cache/recorder.js +4 -1
  84. package/dist/cache/recorder.js.map +1 -1
  85. package/dist/cache/relocate.d.ts.map +1 -1
  86. package/dist/cache/relocate.js +11 -2
  87. package/dist/cache/relocate.js.map +1 -1
  88. package/dist/cache/trace.d.ts +11 -0
  89. package/dist/cache/trace.d.ts.map +1 -1
  90. package/dist/cache/trace.js +9 -0
  91. package/dist/cache/trace.js.map +1 -1
  92. package/dist/cli/index.d.ts.map +1 -1
  93. package/dist/cli/index.js +32 -22
  94. package/dist/cli/index.js.map +1 -1
  95. package/dist/cli/init/backends.d.ts +75 -0
  96. package/dist/cli/init/backends.d.ts.map +1 -0
  97. package/dist/cli/init/backends.js +98 -0
  98. package/dist/cli/init/backends.js.map +1 -0
  99. package/dist/cli/init/package.d.ts +43 -0
  100. package/dist/cli/init/package.d.ts.map +1 -0
  101. package/dist/cli/init/package.js +64 -0
  102. package/dist/cli/init/package.js.map +1 -0
  103. package/dist/cli/init/scaffold.d.ts +12 -0
  104. package/dist/cli/init/scaffold.d.ts.map +1 -0
  105. package/dist/cli/init/scaffold.js +36 -0
  106. package/dist/cli/init/scaffold.js.map +1 -0
  107. package/dist/cli/init.d.ts +8 -3
  108. package/dist/cli/init.d.ts.map +1 -1
  109. package/dist/cli/init.js +99 -72
  110. package/dist/cli/init.js.map +1 -1
  111. package/dist/cli/signals.d.ts +23 -0
  112. package/dist/cli/signals.d.ts.map +1 -0
  113. package/dist/cli/signals.js +42 -0
  114. package/dist/cli/signals.js.map +1 -0
  115. package/dist/collect/registry.d.ts +14 -4
  116. package/dist/collect/registry.d.ts.map +1 -1
  117. package/dist/collect/registry.js +10 -10
  118. package/dist/collect/registry.js.map +1 -1
  119. package/dist/config/app.d.ts +50 -0
  120. package/dist/config/app.d.ts.map +1 -0
  121. package/dist/config/app.js +168 -0
  122. package/dist/config/app.js.map +1 -0
  123. package/dist/config/esm.d.ts +4 -0
  124. package/dist/config/esm.d.ts.map +1 -0
  125. package/dist/config/esm.js +35 -0
  126. package/dist/config/esm.js.map +1 -0
  127. package/dist/config/load.d.ts.map +1 -1
  128. package/dist/config/load.js +4 -0
  129. package/dist/config/load.js.map +1 -1
  130. package/dist/config/resolve.d.ts +6 -16
  131. package/dist/config/resolve.d.ts.map +1 -1
  132. package/dist/config/resolve.js +18 -110
  133. package/dist/config/resolve.js.map +1 -1
  134. package/dist/config/validate.d.ts +3 -1
  135. package/dist/config/validate.d.ts.map +1 -1
  136. package/dist/config/validate.js +17 -1
  137. package/dist/config/validate.js.map +1 -1
  138. package/dist/index.d.ts +3 -2
  139. package/dist/index.d.ts.map +1 -1
  140. package/dist/index.js +1 -1
  141. package/dist/index.js.map +1 -1
  142. package/dist/internal/errors.d.ts +9 -0
  143. package/dist/internal/errors.d.ts.map +1 -1
  144. package/dist/internal/errors.js +15 -0
  145. package/dist/internal/errors.js.map +1 -1
  146. package/dist/internal/time.d.ts +10 -0
  147. package/dist/internal/time.d.ts.map +1 -1
  148. package/dist/internal/time.js +45 -0
  149. package/dist/internal/time.js.map +1 -1
  150. package/dist/internal/urls.d.ts +2 -1
  151. package/dist/internal/urls.d.ts.map +1 -1
  152. package/dist/internal/urls.js +22 -2
  153. package/dist/internal/urls.js.map +1 -1
  154. package/dist/locator/engine.d.ts +5 -3
  155. package/dist/locator/engine.d.ts.map +1 -1
  156. package/dist/locator/engine.js +7 -6
  157. package/dist/locator/engine.js.map +1 -1
  158. package/dist/report/build.d.ts +0 -1
  159. package/dist/report/build.d.ts.map +1 -1
  160. package/dist/report/build.js +2 -3
  161. package/dist/report/build.js.map +1 -1
  162. package/dist/report/junit.d.ts +11 -0
  163. package/dist/report/junit.d.ts.map +1 -0
  164. package/dist/report/junit.js +202 -0
  165. package/dist/report/junit.js.map +1 -0
  166. package/dist/report/list.d.ts +2 -0
  167. package/dist/report/list.d.ts.map +1 -1
  168. package/dist/report/list.js +15 -0
  169. package/dist/report/list.js.map +1 -1
  170. package/dist/report/live-status.d.ts.map +1 -1
  171. package/dist/report/live-status.js +2 -1
  172. package/dist/report/live-status.js.map +1 -1
  173. package/dist/report/write.d.ts +2 -0
  174. package/dist/report/write.d.ts.map +1 -1
  175. package/dist/report/write.js +7 -3
  176. package/dist/report/write.js.map +1 -1
  177. package/dist/run/budget.d.ts +25 -0
  178. package/dist/run/budget.d.ts.map +1 -0
  179. package/dist/run/budget.js +38 -0
  180. package/dist/run/budget.js.map +1 -0
  181. package/dist/run/events.d.ts +15 -0
  182. package/dist/run/events.d.ts.map +1 -1
  183. package/dist/run/events.js.map +1 -1
  184. package/dist/run/execute.d.ts +8 -0
  185. package/dist/run/execute.d.ts.map +1 -1
  186. package/dist/run/execute.js +53 -8
  187. package/dist/run/execute.js.map +1 -1
  188. package/dist/run/fixture-legacy.d.ts +36 -0
  189. package/dist/run/fixture-legacy.d.ts.map +1 -0
  190. package/dist/run/fixture-legacy.js +143 -0
  191. package/dist/run/fixture-legacy.js.map +1 -0
  192. package/dist/run/fixture-recording.d.ts +15 -0
  193. package/dist/run/fixture-recording.d.ts.map +1 -0
  194. package/dist/run/fixture-recording.js +75 -0
  195. package/dist/run/fixture-recording.js.map +1 -0
  196. package/dist/run/fixtures.d.ts +6 -3
  197. package/dist/run/fixtures.d.ts.map +1 -1
  198. package/dist/run/fixtures.js +32 -166
  199. package/dist/run/fixtures.js.map +1 -1
  200. package/dist/run/in-process.d.ts.map +1 -1
  201. package/dist/run/in-process.js +11 -2
  202. package/dist/run/in-process.js.map +1 -1
  203. package/dist/run/managed-process.d.ts +49 -0
  204. package/dist/run/managed-process.d.ts.map +1 -0
  205. package/dist/run/managed-process.js +202 -0
  206. package/dist/run/managed-process.js.map +1 -0
  207. package/dist/run/realm.d.ts +43 -8
  208. package/dist/run/realm.d.ts.map +1 -1
  209. package/dist/run/realm.js +67 -24
  210. package/dist/run/realm.js.map +1 -1
  211. package/dist/run/runner.d.ts +11 -1
  212. package/dist/run/runner.d.ts.map +1 -1
  213. package/dist/run/runner.js +151 -33
  214. package/dist/run/runner.js.map +1 -1
  215. package/dist/run/scheduler.d.ts +8 -0
  216. package/dist/run/scheduler.d.ts.map +1 -1
  217. package/dist/run/scheduler.js +37 -3
  218. package/dist/run/scheduler.js.map +1 -1
  219. package/dist/run/serial.d.ts +2 -0
  220. package/dist/run/serial.d.ts.map +1 -1
  221. package/dist/run/serial.js +10 -0
  222. package/dist/run/serial.js.map +1 -1
  223. package/dist/run/steps.d.ts +1 -1
  224. package/dist/run/steps.d.ts.map +1 -1
  225. package/dist/run/steps.js +12 -9
  226. package/dist/run/steps.js.map +1 -1
  227. package/dist/run/worker/entry.js +17 -2
  228. package/dist/run/worker/entry.js.map +1 -1
  229. package/dist/run/worker/protocol.d.ts +9 -1
  230. package/dist/run/worker/protocol.d.ts.map +1 -1
  231. package/dist/run/worker/protocol.js.map +1 -1
  232. package/dist/run/worker/session.d.ts +12 -0
  233. package/dist/run/worker/session.d.ts.map +1 -1
  234. package/dist/run/worker/session.js +23 -1
  235. package/dist/run/worker/session.js.map +1 -1
  236. package/dist/types.d.ts +33 -2
  237. package/dist/types.d.ts.map +1 -1
  238. package/package.json +2 -2
  239. package/dist/run/app-process.d.ts +0 -18
  240. package/dist/run/app-process.d.ts.map +0 -1
  241. package/dist/run/app-process.js +0 -112
  242. package/dist/run/app-process.js.map +0 -1
@@ -20,6 +20,19 @@ export type LoopGuardVerdict = {
20
20
  readonly kind: 'warn' | 'stop';
21
21
  readonly reason: string;
22
22
  };
23
+ /**
24
+ * Guard thresholds. Identical-call (period 1) counts are consecutive
25
+ * repetitions of one call; cycle (period 2..4) counts are whole repetitions
26
+ * of the sequence. Each warns first, then forces the conclusion.
27
+ */
28
+ export interface LoopGuardThresholds {
29
+ readonly repeatWarn: number;
30
+ readonly repeatStop: number;
31
+ readonly cycleWarn: number;
32
+ readonly cycleStop: number;
33
+ }
34
+ /** The thresholds the built-in agent ships with. */
35
+ export declare const DEFAULT_LOOP_GUARD_THRESHOLDS: LoopGuardThresholds;
23
36
  /**
24
37
  * Extracts the tool-call identity sequence from a model transcript,
25
38
  * excluding the conclusion tool: concluding attempts are never "loops".
@@ -31,5 +44,5 @@ export declare function extractGuardCalls(messages: readonly ModelMessage[], con
31
44
  * on different targets never count as a repeat — only literally re-issuing
32
45
  * the same work does.
33
46
  */
34
- export declare function checkLoopGuards(calls: readonly GuardToolCall[]): LoopGuardVerdict;
47
+ export declare function checkLoopGuards(calls: readonly GuardToolCall[], thresholds?: LoopGuardThresholds): LoopGuardVerdict;
35
48
  //# sourceMappingURL=loop-guards.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loop-guards.d.ts","sourceRoot":"","sources":["../../src/agent/loop-guards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAEvC,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAahE;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,gBAAgB,EAAE,MAAM,GACvB,aAAa,EAAE,CAUjB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,gBAAgB,CAajF"}
1
+ {"version":3,"file":"loop-guards.d.ts","sourceRoot":"","sources":["../../src/agent/loop-guards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAEvC,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAKhE;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,oDAAoD;AACpD,eAAO,MAAM,6BAA6B,EAAE,mBAK3C,CAAC;AAEF;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,gBAAgB,EAAE,MAAM,GACvB,aAAa,EAAE,CAUjB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,UAAU,GAAE,mBAAmD,GAC9D,gBAAgB,CAgBlB"}
@@ -10,12 +10,13 @@
10
10
  */
11
11
  /** Longest cycle period the detector considers. */
12
12
  const MAX_CYCLE_PERIOD = 4;
13
- /** Identical-call (period 1) thresholds: warn, then force the conclusion. */
14
- const REPEAT_WARN = 3;
15
- const REPEAT_STOP = 5;
16
- /** Cycle (period 2..4) thresholds, counted in whole repetitions. */
17
- const CYCLE_WARN = 2;
18
- const CYCLE_STOP = 3;
13
+ /** The thresholds the built-in agent ships with. */
14
+ export const DEFAULT_LOOP_GUARD_THRESHOLDS = {
15
+ repeatWarn: 3,
16
+ repeatStop: 5,
17
+ cycleWarn: 2,
18
+ cycleStop: 3,
19
+ };
19
20
  /**
20
21
  * Extracts the tool-call identity sequence from a model transcript,
21
22
  * excluding the conclusion tool: concluding attempts are never "loops".
@@ -39,11 +40,13 @@ export function extractGuardCalls(messages, concludeToolName) {
39
40
  * on different targets never count as a repeat — only literally re-issuing
40
41
  * the same work does.
41
42
  */
42
- export function checkLoopGuards(calls) {
43
+ export function checkLoopGuards(calls, thresholds = DEFAULT_LOOP_GUARD_THRESHOLDS) {
43
44
  let warning;
44
45
  for (let period = 1; period <= MAX_CYCLE_PERIOD; period += 1) {
45
46
  const repeats = trailingRepeats(calls, period);
46
- const [warnAt, stopAt] = period === 1 ? [REPEAT_WARN, REPEAT_STOP] : [CYCLE_WARN, CYCLE_STOP];
47
+ const [warnAt, stopAt] = period === 1
48
+ ? [thresholds.repeatWarn, thresholds.repeatStop]
49
+ : [thresholds.cycleWarn, thresholds.cycleStop];
47
50
  if (repeats >= stopAt) {
48
51
  return { kind: 'stop', reason: describe(calls, period, repeats) };
49
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"loop-guards.js","sourceRoot":"","sources":["../../src/agent/loop-guards.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loop-guards.js","sourceRoot":"","sources":["../../src/agent/loop-guards.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,21 @@
1
1
  /** Observation capture, redaction, and model serialization (spec 09-drivers.md, 14-security.md). */
2
- import type { Observation, ObservationPixels, SemanticNode } from '../backend/surface.ts';
2
+ import type { Observation, SemanticNode } from '../backend/surface.ts';
3
+ import type { VisionDegradation } from '../run/steps.ts';
4
+ import type { ExecutorNode, ExecutorPixels } from './executor.ts';
3
5
  /** Why pixels the caller asked for are not part of this observation. */
4
6
  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
7
  export interface AgentObservation {
8
+ /** Location captured with this tree, when the backend can provide it. */
9
+ readonly url?: string;
11
10
  readonly revision: string;
12
11
  /** Redacted, size-bounded serialization sent to the model. */
13
12
  readonly text: string;
14
13
  readonly bytes: number;
15
14
  readonly nodes: ReadonlyMap<string, SemanticNode>;
15
+ /** Parent id of every non-root node, for the container a target sits in. */
16
+ readonly parents: ReadonlyMap<string, string>;
17
+ /** The raw tree as the backend reported it; redacted only on the way out. */
18
+ readonly tree: SemanticNode;
16
19
  readonly viewport: {
17
20
  readonly width: number;
18
21
  readonly height: number;
@@ -20,7 +23,7 @@ export interface AgentObservation {
20
23
  };
21
24
  readonly truncated: boolean;
22
25
  /** Present only when the backend captured pixels and masking checks out. */
23
- readonly pixels?: AgentPixels | undefined;
26
+ readonly pixels?: ExecutorPixels | undefined;
24
27
  /** Set when captured pixels were dropped instead of being sent. */
25
28
  readonly pixelsWithheld?: PixelsWithheld | undefined;
26
29
  }
@@ -37,6 +40,24 @@ export declare function prepareObservation(observation: Observation, options: {
37
40
  maxBytes: number;
38
41
  testIdAttribute: string;
39
42
  }): AgentObservation;
43
+ /**
44
+ * Whether requested pixels become model input, decided once per observation
45
+ * for every tier that asks: a tainted viewport (a secret filled this attempt)
46
+ * is denied first, since the secret may be anywhere on screen; then the
47
+ * capture's own reasons; then the pixels themselves.
48
+ */
49
+ export declare function pixelsForModel(observation: AgentObservation, tainted: boolean): {
50
+ readonly pixels: ExecutorPixels;
51
+ } | {
52
+ readonly withheld: VisionDegradation;
53
+ };
54
+ /**
55
+ * Projects the raw tree onto the executor-facing node shape: the same
56
+ * redaction the text serialization applies, field by field, and no value at
57
+ * all for a secure node. Selectors stay behind — they are relocation
58
+ * material for the trace cache, not something a brain reasons about.
59
+ */
60
+ export declare function projectTree(node: SemanticNode, redact: (text: string) => string): ExecutorNode;
40
61
  /**
41
62
  * What the screen looks like, independent of which observation looked at it.
42
63
  *
@@ -1 +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"}
1
+ {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../../src/agent/observation.ts"],"names":[],"mappings":"AAAA,oGAAoG;AAEpG,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKlE,wEAAwE;AACxE,KAAK,cAAc,GAAG,kBAAkB,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,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,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,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,cAAc,GAAG,SAAS,CAAC;IAC7C,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,CAiDlB;AAqBD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,gBAAgB,EAC7B,OAAO,EAAE,OAAO,GACf;IAAE,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;CAAE,CAMhF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,YAAY,CAqB9F;AA8CD;;;;;;;;;;;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"}
@@ -13,7 +13,8 @@ const TRUNCATION_MARKER = '[observation truncated at the resolved observation by
13
13
  */
14
14
  export function prepareObservation(observation, options) {
15
15
  const nodes = new Map();
16
- indexNodes(observation.tree, nodes);
16
+ const parents = new Map();
17
+ indexNodes(observation.tree, nodes, parents);
17
18
  const redact = options.redact;
18
19
  const lines = [];
19
20
  const encoder = new TextEncoder();
@@ -48,9 +49,12 @@ export function prepareObservation(observation, options) {
48
49
  const pixels = clearPixels(observation);
49
50
  return {
50
51
  revision: observation.revision,
52
+ ...(observation.url === undefined ? {} : { url: options.redact(observation.url) }),
51
53
  text,
52
54
  bytes: textBytes,
53
55
  nodes,
56
+ parents,
57
+ tree: observation.tree,
54
58
  viewport: observation.viewport,
55
59
  truncated,
56
60
  ...(pixels.cleared === undefined ? {} : { pixels: pixels.cleared }),
@@ -72,7 +76,48 @@ function clearPixels(observation) {
72
76
  const { secureNodeCount, maskedRegionCount } = observation.redaction;
73
77
  if (maskedRegionCount < secureNodeCount)
74
78
  return { withheld: 'MASKING_UNPROVEN' };
75
- return { cleared: { ...pixels, maskedRegionCount, bytes: pixels.data.byteLength } };
79
+ return { cleared: { ...pixels, maskedRegionCount } };
80
+ }
81
+ /**
82
+ * Whether requested pixels become model input, decided once per observation
83
+ * for every tier that asks: a tainted viewport (a secret filled this attempt)
84
+ * is denied first, since the secret may be anywhere on screen; then the
85
+ * capture's own reasons; then the pixels themselves.
86
+ */
87
+ export function pixelsForModel(observation, tainted) {
88
+ if (tainted)
89
+ return { withheld: 'PIXEL_TAINTED' };
90
+ if (observation.pixels === undefined) {
91
+ return { withheld: observation.pixelsWithheld ?? 'UNSUPPORTED_CAPABILITY' };
92
+ }
93
+ return { pixels: observation.pixels };
94
+ }
95
+ /**
96
+ * Projects the raw tree onto the executor-facing node shape: the same
97
+ * redaction the text serialization applies, field by field, and no value at
98
+ * all for a secure node. Selectors stay behind — they are relocation
99
+ * material for the trace cache, not something a brain reasons about.
100
+ */
101
+ export function projectTree(node, redact) {
102
+ const secure = node.states?.secure === true;
103
+ const attributes = node.attributes === undefined
104
+ ? undefined
105
+ : Object.fromEntries(Object.entries(node.attributes).map(([key, value]) => [key, redact(value)]));
106
+ return {
107
+ id: node.ref.id,
108
+ ...(node.role === undefined ? {} : { role: node.role }),
109
+ ...(node.name === undefined ? {} : { name: redact(node.name) }),
110
+ ...(node.text === undefined ? {} : { text: redact(node.text) }),
111
+ ...(node.value === undefined || secure ? {} : { value: redact(node.value) }),
112
+ ...(node.inputPurpose === undefined ? {} : { inputPurpose: node.inputPurpose }),
113
+ ...(node.states === undefined ? {} : { states: node.states }),
114
+ ...(attributes === undefined ? {} : { attributes }),
115
+ ...(node.rect === undefined ? {} : { rect: node.rect }),
116
+ ...(node.framePath === undefined ? {} : { framePath: node.framePath }),
117
+ ...(node.children === undefined
118
+ ? {}
119
+ : { children: node.children.map((child) => projectTree(child, redact)) }),
120
+ };
76
121
  }
77
122
  /** Depth beyond this renders flat; deep chrome must not buy tokens with spaces. */
78
123
  const MAX_INDENT_DEPTH = 10;
@@ -166,9 +211,11 @@ export async function settleObservation(capture, shapeOf, clock) {
166
211
  }
167
212
  return value;
168
213
  }
169
- function indexNodes(node, into) {
214
+ function indexNodes(node, into, parents) {
170
215
  into.set(node.ref.id, node);
171
- for (const child of node.children ?? [])
172
- indexNodes(child, into);
216
+ for (const child of node.children ?? []) {
217
+ parents.set(child.ref.id, node.ref.id);
218
+ indexNodes(child, into, parents);
219
+ }
173
220
  }
174
221
  //# sourceMappingURL=observation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"observation.js","sourceRoot":"","sources":["../../src/agent/observation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"observation.js","sourceRoot":"","sources":["../../src/agent/observation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * The primitives under the built-in agent (RFC0001, layer 4). Each is one
3
+ * piece of the discipline the chassis and `createAgent` are assembled from,
4
+ * usable on its own with a raw AI SDK `ToolLoopAgent` or `generateText` —
5
+ * the way the AI SDK itself is a small opinionated agent over primitives you
6
+ * can also call directly:
7
+ *
8
+ * - `createGrammarTools` — AI SDK tools over the harness action grammar;
9
+ * - `createVerdictTool` — the `complete_step` tool and the closed blocked-code policy;
10
+ * - `trackModelCalls` — step handlers that report usage to the harness budgets;
11
+ * - `conversationMemory` — a message history kept across the steps of an attempt.
12
+ *
13
+ * Nothing here loads the `ai` package: an AI SDK tool is a plain object, so
14
+ * the module is safe to import from a config that never calls a model.
15
+ */
16
+ import type { ModelMessage, StepResult, Tool, ToolSet } from 'ai';
17
+ import { type StepExecutorContext, type StepVerdict } from './executor.ts';
18
+ /** The verdict rules the built-in agent appends to its instructions. */
19
+ export declare const VERDICT_RULES = "Verdict rules:\n- When the step's goal is achieved, or you are certain it cannot be, call complete_step exactly once.\n- Verify outcomes with your tools before concluding; never guess success.\n- \"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 \u2014 blocked says nothing about the product and requires an errorCode.";
20
+ /** The conclusion tool and the verdict it collected. */
21
+ export interface VerdictTool {
22
+ /** The `complete_step` tool; add it to the toolset under that name. */
23
+ readonly tool: Tool;
24
+ /** The verdict once the model called the tool with an accepted one. */
25
+ verdict(): StepVerdict | undefined;
26
+ /** True once a verdict landed; a `stopWhen` condition for a raw loop. */
27
+ concluded(): boolean;
28
+ }
29
+ /**
30
+ * The `complete_step` verdict tool. A blocked verdict without a blockable
31
+ * code is rejected back to the model, a passed verdict never carries a code,
32
+ * and the first accepted verdict is final.
33
+ */
34
+ export declare function createVerdictTool(): VerdictTool;
35
+ /** What a tool body runs under; the chassis supplies its loop policy here. */
36
+ export interface GrammarToolOptions {
37
+ /**
38
+ * Wraps every tool body. The default runs it as is, so a harness hard stop
39
+ * (budget, timeout, cancel) propagates out of the tool; the chassis's guard
40
+ * instead turns it into text and ends the loop.
41
+ */
42
+ readonly guard?: (body: () => Promise<string>) => Promise<string>;
43
+ }
44
+ /**
45
+ * AI SDK tools over the harness action grammar, limited to the verbs the
46
+ * target's backend declared. A verb the surface cannot honor is not offered
47
+ * at all, so the model never learns vocabulary it can only be rejected on.
48
+ * Every mutating tool returns the updated screen.
49
+ */
50
+ export declare function createGrammarTools(context: StepExecutorContext, options?: GrammarToolOptions): ToolSet;
51
+ /** Step handlers that report every model round trip to the harness budgets. */
52
+ export interface ModelCallTracker {
53
+ /** Pass as `onStepStart`; marks the turn's start for its duration. */
54
+ onStepStart(): void;
55
+ /**
56
+ * Pass as `onStepEnd` (or `onStepFinish`); records the turn's usage, cost,
57
+ * and provenance. Throws `STEP_BUDGET_EXHAUSTED` past the model-call budget,
58
+ * which ends a raw loop the same way it ends the chassis.
59
+ */
60
+ onStepEnd(step: Pick<StepResult<ToolSet>, 'usage' | 'providerMetadata'>): void;
61
+ }
62
+ /**
63
+ * Model-call accounting for a loop the executor runs itself. `model` names
64
+ * the provider and model id in the report; pass the AI SDK model instance.
65
+ */
66
+ export declare function trackModelCalls(context: StepExecutorContext, model?: {
67
+ readonly provider?: string;
68
+ readonly modelId?: string;
69
+ }): ModelCallTracker;
70
+ /** A conversation kept in the attempt memory across the steps of one test. */
71
+ export interface ConversationMemory {
72
+ /** Messages remembered by earlier steps of this attempt; empty on the first. */
73
+ readonly messages: readonly ModelMessage[];
74
+ /** Index of the last step that remembered, or -1. */
75
+ readonly lastStepIndex: number;
76
+ /** Stores the history for the next step of the attempt. */
77
+ remember(messages: readonly ModelMessage[]): void;
78
+ }
79
+ /**
80
+ * The executor's own conversation across an attempt, kept in
81
+ * `context.attempt.memory` under `key`. Open a step with
82
+ * `[...memory.messages, { role: 'user', content }]` and `remember` the full
83
+ * transcript when it ends; the harness drops it with the attempt.
84
+ */
85
+ export declare function conversationMemory(context: StepExecutorContext, key?: string): ConversationMemory;
86
+ //# sourceMappingURL=primitives.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/agent/primitives.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAGlE,OAAO,EAAmB,KAAK,mBAAmB,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAsB5F,wEAAwE;AACxE,eAAO,MAAM,aAAa,ucAG4N,CAAC;AAcvP,wDAAwD;AACxD,MAAM,WAAW,WAAW;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,uEAAuE;IACvE,OAAO,IAAI,WAAW,GAAG,SAAS,CAAC;IACnC,yEAAyE;IACzE,SAAS,IAAI,OAAO,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,CA0C/C;AAED,8EAA8E;AAC9E,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACnE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,mBAAmB,EAC5B,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAsHT;AAED,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,WAAW,IAAI,IAAI,CAAC;IACpB;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,kBAAkB,CAAC,GAAG,IAAI,CAAC;CAChF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,mBAAmB,EAC5B,KAAK,CAAC,EAAE;IAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAChE,gBAAgB,CAkBlB;AAED,8EAA8E;AAC9E,MAAM,WAAW,kBAAkB;IACjC,gFAAgF;IAChF,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,qDAAqD;IACrD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,IAAI,CAAC;CACnD;AAOD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,mBAAmB,EAC5B,GAAG,SAAqB,GACvB,kBAAkB,CAapB"}
@@ -0,0 +1,255 @@
1
+ /**
2
+ * The primitives under the built-in agent (RFC0001, layer 4). Each is one
3
+ * piece of the discipline the chassis and `createAgent` are assembled from,
4
+ * usable on its own with a raw AI SDK `ToolLoopAgent` or `generateText` —
5
+ * the way the AI SDK itself is a small opinionated agent over primitives you
6
+ * can also call directly:
7
+ *
8
+ * - `createGrammarTools` — AI SDK tools over the harness action grammar;
9
+ * - `createVerdictTool` — the `complete_step` tool and the closed blocked-code policy;
10
+ * - `trackModelCalls` — step handlers that report usage to the harness budgets;
11
+ * - `conversationMemory` — a message history kept across the steps of an attempt.
12
+ *
13
+ * Nothing here loads the `ai` package: an AI SDK tool is a plain object, so
14
+ * the module is safe to import from a config that never calls a model.
15
+ */
16
+ import { z } from 'zod';
17
+ import { BLOCKABLE_CODES } from './executor.js';
18
+ import { readCost } from './model/sdk.js';
19
+ /** Codes the model may pick when concluding; runtime codes are runtime-assigned. */
20
+ const MODEL_ERROR_CODES = [
21
+ 'ACTION_FAILED',
22
+ 'AUTOMATION_UNSUPPORTED',
23
+ 'ASSERTION_FAILED',
24
+ 'AUTHENTICATION_FAILED',
25
+ 'AUTH_CREDENTIAL_UNAVAILABLE',
26
+ 'AUTH_CREDENTIAL_INVALID',
27
+ 'ENVIRONMENT_UNAVAILABLE',
28
+ 'SEED_DATA_MISSING',
29
+ 'TEST_SETUP_FAILED',
30
+ 'APP_UNREACHABLE',
31
+ 'APP_NOT_OPEN',
32
+ 'POLICY_DENIED',
33
+ ];
34
+ /** The model-pickable codes a blocked verdict accepts; derived, never restated. */
35
+ const MODEL_BLOCKABLE_CODES = MODEL_ERROR_CODES.filter((code) => BLOCKABLE_CODES.has(code));
36
+ /** The verdict rules the built-in agent appends to its instructions. */
37
+ export 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
+ /**
42
+ * A plain AI SDK function tool with its input typed from the schema — what
43
+ * `tool()` from `ai` does, without loading `ai` to do it.
44
+ */
45
+ function schemaTool(definition) {
46
+ return definition;
47
+ }
48
+ /**
49
+ * The `complete_step` verdict tool. A blocked verdict without a blockable
50
+ * code is rejected back to the model, a passed verdict never carries a code,
51
+ * and the first accepted verdict is final.
52
+ */
53
+ export function createVerdictTool() {
54
+ let verdict;
55
+ const tool = schemaTool({
56
+ 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.',
57
+ inputSchema: z.object({
58
+ status: z.enum(['passed', 'failed', 'blocked']),
59
+ summary: z
60
+ .string()
61
+ .min(1)
62
+ .max(500)
63
+ .describe('What you did and what you saw, in plain language'),
64
+ errorCode: z.enum(MODEL_ERROR_CODES).optional(),
65
+ }),
66
+ execute: async (input) => {
67
+ if (verdict !== undefined)
68
+ return 'The step already concluded.';
69
+ if (input.status === 'blocked' &&
70
+ (input.errorCode === undefined ||
71
+ !MODEL_BLOCKABLE_CODES.includes(input.errorCode))) {
72
+ return ('Rejected: a blocked verdict requires errorCode naming what blocked you ' +
73
+ `(one of ${MODEL_BLOCKABLE_CODES.join(', ')}). ` +
74
+ 'If the application itself misbehaved, use status "failed" instead.');
75
+ }
76
+ verdict = {
77
+ status: input.status,
78
+ summary: input.summary,
79
+ ...(input.errorCode === undefined || input.status === 'passed'
80
+ ? {}
81
+ : { errorCode: input.errorCode }),
82
+ };
83
+ return 'Step concluded.';
84
+ },
85
+ });
86
+ return {
87
+ tool,
88
+ verdict: () => verdict,
89
+ concluded: () => verdict !== undefined,
90
+ };
91
+ }
92
+ /**
93
+ * AI SDK tools over the harness action grammar, limited to the verbs the
94
+ * target's backend declared. A verb the surface cannot honor is not offered
95
+ * at all, so the model never learns vocabulary it can only be rejected on.
96
+ * Every mutating tool returns the updated screen.
97
+ */
98
+ export function createGrammarTools(context, options = {}) {
99
+ const guard = options.guard ?? ((body) => body());
100
+ const { verbs } = context.target;
101
+ /** Re-observes after a mutating action so the model always sees the result. */
102
+ const acted = async (description) => {
103
+ const observation = await context.observe();
104
+ return `${description}\n\nUpdated screen (revision ${observation.revision}):\n${observation.text}`;
105
+ };
106
+ const target = z.string().min(1).describe('Node id from the newest observation, e.g. "n42"');
107
+ const tools = {
108
+ observe: schemaTool({
109
+ description: 'Capture a fresh observation of the current screen without acting.',
110
+ inputSchema: z.object({}),
111
+ execute: () => guard(async () => {
112
+ const observation = await context.observe();
113
+ return `Current screen (revision ${observation.revision}):\n${observation.text}`;
114
+ }),
115
+ }),
116
+ };
117
+ if (verbs.has('tap')) {
118
+ tools['tap'] = schemaTool({
119
+ description: 'Tap or click one node.',
120
+ inputSchema: z.object({ target }),
121
+ execute: ({ target: id }) => guard(async () => {
122
+ await context.actions.tap({ id });
123
+ return acted(`Tapped #${id}.`);
124
+ }),
125
+ });
126
+ }
127
+ if (verbs.has('type')) {
128
+ tools['type'] = schemaTool({
129
+ description: 'Type a plain-text value into one input node. Replaces the current value.',
130
+ inputSchema: z.object({ target, value: z.string() }),
131
+ execute: ({ target: id, value }) => guard(async () => {
132
+ await context.actions.type({ id }, value);
133
+ return acted(`Typed into #${id}.`);
134
+ }),
135
+ });
136
+ }
137
+ if (verbs.has('press')) {
138
+ tools['press'] = schemaTool({
139
+ description: 'Send one key (e.g. "Enter", "Escape", "Tab") to one node.',
140
+ inputSchema: z.object({ target, key: z.string().min(1).max(64) }),
141
+ execute: ({ target: id, key }) => guard(async () => {
142
+ await context.actions.press({ id }, key);
143
+ return acted(`Pressed ${key} on #${id}.`);
144
+ }),
145
+ });
146
+ }
147
+ if (verbs.has('select')) {
148
+ tools['select'] = schemaTool({
149
+ description: 'Pick one option from a select-like control by its visible label.',
150
+ inputSchema: z.object({ target, value: z.string().min(1) }),
151
+ execute: ({ target: id, value }) => guard(async () => {
152
+ await context.actions.select({ id }, value);
153
+ return acted(`Selected "${value}" in #${id}.`);
154
+ }),
155
+ });
156
+ }
157
+ if (verbs.has('scroll')) {
158
+ const direction = z.enum(['up', 'down', 'left', 'right']);
159
+ // Node-targeted scrolling rides `perform`; without it only the viewport scrolls.
160
+ tools['scroll'] = verbs.has('tap')
161
+ ? schemaTool({
162
+ description: 'Scroll the viewport, or one scrollable node when target is given.',
163
+ inputSchema: z.object({ direction, target: target.optional() }),
164
+ execute: ({ direction: way, target: id }) => guard(async () => {
165
+ await context.actions.scroll(way, id === undefined ? undefined : { id });
166
+ return acted(`Scrolled ${way}.`);
167
+ }),
168
+ })
169
+ : schemaTool({
170
+ description: 'Scroll the viewport.',
171
+ inputSchema: z.object({ direction }),
172
+ execute: ({ direction: way }) => guard(async () => {
173
+ await context.actions.scroll(way);
174
+ return acted(`Scrolled ${way}.`);
175
+ }),
176
+ });
177
+ }
178
+ if (verbs.has('navigate')) {
179
+ tools['navigate'] = schemaTool({
180
+ description: 'Navigate to a URL or app-relative path within the allowed origins.',
181
+ inputSchema: z.object({ url: z.string().min(1) }),
182
+ execute: ({ url }) => guard(async () => {
183
+ await context.actions.navigate(url);
184
+ return acted(`Navigated to ${url}.`);
185
+ }),
186
+ });
187
+ }
188
+ // Offered only when the step declared secrets and the surface can fill: an
189
+ // empty vocabulary is better than a tool the model can only be rejected on.
190
+ if (verbs.has('typeSecret') && context.step.secrets.length > 0) {
191
+ tools['type_secret'] = schemaTool({
192
+ description: 'Fill one declared secret credential into a secure input field; the plaintext never passes through you. Available: ' +
193
+ context.step.secrets.map((secret) => `"${secret.name}" (${secret.purpose})`).join(', ') +
194
+ '.',
195
+ inputSchema: z.object({ target, name: z.string().min(1) }),
196
+ execute: ({ target: id, name }) => guard(async () => {
197
+ await context.actions.typeSecret({ id }, name);
198
+ return acted(`Filled secret "${name}" into #${id}.`);
199
+ }),
200
+ });
201
+ }
202
+ return tools;
203
+ }
204
+ /**
205
+ * Model-call accounting for a loop the executor runs itself. `model` names
206
+ * the provider and model id in the report; pass the AI SDK model instance.
207
+ */
208
+ export function trackModelCalls(context, model) {
209
+ let turnStartedMs = Date.now();
210
+ return {
211
+ onStepStart: () => {
212
+ turnStartedMs = Date.now();
213
+ },
214
+ onStepEnd: (step) => {
215
+ const estimatedCostUsd = readCost(step.providerMetadata);
216
+ context.budgets.recordModelCall({
217
+ ...(step.usage.inputTokens === undefined ? {} : { inputTokens: step.usage.inputTokens }),
218
+ ...(step.usage.outputTokens === undefined ? {} : { outputTokens: step.usage.outputTokens }),
219
+ durationMs: Date.now() - turnStartedMs,
220
+ ...(typeof model?.provider === 'string' ? { provider: model.provider } : {}),
221
+ ...(typeof model?.modelId === 'string' ? { modelId: model.modelId } : {}),
222
+ ...(estimatedCostUsd === undefined ? {} : { estimatedCostUsd }),
223
+ });
224
+ },
225
+ };
226
+ }
227
+ /**
228
+ * The executor's own conversation across an attempt, kept in
229
+ * `context.attempt.memory` under `key`. Open a step with
230
+ * `[...memory.messages, { role: 'user', content }]` and `remember` the full
231
+ * transcript when it ends; the harness drops it with the attempt.
232
+ */
233
+ export function conversationMemory(context, key = 'e2e/conversation') {
234
+ const stored = context.attempt.memory.get(key);
235
+ const current = isStoredConversation(stored)
236
+ ? stored
237
+ : { messages: [], lastStepIndex: -1 };
238
+ return {
239
+ messages: current.messages,
240
+ lastStepIndex: current.lastStepIndex,
241
+ remember: (messages) => {
242
+ const kept = { messages: [...messages], lastStepIndex: context.step.index };
243
+ context.attempt.memory.set(key, kept);
244
+ },
245
+ };
246
+ }
247
+ function isStoredConversation(value) {
248
+ return (typeof value === 'object' &&
249
+ value !== null &&
250
+ 'messages' in value &&
251
+ Array.isArray(value.messages) &&
252
+ 'lastStepIndex' in value &&
253
+ typeof value.lastStepIndex === 'number');
254
+ }
255
+ //# sourceMappingURL=primitives.js.map