The caller-connection work — forwarded-event opt-in, physical socket
ownership, and the Node/MCP artifact-only consumer fixture — moves to a
stacked PR on top of this one. This branch now changes only how Remote
definitions are generated (Typert artifacts, lazy method info,
consumer-selected input strictness, tool-schema projection) and how the
existing Registry consumes them.
Add a placement table to the Definition section: which `groupTree`
position a Chat Node declares for an opening human input, another Turn
input, a Turn notice outside folding, an independent folded row, and
ordinary process content, with links to the contract and the built-in
positions, and a pointer to `exclusive` claims.
State in the `exclusive` JSDoc and the Conversation reference that the
claimed target's fallback does not run and that a fallback's own claim
has no effect. Reword the `input` position as the Turn's opening input
and separate the finalized-answer exemption from position-less
`assistant-step` rows. Point both package READMEs at the claim and the
group-tree positions.
Add the exclusive Conversation matches Agent Note; bring the group-tree
note up to the `input` position and the migrated kind lists, and the
timed-question note up to claim-based reply deduplication. Pair the
Chinese Conversation reference and Chat grouping README with the
English updates.
A match result may set `exclusive: true`. The assembler evaluates every
match of an event before accepting any, so a claim is independent of
registration order: other Definitions of the claimed target build no
Context for the event and the target's fallback does not run, while
Definitions of other targets and target-less Definitions still receive
it. Two claims on one target, or a claim without a target, throw.
Users of v0.2.1-alpha.2 who saved an account catalog through the Models
page editor must move single-model changes into modelOverrides, because
a models field now stops llm-deepseek-account at load. pi-ai routes that
name a missing credential now list no models.
The account route no longer accepts a models catalog, so paid Flash
translation compares Account modelOverrides (Official keeps models) when
it checks that the owner's model configuration is unchanged before
dispatch. The paid fixture and the Web e2e serve the account GET /models
listing instead of configuring models on the account entry.
Reuse read_image and automatic compaction in the standalone profile without
adding SDK slash-command handling. Update profile guidance, upgrade steps,
and startup and recorded-session coverage.
The account route always reads /models at the Messages origin; the
modelsURL option is removed so a configuration cannot point the listing
elsewhere. Model refusals now report "current version is <version>"
instead of "this build is", since users usually run a downloaded release
rather than a local build, and override diagnostics name the built-in
catalog instead of the build.
The session.create change is not perceptible to users: its only caller is the
Web client that ships in the same release. Remove the guide and the
cross-reference added to the New Session upgrade guide.
doc-sync, test:docs, hygiene, and check:all run at most 8 gates in CI as
well; the constant, the development guide, and the Agent Note now say so.
The Note also states that the source-only Typert guard rejects unresolved
workspace imports, so a missing alias fails before or after host-src.
Refs #5852
gen-doc-graphs states that its probe memo patches the system and needs a synchronous, non-nested caller; the typecheck graph comments why host-check does not wait for host-typert; the API gateway guide names the CI build lanes as the bundling Typert path; and the build-split Note marks its host-libraries measurement as superseded by host-contracts.
Refs #5852
Browser inputs make every package source file a generator input, so the
pre-commit job ran the 16-second generator on nearly every commit while
few commits change its output. gen-third-party-notices.spec.ts already
asserts the committed bytes in the test lane, including the required
node 24 / coverage pull-request lane, and names the regeneration command
when they are stale. The generated preamble, the notices decision, and
the development guide now describe that ownership.
Refs #5852
os.availableParallelism() reports host CPUs rather than a container's
CPU quota (256 against a 64-CPU quota here), so local defaults spawned
255 Vitest forks (55 GiB peak RSS) and oversubscribed every scheduler.
scripts/parallelism.ts keeps the CPU count in CI and caps other runs at
12, or 48 for Vitest forks and the local coverage budget; documentation
and hygiene aggregates run up to 8 gates instead of 4. Explicit
DSH_GATE_CONCURRENCY, DSH_OXLINT_THREADS, DSH_COVERAGE_MAX_WORKERS, and
--maxWorkers still win.
Refs #5852
Type checks only need Host declarations and Typert-generated
declarations, but typecheck, lint, lint:fix, doc-typecheck, and the CI
typert-contracts gate rebuilt the whole Host tsdown pass, Desktop bundle
included, to obtain them. A source-only scripts/generate-typert.ts now
runs the same generator and artifact writer as the tsdown plugin, beside
Host package compilation: Typert reads only sources once the missing
@deepseek-ai/dsh-client-file-upload/types path alias exists, and
rejectBuildOutputs fails the pass when a workspace lib/ declaration
enters its program. typecheck runs as a build.ts scope that checks both
aggregates in build mode after their own face compiles.
Refs #5852
Share locationCoordinates between the Chat Builder and GroupTreeSegments,
find the last opening Turn with a loop instead of spreading every key,
and pass the resolved Location through chatNode so message Nodes resolve
it once. The notice e2e now waits for observable barriers (each Step's
row, the notice Turn's start, the notice row) instead of fixed sleeps,
asserts the settled tail through polling plus a later-frame recheck
instead of one absolute blank threshold, and fails on console warnings.
Record exchange in the terminology table and keep Goal Round in English.
Under "On next message" folding, a Turn woken by a notice (settled
subagent, goal round, schedule, background job) advanced the bottom Turn
and folded the finished Turn without an own-input driver, so the generic
fold room left a following reader looking at blank space.
Chat Nodes now declare a group-tree position (`groupTree`, ordered
`exchange` > `turn` > `process`). Human input claimed in Step 1 marks its
Turn as opening an exchange; notices and later steering carry no
position. `GroupTreeSegments` splits the loaded Turns at opening Turns,
and `bottomSource` covers the whole latest exchange, so notice-woken
Turns no longer fold earlier ones while the next human message folds the
exchange through the own-input path. Only `exchange` is read today; the
`turn` and `process` positions are reserved for the existing kind lists.