diff --git a/packages/durable/README.md b/packages/durable/README.md index 6f8898d26..ca9826575 100644 --- a/packages/durable/README.md +++ b/packages/durable/README.md @@ -594,7 +594,7 @@ stream.start(async (events) => { }); ``` -Events are derived from commits, one batch per commit, and apply on top of the snapshot. Message and tool updates carry deltas: text and thinking appends, appended tool-call argument text, and output trims and appends. When a consumer falls more than 100 batches behind, it receives a fresh `snapshot` event instead. See `test/examples/19-json.ts` for the full stream of one run. +Events are derived from commits, one batch per commit, and apply on top of the snapshot. Message and tool updates carry deltas: text and thinking appends, appended tool-call argument text, and output trims and appends. When a consumer falls more than 100 batches behind, it receives a fresh `snapshot` event instead. See `test/examples/18-json.ts` for the full stream of one run. ## Hooks @@ -670,8 +670,8 @@ Owned work belongs to its owner: The examples show both patterns as product code: -- [`22-subagent-foreground.ts`](test/examples/22-subagent-foreground.ts): the tool above, returning the child's answer. The UI finds the child through the call's `details` and prints the child's events indented under the call. -- [`23-subagent-background.ts`](test/examples/23-subagent-background.ts): persistent subagents behind one `subagent` tool that spawns, messages (steer or follow-up), waits for, stops, and lists them. Each child is owned by a background anchor task, so the parent's Esc and idle waits never reach it. Each message is delivered by a background reporter task that posts the answer back to the parent as a follow-up input once it arrives; request IDs keep a restart from sending a message or a report twice. +- [`21-subagent-foreground.ts`](test/examples/21-subagent-foreground.ts): the tool above, returning the child's answer. The UI finds the child through the call's `details` and prints the child's events indented under the call. +- [`22-subagent-background.ts`](test/examples/22-subagent-background.ts): persistent subagents behind one `subagent` tool that spawns, messages (steer or follow-up), waits for, stops, and lists them. Each child is owned by a background anchor task, so the parent's Esc and idle waits never reach it. Each message is delivered by a background reporter task that posts the answer back to the parent as a follow-up input once it arrives; request IDs keep a restart from sending a message or a report twice. ## Child Tasks @@ -698,7 +698,7 @@ decide: async (task, runtime, context) => { - **Finishing:** a task that finishes while work it owns is still running is `completing`: its outcome is decided, but it becomes terminal, and `waitForTask()` returns, only once that work is done. A failed or aborted outcome aborts that work first. - **Aborting:** abort runs bottom-up. Aborting a task aborts the work it owns first, and its own abort handler starts only once that work is done, so each task undoes its own effects. -[`24-child-tasks.ts`](test/examples/24-child-tasks.ts) runs a checkout with four payments: a declined card, a cancelled checkout, and a restart while the payments run. +[`23-child-tasks.ts`](test/examples/23-child-tasks.ts) runs a checkout with four payments: a declined card, a cancelled checkout, and a restart while the payments run. ## Task Graph @@ -714,7 +714,7 @@ graph.start(async (value) => { }); ``` -A task appears with the commit that creates it and leaves with the commit that makes it terminal. Statuses are the committed ones: `pending`, `running`, `waiting` (with `on` and `policy`), and `completing` (with the held outcome's status). After a restart, tasks that were `running` show as `pending` until they run again. Whether a pending task is blocked by a missing definition is not part of the graph; `harness.inspect()` reports that. The graph lists live tasks only: once a subagent's owner task is terminal, a later task in its conversation is a top-level node, and the conversation's `ConversationRecord.owner` (also in its view's `conversation`) links it to its parent. [`24-child-tasks.ts`](test/examples/24-child-tasks.ts) prints the checkout's tree while its payments run. +A task appears with the commit that creates it and leaves with the commit that makes it terminal. Statuses are the committed ones: `pending`, `running`, `waiting` (with `on` and `policy`), and `completing` (with the held outcome's status). After a restart, tasks that were `running` show as `pending` until they run again. Whether a pending task is blocked by a missing definition is not part of the graph; `harness.inspect()` reports that. The graph lists live tasks only: once a subagent's owner task is terminal, a later task in its conversation is a top-level node, and the conversation's `ConversationRecord.owner` (also in its view's `conversation`) links it to its parent. [`23-child-tasks.ts`](test/examples/23-child-tasks.ts) prints the checkout's tree while its payments run. ## Your Own State @@ -739,7 +739,7 @@ await root.commit(async (tx) => { console.log(await harness.snapshot(Todos, root.id, context)); ``` -`harness.watchDoc()` watches one document like the view above. `HarnessOptions.conversationCreated(tx, conversation)` runs in every commit that creates or forks a conversation, including a tool's raw `tx.createConversation()`, so every conversation gets your documents; `init` in `createConversation()`, `fork()`, and `root()` writes per-call data in the same commit. An extension's tools, sections, and hooks read their own documents through `api` or `input.read`, and treat an absent one as its default ([`11-extension-state.ts`](test/examples/11-extension-state.ts)). +`harness.watchDoc()` watches one document like the view above. `HarnessOptions.conversationCreated(tx, conversation)` runs in every commit that creates or forks a conversation, including a tool's raw `tx.createConversation()`, so every conversation gets your documents; `init` in `createConversation()`, `fork()`, and `root()` writes per-call data in the same commit. An extension's tools, sections, and hooks read their own documents through `api` or `input.read`, and treat an absent one as its default ([`10-extension-state.ts`](test/examples/10-extension-state.ts)). ## Usage and Cost @@ -832,29 +832,29 @@ A failure closes the Harness by itself; `closed` settles once that close is done Runnable examples live in [`test/examples`](test/examples). Run one from this package directory with: ```bash -node --conditions=source --experimental-strip-types test/examples/14-chat.ts +node --conditions=source --experimental-strip-types test/examples/13-chat.ts ``` | Example | Shows | |---|---| -| [14-chat](test/examples/14-chat.ts) | One question and answer | -| [16-real-model](test/examples/16-real-model.ts) | Streaming an answer from OpenAI | -| [17-coding-tools](test/examples/17-coding-tools.ts) | A tool-using turn on JSONL storage | -| [18-print](test/examples/18-print.ts) | Print mode: submit a prompt, print the answer | -| [19-json](test/examples/19-json.ts) | JSON mode: agent events or raw view operations, on SQLite, JSONL, or memory | -| [20-inbox](test/examples/20-inbox.ts) | Steers, follow-ups, writes, and withdrawal while busy | -| [21-late-join](test/examples/21-late-join.ts) | Attaching a view and an event stream mid-run | -| [22-subagent-foreground](test/examples/22-subagent-foreground.ts) | A replay-safe subagent tool whose child the call owns, with the child's events under the call | -| [23-subagent-background](test/examples/23-subagent-background.ts) | Persistent subagents: spawn, steer, stop, list, answers reported back, restart-safe | -| [24-child-tasks](test/examples/24-child-tasks.ts) | A checkout that owns and waits for four payments: failFast, abort, restart | -| [25-compaction](test/examples/25-compaction.ts) | A long chat compacted in the background, manually, and after a context overflow | -| [26-coding-agent](test/examples/26-coding-agent.ts) | CodingTools, live settings from a settings object, an environment that follows the conversation's directory | -| [27-plan-mode](test/examples/27-plan-mode.ts) | A read-only plan mode as an extension with its own document, switched with `configure()` | -| [28-reviewer](test/examples/28-reviewer.ts) | A reviewer conversation with its own model, extensions, tools, directory, and review loop | -| [29-sandbox-per-conversation](test/examples/29-sandbox-per-conversation.ts) | An environment per conversation, looked up from an app document | -| [30-tool-override](test/examples/30-tool-override.ts) | A same-name bash for some conversations, and a wrapper that times whichever bash won | -| [31-reload-and-restart](test/examples/31-reload-and-restart.ts) | Reloading an extension mid-call, and stored choices surviving a restart | -| [00](test/examples/00-conversation.ts)–[13](test/examples/13-recovery.ts) | The layers underneath: sessions, documents, forks, watches, the Harness, agent configuration, reload, extension state, tasks, recovery | +| [13-chat](test/examples/13-chat.ts) | One question and answer | +| [15-real-model](test/examples/15-real-model.ts) | Streaming an answer from OpenAI | +| [16-coding-tools](test/examples/16-coding-tools.ts) | A tool-using turn on JSONL storage | +| [17-print](test/examples/17-print.ts) | Print mode: submit a prompt, print the answer | +| [18-json](test/examples/18-json.ts) | JSON mode: agent events or raw view operations, on SQLite, JSONL, or memory | +| [19-inbox](test/examples/19-inbox.ts) | Steers, follow-ups, writes, and withdrawal while busy | +| [20-late-join](test/examples/20-late-join.ts) | Attaching a view and an event stream mid-run | +| [21-subagent-foreground](test/examples/21-subagent-foreground.ts) | A replay-safe subagent tool whose child the call owns, with the child's events under the call | +| [22-subagent-background](test/examples/22-subagent-background.ts) | Persistent subagents: spawn, steer, stop, list, answers reported back, restart-safe | +| [23-child-tasks](test/examples/23-child-tasks.ts) | A checkout that owns and waits for four payments: failFast, abort, restart | +| [24-compaction](test/examples/24-compaction.ts) | A long chat compacted in the background, manually, and after a context overflow | +| [25-coding-agent](test/examples/25-coding-agent.ts) | CodingTools, live settings from a settings object, an environment that follows the conversation's directory | +| [26-plan-mode](test/examples/26-plan-mode.ts) | A read-only plan mode as an extension with its own document, switched with `configure()` | +| [27-reviewer](test/examples/27-reviewer.ts) | A reviewer conversation with its own model, extensions, tools, directory, and review loop | +| [28-sandbox-per-conversation](test/examples/28-sandbox-per-conversation.ts) | An environment per conversation, looked up from an app document | +| [29-tool-override](test/examples/29-tool-override.ts) | A same-name bash for some conversations, and a wrapper that times whichever bash won | +| [30-reload-and-restart](test/examples/30-reload-and-restart.ts) | Reloading an extension mid-call, and stored choices surviving a restart | +| [00](test/examples/00-conversation.ts)–[12](test/examples/12-recovery.ts) | The layers underneath: sessions, documents, forks, watches, the Harness, agent configuration, reload, extension state, tasks, recovery | Examples that call OpenAI need `OPENAI_API_KEY`; most use the faux provider otherwise. diff --git a/packages/durable/test/examples/03-owned-conversations.ts b/packages/durable/test/examples/03-owned-conversations.ts index a6086a4cc..c70095b25 100644 --- a/packages/durable/test/examples/03-owned-conversations.ts +++ b/packages/durable/test/examples/03-owned-conversations.ts @@ -13,7 +13,7 @@ const session = createSession(new MemoryStorage()); // all of them exist or none do. // A task definition needs a name, a version, the task's starting state, a -// handler for every phase, and an abort handler (12-tasks.ts runs a task). +// handler for every phase, and an abort handler (11-tasks.ts runs a task). // This example only creates the task record; a plain Session never runs it. const Supervisor = defineTask({ name: "example.supervisor", diff --git a/packages/durable/test/examples/05-watches.ts b/packages/durable/test/examples/04-watches.ts similarity index 98% rename from packages/durable/test/examples/05-watches.ts rename to packages/durable/test/examples/04-watches.ts index 9dba1c965..4ed33f1af 100644 --- a/packages/durable/test/examples/05-watches.ts +++ b/packages/durable/test/examples/04-watches.ts @@ -1,6 +1,6 @@ // Serialize asynchronous document work with a watch. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/05-watches.ts +// node --conditions=source --experimental-strip-types test/examples/04-watches.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { createSession, defineDoc, MemoryStorage } from "../../src/index.ts"; diff --git a/packages/durable/test/examples/06-harness.ts b/packages/durable/test/examples/05-harness.ts similarity index 99% rename from packages/durable/test/examples/06-harness.ts rename to packages/durable/test/examples/05-harness.ts index e4ebdeb6d..ad33c0d0c 100644 --- a/packages/durable/test/examples/06-harness.ts +++ b/packages/durable/test/examples/05-harness.ts @@ -1,6 +1,6 @@ // Open a Harness with a registry of extensions. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/06-harness.ts +// node --conditions=source --experimental-strip-types test/examples/05-harness.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { Type } from "@earendil-works/pi-ai"; import { createModels } from "@earendil-works/pi-ai/models"; diff --git a/packages/durable/test/examples/07-configuration.ts b/packages/durable/test/examples/06-configuration.ts similarity index 99% rename from packages/durable/test/examples/07-configuration.ts rename to packages/durable/test/examples/06-configuration.ts index 1d6a7c019..03184b6d8 100644 --- a/packages/durable/test/examples/07-configuration.ts +++ b/packages/durable/test/examples/06-configuration.ts @@ -1,6 +1,6 @@ // Per-conversation agent choices and Harness-wide settings. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/07-configuration.ts +// node --conditions=source --experimental-strip-types test/examples/06-configuration.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { Type } from "@earendil-works/pi-ai"; import { createModels } from "@earendil-works/pi-ai/models"; diff --git a/packages/durable/test/examples/08-harness-conversations.ts b/packages/durable/test/examples/07-harness-conversations.ts similarity index 98% rename from packages/durable/test/examples/08-harness-conversations.ts rename to packages/durable/test/examples/07-harness-conversations.ts index da07f3055..4ade44b67 100644 --- a/packages/durable/test/examples/08-harness-conversations.ts +++ b/packages/durable/test/examples/07-harness-conversations.ts @@ -1,6 +1,6 @@ // Conversation handles, typed entries, created conversations, and forks. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/08-harness-conversations.ts +// node --conditions=source --experimental-strip-types test/examples/07-harness-conversations.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { createModels } from "@earendil-works/pi-ai/models"; import { createRegistry, defineEntry, Harness, MemoryStorage } from "../../src/index.ts"; diff --git a/packages/durable/test/examples/09-context.ts b/packages/durable/test/examples/08-context.ts similarity index 99% rename from packages/durable/test/examples/09-context.ts rename to packages/durable/test/examples/08-context.ts index 8082b8c1e..98c1642b7 100644 --- a/packages/durable/test/examples/09-context.ts +++ b/packages/durable/test/examples/08-context.ts @@ -1,6 +1,6 @@ // Transcript history and model context. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/09-context.ts +// node --conditions=source --experimental-strip-types test/examples/08-context.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import type { AssistantMessage, Message, StopReason, ToolResultMessage } from "@earendil-works/pi-ai"; import { createModels } from "@earendil-works/pi-ai/models"; diff --git a/packages/durable/test/examples/10-registry-reload.ts b/packages/durable/test/examples/09-registry-reload.ts similarity index 98% rename from packages/durable/test/examples/10-registry-reload.ts rename to packages/durable/test/examples/09-registry-reload.ts index 97c668be0..4135650ee 100644 --- a/packages/durable/test/examples/10-registry-reload.ts +++ b/packages/durable/test/examples/09-registry-reload.ts @@ -1,6 +1,6 @@ // Reload extension code through the registry. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/10-registry-reload.ts +// node --conditions=source --experimental-strip-types test/examples/09-registry-reload.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { Type } from "@earendil-works/pi-ai"; import { createModels } from "@earendil-works/pi-ai/models"; diff --git a/packages/durable/test/examples/11-extension-state.ts b/packages/durable/test/examples/10-extension-state.ts similarity index 99% rename from packages/durable/test/examples/11-extension-state.ts rename to packages/durable/test/examples/10-extension-state.ts index 8bd2e75da..f2d518214 100644 --- a/packages/durable/test/examples/11-extension-state.ts +++ b/packages/durable/test/examples/10-extension-state.ts @@ -1,6 +1,6 @@ // An extension that keeps its own per-conversation document. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/11-extension-state.ts +// node --conditions=source --experimental-strip-types test/examples/10-extension-state.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { Type } from "@earendil-works/pi-ai"; import { createModels } from "@earendil-works/pi-ai/models"; diff --git a/packages/durable/test/examples/12-tasks.ts b/packages/durable/test/examples/11-tasks.ts similarity index 97% rename from packages/durable/test/examples/12-tasks.ts rename to packages/durable/test/examples/11-tasks.ts index 26865ca97..bb55b554f 100644 --- a/packages/durable/test/examples/12-tasks.ts +++ b/packages/durable/test/examples/11-tasks.ts @@ -1,6 +1,6 @@ // Run a durable task. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/12-tasks.ts +// node --conditions=source --experimental-strip-types test/examples/11-tasks.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { createModels } from "@earendil-works/pi-ai/models"; import { createRegistry, defineExtension, defineTask, Harness, MemoryStorage } from "../../src/index.ts"; @@ -52,7 +52,7 @@ registry.install(defineExtension({ name: "payments", tasks: [Payment] })); const harness = await Harness.open(new MemoryStorage(), { models: createModels(), registry }, context); const root = await harness.root(context); // Every task names its owner. This one belongs to the conversation; a task can -// also own child tasks and wait for them (24-child-tasks.ts). +// also own child tasks and wait for them (23-child-tasks.ts). const paymentId = await root.commit( (tx) => tx.createTask(Payment, { amount: 5 }, { ownership: { kind: "conversation" } }), context, diff --git a/packages/durable/test/examples/13-recovery.ts b/packages/durable/test/examples/12-recovery.ts similarity index 99% rename from packages/durable/test/examples/13-recovery.ts rename to packages/durable/test/examples/12-recovery.ts index 2b8c23ca9..42063e173 100644 --- a/packages/durable/test/examples/13-recovery.ts +++ b/packages/durable/test/examples/12-recovery.ts @@ -1,6 +1,6 @@ // Close, reopen, and continue where a task stopped. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/13-recovery.ts +// node --conditions=source --experimental-strip-types test/examples/12-recovery.ts import { mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; diff --git a/packages/durable/test/examples/14-chat.ts b/packages/durable/test/examples/13-chat.ts similarity index 95% rename from packages/durable/test/examples/14-chat.ts rename to packages/durable/test/examples/13-chat.ts index 5abc706f0..5a6d1a3b3 100644 --- a/packages/durable/test/examples/14-chat.ts +++ b/packages/durable/test/examples/13-chat.ts @@ -1,6 +1,6 @@ // A chat turn. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/14-chat.ts +// node --conditions=source --experimental-strip-types test/examples/13-chat.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { createModels } from "@earendil-works/pi-ai/models"; import { fauxAssistantMessage, fauxProvider } from "@earendil-works/pi-ai/providers/faux"; @@ -8,7 +8,7 @@ import { AssistantEntry, createRegistry, defineExtension, Harness, MemoryStorage const context = BACKGROUND_CONTEXT; -// The faux provider stands in for a real model (see 16-real-model.ts). +// The faux provider stands in for a real model (see 15-real-model.ts). const faux = fauxProvider(); const models = createModels(); models.setProvider(faux.provider); diff --git a/packages/durable/test/examples/15-system-prompt.ts b/packages/durable/test/examples/14-system-prompt.ts similarity index 99% rename from packages/durable/test/examples/15-system-prompt.ts rename to packages/durable/test/examples/14-system-prompt.ts index 2202871c9..c83083de3 100644 --- a/packages/durable/test/examples/15-system-prompt.ts +++ b/packages/durable/test/examples/14-system-prompt.ts @@ -1,6 +1,6 @@ // System prompt sections and per-conversation instructions. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/15-system-prompt.ts +// node --conditions=source --experimental-strip-types test/examples/14-system-prompt.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { createModels } from "@earendil-works/pi-ai/models"; import { fauxAssistantMessage, fauxProvider } from "@earendil-works/pi-ai/providers/faux"; diff --git a/packages/durable/test/examples/16-real-model.ts b/packages/durable/test/examples/15-real-model.ts similarity index 99% rename from packages/durable/test/examples/16-real-model.ts rename to packages/durable/test/examples/15-real-model.ts index 00ce62856..b5cbe1244 100644 --- a/packages/durable/test/examples/16-real-model.ts +++ b/packages/durable/test/examples/15-real-model.ts @@ -1,6 +1,6 @@ // A real model: stream an answer from OpenAI. // Run from packages/durable (needs OPENAI_API_KEY): -// node --conditions=source --experimental-strip-types test/examples/16-real-model.ts +// node --conditions=source --experimental-strip-types test/examples/15-real-model.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { createModels } from "@earendil-works/pi-ai/models"; import { openaiProvider } from "@earendil-works/pi-ai/providers/openai"; diff --git a/packages/durable/test/examples/17-coding-tools.ts b/packages/durable/test/examples/16-coding-tools.ts similarity index 99% rename from packages/durable/test/examples/17-coding-tools.ts rename to packages/durable/test/examples/16-coding-tools.ts index 033313ff8..b150b584b 100644 --- a/packages/durable/test/examples/17-coding-tools.ts +++ b/packages/durable/test/examples/16-coding-tools.ts @@ -2,7 +2,7 @@ // `cat` of /tmp/1gb.txt (create it first to measure; without it that call ends in an error result). The storage // directory is left behind for inspection. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/17-coding-tools.ts +// node --conditions=source --experimental-strip-types test/examples/16-coding-tools.ts import { mkdtemp, readFile, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; diff --git a/packages/durable/test/examples/18-print.ts b/packages/durable/test/examples/17-print.ts similarity index 98% rename from packages/durable/test/examples/18-print.ts rename to packages/durable/test/examples/17-print.ts index 2438efbb8..5dfd8f46e 100644 --- a/packages/durable/test/examples/18-print.ts +++ b/packages/durable/test/examples/17-print.ts @@ -1,7 +1,7 @@ // Print mode: submit one prompt and print its answer, like `pi -p`. The host awaits its own Submission, not global // idle. Uses OpenAI when OPENAI_API_KEY is set, and a scripted faux model otherwise. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/18-print.ts "What is in this directory?" +// node --conditions=source --experimental-strip-types test/examples/17-print.ts "What is in this directory?" import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import type { AssistantMessage } from "@earendil-works/pi-ai"; import { createModels } from "@earendil-works/pi-ai/models"; diff --git a/packages/durable/test/examples/19-json.ts b/packages/durable/test/examples/18-json.ts similarity index 98% rename from packages/durable/test/examples/19-json.ts rename to packages/durable/test/examples/18-json.ts index 95a894f1d..f1348cfe1 100644 --- a/packages/durable/test/examples/19-json.ts +++ b/packages/durable/test/examples/18-json.ts @@ -5,7 +5,7 @@ // neither is deleted, and the path is printed to stderr at the end. // Uses OpenAI when OPENAI_API_KEY is set, and a scripted faux model otherwise. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/19-json.ts --events "What is in this directory?" +// node --conditions=source --experimental-strip-types test/examples/18-json.ts --events "What is in this directory?" import { mkdtemp } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; diff --git a/packages/durable/test/examples/20-inbox.ts b/packages/durable/test/examples/19-inbox.ts similarity index 99% rename from packages/durable/test/examples/20-inbox.ts rename to packages/durable/test/examples/19-inbox.ts index 90beb1ae3..b90560267 100644 --- a/packages/durable/test/examples/20-inbox.ts +++ b/packages/durable/test/examples/19-inbox.ts @@ -1,6 +1,6 @@ // The inbox: what happens to submissions while a conversation is busy. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/20-inbox.ts +// node --conditions=source --experimental-strip-types test/examples/19-inbox.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import type { FauxResponseStep } from "@earendil-works/pi-ai"; import { createModels } from "@earendil-works/pi-ai/models"; diff --git a/packages/durable/test/examples/21-late-join.ts b/packages/durable/test/examples/20-late-join.ts similarity index 99% rename from packages/durable/test/examples/21-late-join.ts rename to packages/durable/test/examples/20-late-join.ts index 76d99530b..122ad70ee 100644 --- a/packages/durable/test/examples/21-late-join.ts +++ b/packages/durable/test/examples/20-late-join.ts @@ -1,7 +1,7 @@ // Late join: a client attaches while a run is already underway. It gets the current state first, the conversation // view or the snapshot event, and then only what changes after that. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/21-late-join.ts +// node --conditions=source --experimental-strip-types test/examples/20-late-join.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { Type } from "@earendil-works/pi-ai"; import { createModels } from "@earendil-works/pi-ai/models"; diff --git a/packages/durable/test/examples/22-subagent-foreground.ts b/packages/durable/test/examples/21-subagent-foreground.ts similarity index 99% rename from packages/durable/test/examples/22-subagent-foreground.ts rename to packages/durable/test/examples/21-subagent-foreground.ts index 69d7ec5c4..c766803fb 100644 --- a/packages/durable/test/examples/22-subagent-foreground.ts +++ b/packages/durable/test/examples/21-subagent-foreground.ts @@ -3,7 +3,7 @@ // details and shows its events under the call. // Uses OpenAI when OPENAI_API_KEY is set, and a scripted faux model otherwise. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/22-subagent-foreground.ts +// node --conditions=source --experimental-strip-types test/examples/21-subagent-foreground.ts import type { Context } from "@earendil-works/chord"; import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { type AssistantMessage, type FauxResponseStep, Type } from "@earendil-works/pi-ai"; diff --git a/packages/durable/test/examples/23-subagent-background.ts b/packages/durable/test/examples/22-subagent-background.ts similarity index 99% rename from packages/durable/test/examples/23-subagent-background.ts rename to packages/durable/test/examples/22-subagent-background.ts index 6b2b4a533..19fba5dc5 100644 --- a/packages/durable/test/examples/23-subagent-background.ts +++ b/packages/durable/test/examples/22-subagent-background.ts @@ -4,7 +4,7 @@ // survives a restart: the example closes the Harness while a subagent works and reopens it. // Uses OpenAI when OPENAI_API_KEY is set, and a scripted faux model otherwise. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/23-subagent-background.ts +// node --conditions=source --experimental-strip-types test/examples/22-subagent-background.ts import { mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; diff --git a/packages/durable/test/examples/24-child-tasks.ts b/packages/durable/test/examples/23-child-tasks.ts similarity index 99% rename from packages/durable/test/examples/24-child-tasks.ts rename to packages/durable/test/examples/23-child-tasks.ts index 63d67759f..2fd1154a4 100644 --- a/packages/durable/test/examples/24-child-tasks.ts +++ b/packages/durable/test/examples/23-child-tasks.ts @@ -1,7 +1,7 @@ // A task that owns child tasks: a checkout charges four payments at once and waits for them. // The task graph view prints the checkout's tree while its payments run. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/24-child-tasks.ts +// node --conditions=source --experimental-strip-types test/examples/23-child-tasks.ts import { mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; diff --git a/packages/durable/test/examples/25-compaction.ts b/packages/durable/test/examples/24-compaction.ts similarity index 99% rename from packages/durable/test/examples/25-compaction.ts rename to packages/durable/test/examples/24-compaction.ts index 5fb353ce1..ac593bf22 100644 --- a/packages/durable/test/examples/25-compaction.ts +++ b/packages/durable/test/examples/24-compaction.ts @@ -1,6 +1,6 @@ // Compaction: a long trip-planning chat whose older messages are summarized so the model context stays small. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/25-compaction.ts +// node --conditions=source --experimental-strip-types test/examples/24-compaction.ts import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import type { AssistantMessage, Message, TranscriptContext } from "@earendil-works/pi-ai"; import { createModels } from "@earendil-works/pi-ai/models"; diff --git a/packages/durable/test/examples/26-coding-agent.ts b/packages/durable/test/examples/25-coding-agent.ts similarity index 99% rename from packages/durable/test/examples/26-coding-agent.ts rename to packages/durable/test/examples/25-coding-agent.ts index d5b0e7c47..a25f5d617 100644 --- a/packages/durable/test/examples/26-coding-agent.ts +++ b/packages/durable/test/examples/25-coding-agent.ts @@ -1,7 +1,7 @@ // A small coding agent: the built-in coding tools, a prompt that knows the working directory, settings backed by the // app's settings file, and an environment that follows the conversation's directory. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/26-coding-agent.ts +// node --conditions=source --experimental-strip-types test/examples/25-coding-agent.ts import { mkdir, mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; diff --git a/packages/durable/test/examples/27-plan-mode.ts b/packages/durable/test/examples/26-plan-mode.ts similarity index 99% rename from packages/durable/test/examples/27-plan-mode.ts rename to packages/durable/test/examples/26-plan-mode.ts index 9736140f0..b0bedd056 100644 --- a/packages/durable/test/examples/27-plan-mode.ts +++ b/packages/durable/test/examples/26-plan-mode.ts @@ -1,7 +1,7 @@ // Plan mode: the user switches a conversation into a read-only planning mode, the agent writes a plan into the // extension's own document, and switching back restores the full tool set. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/27-plan-mode.ts +// node --conditions=source --experimental-strip-types test/examples/26-plan-mode.ts import { mkdtemp, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; diff --git a/packages/durable/test/examples/28-reviewer.ts b/packages/durable/test/examples/27-reviewer.ts similarity index 99% rename from packages/durable/test/examples/28-reviewer.ts rename to packages/durable/test/examples/27-reviewer.ts index f219aa9e0..6dbdf25b3 100644 --- a/packages/durable/test/examples/28-reviewer.ts +++ b/packages/durable/test/examples/27-reviewer.ts @@ -1,7 +1,7 @@ // A reviewer agent next to the main one: a cheaper model, a review role and loop, read-only tools, and its own // checkout of the project. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/28-reviewer.ts +// node --conditions=source --experimental-strip-types test/examples/27-reviewer.ts import { mkdtemp, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; diff --git a/packages/durable/test/examples/29-sandbox-per-conversation.ts b/packages/durable/test/examples/28-sandbox-per-conversation.ts similarity index 98% rename from packages/durable/test/examples/29-sandbox-per-conversation.ts rename to packages/durable/test/examples/28-sandbox-per-conversation.ts index d570b5721..dbc7879f5 100644 --- a/packages/durable/test/examples/29-sandbox-per-conversation.ts +++ b/packages/durable/test/examples/28-sandbox-per-conversation.ts @@ -2,7 +2,7 @@ // environment function looks it up for every tool call. Here a sandbox is a directory; a hosted product would return // an ExecutionEnv that runs inside the conversation's container. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/29-sandbox-per-conversation.ts +// node --conditions=source --experimental-strip-types test/examples/28-sandbox-per-conversation.ts import { mkdtemp, readFile, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; diff --git a/packages/durable/test/examples/30-tool-override.ts b/packages/durable/test/examples/29-tool-override.ts similarity index 99% rename from packages/durable/test/examples/30-tool-override.ts rename to packages/durable/test/examples/29-tool-override.ts index bafdcaa3a..b33a94c89 100644 --- a/packages/durable/test/examples/30-tool-override.ts +++ b/packages/durable/test/examples/29-tool-override.ts @@ -1,7 +1,7 @@ // Replace a tool for some conversations, and decorate whichever tool wins: a bash that runs inside a Python // virtualenv, and a wrapper that times every bash call. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/30-tool-override.ts +// node --conditions=source --experimental-strip-types test/examples/29-tool-override.ts import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; diff --git a/packages/durable/test/examples/31-reload-and-restart.ts b/packages/durable/test/examples/30-reload-and-restart.ts similarity index 99% rename from packages/durable/test/examples/31-reload-and-restart.ts rename to packages/durable/test/examples/30-reload-and-restart.ts index 3da03b0b2..6813a7659 100644 --- a/packages/durable/test/examples/31-reload-and-restart.ts +++ b/packages/durable/test/examples/30-reload-and-restart.ts @@ -1,7 +1,7 @@ // Reload an extension while a call runs, then restart the process. Running work finishes on the code it started // with; stored choices are names, so they survive a restart and bind to whatever code the new process installs. // Run from packages/durable: -// node --conditions=source --experimental-strip-types test/examples/31-reload-and-restart.ts +// node --conditions=source --experimental-strip-types test/examples/30-reload-and-restart.ts import { mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path";