Skip to content

Commit 79bb441

Browse files
committed
chore: update docs and schemas
1 parent 4083baa commit 79bb441

7 files changed

Lines changed: 720 additions & 919 deletions

File tree

CLAUDE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ Universal schema guidance:
3434
- Do not make breaking changes to API endpoints.
3535
- When changing API routes, ensure the HTTP/SSE test suite has full coverage of every route.
3636
- When agent schema changes, ensure API tests cover the new schema and event shapes end-to-end.
37+
- Update `docs/conversion.md` whenever agent-native schema terms, synthetic events, identifier mappings, or conversion logic change.
3738
- Never use synthetic data or mocked responses in tests.
3839
- Never manually write agent types; always use generated types in `resources/agent-schemas/`. If types are broken, fix the generated types.
40+
- The universal schema must provide consistent behavior across providers; avoid requiring frontend/client logic to special-case agents.
3941

4042
### CLI ⇄ HTTP endpoint map (keep in sync)
4143

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,9 @@ TODO
9393
- more difficult to interact with, harder to analyze, doesn't support inspector for debugging
9494
- may add at some point
9595
- codex does this. claude sort of does this.
96+
97+
**Why not OpenCode?**
98+
99+
- the harnesses do a lot of heavy lifting
100+
- the difference between opencode, claude, and codex is vast & vastly opinionated
101+

ROADMAP.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,14 @@
1717
- **Vercel AI SDK Compatibility**: Works with existing AI SDK tooling, like `useChat`
1818
- **Auto-configure MCP & Skills**: Auto-load MCP servers & skills for your agents
1919
- **Process & logs manager**: Manage processes, logs, and ports for your agents to run background processes
20+
- **Codex app-server concurrency**: Run a single shared Codex app-server with multiple threads in parallel (like OpenCode), with file-write safety
2021

2122
## later
2223

24+
- guides:
25+
- ralph
26+
- swarms
27+
- opencode compatible api
2328
- review all flags available on coding agents clis
2429
- set up agent to check diffs in versions to recommend updates
2530
- auto-updating for long running job

docs/conversion.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Universal ↔ Agent Term Mapping
2+
3+
Source of truth: generated agent schemas in `resources/agent-schemas/artifacts/json-schema/`.
4+
5+
Identifiers
6+
7+
+----------------------+------------------------+------------------------------------------+-----------------------------+------------------------+
8+
| Universal term | Claude | Codex (app-server) | OpenCode | Amp |
9+
+----------------------+------------------------+------------------------------------------+-----------------------------+------------------------+
10+
| session_id | n/a (daemon-only) | n/a (daemon-only) | n/a (daemon-only) | n/a (daemon-only) |
11+
| native_session_id | none | threadId | sessionID | none |
12+
| item_id | synthetic | ThreadItem.id | Message.id | StreamJSONMessage.id |
13+
| native_item_id | none | ThreadItem.id | Message.id | StreamJSONMessage.id |
14+
+----------------------+------------------------+------------------------------------------+-----------------------------+------------------------+
15+
16+
Notes:
17+
- When a provider does not supply IDs (Claude), we synthesize item_id values and keep native_item_id null.
18+
- native_session_id is the only provider session identifier. It is intentionally used for thread/session/run ids.
19+
- native_item_id preserves the agent-native item/message id when present.
20+
21+
Events / Message Flow
22+
23+
+------------------------+------------------------------+--------------------------------------------+-----------------------------------------+----------------------------------+
24+
| Universal term | Claude | Codex (app-server) | OpenCode | Amp |
25+
+------------------------+------------------------------+--------------------------------------------+-----------------------------------------+----------------------------------+
26+
| session.started | none | method=thread/started | type=session.created | none |
27+
| session.ended | SDKMessage.type=result | no explicit session end (turn/completed) | no explicit session end (session.deleted)| type=done |
28+
| message (user) | SDKMessage.type=user | item/completed (ThreadItem.type=userMessage)| message.updated (Message.role=user) | type=message |
29+
| message (assistant) | SDKMessage.type=assistant | item/completed (ThreadItem.type=agentMessage)| message.updated (Message.role=assistant)| type=message |
30+
| message.delta | synthetic | method=item/agentMessage/delta | type=message.part.updated (delta) | synthetic |
31+
| tool call | synthetic from tool usage | method=item/mcpToolCall/progress | message.part.updated (part.type=tool) | type=tool_call |
32+
| tool result | synthetic from tool usage | item/completed (tool result ThreadItem variants) | message.part.updated (part.type=tool, state=completed) | type=tool_result |
33+
| permission.requested | none | none | type=permission.asked | none |
34+
| permission.resolved | none | none | type=permission.replied | none |
35+
| question.requested | ExitPlanMode tool (synthetic)| experimental request_user_input (payload) | type=question.asked | none |
36+
| question.resolved | ExitPlanMode reply (synthetic)| experimental request_user_input (payload) | type=question.replied / question.rejected | none |
37+
| error | SDKResultMessage.error | method=error | type=session.error (or message error) | type=error |
38+
+------------------------+------------------------------+--------------------------------------------+-----------------------------------------+----------------------------------+
39+
40+
Synthetics
41+
42+
+------------------------------+------------------------+--------------------------+--------------------------------------------------------------+
43+
| Synthetic element | When it appears | Stored as | Notes |
44+
+------------------------------+------------------------+--------------------------+--------------------------------------------------------------+
45+
| session.started | When agent emits no explicit start | session.started event | Mark origin=daemon |
46+
| session.ended | When agent emits no explicit end | session.ended event | Mark origin=daemon; reason may be inferred |
47+
| item_id (Claude) | Claude provides no item IDs | item_id | Maintain provider_item_id map when possible |
48+
| user message (Claude) | Claude emits only assistant output | item.completed | Mark origin=daemon; preserve raw input in event metadata |
49+
| question events (Claude) | Plan mode ExitPlanMode tool usage | question.requested/resolved | Synthetic mapping from tool call/result |
50+
| native_session_id (Codex) | Codex uses threadId | native_session_id | Intentionally merged threadId into native_session_id |
51+
+------------------------------+------------------------+--------------------------+--------------------------------------------------------------+
52+
| message.delta (Claude/Amp) | No native deltas | item.delta | Synthetic delta with full message content; origin=daemon |
53+
+------------------------------+------------------------+--------------------------+--------------------------------------------------------------+
54+
| message.delta (OpenCode) | part delta before message | item.delta | If part arrives first, create item.started stub then delta |
55+
+------------------------------+------------------------+--------------------------+--------------------------------------------------------------+
56+
57+
Delta handling
58+
59+
- Codex emits agent message and other deltas (e.g., item/agentMessage/delta).
60+
- OpenCode emits part deltas via message.part.updated with a delta string.
61+
- Claude and Amp do not emit deltas in their schemas.
62+
63+
Policy:
64+
- Always emit item.delta across all providers.
65+
- For providers without native deltas, emit a single synthetic delta containing the full content prior to item.completed.
66+
- For providers with native deltas, forward as-is; also emit item.completed when final content is known.
67+
68+
Message normalization notes
69+
70+
- user vs assistant: normalized via role in the universal item; provider role fields or item types determine role.
71+
- OpenCode unrolling: message.updated creates/updates the parent message item; tool-related parts emit separate tool item events (item.started/ item.completed) with parent_id pointing to the message item.
72+
- If a message.part.updated arrives before message.updated, we create a stub item.started (origin=daemon) so deltas have a parent.

0 commit comments

Comments
 (0)