eve 0.75.0 → 0.75.1

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 (86) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/src/cli/commands/deploy.js +1 -1
  3. package/dist/src/cli/commands/link.d.ts +2 -1
  4. package/dist/src/cli/commands/link.js +1 -1
  5. package/dist/src/cli/commands/registry.js +1 -1
  6. package/dist/src/cli/commands/vercel-non-interactive.d.ts +6 -4
  7. package/dist/src/cli/commands/vercel-non-interactive.js +1 -1
  8. package/dist/src/compiled/.vendor-stamp.json +8 -8
  9. package/dist/src/compiled/@eve/catalog/index.js +1 -1
  10. package/dist/src/compiled/@workflow/core/global.d.ts +10 -0
  11. package/dist/src/compiled/@workflow/core/index.js +1 -1
  12. package/dist/src/compiled/@workflow/core/private.d.ts +11 -0
  13. package/dist/src/compiled/@workflow/core/private.js +1 -1
  14. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +36 -8
  15. package/dist/src/compiled/@workflow/core/runtime/helpers.js +1 -1
  16. package/dist/src/compiled/@workflow/core/runtime/lifecycle-hooks.d.ts +10 -6
  17. package/dist/src/compiled/@workflow/core/runtime/out-of-band-observation.d.ts +159 -0
  18. package/dist/src/compiled/@workflow/core/runtime/vm-mode.d.ts +28 -4
  19. package/dist/src/compiled/@workflow/core/runtime.js +4 -4
  20. package/dist/src/compiled/@workflow/core/serialization.js +1 -1
  21. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  22. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  23. package/dist/src/compiled/@workflow/world-local/index.js +5 -5
  24. package/dist/src/compiled/@workflow/world-vercel/index.js +4 -4
  25. package/dist/src/compiled/_chunks/workflow/{attribute-changes-CSqvJx6j.js → attribute-changes-BW-kbMMn.js} +1 -1
  26. package/dist/src/compiled/_chunks/workflow/dist-CyBgVS7g.js +1 -0
  27. package/dist/src/compiled/_chunks/workflow/{helpers-BXCuoPUb.js → helpers-DlLD3ov_.js} +1 -1
  28. package/dist/src/compiled/_chunks/workflow/private-tQUuwBoQ.js +1 -0
  29. package/dist/src/compiled/_chunks/workflow/{resume-hook-CvENCrxc.js → resume-hook-DMsV_b4n.js} +1 -1
  30. package/dist/src/compiled/_chunks/workflow/{run-8pLWuR2U.js → run-DzdAqdb1.js} +1 -1
  31. package/dist/src/compiled/_chunks/workflow/{serialization-vDozzDhh.js → serialization-DPdYS_w2.js} +2 -2
  32. package/dist/src/compiled/_chunks/workflow/sleep-BY6leHh8.js +1 -0
  33. package/dist/src/compiled/_chunks/workflow/{token-BKeK6DmC.js → token-D5ugC3PI.js} +1 -1
  34. package/dist/src/compiled/_chunks/workflow/{token-util-CddTZ_ef.js → token-util-Bla5Z0G9.js} +1 -1
  35. package/dist/src/compiled/_chunks/workflow/undici-D-ILjOKD.js +95 -0
  36. package/dist/src/compiled/_chunks/workflow/{wait-until-A344L2AG.js → wait-until-xbRRDuUf.js} +1 -1
  37. package/dist/src/eve-channel/request.js +1 -1
  38. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  39. package/dist/src/execution/ndjson-stream.d.ts +6 -6
  40. package/dist/src/execution/ndjson-stream.js +3 -3
  41. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  42. package/dist/src/harness/compaction/engine.d.ts +8 -19
  43. package/dist/src/harness/compaction/engine.js +1 -1
  44. package/dist/src/harness/compaction/step.d.ts +7 -1
  45. package/dist/src/harness/compaction/step.js +1 -1
  46. package/dist/src/harness/emission.js +1 -1
  47. package/dist/src/harness/model-call/call.d.ts +2 -3
  48. package/dist/src/harness/model-call/call.js +1 -1
  49. package/dist/src/harness/model-call/model.d.ts +4 -5
  50. package/dist/src/harness/model-call/model.js +1 -1
  51. package/dist/src/harness/model-call/request.d.ts +1 -2
  52. package/dist/src/harness/model-call/request.js +1 -1
  53. package/dist/src/harness/model-call/retry.d.ts +1 -1
  54. package/dist/src/harness/model-call/retry.js +1 -1
  55. package/dist/src/harness/model-call/tools.d.ts +3 -4
  56. package/dist/src/harness/model-call/tools.js +1 -1
  57. package/dist/src/harness/model-call/usage.js +1 -1
  58. package/dist/src/harness/model-profile.d.ts +23 -0
  59. package/dist/src/harness/model-profile.js +1 -0
  60. package/dist/src/harness/prompt-cache.d.ts +5 -53
  61. package/dist/src/harness/prompt-cache.js +1 -1
  62. package/dist/src/harness/provider-safety.d.ts +3 -5
  63. package/dist/src/harness/provider-safety.js +1 -1
  64. package/dist/src/harness/provider-tools.d.ts +5 -13
  65. package/dist/src/harness/provider-tools.js +1 -1
  66. package/dist/src/harness/step-hooks.d.ts +2 -3
  67. package/dist/src/harness/step-hooks.js +1 -1
  68. package/dist/src/harness/tools.d.ts +2 -3
  69. package/dist/src/harness/tools.js +1 -1
  70. package/dist/src/harness/turn-tag-state.d.ts +12 -0
  71. package/dist/src/harness/turn-tag-state.js +1 -1
  72. package/dist/src/internal/application/package.js +1 -1
  73. package/dist/src/internal/gateway.d.ts +0 -13
  74. package/dist/src/internal/gateway.js +1 -1
  75. package/dist/src/setup/scaffold/create/project.js +1 -1
  76. package/dist/src/setup/scaffold/create/web-template.d.ts +3 -2
  77. package/dist/src/setup/scaffold/create/web-template.js +383 -411
  78. package/dist/src/setup/vercel-project.d.ts +1 -1
  79. package/dist/src/setup/vercel-project.js +0 -0
  80. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  81. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  82. package/package.json +6 -6
  83. package/dist/src/compiled/_chunks/workflow/dist-DmXynLVH.js +0 -1
  84. package/dist/src/compiled/_chunks/workflow/private-Dlf90Zvn.js +0 -1
  85. package/dist/src/compiled/_chunks/workflow/signal-exit-iIdjQcCK.js +0 -95
  86. package/dist/src/compiled/_chunks/workflow/sleep-BMqbraZM.js +0 -1
@@ -0,0 +1,159 @@
1
+ import type { QueueItem } from '../global.js';
2
+ /**
3
+ * Whether any event an out-of-band writer could append right now is able to
4
+ * change the decisions a suspension leads to. Computed once per suspension
5
+ * that schedules inline steps, and exposed for the run-ahead gate described
6
+ * below. Nothing consumes it for control flow yet; the runtime records it on
7
+ * the invocation span so the eligible share of boundaries can be measured.
8
+ *
9
+ * ## Writers
10
+ *
11
+ * The orchestrator replaying the run is one writer. Every other writer is
12
+ * out-of-band to it:
13
+ *
14
+ * | Writer | Event | Path-changing when |
15
+ * |---|---|---|
16
+ * | webhook / `resumeHook()` | `hook_received` | workflow code is waiting on that hook's next payload |
17
+ * | another run's `createHook({ experimental_force })` | `hook_disposed` | same: it rejects waiting payload awaiters, and later awaits |
18
+ * | a step's `AbortController.abort()` | `hook_received` on a system hook | always: `signal.aborted` and abort listeners are read synchronously, with no `then` to observe |
19
+ * | wait timer | `wait_completed` | the wait is due (see below) |
20
+ * | `run.wakeUp()` / dashboard "cancel sleeps" | `wait_completed` | any time; not detected, see below |
21
+ * | step executors in other invocations | `step_completed` / `step_failed` / `step_retrying` | unknown: step promises are native, so their awaiters are invisible |
22
+ * | `runs.cancel()` | `run_cancelled` | never changes a decision; it ends the run (see "Pipeline depth") |
23
+ * | `setAttributes()` API | `attr_set` | never: workflow code writes attributes but cannot read them |
24
+ *
25
+ * ## Why an unawaited hook is inert
26
+ *
27
+ * On the node:vm engine a `hook_received` for a hook with no waiting consumer
28
+ * is hydrated and buffered as an UNARMED delivery barrier (`workflow/hook.ts`).
29
+ * Step results do not order behind unarmed barriers, the log-order-draws
30
+ * turnstile only waits on armed ones, and the workflow clock advances on
31
+ * delivery rather than consumption (`WorkflowOrchestratorContext.advanceClock`),
32
+ * so the buffered payload moves neither the step results around it nor
33
+ * `Date.now()`. A replay over a log with the payload inserted at any position
34
+ * after the hook's creation, and before its first await, makes the same
35
+ * decisions as one without it. The first `then()` on the hook is visible to the
36
+ * runtime because `Hook` is a custom thenable, which is what
37
+ * `WorkflowSuspension.observedHookIds` records.
38
+ *
39
+ * Over-reporting is possible and safe: a `.then` left behind by a settled
40
+ * `Promise.race` keeps its hook observed although the branch that would read
41
+ * it is gone.
42
+ *
43
+ * The QuickJS engine advances its clock on every event it reads, unclaimed
44
+ * payloads included, so this argument does not hold there. Its suspensions do
45
+ * not carry `observedHookIds`, which classifies every open hook as observed.
46
+ *
47
+ * ## Waits
48
+ *
49
+ * Sleep promises are native, so whether anything still awaits a wait cannot be
50
+ * told. A wait is instead classified by time: one whose `resumeAt` falls within
51
+ * the invocation's inline window plus the clock-skew allowance
52
+ * (`OPEN_WAIT_CLOCK_SKEW_MS`) can have its timer fire while this invocation is
53
+ * still deciding, and counts as path-changing; one due later cannot. The
54
+ * caller computes this from both the log and the suspension's own queue,
55
+ * because either can hold a wait the other lacks.
56
+ *
57
+ * `run.wakeUp()` completes waits regardless of `resumeAt`, so a far-future
58
+ * wait is only inert with respect to its own timer. Today that is a delayed
59
+ * wake at worst. Under run-ahead it is not (see below), so run-ahead has to
60
+ * close that gap before it relies on {@link OutOfBandObservation.inert} with
61
+ * any wait open, for example by treating every open wait as observed while a
62
+ * pipeline is in flight, or by having wake-ups enqueue a delivery instead of
63
+ * writing `wait_completed` directly.
64
+ *
65
+ * ## Intended use: de-opting run-ahead
66
+ *
67
+ * Run-ahead: once an inline step's body returns, feed its result to the
68
+ * retained VM and continue to the next boundary without waiting for the
69
+ * `step_completed` write (and the inline delta it carries) to come back, so
70
+ * consecutive steps overlap their writes. It requires a single-orchestrator
71
+ * guarantee whose stale holders are fenced (their writes refused, not merely
72
+ * their lease taken), which does not exist yet. Without it a second
73
+ * orchestrator is a writer this classification does not cover.
74
+ *
75
+ * Run-ahead removes the property today's replays rest on: a replay's view is a
76
+ * *prefix* of the log, and anything it missed lands after everything it read.
77
+ * A speculative view is the committed prefix plus this invocation's own
78
+ * in-flight writes, and an out-of-band event can commit *between* those writes.
79
+ * A later fresh replay sees it there. If the event was path-changing, that
80
+ * replay decides differently from the writes already committed after it,
81
+ * which is a corrupted log, not a late observation. {@link inert} is the
82
+ * condition under which such an interleaving cannot change any decision.
83
+ *
84
+ * The gate, once run-ahead exists:
85
+ *
86
+ * 1. Evaluate at every boundary, before issuing that boundary's writes.
87
+ * Observation changes as code runs: the first `await hook` turns a hook
88
+ * from inert to observed.
89
+ * 2. `inert === false`: do not run ahead past this boundary. Drain the
90
+ * in-flight writes, fold their skipped-slot reports and deltas into the
91
+ * log, and let the VM consume them in log order before deciding. That is
92
+ * today's per-step cost, paid only at these boundaries.
93
+ * 3. `inert === true`: run ahead. Events the in-flight writes report back are
94
+ * for entities nobody waits on; folding them buffers them, which changes no
95
+ * decision already taken.
96
+ * 4. A boundary where code is waiting on a hook with nothing else to run needs
97
+ * no drain to be safe: suspending without a payload only delays the run.
98
+ * It still drains before parking, so a payload already committed below an
99
+ * in-flight write is acted on now.
100
+ *
101
+ * ## Pipeline depth
102
+ *
103
+ * Run-ahead must cap how many steps it executes past the last write it has
104
+ * seen confirmed, independently of this classification:
105
+ *
106
+ * - Cancellation. `run_cancelled` never changes a decision, but every step
107
+ * body started after it committed is a side effect the user asked not to
108
+ * happen. The depth bounds that to the cap.
109
+ * - Lost invocations. Writes that never land (crash, timeout, lost lease) are
110
+ * re-executed by whoever recovers the run, so every unconfirmed step is a
111
+ * possible duplicate side effect.
112
+ * - Drain cost. Rule 2 above waits for every in-flight write; the cap bounds
113
+ * how long a sync point can stall.
114
+ * - Exposure. The writers this classification cannot see (`run.wakeUp()`,
115
+ * other step executors, a stale orchestrator) can only interleave inside the
116
+ * in-flight window, which the cap keeps short.
117
+ *
118
+ * A small fixed depth (one or two unconfirmed steps) captures most of the
119
+ * latency win, since each extra step only saves one more round trip, and
120
+ * should be tunable per deployment like the other inline-loop knobs.
121
+ */
122
+ export interface OutOfBandObservation {
123
+ /** Open user hooks with workflow code waiting on their next payload. */
124
+ observedHookCount: number;
125
+ /** Open user hooks nobody is waiting on: their payloads are inert. */
126
+ unobservedHookCount: number;
127
+ /**
128
+ * Open user hooks with unknown observation, because the suspension carried
129
+ * no `observedHookIds`. Counted as path-changing.
130
+ */
131
+ unknownHookCount: number;
132
+ /** Open `AbortController` system hooks: always path-changing. */
133
+ abortSignalHookCount: number;
134
+ /**
135
+ * Pending steps this invocation does not execute itself. Their terminal
136
+ * events come from another executor, and their awaiters cannot be seen, so
137
+ * any of them is counted as path-changing.
138
+ */
139
+ externalStepCount: number;
140
+ /** An open wait can fire before this invocation's inline window ends. */
141
+ waitDue: boolean;
142
+ /**
143
+ * No writer this classification can see is able to append an event that
144
+ * changes the decisions this suspension leads to. Excludes `run.wakeUp()`
145
+ * and a second orchestrator; see the module documentation.
146
+ */
147
+ inert: boolean;
148
+ }
149
+ export declare function observeOutOfBandWriters(input: {
150
+ /** The suspension's queue: every open hook, wait, and pending step. */
151
+ items: readonly QueueItem[];
152
+ /** `WorkflowSuspension.observedHookIds`. */
153
+ observedHookIds: ReadonlySet<string> | undefined;
154
+ /** Steps this invocation executes itself (inline or as owner recovery). */
155
+ selfExecutedStepIds: ReadonlySet<string>;
156
+ /** Whether an open wait is due within the invocation's inline window. */
157
+ waitDue: boolean;
158
+ }): OutOfBandObservation;
159
+ //# sourceMappingURL=out-of-band-observation.d.ts.map
@@ -41,6 +41,14 @@ export declare function getWorkflowVmFromEnv(env?: NodeJS.ProcessEnv): WorkflowV
41
41
  * unknown value.
42
42
  */
43
43
  export declare function useQuickJSVm(workflowRun: Pick<WorkflowRun, 'executionContext'>): boolean;
44
+ /**
45
+ * Snapshot threshold the QuickJS engine uses when neither the run's
46
+ * `executionContext` nor `WORKFLOW_SNAPSHOT_THRESHOLD` specifies one.
47
+ * Short runs (most workflows) never reach it and so never pay the
48
+ * snapshot cost; long-running runs stop scaling their resume cost with
49
+ * total event-log length. Set `WORKFLOW_SNAPSHOT_THRESHOLD=0` to opt out.
50
+ */
51
+ export declare const DEFAULT_QUICKJS_SNAPSHOT_THRESHOLD = 1000;
44
52
  /**
45
53
  * Read and validate the `WORKFLOW_SNAPSHOT_THRESHOLD` env var.
46
54
  *
@@ -49,9 +57,9 @@ export declare function useQuickJSVm(workflowRun: Pick<WorkflowRun, 'executionCo
49
57
  * invocations restore the VM and replay only the events recorded since —
50
58
  * instead of re-executing the workflow from the top against the full log.
51
59
  *
52
- * `0` (or unset) disables snapshotting entirely: short-lived runs never
53
- * pay the snapshot cost, while long/forever runs can opt in. `1`
54
- * effectively snapshots at every suspension.
60
+ * When unset, the QuickJS engine uses
61
+ * {@link DEFAULT_QUICKJS_SNAPSHOT_THRESHOLD}. `0` explicitly disables
62
+ * snapshotting. `1` effectively snapshots at every suspension.
55
63
  *
56
64
  * Returns the configured threshold, or `undefined` if unset/empty.
57
65
  * Throws {@link WorkflowRuntimeError} for non-integer or negative values.
@@ -62,12 +70,28 @@ export declare function getSnapshotThresholdFromEnv(env?: NodeJS.ProcessEnv): nu
62
70
  * `executionContext.snapshotThreshold` (set by the SDK at `start()` when
63
71
  * `WORKFLOW_SNAPSHOT_THRESHOLD` is set on the client) wins so a run keeps
64
72
  * the policy it started with; otherwise the handler's env var; otherwise
65
- * `0` (disabled). Only consulted by the QuickJS engine.
73
+ * {@link DEFAULT_QUICKJS_SNAPSHOT_THRESHOLD}. Only consulted by the QuickJS
74
+ * engine.
66
75
  *
67
76
  * Throws on an invalid value. The workflow handler uses
68
77
  * {@link getSnapshotThresholdForHandler}, which doesn't.
69
78
  */
70
79
  export declare function getSnapshotThreshold(workflowRun: WorkflowRun): number;
80
+ /**
81
+ * The snapshot threshold explicitly configured for a run (stamped into its
82
+ * `executionContext` or set via `WORKFLOW_SNAPSHOT_THRESHOLD` on the
83
+ * handler), or `undefined` when the run falls back to
84
+ * {@link DEFAULT_QUICKJS_SNAPSHOT_THRESHOLD}.
85
+ *
86
+ * Throws on an invalid value.
87
+ */
88
+ export declare function getConfiguredSnapshotThreshold(workflowRun: WorkflowRun): number | undefined;
89
+ /**
90
+ * Whether the run's snapshot threshold was explicitly configured rather
91
+ * than falling back to {@link DEFAULT_QUICKJS_SNAPSHOT_THRESHOLD}. Never
92
+ * throws: an invalid value counts as configured.
93
+ */
94
+ export declare function isSnapshotThresholdConfigured(workflowRun: WorkflowRun): boolean;
71
95
  /**
72
96
  * {@link getSnapshotThreshold} for the workflow handler: an invalid value
73
97
  * disables snapshotting (with a warning through `onInvalid`) instead of