Commit Graph

3376 Commits

Author SHA1 Message Date
Yichen Jiang
df2d2adbb8 Merge branch 'stack/agent-profiles-3-wire' into stack/agent-profiles-5-web-ui
# Conflicts:
#	packages/host/apiproxy/README.i18n.yaml
2026-08-07 15:41:14 +08:00
Yichen Jiang
6093c266c6 Merge branch 'stack/agent-profiles-1-seam' into stack/agent-profiles-3-wire 2026-08-07 15:41:09 +08:00
Yichen Jiang
23fea5e70d Merge remote-tracking branch 'origin/master' into stack/agent-profiles-1-seam 2026-08-07 15:41:03 +08:00
Yichen Jiang
7ce9c244ae Merge pull request #1810 from deepseek-harness/claude/docs-model-providers
docs(user): 新增「配置模型」入门文档,并让文档站点自带图片
2026-08-07 15:15:27 +08:00
Yichen Jiang
ce468c87f2 chore(docs): re-record the agent-preset note pairing after the merge 2026-08-07 14:47:08 +08:00
Yichen Jiang
c5f3dc3317 Merge branch 'stack/agent-profiles-6-cordis-agent' into stack/agent-profiles-7-docs
# Conflicts:
#	.agents/notes/implemented/architecture/2026-08-03-per-session-agent-presets.i18n.yaml
2026-08-07 14:46:46 +08:00
Yichen Jiang
51e1f48540 fix(cli): keep the subagent registry host-plane in the cordis preset
The cordis preset moved `bash-env`, the `subagents` registry, and its
spawn/fork backends into entry-local realms. A host row that injects a service
is the criterion for host-plane ownership: `apps/cli/src/web.ts` injects
`bash-env`, and `dsh-host-apiproxy` injects `subagents` to answer the
browser's cross-session queries, so both waited forever for a service only
sessions provided. A provider name also registers once, so the second session
would have collided regardless.

This layer introduces the preset, so it is where the plane belongs — a later
layer already corrected it, which left this layer and the docs one unmountable
on their own. The composition test stops disabling `api-gateway` with it: the
row whose pending injection names the break cannot be the row the test turns
off, so the boot audit now covers the whole host-plane injection graph.
2026-08-07 14:45:30 +08:00
Yichen Jiang
23a4c0a51e Merge pull request #1827 from deepseek-harness/worktree/charming-swartz-83bf33
fix(llm,web): validate API key format before it reaches an HTTP header
2026-08-07 14:36:04 +08:00
_Kerman
57749361ec Merge pull request #1343 from deepseek-harness/feat/fs-tool-error-remedy
feat(fs): append recovery remedy to guarded-mutation errors
2026-08-07 14:15:08 +08:00
Yichen Jiang
d5c5e7f2e9 Merge remote-tracking branch 'origin/master' into worktree/charming-swartz-83bf33
# Conflicts:
#	apps/web/tests/models-settings.e2e.ts
#	docs/config-catalog.md
#	packages/client/ui-models/README.i18n.yaml
#	packages/client/ui-models/README.md
#	packages/client/ui-models/README.zh.md
#	packages/client/ui-models/src/client/ProviderEditor.tsx
#	packages/client/ui-models/tests/provider-form.spec.tsx
#	packages/llm/llm-deepseek/README.i18n.yaml
#	packages/llm/llm-deepseek/README.md
#	packages/llm/llm-deepseek/README.zh.md
#	packages/llm/llm-deepseek/src/index.ts
2026-08-07 14:12:17 +08:00
Yichen Jiang
63724ed5f9 Merge pull request #1856 from deepseek-harness/worktree/fix-wsl-open-config
fix(apiproxy): open config files through Windows on WSL
2026-08-07 14:11:30 +08:00
Yichen Jiang
0823a3484a fix(web): report a wrapped paste as the same API key format failure 2026-08-07 14:03:11 +08:00
fz
1f853d85cd Attribute reader scroll input through the observed-top ledger
ChatView's bottom-follow recognized only wheel gestures as reader input,
so touch panning, scrollbar dragging, and keyboard paging could not leave
the bottom of a streaming transcript. Replace the wheel listener with
device-agnostic attribution: a scroll position deviating from the
observed-top ledger of the last delivered or written scrollTop is reader
input. Adds keyboard-paging and touch-style fling e2e scenarios (red under
the old implementation) and the bilingual Agent Note triplet.
2026-08-07 13:44:49 +08:00
Yichen Jiang
4410fa3dfb Merge branch 'stack/agent-profiles-6-cordis-agent' into stack/agent-profiles-7-docs 2026-08-07 13:39:40 +08:00
Yichen Jiang
e95e413115 Merge branch 'stack/agent-profiles-3-wire' into stack/agent-profiles-4-settings 2026-08-07 13:39:40 +08:00
Yichen Jiang
2e15fc0bfe Merge branch 'stack/agent-profiles-1-seam' into stack/agent-profiles-2-configs 2026-08-07 13:34:19 +08:00
Yichen Jiang
a7be2ecb0f Merge remote-tracking branch 'origin/master' into stack/agent-profiles-1-seam 2026-08-07 13:34:08 +08:00
Yichen Jiang
0cb922199d fix(apiproxy): open config files through Windows on WSL 2026-08-07 13:30:05 +08:00
Chinesezjc
2d5256fd91 Merge pull request #1079 from deepseek-harness/feat/code-runtime-multilang-seam
feat(code-runtime): own portable-identifier exclusions at the seam
2026-08-07 13:27:50 +08:00
Yichen Jiang
ddacc8de45 Merge pull request #1735 from deepseek-harness/worktree/provider-credential-lifecycle
fix(web): recover provider credential lifecycle
2026-08-07 13:27:18 +08:00
Chinesezjc
19e21dff52 Merge remote-tracking branch 'origin/master' into feat/code-runtime-multilang-seam
# Conflicts:
#	docs/core-data-structures/code-runtime.i18n.yaml
#	packages/code-runtime/code-runtime/README.i18n.yaml
2026-08-07 13:20:34 +08:00
Chinesezjc
a9e040a126 Merge pull request #1080 from deepseek-harness/feat/py-types-code-mode
feat(tools): render a Python SDK and dispatch Code Mode by runtime language
2026-08-07 13:14:41 +08:00
creatixchu
aa831f4f5e Merge remote-tracking branch 'origin/master' into worktree/turn-tail-actions
# Conflicts:
#	packages/client/ui-conversation/README.i18n.yaml
2026-08-07 11:55:53 +08:00
Yichen Jiang
545080105f Merge branch 'master' into worktree/charming-swartz-83bf33 2026-08-07 11:37:57 +08:00
Yichen Jiang
abd2e2973b Merge branch 'master' into worktree/provider-credential-lifecycle 2026-08-07 11:37:41 +08:00
Yichen Jiang
5a422337f8 fix(web): silence the stale gate hint, clear whitespace fields, narrow the paste heuristic 2026-08-07 11:36:01 +08:00
Yichen Jiang
6edd98e2b2 Merge branch 'master' into worktree/provider-credential-lifecycle 2026-08-07 11:28:22 +08:00
Yichen Jiang
91e9d5afa2 Merge branch 'master' into worktree/charming-swartz-83bf33 2026-08-07 11:28:05 +08:00
Chinesezjc
0567727410 Merge remote-tracking branch 'origin/master' into feat/todo-multi-in-progress
# Conflicts:
#	apps/cli/config/base.cordis.yml
#	packages/client/ui-conversation/README.i18n.yaml
2026-08-07 11:27:24 +08:00
Chinesezjc
20651af6a6 Merge branch 'master' into feat/py-types-code-mode 2026-08-07 11:23:41 +08:00
Chinesezjc
efdc78cba3 docs(code-runtime): fix remaining dunder/backend wording and document exports in README
- index.ts: RESERVED_ERROR_MEMBERS JSDoc now says `__x__` (non-empty
  middle), matching DUNDER_MEMBER and the derivative docs; and
  PORTABLE_RESERVED_WORDS is described as covering portable *target*
  languages (Python is a later-PR backend, not yet shipped).
- types.ts + type-equiv docs: CodeBindingNamespace.global points to
  RESERVED_BINDING_GLOBALS by name with an `e.g.` sample rather than
  enumerating the set (single home), no longer implying `__debug__` is a
  seeded slot.
- Agent Note: separate `__debug__` (CPython compile-time constant) from
  the seeded bootstrap globals.
- README (en/zh): document the four exported exclusion sets and the
  portable identifier/naming contract — no cross-package link needed.
- Regenerate cordis services catalog for the shifted source line.
2026-08-07 11:20:05 +08:00
Chinesezjc
c05db227d5 docs(code-runtime): sync Agent Note and public JSDoc with the shipped seam
- Agent Note: correct the stale worker-adoption paragraph — the worker
  consumes the seam constants directly by name (no RESERVED_WORDS /
  RESERVED_ERROR_PROPERTIES re-alias) — and describe DUNDER_MEMBER as
  `__x__` (non-empty middle).
- types.ts: document RESERVED_BINDING_GLOBALS on CodeBindingNamespace.global
  (names like `__dsh_main__` pass the identifier rule but are still refused)
  and the non-empty-middle dunder rule on memberNameProperty; propagate to
  the type-equiv derivative docs (both languages, re-recorded).
2026-08-07 11:20:05 +08:00
Chinesezjc
eb03aa86fe refactor(code-runtime): address seam review — drop worker aliases, tighten dunder
- Worker consumes PORTABLE_RESERVED_WORDS / RESERVED_ERROR_MEMBERS by
  their seam names directly, dropping the local re-alias (symmetry with
  the other two imported constants).
- Split the reserved-vs-duplicate diagnostics: a backend-owned global now
  reports "reserved binding global", not the misleading "duplicate".
- DUNDER_MEMBER uses `__.+__` so a bare `__` (empty middle, not a real
  CPython dunder) is not matched; add coverage.
- Worker misuse tests add `a$b` (second-char `$`) and `lambda` (Python
  keyword) so the identifier narrowing and reserved-word adoption are
  each pinned directly, not only transitively.
- Clarify the seam JSDoc (dunder-vs-explicit-set wording, Python backend
  is a later stack PR) and record in the Agent Note the obligation to
  widen RESERVED_BINDING_GLOBALS when the bootstrap seeds more globals.
2026-08-07 11:20:05 +08:00
Chinesezjc
5d4cea9dc1 feat(code-runtime): own portable-identifier exclusions at the seam
Move the reserved-word, reserved-global, reserved-error-member, and
dunder exclusion sets from the worker backend up to the code-runtime
seam package, and narrow the portable identifier subset to drop the
JS-only `$`. Every backend now imports one contract so a binding
namespace list valid on one backend is valid on all.

Delivers only the seam extension and the worker's adoption; the Python
backend, py-types renderer, and Code Mode language dispatch are later
PRs in the stack that depend on these exports.
2026-08-07 11:20:05 +08:00
Yichen Jiang
ec1111f18e docs: keep the API key Agent Note current with the review fixes 2026-08-07 11:04:02 +08:00
creatixchu
fb8f5f5eb4 Merge master into fix/conversation-column-one-axis-scroll 2026-08-07 10:51:29 +08:00
creatixchu
600ee462d5 Merge remote-tracking branch 'origin/master' into worktree/turn-tail-actions 2026-08-07 10:50:49 +08:00
imccyu
3216150ae0 fix: address review round next
- subagents.history computes its projections best-effort on both arms
  (a hostile unit's fold rejection serves the page without the block,
  matching the session-list precedent) with dual-arm coverage
- the lifecycle-witness spec probes every field of the seven-key
  witness, protecting the key list itself
- list-children's own module docs catch up with the seq-gate contract,
  and the design note records the rung-two later-event window as an
  accepted, self-healing deviation of the corruption class
2026-08-07 10:17:35 +08:00
Yichen Jiang
97ef0fa73a Merge branch 'stack/agent-profiles-6-cordis-agent' into stack/agent-profiles-7-docs
# Conflicts:
#	docs/architecture.i18n.yaml
2026-08-07 01:09:50 +08:00
Yichen Jiang
5f20de5e83 Merge branch 'stack/agent-profiles-3-wire' into stack/agent-profiles-4-settings 2026-08-07 01:01:50 +08:00
Yichen Jiang
380eaec39b Merge branch 'stack/agent-profiles-1-seam' into stack/agent-profiles-2-configs 2026-08-07 01:01:38 +08:00
Yichen Jiang
7c7cd1aa35 Merge remote-tracking branch 'origin/master' into stack/agent-profiles-1-seam 2026-08-07 00:59:28 +08:00
Yichen Jiang
52607cab69 docs(agent-presets): bring the note and the architecture map up to what shipped
The Agent Note was written when only the seam existed and never caught up.
Rewritten in place, per the implemented-note contract, with the four facts the
later work established:

- a preset file is an INPUT: `EntryTree.write()` persists a tree whenever the
  Loader thinks the config changed, and a self-disposing plugin is enough, so
  the inherited behaviour truncates a shipped preset to `[]` the first time a
  session ends
- a plugin that looks itself up in the global registry breaks inside a preset,
  because `register()` files into the calling context's scope — the general
  rule behind the `dsh-tool-skill` fix
- an entry-local `isolate` realm is invisible to the agent's own scope too, not
  only to the host, which is what makes a preset's registry that agent's own
  and also why a consumer left outside the group silently contributes nothing
- switching is blank-only, and why it swaps the subtree rather than the session

`docs/architecture.md` gains an Agent Presets section: the map has to carry a
new architectural concept or it is wrong, and the root layout gains the group.

Both budget ceilings are raised rather than the content cut. `AGENTS.md` sat at
1774/1775 — one word of room, already far under the 5% headroom the standard
asks for — so no group line could be added at all; `architecture.md` was in the
same shape. Raising restores headroom instead of encoding "the map may not grow".
2026-08-07 00:40:43 +08:00
Yichen Jiang
8d06b2d576 feat(agent-presets): make the default preset a user setting
`config.default` becomes the composition base of an `agent-presets` settings
namespace, so the user document layers over the deployment's engineering
default and a person can change which preset new sessions get without a
restart.

The value is read per resolution rather than snapshotted: a hot-reloaded
document takes effect on the next session created, and every running session
stays on the preset it was composed from — which is the same rule the
session-header guard enforces from the other side.

`resolve()` read `config.default` directly, which would have made the whole
setting inert; it now goes through `defaultId` like every other caller.

The write-protection test is rewritten against a temp profile root. It was
passing vacuously: the un-overridden Loader REWRITES the composition it read —
stamping `disabled: true` onto the self-disposing row — so the committed
fixture had been mutated by the very run that proved the bug, and every later
run compared against the damaged file and passed. Building the preset in a
temp directory makes the assertion immune to its own failure mode, and it now
fails with a visible `+ disabled: true` when the override is removed.

Review follow-ups on this layer. The exported schema is
`AgentPresetSettingsSchema`, symmetric with the `AgentPresetSettings`
interface it resolves and self-describing at an import site. The `session.create`
JSDoc promised "the deployment's default preset" for an omitted `agentPreset`,
which this layer makes false — it now names the effective default. The
constructor records why it does not use `installSettingsSection`: that helper
re-judges what a consumer DERIVED across attach and detach, and nothing here is
derived. The provider-unload test disposes the fiber `ctx.plugin()` handed back
instead of reaching into `ctx.reflect.store`, and the write-protection wait says
why slack is the right shape for an absence assertion.

The real composition covers the layering too. `apps/cli` boots the shipped
`cordis.yml`, stores `agent-presets.default`, and asserts an unnamed session
composes from it — the package suite proves the layering against a hand-built
context, this proves the roster and the settings provider are wired to each
other. That test also pins the settings row at a temp file: it defaulted to
`$DSH_HOME/settings.yaml`, so a developer's own stored default decided the
outcome of a file whose whole point is that only the shipped root does.

The Agent Note records the per-resolution read and its correspondence with the
session header, and the vacuous-test finding above.
2026-08-07 00:36:54 +08:00
Yichen Jiang
e27d38efd6 feat(app-boot): register cordis:group beside cordis:include
A composition that shares one `isolate` realm across rows needs a
`cordis:group` row, and a preset living outside this workspace — the
authored ones under the Harness home — cannot resolve
`@cordisjs/plugin-group` by name: Node's upward `node_modules` walk
never reaches the harness from there. Registering it as a loader builtin
beside `cordis:include` loads both through the ambient module pipeline
instead.

Record it in the preset Agent Note, which leans on the realm vocabulary
without saying where the group row comes from, and drop the preset
README's limitation claiming this builtin is unavailable — it described
the state this change ends.

The test's assertion had a vacuous escape: `provide` mints the root
symbol unconditionally, so the `rootKey === undefined` disjunct could
never hold and the comment claiming the root realm never learned the
name was wrong. Pin both halves — the symbol exists, nothing is stored
under it — and clean up the global the fixture writes.
2026-08-07 00:34:19 +08:00
Yichen Jiang
065257addb fix(agent-presets): bound the mount registry on a host that never reads it
Records are pruned by observation rather than by a disposal hook, for the
reason the module already states: three different owners can tear a
subtree down, and a cleared `uid` is what they share. That leaves the
pruning to whoever reads — and the only production reader is the
invariant companion, whose package is a development composition a
shipped host never loads.

So a live host pruned nothing: every session ever composed left a record
retaining its whole disposed subtree, since the fiber holds its config
and that config is the key its EntryTree is stored under.

Prune on the mount path too. Every session takes it, which bounds the
set at one generation of dead records instead of one per session.
2026-08-07 00:33:40 +08:00
imccyu
c98a754ccb fix: address review round four
- the cached-identity rung gains a finality gate: the identity value
  carries its descriptor seq and a cached row is served only when that
  seq lands in the child's own suffix, so a fork seed's replayed
  ancestor identity can never outrank the authoritative refold
  (stateVersion bumped for the state-shape change)
- the cold preparation validates the inspected header against the
  enumerated candidate's lifecycle witness; a republished id degrades to
  that child's corrupt diagnostic instead of leaking the new owner's log
- the new projection registration proves HMR disposal; companion notes
  qualify the superseded decision text and record the deliberate
  error-face asymmetry
2026-08-07 00:05:43 +08:00
imccyu
b9886d1615 refactor(apiproxy): read subagent history like session history
subagents.history drops its session-query read: a live child serves its
in-memory events with the registry watermark snapshot, a cold child goes
through inspectServable with a detached fold, and the retired
SESSION_QUERY_* arms disappear while every wire face stays put. The
design note records the shared read source.
2026-08-07 00:05:43 +08:00
imccyu
397d70d545 fix: address review round three
- the subagent projection's empty state becomes a serializable null
  sentinel (undefined fields vanish in JSON push frames, leaving stale
  identities in clients); consumers treat null and a missing key alike,
  and cached sentinels defer to the authoritative refold
- the tool catalog generator mounts the projection registry for
  list_agents; the shared unavailable-error copy goes catalog-neutral
- the design note's verification section records the new
  subagent-diagnostic snapshot honestly, the 2026-07-22 note's test
  inventory is rewritten to the current mechanism, and the session-store
  error code is documented
2026-08-07 00:05:43 +08:00
imccyu
a25d4331d7 feat(subagent): opportunistic projection-cache rung for cold listings
Cold children consult the optional session-projection-cache checkpoint
before paying a preparation recompute: the identity is immutable once
appended, so a cached value is definitive regardless of its watermark.
The cache stays a read-only accelerator (absent service or any rung-two
fault falls through silently; verdicts stay with the authoritative
refold), and the note plus core-data-structures pages describe the
three-rung ladder.
2026-08-07 00:05:42 +08:00