Skip to content

Declare presentation for every tool call (v0.9.0) - #17

Merged
happyren merged 1 commit into
masterfrom
feat/cards-ui
Aug 15, 2026
Merged

happyren merged 1 commit into
masterfrom
feat/cards-ui

Conversation

@happyren

Copy link
Copy Markdown
Owner

Tools now declare presentCall/presentResult — the harness's documented render-intent vocabulary, which first-party tools (dsh-tool-jobs, dsh-tool-workflow, dsh-schedule, dsh-tool-skill) already use.

The point is that these calls have a fact worth putting in a title:

Instead of The card says
peer_claim · api/charges.ts Claim refused — a peer holds it
peer_verify_reply · checkout REFUTED — answering checkout
peer_status · blocked DEADLOCK — mutual wait detected
peer_send · checkout-client Message checkout-client (interrupt)

Verified as not yet visible — stating it plainly

Against the rc build this was developed on, the Web UI renders its generic row regardless. I checked both the collapsed row and the detail panel: the presenter title does not appear in either.

The declarations are correct against the published types, they cost nothing to carry, and they will render when a build surfaces them. But this is not a UI improvement today and I'm not describing it as one. No README claim, no screenshot.

The real path to custom rendering

Recorded in the roadmap rather than half-built: an inbound peer message shown as a genuine card instead of a Context injection row needs a client bundle — a Conversation Node folding the events, a keyed renderer on conversation.chat.node, CSS modules, and the client/host tsconfig split. Substantially larger than anything in this roadmap. Not started.

Replay safety

Presenters are pure and undefined-tolerant by contract: they run on replayed history, where a logged call may carry arguments from an older version of a tool. A presenter that threw would break the whole transcript, not one card — so there's a test that every presenter survives empty arguments and empty results, and that titles stay one line whatever the input.

18 new tests, 326 total.

Tools now declare presentCall/presentResult — the harness's documented
render-intent vocabulary, which first-party tools already use — so a card
can carry the fact that matters in its title: which resource was claimed,
whether a claim was refused and by whom, the verdict on a verification,
that a status published a deadlock.

Presenters are pure and undefined-tolerant by contract, because they run on
replayed history as well as live calls: a logged call may carry arguments
from an older version of a tool, and a presenter that threw would break the
transcript rather than one card. There is a test for exactly that.

Verified as NOT yet visible, and worth stating plainly. Against the rc build
this was developed on, the Web UI renders its generic row regardless, and a
presenter title appears in neither the row nor the detail panel. The
declarations are correct against the published types, cost nothing to carry,
and will render when a build surfaces them — but this is not a UI
improvement today and should not be described as one.

Records the real path to custom rendering in the roadmap: an inbound peer
message shown as a card rather than a "Context injection" row needs a client
bundle — a Conversation Node, a keyed renderer on conversation.chat.node,
CSS modules, and the client/host tsconfig split. Substantially larger than
anything in the roadmap, and not started.

18 new tests, 326 total. Version 0.9.0.
@happyren
happyren merged commit 2fe319a into master Aug 15, 2026
1 check passed
@happyren
happyren deleted the feat/cards-ui branch August 15, 2026 08:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant