diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 4e019dd8..c6a3ca4e 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -35,8 +35,8 @@ this repo: - **Inference** — LLM calls (`@intx/inference`). - **Workflow runtime** — definitions, runs, and the workflow host (`@intx/workflow`, `@intx/workflow-host`, `@intx/workflow-deploy`). -- **Mail** — the transport every agent run, including a workbench's own, - uses to receive and send messages. +- **Mail** — the transport an agent turn uses to receive and send + messages. A workbench itself is not a mail-holding host run. Workbench adds product contracts on top of these primitives; it never forks or patches Interchange internals. See [docs/TENANCY.md](docs/TENANCY.md) @@ -67,33 +67,26 @@ workbench's own child tenancy (native tenants carry no `kind` field), and [docs/GLOSSARY.md](docs/GLOSSARY.md) for the term mapping between product nouns and platform primitives. -## Conversation as a folded workflow run - -A workbench is not a parallel messaging system bolted onto Interchange — -it is an ordinary folded, credential-free interactive workflow run whose -only job is to hold a mailbox. Creating a workbench launches that run (its -**workbench host**, sometimes called its anchor); the host's system prompt -forbids it from ever replying or acting — it exists purely to give the -conversation a durable, listable mailbox. Reading that mailbox back in -order is the conversation's timeline. - -Because a workbench is an ordinary run, it goes through the same launch, -addressing, and mail machinery any other interactive agent run uses — no -parallel transport is invented for chat. An invited agent participant -replies by emitting `connector.reply` events on its own stream; a reply -bridge turns those events into timeline messages, mirroring how an -`@mention` fans a message out to an agent participant. See -[docs/CHAT.md](docs/CHAT.md) for the full message, thread, and -participant model built on top of this run. Per-workbench settings (name, -participants, capacity, connector overrides, notification prefs — see -PRODUCT.md's "Workbench settings") are composition on top of this same -run and its tenant, not a separate object; the surface lives in -`packages/chat-ui`'s `workbench-settings`. +## Conversation as workbench data + +A workbench is not a parallel messaging system bolted onto Interchange, +and it is not itself a workflow run. Creating a workbench mints a child +tenant and writes settings rows — no deploy, no host, no anchor instance +(`provisionSpaceWorkbench` and the chat create path). A workbench holds a +**timeline** of `chat.workbench_messages` rows; posting is one insert plus +one publish onto the workbench's live stream, so the conversation takes +messages whether or not any agent process is running. -**Direction (CL-6093):** today a workbench's run is "settle-and-wake" — -the anchor run settles between deliveries and wakes on the next mail -event. This is the current mechanism, not a permanent constraint; see -CL-6093 for where the self-anchored run model is headed next. +A workbench's address is derived, not resolved. Asking an invited agent +for a turn is a separate act over Interchange mail; the agent replies by +emitting `connector.reply` events on its own stream, and a reply bridge +turns those events into timeline messages. See +[docs/CHAT.md](docs/CHAT.md) for the full message, thread, and +participant model. Per-workbench settings (name, participants, capacity, +connector overrides, notification prefs — see PRODUCT.md's "Workbench +settings") are composition on top of this tenant and its settings rows, +not a separate object; the surface lives in `packages/chat-ui`'s +`workbench-settings`. **Streaming a reply.** An agent's live reply reaches the timeline through one path, deltas to pixels: @@ -156,9 +149,6 @@ does not maintain a parallel scheduler. ## Open questions -- The exact shape of the CL-6093 self-anchored run model beyond - "settle-and-wake today" is not yet documented in this repo — treat it - as in-flight design, not a settled architecture. - Sidecar placement policy specifics (how a run is assigned to a particular sidecar instance under multi-sidecar deployment) are not detailed in the docs reviewed for this pass. diff --git a/DESIGN.md b/DESIGN.md index 8bcb7da8..fcae98e1 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -14,7 +14,8 @@ column and no collapse affordance — it is always present, at a fixed width. Top to bottom: -1. **Brand row** — logo mark and a "New workbench" button (`+`). +1. **Brand row** — logo mark and a "New workbench" button (`+`) that + opens `/new`. 2. **Bench list** — the "Workbenches" label, then rows of workbench conversations, with search built into the list itself. Nothing page-scoped ever renders in this body; it lists conversations, not @@ -54,6 +55,14 @@ consumed by both). A route that gets renamed or relocated leaves a redirect behind at its old path — old links and bookmarks always land somewhere real, never a 404. +**`/new` is the shipped create surface** (`NewWorkbenchPickerRoute`). The +primary act is a prompt: say what the workbench should do, or pick a +template shortcut underneath. The sidebar `+` and an empty-bench land on +`/` both open this route — there is no Describe door. + +**`/inbox` is gone as a page** (CL-6151). The path stays as a redirect +home so old links still resolve; it is not a live groups inbox. + ## Tables & Lists The default shape for "many of the same thing" is a data table, not a card diff --git a/PRODUCT.md b/PRODUCT.md index 7992d3b7..8c2017ce 100644 --- a/PRODUCT.md +++ b/PRODUCT.md @@ -1,8 +1,8 @@ # Product Corbits Workbench is the multiplayer workspace for humans and agents — a -team and its AI agents working side by side, with the same conversations, -routines, and inbox. It is the default implementation of the Corbits +team and its AI agents working side by side, with the same conversations +and routines. It is the default implementation of the Corbits Platform, built on [Interchange](https://github.com/faremeter/interchange). ## The one concept @@ -36,9 +36,10 @@ column at a time: bench, flat, most-recently-active first. There is no separate "channels" vs. "chats" grouping the sidebar exposes to a person — every row is a workbench. -- **"+ New Workbench" always creates.** It never opens a picker of existing - things to join — starting a new workbench is the one way in, whether the - result is a one-on-one conversation with an agent or a group conversation +- **"+ New Workbench" always creates.** It opens `/new` — the shipped + prompt-primary picker — never a picker of existing things to join. + Starting a new workbench is the one way in, whether the result is a + one-on-one conversation with an agent or a group conversation with people and agents together. - **Agents are templates.** Starting a new agent conversation means picking an agent definition (a named, reusable capability) as the starting point @@ -48,29 +49,24 @@ column at a time: it carries account-wide surfaces (approvals, recent activity) that stay visible regardless of which workbench is open. -## First run (CL-6104) +## First run -A brand-new account is walked through four steps, ending in a live -conversation rather than an empty shell: +A brand-new account is walked through login and a credential connect, then +lands on the create surface rather than an empty shell: 1. **Login.** 2. **Credential** — connect a model provider (one-click OAuth for supported providers, or a pasted API key); see `packages/onboarding`. -3. **Describe** — a single free-text field asking what the first agent - should do. No name field, no template picker: a name and a handle are - derived from the description, and submitting drafts an agent - definition the same way `CreateAgentPanel` does - (`draftAgentDefinition` → `createAgentDefinition`, CL-6074/CL-6086). - See `apps/web/src/pages/describe-first-workbench.tsx`. -4. **Greeting** — the drafted agent is deployed and opened into a fresh - conversation, and its first reply introduces itself and names what it - can do. There is no separate screen for this step: the drafted system - prompt itself carries the instruction (see - `packages/agent-directory/src/agent-definition-drafting.ts`), so the - greeting arrives as an ordinary streamed reply in the new workbench. - -A bench that already has one or more workbenches skips straight past step -3 and 4 and lands in its existing conversation instead (see +3. **Create** — `/` hops an empty bench to `/new`, the prompt-primary + picker (`apps/web/src/pages/new-workbench-picker.tsx`). A prompt box is + the primary act: typing a goal and submitting creates a blank + workbench and sends that text as the first message. Prefab template + rows underneath are one-click shortcuts, not a kind-then-Create + second step. There is no Describe door and no + `describe-first-workbench.tsx`. + +A bench that already has one or more workbenches skips create and lands +in an existing conversation instead (see `apps/web/src/pages/home-page.tsx`). ## Plugins and Skills @@ -94,8 +90,8 @@ and capabilities; dedicated vs. shared inference capacity (CL-6117); per-workbench connector and plugin overrides against the account default (CL-6099); inference model/provider fallback order; applying a saved config profile; per-person notification preferences for that workbench; -and archiving. See ARCHITECTURE.md's "Conversation as a folded workflow -run" for how a workbench's settings relate to its underlying run, and +and archiving. See ARCHITECTURE.md's "Conversation as workbench data" +for how a workbench's settings relate to its tenant, and `packages/chat-ui`'s `workbench-settings` for the implementation. ## Routines, through conversation @@ -109,12 +105,13 @@ again, on what schedule, and where the result should land. See ## Inbox and approvals -Two account-wide surfaces sit outside any single workbench: +Approvals sit outside any single workbench. Inbox does not: -- **Inbox** projects a person's mail into three groups — action, mention, - delivery — with mark-all-read and clear-done bulk actions. It is where - a mention or a routine's delivery lands once the triggering activity is - done. See `packages/inbox`. +- **Inbox is not a product page.** The groups UI (action / mention / + delivery) is gone. `/inbox` stays routable only as a redirect home + (CL-6151) so old links and bookmarks land somewhere real. The hub + inbox API (`packages/inbox`, `/api/tenants/:tenantId/inbox`) may still + exist as a backend; it is not a live groups page. - **Approvals ("needs you")** surface a paused agent run waiting on a human decision. There is no dedicated Approvals page — pending approvals show up in the Activity band, a permanent section of the contextual diff --git a/docs/CHAT.md b/docs/CHAT.md index 1091c233..3d416964 100644 --- a/docs/CHAT.md +++ b/docs/CHAT.md @@ -109,8 +109,8 @@ event log. The shape lives in `@corbits/agent-runtime` (`buildAgentRuntimeWorkflow`, `mode: "section"`), and `platform-adapter.ts`'s `ROOM_AGENT_MODE` is the single place that pins it — one switch feeding both the wake and the relaunch path. The -workbench host keeps the folded step shape: it holds a mailbox and never -takes a turn, so it has no occurrences to name. +workbench itself has no host run and no occurrences to name; only invited +agents deploy as sections. `onBodyFailure: "continue"` — authored in the section shape itself — is the failure edge: a turn that ends `failed` records the failed occurrence @@ -332,7 +332,7 @@ following routes: | Method & path | What it does | | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `POST /workbenches` | Mints the workbench's own tenant, launches its host, writes its initial settings, and — for a chat — joins its one counterpart (an agent or a person; see [Chats and direct messages](#chats-and-direct-messages-dms)) | +| `POST /workbenches` | Mints the workbench's own tenant, writes its initial settings, and — for a chat — joins its one counterpart (an agent or a person; see [Chats and direct messages](#chats-and-direct-messages-dms)) | | `GET /workbenches` | Lists the tenant's workbenches, optionally filtered by kind | | `GET /workbenches/:id/messages` | Reads the workbench's timeline, decoded into parts, paginated by cursor | | `POST /workbenches/:id/messages` | Posts a message, fanning a copy to every @mentioned agent participant. `threadId` or `inReplyToMessageId` route it into a thread instead of the root feed; a reply that would nest past depth 2 is a `409 conflict` |