Merge remote-tracking branch 'origin/master' into codex/rfc-subagent-background-tasks

# Conflicts:
#	docs/architecture.md
#	docs/config-catalog.md
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/bash.md
#	docs/event-producer-consumer.md
#	docs/rfc/implemented/feature/2026-07-06-sandbox.md
#	docs/rfc/proposed/architecture/2026-06-20-generic-long-running-tool-runtime.md
#	examples/AGENTS.md
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/system-prompt.golden.md
#	examples/acp-agent/tests/snapshots/both-mode-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/both-mode-turn/system-prompt.golden.md
#	examples/acp-agent/tests/snapshots/code-mode-turn/system-prompt.golden.md
#	examples/acp-agent/tests/snapshots/permission-switching/system-prompt.golden.md
#	examples/acp-agent/tests/snapshots/skill-load/session.jsonl
#	examples/acp-agent/tests/snapshots/skill-load/system-prompt.golden.md
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/text-turn/system-prompt.golden.md
#	examples/coding-agent/cordis.yml
#	examples/sandbox-acp-agent/tests/snapshots/escalation-approved/session.jsonl
#	examples/sandbox-acp-agent/tests/snapshots/escalation-rejected/session.jsonl
#	examples/sandbox-acp-agent/tests/snapshots/mode-switching/session.jsonl
#	packages/bash/bash-local/README.md
#	packages/bash/bash-local/src/index.ts
#	packages/bash/bash-local/tests/executor.spec.ts
#	packages/bash/bash-sandbox/README.md
#	packages/bash/bash-sandbox/src/index.ts
#	packages/bash/bash/README.md
#	packages/bash/bash/src/index.ts
#	packages/bash/bash/src/types.ts
#	packages/bash/tool-bash/README.md
#	packages/bash/tool-bash/src/index.ts
#	packages/bash/tool-bash/tests/tools.spec.ts
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/core/agent-core/README.md
#	packages/core/agent-core/src/index.ts
#	packages/subagent/subagent/README.md
#	packages/subagent/tool-subagent/README.md
#	packages/subagent/tool-subagent/src/index.ts
#	packages/ui/acp-agent/README.md
#	packages/ui/acp/README.md
#	packages/ui/stdio-agent/README.md
#	packages/util/brand/src/index.ts
#	scripts/doc-budgets.manifest.json
This commit is contained in:
Yichen Jiang
2026-07-14 18:05:46 +08:00
669 changed files with 10081 additions and 13745 deletions

View File

@@ -26,7 +26,7 @@ The leaf `cordis.yml` supplies only the **swappable backends** — an LLM adapte
| Key | Default | Routed to |
|---|---|---|
| `model` | (required) | the pre-created `main` agent's model |
| `persona` | — | the deployment persona template (may reference `{{model}}`), routed to `dsh-system-prompt` |
| `persona` | — | the deployment persona template (may reference `{{model}}`/`{{cwd}}`), routed to `dsh-system-prompt` |
| `toolOrder` | — | explicit model-facing tool order (a name list with one `'<unlisted-tools>'` rest entry; absent — lexicographic; an unregistered name fails each turn at prompt assembly), routed to `dsh-system-prompt` |
| `tools` | `{ mode: 'native' }` | tool-registry presentation config through `agent-core` |
| `skills` | owner defaults | skill registry, local provider, and model-facing skill-tool config through `agent-core` |
@@ -67,3 +67,23 @@ Fresh stdio sessions use the process launch directory as `session.header.cwd`, s
```
Swap `llm-deepseek` for a `mock-llm` leaf plugin and you have the echo demo — "swap the backend, keep the app".
## Model Experience
### Composed terminal agent request
**What the model sees**: Through `dsh-agent-core`, the `main` agent receives the harness identity, configured persona, skill catalog, and visible tools; this app also composes the generated [`ask_user_question` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tool-ask-user). Each readline submission becomes a user message.
**Token effect**: Child prompt and schema costs repeat per request; user input and tool history grow until compaction. The welcome banner, logger output, and rendered transcript are terminal-only and add zero model tokens.
### Human-answer result
**What the model sees**: Through `dsh-tool-ask-user`, successful terminal answers use that package's exact compact JSON shape. Interruption becomes exactly `Error: ask_user_question was interrupted before the user answered`; a closed stdin becomes `Error: ask_user_question cannot be answered because stdin is closed`.
**Token effect**: Only a completed or failed tool call adds retained result tokens; prompts printed while waiting are terminal-only.
## Known Limitations and Deferred Work
- **One pre-created `main` agent drives the readline UI** — there is no multi-session or concurrent-agent surface in this app; a run is one conversation.
- **The front-door cluster is fixed in code** — the JSONL persistence backend and the ask-user tooling are baked; a different composition is a leaf-level sibling entry or another app package.
- **The question tool is not an approval answerer** — this app mounts `user-interaction` and `ask_user_question`, but not `ctx.approval`; a `tools/pre-execute` `ask` therefore fails closed unless the leaf composes an approval service and terminal answerer.