Merge remote-tracking branch 'origin/master' into worktree/provider-routed-llm-adapters

# Conflicts:
#	docs/config-catalog.md
#	packages/examples/acp-demo/tests/acp-agent.spec.ts
#	packages/examples/stdio-demo/README.md
#	packages/examples/stdio-demo/src/index.ts
#	packages/examples/stdio-demo/tests/stdio-agent.spec.ts
This commit is contained in:
Yichen Jiang
2026-07-15 20:14:09 +08:00
138 changed files with 613 additions and 530 deletions

View File

@@ -4,7 +4,7 @@ Runnable demo: stdin chat with a scripted mock model and an echo tool. The all-m
## What it shows
This example is just a leaf `cordis.yml`: it loads the [`@deepseek-ai/dsh-stdio-agent`](../../packages/ui/stdio-agent) app (which bundles the whole [`@deepseek-ai/dsh-agent-core`](../../packages/core/agent-core) spine, the console logger, JSONL persistence, the readline UI, and a pre-created `main` agent), and swaps in two example-local backends plus `hmr`:
This example is just a leaf `cordis.yml`: it loads the [`@deepseek-ai/dsh-stdio-demo`](../../packages/examples/stdio-demo) app (which bundles the whole [`@deepseek-ai/dsh-agent-spine-demo`](../../packages/examples/agent-spine-demo) spine, the console logger, JSONL persistence, the readline UI, and a pre-created `main` agent), and swaps in two example-local backends plus `hmr`:
- `mock-llm.ts` — a mock `LlmAdapter` that streams scripted responses and calls the `echo` tool when the user types "echo <something>". Registered with `ctx.llm.registerAdapter(['mock-echo'], …)`.
- `echo-tool.ts` — a tool registered via `ctx.tools.register(defineTool(…))` with typed `execute` args; echoes text back uppercased.
@@ -17,16 +17,16 @@ Swapping `mock-llm` for the real `llm-deepseek` adapter is all that separates th
|---|---|---|
| `src/mock-llm.ts` | `LlmAdapter` registration | `ctx.llm.registerAdapter(['mock-echo'], …)`, streaming chunks with the proper `block-start`/`block-end` protocol |
| `src/echo-tool.ts` | Tool registration | `ctx.tools.register(defineTool(…))` with typed `execute` args, returning `ContentBlock[]` |
| `cordis.yml` | Leaf wiring | the two backends + `hmr` + one `@deepseek-ai/dsh-stdio-agent` entry carrying the app config |
| `cordis.yml` | Leaf wiring | the two backends + `hmr` + one `@deepseek-ai/dsh-stdio-demo` entry carrying the app config |
The spine, UI, persistence, and boot glue all live in `@deepseek-ai/dsh-stdio-agent` and the bundle it loads — this folder holds only the demo-specific mocks and the leaf wiring.
The spine, UI, persistence, and boot glue all live in `@deepseek-ai/dsh-stdio-demo` and the bundle it loads — this folder holds only the demo-specific mocks and the leaf wiring.
## Run
```sh
pnpm run demo:echo
# or:
node --expose-internals --import tsx packages/ui/stdio-agent/src/bin.ts examples/echo-agent/cordis.yml
node --expose-internals --import tsx packages/examples/stdio-demo/src/bin.ts examples/echo-agent/cordis.yml
```
Type a message and press Enter. "echo <text>" triggers a tool call round-trip (the mock model requests the `echo` tool, which echoes the text uppercased, and the next model step acknowledges it).

View File

@@ -16,9 +16,9 @@ flowchart LR
cfg --> plugin_echo_echo_tool
plugin_echo_bash["bash<br/>@deepseek-ai/dsh-bash-local"]
cfg --> plugin_echo_bash
plugin_echo_stdio_agent["stdio-agent<br/>@deepseek-ai/dsh-stdio-agent"]
plugin_echo_stdio_agent["stdio-agent<br/>@deepseek-ai/dsh-stdio-demo"]
cfg --> plugin_echo_stdio_agent
plugin_echo_stdio_agent --> bundle_agent_core["@deepseek-ai/dsh-agent-core"]
plugin_echo_stdio_agent --> bundle_agent_core["@deepseek-ai/dsh-agent-spine-demo"]
plugin_echo_stdio_agent --> bundle_jsonl["@deepseek-ai/dsh-session-persistence-jsonl"]
plugin_echo_stdio_agent --> frontdoor_stdio["readline UI<br/>console logger<br/>pre-created main agent"]
bundle_agent_core --> spine_llm["ctx.llm"]
@@ -33,7 +33,7 @@ flowchart LR
| `mock-llm` | `./src/mock-llm.ts` |
| `echo-tool` | `./src/echo-tool.ts` |
| `bash` | `@deepseek-ai/dsh-bash-local` |
| `stdio-agent` | `@deepseek-ai/dsh-stdio-agent` |
| `stdio-agent` | `@deepseek-ai/dsh-stdio-demo` |
Source config: [`examples/echo-agent/cordis.yml`](cordis.yml).

View File

@@ -3,7 +3,7 @@
# No API key: the `mock-echo` adapter never touches the network.
# Hot-module reload for the dev/demo loop (a leaf entry, not baked into
# dsh-stdio-agent — it needs `node --expose-internals`, which `demo:echo` passes).
# dsh-stdio-demo — it needs `node --expose-internals`, which `demo:echo` passes).
- id: hmr
name: '@cordisjs/plugin-hmr'
config:
@@ -24,7 +24,7 @@
# The app pre-creates `main` on the mock model and supplies logging, persistence, and readline UI.
- id: stdio-agent
name: '@deepseek-ai/dsh-stdio-agent'
name: '@deepseek-ai/dsh-stdio-demo'
config:
provider: mock
model: mock-echo

View File

@@ -8,7 +8,7 @@ import { LOADER_SMOKE_TEST_TIMEOUT_MS, runLoaderSmoke } from '@deepseek-ai/dsh-l
* and the complete behavior proof for the example.
*/
const binScript = fileURLToPath(new URL('../../../packages/ui/stdio-agent/src/bin.ts', import.meta.url))
const binScript = fileURLToPath(new URL('../../../packages/examples/stdio-demo/src/bin.ts', import.meta.url))
const configPath = fileURLToPath(new URL('../cordis.yml', import.meta.url))
const tsconfigPath = fileURLToPath(new URL('../../../tsconfig.json', import.meta.url))