Repository navigation
v0.201.0
v0.201.0: interactive answers in chat
The agent can now answer with a working UI right in the conversation: a calculator, a chart, a small tool or a 3D scene, not just a link to a side panel. You watch it being built, use it in place, and it can send your choices back to the chat after you confirm. This is ADR 0118 (epic #4076).
Upgrade notes
- Artifacts render inline by default.
show_artifactand theartifact.showservice now default toplacement="inline"for kinds that render in a frame (html, svg, react, vega-lite, mermaid). Documents and work products still go to the panel: passplacement="panel"to keep the old behaviour. Text-only clients (/v1,POST /api/chat, relay plugins) get an honest text reply instead of an inline embed. - Artifacts propose; you confirm.
protoArtifact.send(text)andprotoArtifact.openLink(url)(and theprotoComponent.*equivalents) no longer act on their own. A confirm chip asks first: Send / Dismiss / Always allow for messages, Open / Dismiss / Always allow links for https links. Send trust and link trust are stored separately, per artifact. A dismissal or a blocked pop-up rejects the frame's Promise. artifact.open_link_originsis now enforced. It was documented but never wired. If it can't be read, links are refused.- Inline frames are click-to-activate. Frames run live but don't take the keyboard until you click or Tab into them. A frame that grabs focus by itself is replaced by "This artifact tried to take keyboard focus" with Run it, and your typing stays in the composer.
turn_stall_timeout_secondshas a 15 s floor. Non-zero values below 15 s are raised to 15 s, with a one-time warning, and Settings refuses them.0still disables the guard.- Secret redaction is stricter. Tool output redaction no longer swallows the quote or bracket after a token. Quoted values are redacted up to their closing quote, and unquoted values now run through commas and semicolons, so a trailing
,nextafter a secret is also hidden. Sensitive dict keys are matched in any case or separator (ApiKey,x-api-key, …). - The artifact store keeps 200 artifacts by default (up from 20). Artifacts still referenced by a chat are never evicted.
Highlights
- Inline interactive artifacts. The artifact's own sandboxed frame now renders in the transcript, using the same nonce CSP, vendored libraries and deny-everything loader as the panel. It follows your theme live, lazy-mounts, and keeps at most 6 frames live per chat; older ones turn into a Click to resume card that holds its height.
- Watch it being built. While the model writes an inline html artifact, a live preview builds at most once a second (new
tool-args-v1streamed tool arguments), then hands over to the real frame without a layout jump. - Charts, diagrams and 3D. Vega-Lite charts take the design-system theme. Mermaid diagrams zoom and pan. three.js, d3 and anime.js are vendored, SRI-pinned and available to html/react artifacts.
- Plugin components without a console rebuild.
register_component(..., frame="page.html")plusGET /api/componentslet a plugin render a chat component from its own page, in a bearer-free sandbox, with the same send/openLink bridge. - The console uses the design system's new components:
ConfirmChip,InlineFrameCard, theMessageorigin line and theTablesource caption (@protolabsai/ui0.67). graph.sdk.record_frictionlets plugins record friction from background work. projectBoard v0.65 uses it to log its loop's machinery failures.
Fixes
- Artifact panel:
- "Open in panel" always shows the artifact you clicked, never a blank or stale frame.
- The panel only follows the active chat's panel artifacts.
- It never opens 0 px wide.
- Inline frames:
- They no longer stick at 80 px with a clipped heading.
- They come back live after switching chats.
- They keep their own colours at handover.
- Chat history:
- A reloaded chat now shows the turns another browser ran in it after this one cached it (ADR 0104 amended).
- Timestamps are correct again (zoned UTC).
- Stopped turns now read as stopped. Inline charts report their render check from their first draw.
- Liveness tests no longer flake under load: the stall guard is now testable with a virtual clock.
The full list is in the changelog below.
What's Changed
- feat: [ADR0118 S1a] table.source prop — server validator + show_component docstring by @mabry1985 in #4090
- feat: [ADR0118 S6] extract PluginView bearer/theme handshake into shared module by @mabry1985 in #4093
- feat: [ADR0118 S1b] table.source caption — console renderer by @mabry1985 in #4094
- feat: [ADR0118 S4] artifact placement=inline + artifact-ref inline/height + stream_args marks by @mabry1985 in #4092
- feat: [ADR0118 S7a] inline frame manager — height clamp, lazy mount, 6-frame cap (pure logic) by @mabry1985 in #4098
- feat: [ADR0118 S2] server stream_args → tool-args-v1 DataPart by @mabry1985 in #4097
- feat: [ADR0118 S11a] register_component(frame=) — registry + testkit validation by @mabry1985 in #4091
- feat: [ADR0118 S5] artifact shell chrome-less embed mode (?embed=&v=) by @mabry1985 in #4095
- feat: [ADR0118 S9] rendering-artifacts skill: presentation ladder, authoring order, quality bar + evals by @mabry1985 in #4096
- feat: [ADR0118 S11b] component frames through loader + GET /api/components catalog by @mabry1985 in #4100
- feat: [ADR0118 S3] console decode tool-args-v1 into per-tool-call buffer by @mabry1985 in #4099
- feat: [ADR0118 S8a] processPartialHtml port (OIU, MIT) + tests by @mabry1985 in #4103
- feat: [ADR0118 S12a] frame-component host (sandboxed, no bearer) by @mabry1985 in #4102
- feat: [ADR0118 S7b] inline artifact host in ArtifactRefChip by @mabry1985 in #4101
- feat: [ADR0118 S10a] protoArtifact.send/openLink shim + host gate module by @mabry1985 in #4105
- feat: [ADR0118 S8b] streamed preview frame + Idiomorph vendoring by @mabry1985 in #4106
- feat: [ADR0118 S10b] wire send/openLink into chat — origin-tagged user turn by @mabry1985 in #4107
- feat: [ADR0118 S7c] fix inline frame slot leak on resume + resume-card flash + remount height by @mabry1985 in #4112
- feat: [ADR0118 S8c] preview throttle/flush + handover to final inline frame by @mabry1985 in #4109
- feat: [ADR0118 S12b] ChatComponent resolution order → frame host + bridge reuse by @mabry1985 in #4114
- docs(adr): 0118 interactive answers — inline artifacts, streamed previews, send bridge, frame components by @mabry1985 in #4089
- feat: [ADR0118 S15a] anthropic-oauth: eager_input_streaming for stream_args tools by @mabry1985 in #4127
- feat: [ADR0118 S15b] render streamed preview on unfolded turns (no reasoning part) by @mabry1985 in #4129
- feat: [ADR0118 S16] SECURITY: send gate requires a gesture IN the frame by @mabry1985 in #4128
- feat: [ADR0118 S13] show_artifact defaults to inline placement for interactive kinds by @mabry1985 in #4125
- feat: [ADR0118 S17] inline frames reclaim a slot after switching chats by @mabry1985 in #4130
- feat: [ADR0118 S14a] vendor three.js into the artifact LIB map (SRI-pinned) by @mabry1985 in #4126
- feat: [ADR0118 S18b] from-artifact label layout + debounce preview placeholder by @mabry1985 in #4131
- fix(artifact): inline artifacts say they're inline; check_artifact is placement-aware (ADR 0118 S18a) by @mabry1985 in #4132
- fix(artifact): inline artifacts keep their own colours at handover (S18c, #4124) by @mabry1985 in #4136
- fix: [ADR0118 S18d] one live inline card per artifact (#4124) by @mabry1985 in #4134
- feat: [ADR0118 S14b] vendor anime.js (MIT) into the artifact import map — in place of GSAP by @mabry1985 in #4133
- docs(artifact): three, d3 and animejs as offline imports; html import map (ADR 0118 S14c) by @mabry1985 in #4135
- feat(artifact): cap 200 + never evict an answer a live chat shows (ADR 0118 S20, #4138) by @mabry1985 in #4139
- fix(artifacts): send-to-chat is a proposal the operator confirms (ADR 0118 S19, #4137) by @mabry1985 in #4140
- fix(artifacts): trusted sends use the host ref; Always-allow resets per proposal (S19 follow-up) by @mabry1985 in #4141
- fix(artifact): artifacts follow the operator theme — full palette, themed defaults, DS-required styling by @mabry1985 in #4142
- fix(artifact): first chart draw reports its verdict; send refusals stay quiet; charts are vega-lite (#4076) by @mabry1985 in #4146
- fix(artifact): the live turn's newest inline artifact mounts eagerly so it reports a render verdict (#4147) by @mabry1985 in #4148
- fix(chat): session/turn timestamps as zoned UTC; console reads zoneless as UTC (#4145) by @mabry1985 in #4149
- fix(artifact): plain API clients get honest artifact replies, no check loop (#4144) by @mabry1985 in #4150
- refactor(artifact): _renders_ui delegates to graph.sdk.renders_ui (S21 review) by @mabry1985 in #4152
- fix(chat): a stopped tool call reads stopped, not ✓; confirm chip keeps its checkbox with the label (#4076) by @mabry1985 in #4151
- fix(artifact): verify inline renders, panel documents, de-dup render-status (#4076) by @mabry1985 in #4153
- fix(artifact): frame color-scheme follows the console theme, not the OS by @mabry1985 in #4155
- fix(artifact): themed streamed preview, no focus theft, honest tool durations (#4076) by @mabry1985 in #4154
- fix(artifact): "Open in panel" lands the clicked artifact, never a blank/stale frame (#4076) by @mabry1985 in #4156
- test(adr0118): fix stream-args flake — reset sse-starlette's leaked shutdown flag by @mabry1985 in #4157
- fix(artifact): panel follows panel artifacts only; live re-theme flips color-scheme (#4076) by @mabry1985 in #4158
- fix(artifact): openLink behind the confirm chip; focus hand-back loses no keys (#4076) by @mabry1985 in #4159
- fix(artifact): panel drops stale poll answers; in-flight poll can't drop a deep-link (#4076) by @mabry1985 in #4160
- feat: ADR 0118 interactive answers — inline artifacts, streamed previews, send bridge, frame components (epic #4076) by @mabry1985 in #4116
- docs(adr): amend ADR 0118 to what shipped (confirm chip, anime.js, click-to-activate) by @mabry1985 in #4161
- fix(chat): a reload shows turns another browser ran after this one cached the chat by @mabry1985 in #4162
- fix(artifact): ADR 0118 follow-ups — chat-scoped panel follow, 0px dock, 80px inline frames, review nits by @mabry1985 in #4163
- feat(sdk): record_friction — plugin background work reaches the friction ledger by @mabry1985 in #4164
- feat(console): adopt DS 0.67 ConfirmChip, InlineFrameCard, Message origin, Table source by @mabry1985 in #4165
- fix(redaction): token matches never consume surrounding syntax; reviewers told [REDACTED] is ours by @mabry1985 in #4166
- fix(redaction): sensitive dict keys match regardless of case, - or _ (#4166 follow-up) by @mabry1985 in #4167
- test(liveness): measure the stall window on virtual time, not a sub-second wall clock by @mabry1985 in #4168
Full Changelog: v0.200.0...v0.201.0