Repository navigation
2026.10.13 - Phase 2: Compression Tool Call and Result Rendering - #83
Merged
lanhhoang merged 4 commits intoOct 13, 2026
Merged
Conversation
…ion rendering adjustments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Diff-sketch of the phase 2 deliverable on
20261013-dcp-ui-refactor-phase-02-compression-rendering(planningacb9de1, implementation329235c; implementation rangeacb9de1..329235c):theme.tsandcompress-render.tsare the only new source files.index.tsis a minimal additive change at the existing registration/execution boundary; both registered definitions closerenderCompressCallover their own mode and sharerenderCompressResult. Existing builder signatures, command names and arguments, TypeBox schemas, the registeredexecute/tool-call/tool-execution-end callback contracts, nativeui.confirmapproval, the policy recheck after approval, the post-approval policy-rejection path, and the notification/timing/persistence/pipeline behavior are unchanged.Evidence
pnpm checkis green on the pushed result: format, warning-free lint, typecheck, 1070 tests / 65 suites (baseline 1005 / 63;+8theme,+46compress-render,+10index rendering and metadata describe,+1sdk-contract renderer exposure =+65).git diff --checkexits0.Red→green sequence per task was observed before each implementation step. Selected red examples:
tests/theme.test.tspins the adapter contract: delegation across all four methods, live delegation after the underlying implementation changes (test mutatesprefixbetween calls),NO_COLORpresence including""and"0", absence ofNO_COLOR, one throwingfgwithbg/bold/inversestill operating, and a non-stringboldreturn falling back to the input text.tests/compress-render.test.tsexercises every row of the plan's Visible Rendering Contract. Calls: the four call-table strings (compress range · Auth system · 2 ranges,compress message · Auth · 1 message,compress range,compress message · 0 messages) plus singular/plural coverage and a wrong-mode-array exclusion (range mode ignorestargets; message mode ignorescontent), Unicode topic flattening (認証 system), no submitted summaries (the visible text never containsSECRET), and semantic role assertions (fgcalled withtoolTitle/accent/text/muted,boldinvoked exactly once);visibleWidth(line) <= widthis pinned at widths1,12, and60. Results: the collapsed/expanded exact strings and ordering, multiple text content items joined in source order, theBlocks: b1, b2expansion (omitted whenblockIdsis empty), the topic segment omitted when its flattened value is empty, 0/1/many message singular/plural rendering, partial-before-metadata precedence ("Compression in progress"with no metrics), error-before-metadata precedence (the original text in theerrorrole, no metrics), empty error text →"Compression failed", empty legacy text →"Compression result unavailable", the eight malformed-details cases (bad mode, non-string topic, negative count, non-finite count, missing count,blockIdsnot an array,blockIdscontaining a non-integer,blockIdscontaining a negative), multiline Unicode content preserved,NO_COLORproducing zero ANSI escapes and zerofgcalls on the theme spy, one throwing theme method leaving the visible text readable, and expanded-path line-width bounding at widths1,12, and60.createCompressionDisplayDetailstests pin the exact field copy, ablockIdsarray copy that survives later mutation, and aJSON.stringify(details)that contains neither the submitted nor the combined summary text.tests/index.test.tsadds thecompression rendering and success metadatadescribe. The first two tests prove the registration boundary: the initial range definition exposesrenderCall/renderResult; the registeredrenderCallproducescompress range · Auth · 1 range; the trusted-project message reload re-registers both callbacks (withparameters.properties.targetsinstead ofcontent), the messagerenderCallproducescompress message · Auth · 1 message, and the registeredrenderResulthonoursoptions.isPartialwith"Compression in progress". The next two tests run the fullcreateExtensionlifecycle: firesession_start, run acontextpass to assign canonicalm0001/m0002message refs, then callcompress.execute; a range compression returnsdetails.dcpCompressionequal to{ mode: "range", topic: "Auth", messagesCompressed: 2, compressedTokens: any Number, summaryTokens: any Number, blockIds: [1] }; a message compression (config file{ compress: { mode: "message" } }) returns the same shape withmode: "message",messagesCompressed: 1, andblockIds: [1]; the serializeddetailscontains neither"private summary text"nor"private target summary". The remaining tests pin every rejection path todetails: {}+isError: true: capability denial via a disabled-model config, approvalfalse, approvalcancelled(confirm throws), the effective signal aborted, and a post-approval policy change (theconfirmcallback flipsctx.modelfrom the enabled test model to the disabled one, so the recheck after approval returns amodelsuppression reason); the content text in each case is the documented suppression or"Compression was not approved"message.tests/sdk-contract.test.tsextends the approved/denied lifecycle test to captureevent.result.detailsfromtool_execution_end: the approved case hasdetailsequal to the documenteddcpCompressionshape withblockIds: [1]and the exact"Host lifecycle"topic, the denied case hasdetailsequal to{}. A new test assertssession.getToolDefinition("compress").renderCalland.renderResultare functions, invokes the registeredrenderCallwith a realTheme-shaped object and the installed SDK parameter type, and asserts the visible text is"compress range · Auth · 1 range".Domain invariants match the plan: snapshot serialization version
2and reading of versions1and2are unchanged; no snapshot format, schema, dependency, configuration option, or release-version change ships. Compression result text, pruning/compression statistics calculations, thecompresstool's TypeBox schemas and descriptions, the registeredexecuteboundary (including the policy precheck, theaskpermission approval flow, the post-approval policy recheck, and the post-approval policy-rejection path), thetool_callhandler suppression, thetool_execution_endtiming adapter, notification selection and content, persistence ordering, prompts, and the pipeline are all unchanged. SuccessfulhandleCompressis the only path that returnsdetails: { dcpCompression: ... }; every existing rejection (capability denial, approvalfalse/cancelled/aborted, post-approval policy change) still returnsdetails: {}withisError: true, and an unexpectedhandleCompressthrow still rejects. ThedcpCompressionpayload contains only the five numeric/string fields and a copy ofblockIds; the submitted summary text and the combined summary body never enterdetails. Display metadata falls through to the original text (or"Compression result unavailable") when absent or malformed, so persisted results from before this version, results with missing display metadata, and non-text content remain readable.NO_COLORdisables styling, one throwing theme method falls back to the input text without disabling its siblings, and a non-string return falls back to the input text. No new configuration, sidebar integration, search, block drilldown, domain action, package version bump, or future-phase panel/overlay/tab code is added; thepi-statusrepository is not edited and is not a dependency.Merge Danger
Door: two-way
The change is additive and reverts cleanly: reverting the one implementation commit restores the prior registered definitions (no
renderCall/renderResult,details: {}on success), removes the two new source files and the two new test files, and rolls back the README, CHANGELOG, and plan records. Every prior owner (capability gating, nativeui.confirmapproval, policy recheck,tool_callsuppression,tool_execution_endtiming, persistence codec, prompts, pipeline, notification selection) is untouched. The unchanged snapshot codec and persistence ordering mean a revert does not require migrating saved sessions. Persisted tool results carryingdetails: { dcpCompression: ... }from this version remain harmless structured tool-result details under Pi's default rendering after a revert.Blast Radius: compression tool call and result presentation
Touches:
src/tui/theme.ts(new),src/tui/compress-render.ts(new),src/index.ts(tworenderCall/renderResultattachments and onedetails: createCompressionDisplayDetails(...)replacement inexecuteCompressTool),tests/theme.test.ts(new),tests/compress-render.test.ts(new), the newcompression rendering and success metadatadescribe intests/index.test.ts, the newexposes compression renderers through the real SDK tool definitiontest and the extended lifecycledetailsAtEndcapture intests/sdk-contract.test.ts, README's new "Compression tool rendering" section, CHANGELOG's new[Unreleased] / Addedentry, and the plan file's implementation record. No change to model compression execution, thecompresstool registration schema, parameters, descriptions, default activation, or execution mode; theaskpermission approval flow; the post-approval policy recheck; the suppression paths (capability denial, post-approval policy change, approvalfalse/cancelled/ aborted,tool_callblocking); thetool_execution_endtiming adapter; pruning/compression statistics; notification selection, content, or severity; the snapshot codec or persistence ordering; prompts; the pipeline; the panel; the sidebar; or any release version. The only observable behavior change is the new compact, theme-awarecompresscall line, the new collapsed estimated-metrics line, the new expanded header-plus-text-plus-blocks presentation, the explicit"Compression in progress"partial line, and the error/legacy text fallback.