Adopt current model-switch notices, lazy observation, and open-in-app integration while preserving structural V3 admission. Regenerate only the new model-switch owner’s native V3 recording, prompt-count manifest and expected delimiter; keep the master V2 predecessor byte-exact.
Bring model-switch notices, lazy observations, and open-in-app into the root V3 integration without importing the child structural header changes. Preserve V3 migration, PTC, and all predecessor fixtures.
Refresh only the model-switch-notice owner through dsh --profile headless to harvest native current-writer session.v3.jsonl. Keep the master session.v2.jsonl byte-exact; existing header pin and versioned writer helpers require no changes.
Add the first-party open-in-app host and client packages with a localized Open In menu in the Web Session header.
Resolve installed applications on macOS, Windows, and Linux, launch workspace directories through platform-specific adapters, and remember the selected application.
Closes#1500.
Co-authored-by: ihsiang <ihsiang@deepseek.com>
Preserve the V3 PTC SDK assertion and enable the new human-steering runtime fixture while carrying master’s inbox lifecycle changes. Retain prior deterministic CI repairs and immutable predecessor ownership.
Preserve the V3 PTC scenario while enabling the current subagent human-steering fixture environment. All product changes are inherited from master; no V3 migration semantics are altered.
* feat(subagent): align continuable human inbox controls
* fix: repair rebase documentation and close test persistence
* docs: refresh rebased module dependency graph
Preserve the V3 system-prompt projection while adopting master’s per-agent frozen-message provenance and frontend performance gates. Keep benchmark workload admission and diagnostics fixes intact, and retain both migration and first-open/reopen lifecycle guarantees.
Preserve system/message persistence while adopting named persona prefix/suffix and environment facts after reusable instructions. Resolve the Web assertion against the logged system message, not retired header.system. Keep the existing protected V3 integration PR as the root publication path; no rules are bypassed.
Compose the shared release branch PTC rename with the structural system-head migration in the existing V2-to-V3 stage. Audit source payloads and remap local coordinates before renaming dispatch vocabulary and owned plugin attribution; retain original message identities and generation-qualified references. Native V3 validation combines the same system and PTC lifecycle semantics through a private released-validation view.
Reuse the V3 row-admission owner in current JSONL scanning before recoverable-tail suppression, so malformed rows cannot hide retired required PTC tags or header.system. The new corruption-prefix regressions and all173 existing JSONL scanner tests pass. Combined migration/catalog/persistence suite:300 tests; executable V3 migration source has100% coverage. No released generation, prior migration implementation, shared release branch, benchmark or CI workflow is modified by this integration.
Keep the generated configuration source pointers aligned with the smaller replay module. No configuration semantics or public runtime behavior changes.
Regenerate source-owned catalogs after the oracle simplification and usage-anchor correction. The configuration catalog retains the same declared options while its source location follows removed compatibility stripping; the token-meter service docs now state that the usage anchor includes all admitted request inputs. Keep bilingual generated declarations aligned instead of retaining stale copied contracts.
Validation: pnpm run doc-sync identified only cordis catalog and config catalog freshness failures (31 other gates passed); pnpm run gen-cordis-catalog and pnpm run gen-config-catalog regenerated their owners, and the config pair was updated and recorded. Full layer documentation validation follows integration.
Cause: SystemPromptProjection skipped the first empty rendered prompt. The initial admitted user then occupied surface node zero, so a later nonempty prompt appended behind user history. Routes without in-history system support lost the leading system role; pi-ai demotes a non-leading system message to user content.
Fix: append the initial system node even when its content is empty. The existing loop commit order reserves node zero before admitted user messages; later prompt text replaces that node. Empty content still derives to no wire message. Keep retained-node replacement, clearing, multi-system handling, and pi-ai conversion unchanged; this addresses only the reviewed PR3476 initial-empty finding, not PR3483.
Tests: added initial-empty projection and two-turn loop regressions for empty wire output, reserved surface head, later leading system role, replacement intent, and series header. Negative control failed before the source fix. Focused projection/runtime-context/loop/request-reconstruction/session-surface/pi-ai-context suites passed 176 tests; exact runtime-context.ts coverage is 100% statements, branches, functions, and lines. test:docs passed all 15 gates. Updated README EN/ZH, architecture map and owning architecture note; recorded all three translation pairs. Broad doc-sync/lint stopped at parent request for combined-layer validation. No normalize.ts conflict-comment edit.
The session already derives the protected system head as a Message, and both adapters accept leading system history. Passing it through a separate SummarizationInput.system string unnecessarily flattens that value and rebuilds the same wire message in the adapter. Prepend the derived head to messages and remove textContent, the separate field, and GenerateOptions.system plumbing from the summarizer.
Keep range selection, shadowed seq accounting, session head protection, routed tools, image references, target policy, and the model-visible compaction instruction unchanged. Empty-content heads still derive to null and contribute no request message, but their surface node remains protected. Update subclass consumers/tests, EN/ZH package and subsystem prose, and the existing system-prompt surface owning note with refreshed pairing records.
Evidence: pnpm exec vitest run packages/compaction/compaction-basic/tests packages/llm/llm-deepseek/tests/serialize.spec.ts packages/llm/llm-pi-ai/tests/context.spec.ts --coverage --coverage.include='packages/compaction/compaction-basic/src/region.ts' --coverage.include='packages/compaction/compaction-basic/src/summarizer.ts' passed 203 tests in 6 files; both changed sources have 100% statements, branches, functions, and lines. Region-to-default-summarizer cases pin exact prefix and tools for nonempty Unicode/multiline, empty, and absent heads. DeepSeek JSON byte equality and pi-ai context equality pin leading-message vs separate-system equivalence on text and image-capable conversion paths.
pnpm run doc-sync passed all 33 gates including doc-typecheck, documentation build, translation pairing and model-experience checks. git diff --check passed. Own dependencies installed with pnpm install --frozen-lockfile. An initial test iteration used a nonexistent ctx.dispose teardown on the in-memory fixture; corrected to its existing fixture lifecycle and reran successfully. No runtime/model behavior, normalizer marker, main worktree, push, or rebase changes.
Consolidate the representation-change PR and its rebase reconciliations into one baseline. Preserve the exact tree and keep the in-history feature in the dependent PR. Follow-up fixes remain separate.
Session format v2 embeds each attempt's compact stream in
assistant/message and assistant/attempt, but Host and client consumers
still expanded it into per-member TimedStreamChunk arrays and did
per-member work; expandAssistantStream materializes the full array before
find/toReversed/break can answer. Session Stats (the projection phase of
every Session open), the token meter's usage and provider-assembly folds,
the subagent output fold, and the Session Controller image lookup still
paid O(members) allocation and time per settlement.
The Chat and Trajectory definitions were already settled from
message.content on master; the remaining per-member folds stay.
dsh-llm now exports record-level readers (first token, visible content,
visible text, last raw chunk of a type, raw chunks of a type, joined
text, run-aware assembly, per-run first-token/first-visible times) that
scan the compact records once with early exit. Session Stats reads
assistantStreamFirstTokenTime, the token meter reads
lastAssistantStreamChunk(stream, 'usage') and assembles through
assembleAssistantStream, the subagent output fold appends
joinAssistantStreamText, and the Session Controller scans
assistantStreamChunks(stream, 'block-end').
expandAssistantStream is deliberately not memoized: retaining expansions
costs roughly ten times the compact stream for the Session's lifetime.
It remains the validating path at durable boundaries.
Synthetic 200-turn v0 migration benchmark, median of five: first-open
projection 28.0 ms -> 5.4 ms, first-open total 76.9 -> 50.0 ms, peak RSS
137.2 -> 94.9 MB; reopen projection 17.8 -> 5.6 ms; all phase budgets and
the 128 MB heap constraint keep passing.
Add a benchmark lane (`vitest.bench.config.ts`, `pnpm run test:bench`,
gate mode `ci-bench`) and a required `node 24 / benchmarks` CI job that
runs it alone. Benchmarks synthesize their input in-process from fixed
parameters and fail on documented budgets:
- `open-generation.bench.ts`: a 200-turn released-v0 log with 500 text
and 125 reasoning deltas per reply (127,400 events, ~2.8 MB) encoded
through the frozen v0 codec; the migrating first `open()` must finish
within 2,000 ms in a child process capped at 128 MB of old space, and a
fresh process must open the published current generation within 500 ms.
- `conversation-fold.bench.client.ts`: 200 replies whose compact streams
hold 2,000 text + 500 reasoning deltas each, folded through every Chat
Definition by the real assembler; the fold must finish within 150 ms
and stay within 3x the fold of the same window with 100 deltas per
reply.
On this commit both gates fail: the migration exhausts the 128 MB heap
(4.8 s and 696 MB peak RSS without the cap; the pre-stack decode of the
same bytes took 34 ms and 168 MB) and the fold scales 11x with the delta
count. The stacked fixes bring both paths to O(records).