You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add durable execution retries to `runtime.tool()`. Connectors can throw `RetryableError` with an optional delay; by default the runtime makes three total attempts, honors that delay or uses bounded exponential backoff, and can be customized or disabled with `retry`. Failed passes restart under the same execution id, replaying applied calls from the log and re-executing only the failure boundary. Dynamic-worker timeouts are surfaced as structured failures but are not retried by default, so applications can conservatively decide which executions are safe to retry. Attempt fencing prevents calls or results from a superseded timed-out sandbox from mutating the replay log.
|`runtime.tool(options?)`| The single model-facing AI SDK tool, `codemode({ code })`|
26
+
|`runtime.tool(options?)`| The framework-independent model-facing tool, `codemode({ code })`|
27
27
|`runtime.pending(executionId?)`| Actions awaiting approval — drives approval UIs; no id aggregates all paused runs |
28
28
|`runtime.approve({ executionId })`| Approve the pending action and continue via replay |
29
29
|`runtime.reject({ seq, executionId })`| Reject a pending action; ends the execution. Returns `false` if it was a no-op (action no longer pending — approved or rejected elsewhere) |
@@ -149,6 +149,32 @@ A tool can opt out of result recording with [`replay: "reexecute"`](./connectors
149
149
150
150
Any single recorded value (a call's arguments, a recorded result, the final result) is capped at 1 MB serialized (`MAX_DURABLE_VALUE_BYTES`). Truncating a logged value is never an option — replay would feed resumed code corrupted data — so an oversized argument or call result **fails the run** with a model-actionable error suggesting the data be written to a file/workspace and passed by reference. An oversized **final** result does not fail the run (replay never needs it): the run completes, the model receives the real value, and the audit trail stores a placeholder note.
151
151
152
+
## Retrying failed passes
153
+
154
+
A connector requests a retry by throwing `RetryableError`. By default the runtime makes three total attempts, honoring `retryAfterMs` when present and otherwise using bounded exponential backoff (500ms, 1s, up to 10s). A retry keeps the same execution id and re-runs the stored code: applied calls replay from the durable log, while the call left `executing` at the failure boundary executes again. No configuration is needed for this default.
The error message and optional `retryAfterMs` cross the connector RPC and sandbox boundaries as structured metadata. Dynamic-worker timeouts also arrive as `failure.kind === "timeout"`, but are not retried by default: an operation may have succeeded remotely before its response was lost, so the application must decide whether that boundary is safe to repeat.
175
+
176
+
Before retry policy or delay callbacks run, the runtime advances a durable attempt fence. Late calls and results from the superseded sandbox are inert and cannot overwrite the newer pass.
177
+
152
178
## Rollback
153
179
154
180
Rollback walks the log backward and calls the `revert` of **every** applied action that has one — independent of `requiresApproval`. A non-approval write with a `revert` is still undone; an approval-gated action without a `revert` is not. `revert` (via `revertAction`) returns whether it actually reverted, and the runtime marks only those entries `reverted`:
Copy file name to clipboardExpand all lines: packages/codemode/README.md
+43Lines changed: 43 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -380,6 +380,49 @@ The `tool(name, t)` decoration hook adjusts tools you didn't author inline (used
380
380
381
381
The agent drives approvals through the runtime: `runtime.pending()`, `runtime.approve({ executionId })`, `runtime.reject({ seq, executionId })`, `runtime.rollback({ executionId })` (see [docs/codemode/approvals.md](../../docs/codemode/approvals.md)).
382
382
383
+
### Durable retries
384
+
385
+
A runtime automatically retries `RetryableError` under the same execution id, up to three total attempts. Applied connector calls replay from the durable log; the call at the failure boundary executes again. `retryAfterMs` is honored when present, otherwise retries use bounded exponential backoff (500ms, 1s, up to 10s).
Each pass has a durable attempt fence. If a timed-out old sandbox finishes after its retry started, its later calls and results are ignored rather than corrupting the replay log.
425
+
383
426
### Snippets
384
427
385
428
Snippets are durable, addressable saved scripts. The model writes and runs scripts; the developer promotes the ones worth keeping (`runtime.saveSnippet`), and the model reuses them (`codemode.run`). No authoring step, no skill-source interface.
0 commit comments