Repository navigation
Backend mapping
The kit's backend port is implemented by adapters. BubblePaw is the public
BubblePaw-Core v0.3.0 (plus the v0.3.1 methods listed below, written against origin/release)
runner over stdio JSON-RPC 0.1, through agent_kit_bubblepaw. There is no
client Cargo feature or pre-existing layer that emits kit-shaped JSON.
Scratch is the separate NotesAgent bridge; its column below preserves the
existing bridge mapping and has not been requalified against a new release.
BubblePaw calls and fields were checked against the tagged source:
main.rsstdio dispatcher-
stdio_context.rs,context_reads.rsandquestion_stdio.rs - Session API, context compaction and child sessions
A method available through HTTP, core Rust or a model-facing JS tool is not
necessarily a stdio RPC. The stdio mapping below is deliberately transport-specific.
Missing capabilities are off: commands requiring them fail with KitUnsupported.
Pane send, cancel and approval controls default to the corresponding
capabilities. See the
adapter README for lifecycle, errors,
verification levels and the complete list of desired port changes.
ChatReader is the read-only port used by ChatFeed; AgentBackend also
provides commands. A reader declares its capabilities. A backend can expose
BackendConstraints for finer input limits; the default accepts references,
all question answer shapes and follow-ups while running.
| Capability | BubblePaw | Scratch read-only adapter |
|---|---|---|
createChat, send, cancel
|
Yes | No |
approve |
When approvals is negotiated |
No |
steer, questions, plan, rewind
|
When the respective protocol feature is negotiated | No |
context |
When feature context is negotiated |
No |
answerChildQuestion |
When feature question.answer_child is negotiated |
No |
rename, resume, usage
|
Yes | No |
| Other optional capabilities (jobs, archive, fork) | Not advertised | No |
BubblePaw rejects references, supports a single choice or free-text question
answer, and supports follow-up while running when follow_up is negotiated.
Scratch's adapter declares no write capabilities. The Scratch command column
below describes gateway operations, not permissions granted by that adapter.
| Kit | BubblePaw stdio | Scratch |
|---|---|---|
listChats({cursor, query}) |
Partial: session.list. With feature session.list.pagination (Core v0.3.1) it sends limit 100 and the previous next_cursor, and the host orders pages (newest created first); without it, every chat comes back at once, sorted by updated time, with no cursor. The title query filters the returned page only. Its metadata has no run status. |
sessions(), newest first; no cursor or query. |
loadChat(id) |
Yes: session.state plus approval.list for pending approvals. Snapshot has seq, canonical messages, runs, inputs, outputs, todo, question and usage. |
sessionState(id) with seq, streaming text, messages, runs, approvals, activity, edits. |
events(chat, after: N) |
Yes: events.after {session_id, after, limit:1000}, then buffered/live event notifications. resync or events.gap reloads state and replays from the fresh host cursor. |
eventsAfter then subscribe; resync/gap reloads. |
| Durable sequence | Adapter reserves 16 native kit sequence positions per host HarnessEvent.sequence, permitting multiple kit events per host event. Snapshots use the final position. Replay always converts back to host sequence. |
AgentEvent.sequence. |
| Transient sequence and offset |
paragraph and text_delta carry the last host sequence. Adapter reconciles prefixes, counts UTF-16 offsets and never persists them. Stdio state lacks live_seen; ambiguous fragments at the snapshot cursor are skipped. |
Adapter counts from streamingText. |
loadHistoryRange |
Yes (feature context): history.range {first_seq,last_seq,limit} paged by next_seq. The kit sequence is the host's store seq: increasing, not necessarily dense, so span-derived counts are upper bounds. |
Older-history paging is not mapped here. |
loadContext, loadSummary
|
Yes (feature context): context.structure, context.events, context.view; context.summary {kind,id} with kit IDs episode:<id> / chapter:<id>. Host message IDs are resolved to sequences once and cached. The window comes from session.state usage when it is at or above the view's threshold; the reserve is then window minus threshold, else both are absent. |
No mapping qualified here. |
| Kit event | BubblePaw stdio | Scratch |
|---|---|---|
chat.renamed |
session.rename updates metadata without a harness rename event; adapter emits the snapshot title diff. |
Reload after renameSession. |
chat.archived |
Missing on stdio. | Archive missing (delete only). |
chat.settings |
Model read from runs/run_started; no model-list/settings or profile RPC. |
run_started.model; profile missing. |
chat.workspace |
Host-bound workspace is supplied by the application; no branch/worktree data in stdio state. | Session project id/name. |
run.started |
run_started {model}; run_quota_resumed also clears the wait on the same run. |
Same kinds. |
run.waiting |
run_waiting_for_quota.wait {resume_at, reason}. |
Kind exists; structured quota fields missing. |
run.finished |
run_finished {status,error}; completed, failed, cancelled, interrupted. |
Same kind/status. |
message.user |
Canonical user IDs/text are recovered from session.state.messages; run events omit them. |
Reload after run start/steering. |
message.delta |
text_delta is provisional, paragraph confirms it. Matching prefixes emit only the missing suffix. Mismatch/retry requests resnapshot. |
paragraph. |
message.assistant |
run_finished.text completes the provisional reply without a gap. Explicit snapshot reload recovers canonical message IDs. |
run_finished.text or reload. |
message.system |
Canonical system messages/tool orphan results come from state; output.record text publications map to stable-ID plain system lines. File/image/execution publications have no kit renderer. |
output or reload. |
| Thinking | No reasoning-text capability; model-request boundaries reset/reconcile provisional text. | No reasoning text. |
tool.started, tool.finished
|
Durable tool_started.call and tool_finished {call_id,result} map directly; canonical calls/results are reconstructed on reload. No exit code is invented. |
Tool started/finished, summaries in activity. |
| Nested transient tools | Kit tool events are durable; nested durable:false boundaries request snapshot recovery rather than consume a sequence or invent stored rows. |
Nested tool progress is also transient. |
tool.output, edit/undo events |
No streamed tool-output or edit-undo RPC. File-tool output remains tool activity; no speculative diffs. | Edits read on reload; undo exists. |
plan.updated |
host_state_changed {key:"todo",value}; pending/in_progress/done map to todo/now/done. |
Plan missing. |
approval.requested |
approval_requested.approval; pending records also from approval.list. |
Same kind. |
approval.resolved |
approval_resolved {approval_id,state,reason}; approved_session maps to approvedForSession. |
Same kind. |
question.asked, question.resolved
|
Built: host_state_changed {key:"question",value}. One root question with free text and optional suggestions. A cleared question triggers state reload; snapshots retain only pending questions, so resolved prompt history disappears on reload. Child questions are not root prompts. |
Questions missing. |
| Queue changes |
steering_accepted / followup_queued omit input IDs, so reload real session.state.inputs; response IDs are retained by commands. No edit/remove methods. |
Follow-up kind exists; IDs require reload. |
| Child events |
Built (feature child_events): child_run_state_changed and host_state_changed keys child_question / child_question_answer mark the child stale and refresh; the diff yields ChildSpawned, ChildQuestionAsked, ChildQuestionResolved, ChildFinished. A finished child that runs again forces a gap. |
Children missing. |
| Compaction events |
Built: context_compaction {event_id,kind,trigger} refreshes; CompactionUpdated for an applied fact, ContextChanged when the view differs. |
Missing. |
| Job events | Not advertised: process.list does not supply individual cancellation or streamed output. |
Jobs missing. |
usage.updated |
usage.last_request, run completion and snapshot refresh trigger a diff of authoritative own-session totals/context in session.state.usage. Changed values emit UsageUpdated; per-run totals are never added twice. |
Run token counts; context meter missing. |
gap |
events.gap or events.after.resync; reload state and replay from the last delivered durable cursor. A snapshot cursor does not discard undelivered events. Retention loss requires a snapshot reset. |
gap/resync then reload. |
Other host state / session_settled
|
Unprojected host state is ignored; session_settled refreshes snapshot-derived fields without an unconditional gap. Unknown event kinds are ignored. |
Host-state/settled are read triggers. |
Transient events never become stored items. The display may show provisional assistant IDs until an explicit snapshot reload replaces them; rewind requires a canonical message ID from that snapshot. The unit and local-host tests are distinct from live-model acceptance; neither proves a paid provider.
| Kit command | BubblePaw stdio | Scratch |
|---|---|---|
createChat |
Yes: session.open {title?} in the bound workspace. |
createSession(title). |
send |
Partial: run.start; only a busy error falls back to run.follow_up. Text only. Host slash commands are rejected before RPC because they do not return a run. |
send starts or queues. |
steer, followup
|
Yes: run.steer, run.follow_up; real response input IDs. |
Steer exists; send while busy queues. |
sendQueuedNow, editQueued, removeQueued
|
Missing. Capabilities off. | Missing. |
cancel, resume
|
Yes: run.cancel, run.resume. |
Cancel yes; resume missing. |
decideApproval |
Yes: approval.decide {approval_id,decision,reason?}; approve / approve_session / deny. Verify pending approval belongs to the addressed chat. |
decideApproval. |
answerQuestion |
Partial: question.answer {session_id,question_id,text}. A single item maps one chosen label or one text answer; no skipped/multiple answers. |
Missing. |
answerChildQuestion |
Yes (feature question.answer_child): question.answer_child {parent,child,question_id,text}. Unknown or expired question maps to KitNotFound, already answered to KitConflict, a foreign child or blank text to KitInvalid. |
Missing. |
rename |
Yes: session.rename, followed by snapshot refresh. |
renameSession. |
archive |
Missing: session.delete is not archive. |
Missing. |
fork |
Missing: core Store::fork_at and HTTP fork do not create a stdio RPC. |
Missing. |
rewind |
Partial: session.rewind {session_id,message_id} creates a new session, including the selected message, and restores eligible checkpointed files. Adapter rewindToNewChat returns that summary and emits createdChats; source remains intact. |
Missing. |
cancelChild |
Yes (Core v0.3.1): child.cancel {parent, child}, feature child.cancel turns on children. Cancels the child and what it started; the parent must be the child's direct parent. The adapter refreshes the crew afterwards. |
Children missing. |
cancelJob |
Missing: process.background is not cancellation. |
Jobs missing. |
undoEdit |
Missing: rewind is not per-edit undo. |
editUndo. |
listProviders, setDefaultModel, listModels, setModel
|
Yes (Core v0.3.1): providers.list (feature providers.list, capability providers) returns providers, kinds, whether a key was found (never the key), models, main and active_main. roles.set_main {model} (feature roles.set_main, capability defaultModel) saves the default as provider/model. models needs both. The host has one default, not one per chat, so setModel sets it for every chat and a run in progress keeps its own model. |
models(); choice passed to send. |
listProfiles, setProfile
|
Missing. | Missing. |
BubblePaw stdio wraps command failures in JSON-RPC -32000 with error strings.
The adapter recognizes source-backed busy/not-found/conflict/invalid/denied
patterns and produces safe kit errors; other RPC failures use a fixed failure
message, except code -32004 (Core v0.5.1, a run with no provider configured): that one
becomes KitNeedsSetup carrying the host's message, which names the config keys and
host methods to set up. Raw provider/command errors are not logged. A busy send alone is retried
as follow-up, preventing duplicate admission after unrelated failures.
The host's typed config.set refusals (-32010 unknown key, -32011 wrong type, -32012 invalid value, -32013 write failed) keep their code, message and data: the transport's BubblePawException keeps its fixed code/message and adds rpcCode, rpcMessage and rpcData; the backend throws KitInvalid (-32010..-32012) or KitFailed (-32013) with message = the host's text and hostCode/hostData set. No other host text is exposed.
Protocol mismatch is typed with expected and actual versions. Child exit is typed
BubblePawHostExited (hostExited) with exit code and a bounded fully redacted
stderr tail. The core's sealed KitError prevents these adapter-specific types
from also being kit errors; this is a requested port change, not a core edit.
Pending approvals and interrupted runs recovered by the host are reflected by
fresh snapshots, even where recovery itself emits no durable event.
Core describes an in-place rewind to before the selected item and returns void. BubblePaw instead creates a new chat including that item; its adapter exposes the resulting chat separately.
The adapter does not introduce snapshot-backed message ordinals and leaves the
core contract unchanged. ContextEvent.tokensBefore and tokensAfter,
ContextView.window and responseReserve, and ContextSummary.createdAt are
nullable, so the adapter reports exactly what Core v0.3.0 sends (a view has only
a threshold; the window appears only when the session usage reports one at or
above it). Worked around: host sequences are not dense, so messageCount
is an upper bound, and pendingEpisodeIds is not derivable. The core also groups all context operations
behind one capability, seals error subtypes, returns void from rewind and treats
all tool boundaries as durable. These limits are recorded in the adapter README.
Generated from docs/backend-mapping.md. Edit the file there; changes made on the wiki are overwritten.
Guides
- Package layout and pinning
- agent_kit_core
- Backend mapping
- agent_kit and the gallery
- Icon and README assets
Component sheets
theme
status
transcript
- ActivityGroupView
- AssistantProse
- ChildQuestionRow
- CodeBlock
- DiffView
- ExecOutput
- FileEditRow
- PlanChecklist
- ReturnLine
- SystemLineView
- TranscriptList
- UserBubble
composer
chrome
context
history
outline
workspace
compositions
providers