Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
97e814d
agents: spike sub-agent routing via facet Fetcher
threepointone Apr 21, 2026
b5822db
design: sub-agent routing RFC (external addressability for facets)
threepointone Apr 21, 2026
5d1794c
design: rename authorizeSubAgent → onBeforeSubAgent in routing RFC
threepointone Apr 21, 2026
7f873f8
design: routing RFC — routeSubAgentRequest + getSubAgentByName
threepointone Apr 21, 2026
bb9d007
design: routing RFC — address review feedback (full rewrite)
threepointone Apr 21, 2026
84c5c75
agents: resolve getSubAgentByName passthrough; RFC + Devin feedback
threepointone Apr 21, 2026
54e705a
agents: sub-agent routing phase 1 — parentPath + registry + introspec…
threepointone Apr 21, 2026
b5413b4
agents: sub-agent routing phase 2 — routing + onBeforeSubAgent + helpers
threepointone Apr 21, 2026
f40f6e9
agents: sub-agent routing phase 3 — client-side useAgent({ sub: [...] })
threepointone Apr 21, 2026
fe3e0f9
design: rfcs track the landed routing primitive
threepointone Apr 21, 2026
4c33a9f
changeset: sub-agent routing (minor)
threepointone Apr 21, 2026
6fbad62
agents: sub-agent routing — review fixes (rename, scrub, idempotence)
threepointone Apr 21, 2026
6ed6566
agents: fix two sub-agent routing bugs (URL parse + client path spread)
threepointone Apr 22, 2026
f7dc336
agents: harden sub-agent stub guards + reserved-name check
threepointone Apr 22, 2026
8b7a25f
agents: preserve query params when routeSubAgentRequest uses fromPath
threepointone Apr 22, 2026
3742454
agents: fix flaky multi-WS test — attach listeners before sending
threepointone Apr 22, 2026
a187313
agents: align RFC + JSDoc with actual onBeforeSubAgent URL semantics
threepointone Apr 22, 2026
961cded
changeset: downgrade sub-agent routing to patch
threepointone Apr 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .changeset/sub-agent-routing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
"agents": patch
---

External addressability for sub-agents.

Clients can now reach a facet (a child DO created by `Agent#subAgent()`) directly via a nested URL:

/agents/{parent-class}/{parent-name}/sub/{child-class}/{child-name}[/...]

New public APIs (all `@experimental`):

- `routeSubAgentRequest(req, parent, options?)` — sub-agent analog of `routeAgentRequest`. For custom-routing setups where the outer URL doesn't match the default `/agents/...` shape.
- `getSubAgentByName(parent, Cls, name)` — sub-agent analog of `getAgentByName`. Returns a typed Proxy that round-trips typed RPC calls through the parent. RPC-only (no `.fetch()`); use `routeSubAgentRequest` for external HTTP/WS.
- `parseSubAgentPath(url, options?)` — public URL parser used internally by the routers.
- `SUB_PREFIX` — the `"sub"` separator constant (not configurable; exposed for symbolic URL building).

New public on `Agent`:

- `onBeforeSubAgent(req, { className, name })` — overridable middleware hook, mirrors `onBeforeConnect` / `onBeforeRequest`. Returns `Request | Response | void` for short-circuit responses, request mutation, or passthrough. Default: void.
- `parentPath` / `selfPath` — root-first `{ className, name }` ancestor chains, populated at facet init time. Inductive across recursive nesting.
- `hasSubAgent(ClsOrName, name)` / `listSubAgents(ClsOrName?)` — parent-side introspection backed by an auto-maintained SQLite registry written by `subAgent()` / `deleteSubAgent()`. Both accept either the class constructor or a CamelCase class name string.

New public on `useAgent` (React):

- `sub?: Array<{ agent, name }>` — flat root-first chain addressing a descendant facet. The hook's `.agent` / `.name` report the leaf identity; `.path` exposes the full chain.

Breaking changes: none. `routeAgentRequest` behavior is unchanged when URLs don't contain `/sub/`. `onBeforeSubAgent` defaults to permissive (forward unchanged). `useAgent` without `sub` is unchanged. `subAgent()` / `deleteSubAgent()` gain registry side effects but preserve return types and failure modes. The `_cf_initAsFacet` signature gained an optional `parentPath` parameter. `deleteSubAgent()` is now idempotent — calling it for a never-spawned or already-deleted child no longer throws. Sub-agent class names equal to `"Sub"` are rejected (the `/sub/` URL separator is reserved).

See `design/rfc-sub-agent-routing.md` for the full rationale, design decisions, and edge cases. The spike at `packages/agents/src/tests/spike-sub-agent-routing.test.ts` documents the three candidate approaches considered for cross-DO stub passthrough and why the per-call bridge won.
33 changes: 17 additions & 16 deletions design/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,23 @@ Keep it concise. A few paragraphs is fine. These are records, not essays.

## Current contents

| File | Type | Scope |
| ------------------------- | ---------- | ------------------------------------------------------------------------------------- |
| `chat-shared-layer.md` | design doc | Chat shared layer — streaming, sanitization, and protocol primitives in agents/chat |
| `think.md` | design doc | Think — chat agent base class, streaming, client tools, resumable streams, extensions |
| `think-sessions.md` | design doc | Think + Session integration design (implemented in Phase 1) |
| `think-vs-aichat.md` | design doc | Think vs AIChatAgent — comparison, use cases, architectural differences |
| `think-roadmap.md` | design doc | Think implementation plan — all 5 phases complete, full AIChatAgent parity |
| `chat-api.md` | analysis | AIChatAgent + useAgentChat API analysis — pain points, improvements, Think influence |
| `chat-improvements.md` | design doc | Non-breaking improvements — shared extraction complete, client DX items remain |
| `readonly-connections.md` | design doc | Readonly connections — enforcement, storage wrapping, caveats |
| `retries.md` | design doc | Retry system — primitives, integration points, backoff strategy, tradeoffs |
| `visuals.md` | design doc | UI component library (Kumo), dark mode, custom patterns, routing integration |
| `workspace.md` | design doc | Workspace — hybrid SQLite+R2 filesystem, bash, symlinks, observability |
| `rfc-sub-agents.md` | RFC | Sub-agents — child DOs via facets, typed stubs, built into Agent (accepted) |
| `loopback.md` | design doc | Loopback pattern — cross-boundary RPC for sub-agents and dynamic isolates |
| `worker-bundler.md` | design doc | Worker bundler — host-side assets, no code generation, mounting is caller's concern |
| File | Type | Scope |
| -------------------------- | ---------- | ------------------------------------------------------------------------------------- |
| `chat-shared-layer.md` | design doc | Chat shared layer — streaming, sanitization, and protocol primitives in agents/chat |
| `think.md` | design doc | Think — chat agent base class, streaming, client tools, resumable streams, extensions |
| `think-sessions.md` | design doc | Think + Session integration design (implemented in Phase 1) |
| `think-vs-aichat.md` | design doc | Think vs AIChatAgent — comparison, use cases, architectural differences |
| `think-roadmap.md` | design doc | Think implementation plan — all 5 phases complete, full AIChatAgent parity |
| `chat-api.md` | analysis | AIChatAgent + useAgentChat API analysis — pain points, improvements, Think influence |
| `chat-improvements.md` | design doc | Non-breaking improvements — shared extraction complete, client DX items remain |
| `readonly-connections.md` | design doc | Readonly connections — enforcement, storage wrapping, caveats |
| `retries.md` | design doc | Retry system — primitives, integration points, backoff strategy, tradeoffs |
| `visuals.md` | design doc | UI component library (Kumo), dark mode, custom patterns, routing integration |
| `workspace.md` | design doc | Workspace — hybrid SQLite+R2 filesystem, bash, symlinks, observability |
| `rfc-sub-agents.md` | RFC | Sub-agents — child DOs via facets, typed stubs, built into Agent (accepted) |
| `rfc-sub-agent-routing.md` | RFC | Sub-agent external addressability — nested URLs, `onBeforeSubAgent`, per-call bridge |
| `loopback.md` | design doc | Loopback pattern — cross-boundary RPC for sub-agents and dynamic isolates |
| `worker-bundler.md` | design doc | Worker bundler — host-side assets, no code generation, mounting is caller's concern |

## Relationship to `/docs`

Expand Down
Loading
Loading