mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
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:
@@ -1,12 +1,12 @@
|
||||
# Examples
|
||||
|
||||
Runnable demos (not workspaces) that showcase how the harness is wired. Each example is a **thin leaf**: a `cordis.yml` that picks the swappable backends (an LLM adapter, a bash executor), loads one app package, and may add optional product tools or demo-only mocks. The composition — the spine, the front-door cluster, and the boot glue — lives in the app packages ([`@deepseek-ai/dsh-stdio-agent`](../packages/ui/stdio-agent), [`@deepseek-ai/dsh-acp-agent`](../packages/ui/acp-agent)) and the [`@deepseek-ai/dsh-agent-core`](../packages/core/agent-core) bundle they share. There is no `start.ts`; the `demo:*` scripts invoke each app package's `bin`.
|
||||
Runnable demos (not workspaces) that showcase how the harness is wired. Each example is a **thin leaf**: a `cordis.yml` that picks the swappable backends (an LLM adapter, a bash executor), loads one app package, and may add optional product tools or demo-only mocks. The composition — the spine, the front-door cluster, and the boot glue — lives in the app packages ([`@deepseek-ai/dsh-stdio-demo`](../packages/examples/stdio-demo), [`@deepseek-ai/dsh-acp-demo`](../packages/examples/acp-demo)) and the [`@deepseek-ai/dsh-agent-spine-demo`](../packages/examples/agent-spine-demo) bundle they share. There is no `start.ts`; the `demo:*` scripts invoke each app package's `bin`.
|
||||
|
||||
## echo-agent
|
||||
|
||||
A mock model + echo tool on the stdio chat app — the all-mock skeleton. The leaf swaps `dsh-stdio-agent`'s LLM backend to a local `mock-echo` adapter and adds a local `echo` tool. Demonstrates:
|
||||
A mock model + echo tool on the stdio chat app — the all-mock skeleton. The leaf swaps `dsh-stdio-demo`'s LLM backend to a local `mock-echo` adapter and adds a local `echo` tool. Demonstrates:
|
||||
|
||||
- A thin leaf `cordis.yml` loading the `@deepseek-ai/dsh-stdio-agent` app
|
||||
- A thin leaf `cordis.yml` loading the `@deepseek-ai/dsh-stdio-demo` app
|
||||
- Registering a mock `LlmAdapter` (streaming scripted responses)
|
||||
- Registering a tool via `ctx.tools.register()`
|
||||
- "Swap the backend, keep the app" — the only difference from `coding-agent` is the adapter
|
||||
@@ -15,7 +15,7 @@ Run with: `pnpm run demo:echo`. When prompted, type "echo <something>" to trigge
|
||||
|
||||
## coding-agent
|
||||
|
||||
A REPL agent demo: DeepSeek V4 + the `read`/`write`/`edit` filesystem tools + the bash tool suite, `subagent` delegation, and the `todo_write` task tracker on the same `@deepseek-ai/dsh-stdio-agent` app. The UI is a terminal readline REPL.
|
||||
A REPL agent demo: DeepSeek V4 + the `read`/`write`/`edit` filesystem tools + the bash tool suite, `subagent` delegation, and the `todo_write` task tracker on the same `@deepseek-ai/dsh-stdio-demo` app. The UI is a terminal readline REPL.
|
||||
|
||||
Run with: `pnpm run demo:repl` (needs `DEEPSEEK_API_KEY` in the environment or a gitignored repo-root `.env`). See [coding-agent/README.md](coding-agent/README.md) for details.
|
||||
|
||||
@@ -29,7 +29,7 @@ Run with: `pnpm run demo:cordis` (needs `DEEPSEEK_API_KEY`). See [cordis-agent/R
|
||||
|
||||
## acp-agent
|
||||
|
||||
An agent demo exposed as an **Agent Client Protocol (ACP)** server over JSON-RPC stdio, via the [`@deepseek-ai/dsh-acp-agent`](../packages/ui/acp-agent) app — drive it from Zed or any other ACP client. Also the home of the keyless snapshot tests.
|
||||
An agent demo exposed as an **Agent Client Protocol (ACP)** server over JSON-RPC stdio, via the [`@deepseek-ai/dsh-acp-demo`](../packages/examples/acp-demo) app — drive it from Zed or any other ACP client. Also the home of the keyless snapshot tests.
|
||||
|
||||
Run with: `pnpm run demo:acp` (needs `DEEPSEEK_API_KEY`); `pnpm run demo:code-mode acp` boots the same server in Code Mode via the `code-mode.cordis.yml` overlay. See [acp-agent/README.md](acp-agent/README.md) for the Zed setup and the snapshot-test design.
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ The leaf config loads the ACP app, DeepSeek adapter, sandboxed bash, approval an
|
||||
|
||||
## stdout is the protocol
|
||||
|
||||
This example loads **no stdout logger** — `stdout` carries the JSON-RPC frames, and any other write corrupts them. `@deepseek-ai/dsh-acp-agent` includes no logger entry, so this leaf has none to get wrong by default; do not add one (use a stderr exporter if you need logs).
|
||||
This example loads **no stdout logger** — `stdout` carries the JSON-RPC frames, and any other write corrupts them. `@deepseek-ai/dsh-acp-demo` includes no logger entry, so this leaf has none to get wrong by default; do not add one (use a stderr exporter if you need logs).
|
||||
|
||||
## Zed configuration
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
name: '@deepseek-ai/dsh-llm-deepseek'
|
||||
disabled: true
|
||||
- id: acp-agent
|
||||
name: '@deepseek-ai/dsh-acp-agent'
|
||||
name: '@deepseek-ai/dsh-acp-demo'
|
||||
config:
|
||||
provider: deepseek
|
||||
model: deepseek-v4-flash
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
path: ./cordis.yml
|
||||
patches:
|
||||
- id: acp-agent
|
||||
name: '@deepseek-ai/dsh-acp-agent'
|
||||
name: '@deepseek-ai/dsh-acp-demo'
|
||||
config:
|
||||
provider: deepseek
|
||||
model: deepseek-v4-flash
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
name: '@deepseek-ai/dsh-llm-deepseek'
|
||||
disabled: true
|
||||
- id: acp-agent
|
||||
name: '@deepseek-ai/dsh-acp-agent'
|
||||
name: '@deepseek-ai/dsh-acp-demo'
|
||||
config:
|
||||
provider: deepseek
|
||||
model: deepseek-v4-flash
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
path: ./cordis.yml
|
||||
patches:
|
||||
- id: acp-agent
|
||||
name: '@deepseek-ai/dsh-acp-agent'
|
||||
name: '@deepseek-ai/dsh-acp-demo'
|
||||
config:
|
||||
provider: deepseek
|
||||
model: deepseek-v4-flash
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
name: '@deepseek-ai/dsh-llm-deepseek'
|
||||
disabled: true
|
||||
- id: acp-agent
|
||||
name: '@deepseek-ai/dsh-acp-agent'
|
||||
name: '@deepseek-ai/dsh-acp-demo'
|
||||
config:
|
||||
provider: deepseek
|
||||
model: deepseek-v4-flash
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
path: ./cordis.yml
|
||||
patches:
|
||||
- id: acp-agent
|
||||
name: '@deepseek-ai/dsh-acp-agent'
|
||||
name: '@deepseek-ai/dsh-acp-demo'
|
||||
config:
|
||||
provider: deepseek
|
||||
model: deepseek-v4-flash
|
||||
|
||||
@@ -18,9 +18,9 @@ flowchart LR
|
||||
cfg --> plugin_acp_approval
|
||||
plugin_acp_permission["permission<br/>@deepseek-ai/dsh-permission"]
|
||||
cfg --> plugin_acp_permission
|
||||
plugin_acp_acp_agent["acp-agent<br/>@deepseek-ai/dsh-acp-agent"]
|
||||
plugin_acp_acp_agent["acp-agent<br/>@deepseek-ai/dsh-acp-demo"]
|
||||
cfg --> plugin_acp_acp_agent
|
||||
plugin_acp_acp_agent --> bundle_agent_core["@deepseek-ai/dsh-agent-core"]
|
||||
plugin_acp_acp_agent --> bundle_agent_core["@deepseek-ai/dsh-agent-spine-demo"]
|
||||
plugin_acp_acp_agent --> bundle_jsonl["@deepseek-ai/dsh-session-persistence-jsonl"]
|
||||
plugin_acp_acp_agent --> frontdoor_acp["@deepseek-ai/dsh-acp<br/>JSON-RPC stdio bridge<br/>sessions created by client"]
|
||||
bundle_agent_core --> spine_llm["ctx.llm"]
|
||||
@@ -58,7 +58,7 @@ flowchart LR
|
||||
| `bash` | `@deepseek-ai/dsh-bash-sandbox` |
|
||||
| `approval` | `@deepseek-ai/dsh-user-approval` |
|
||||
| `permission` | `@deepseek-ai/dsh-permission` |
|
||||
| `acp-agent` | `@deepseek-ai/dsh-acp-agent` |
|
||||
| `acp-agent` | `@deepseek-ai/dsh-acp-demo` |
|
||||
| `subagent` | `@deepseek-ai/dsh-subagent` |
|
||||
| `subagent-spawn` | `@deepseek-ai/dsh-subagent-spawn` |
|
||||
| `subagent-fork` | `@deepseek-ai/dsh-subagent-fork` |
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
# Persistence root: $DSH_SNAPSHOT_SESSIONS_ROOT when the snapshot harness sets it
|
||||
# (so it can harvest / isolate the log), else ./.sessions for the demo.
|
||||
- id: acp-agent
|
||||
name: '@deepseek-ai/dsh-acp-agent'
|
||||
name: '@deepseek-ai/dsh-acp-demo'
|
||||
config:
|
||||
provider: deepseek
|
||||
model: deepseek-v4-flash
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
*/
|
||||
|
||||
// The child runs from a temp cwd, so its bin and config path are absolute.
|
||||
const binScript = fileURLToPath(new URL('../../../packages/ui/acp-agent/src/bin.ts', import.meta.url))
|
||||
const binScript = fileURLToPath(new URL('../../../packages/examples/acp-demo/src/bin.ts', import.meta.url))
|
||||
const configPath = fileURLToPath(new URL('../cordis.yml', import.meta.url))
|
||||
// Resolve tsx absolutely because the subprocess runs outside the repo.
|
||||
const tsxLoader = fileURLToPath(import.meta.resolve('tsx'))
|
||||
|
||||
@@ -13,11 +13,11 @@ import { defineAcpSnapshotSuite, type Scenario, type SnapshotSuiteOptions } from
|
||||
* docs/rfc/implemented/testing/2026-06-19-acp-snapshot-tests.md.
|
||||
*/
|
||||
|
||||
// The dsh-acp-agent bin (the demo:acp entry), this example's cordis.yml, and
|
||||
// The dsh-acp-demo bin (the demo:acp entry), this example's cordis.yml, and
|
||||
// the repo-root tsconfig (four levels up from examples/acp-agent/tests) — all
|
||||
// ABSOLUTE: the subprocess cwd is a temp dir outside the repo.
|
||||
const AGENT = {
|
||||
binScript: fileURLToPath(new URL('../../../packages/ui/acp-agent/src/bin.ts', import.meta.url)),
|
||||
binScript: fileURLToPath(new URL('../../../packages/examples/acp-demo/src/bin.ts', import.meta.url)),
|
||||
configPath: fileURLToPath(new URL('../cordis.yml', import.meta.url)),
|
||||
tsconfigPath: fileURLToPath(new URL('../../../tsconfig.json', import.meta.url)),
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
* or runner support self-skip; real denial markers remain on sandbox e2e tiers.
|
||||
*/
|
||||
|
||||
const binScript = fileURLToPath(new URL('../../../packages/ui/acp-agent/src/bin.ts', import.meta.url))
|
||||
const binScript = fileURLToPath(new URL('../../../packages/examples/acp-demo/src/bin.ts', import.meta.url))
|
||||
const configPath = fileURLToPath(new URL('../cordis.yml', import.meta.url))
|
||||
const tsxLoader = fileURLToPath(import.meta.resolve('tsx'))
|
||||
// The subprocess runs from a temp cwd outside the repo; point tsx at the repo
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
* The test owns and disposes the ACP subprocess.
|
||||
*/
|
||||
|
||||
const binScript = fileURLToPath(new URL('../../../packages/ui/acp-agent/src/bin.ts', import.meta.url))
|
||||
const binScript = fileURLToPath(new URL('../../../packages/examples/acp-demo/src/bin.ts', import.meta.url))
|
||||
const configPath = fileURLToPath(new URL('../cordis.yml', import.meta.url))
|
||||
const tsxLoader = fileURLToPath(import.meta.resolve('tsx'))
|
||||
const repoTsconfig = fileURLToPath(new URL('../../../tsconfig.json', import.meta.url))
|
||||
|
||||
@@ -48,14 +48,14 @@ and watch the transcript: one `run_code` call, a program looping over tools, and
|
||||
|
||||
## What each leaf entry demonstrates
|
||||
|
||||
This example is a thin leaf `cordis.yml`: it picks the swappable backends, loads one app package, and adds product tools that are intentionally outside the shared spine. The spine (sessions, system-prompt, tools, agents, invariants, `agent-loop`) and the front-door cluster (console logger, JSONL persistence, readline UI, the pre-created `main` agent) live inside the [`@deepseek-ai/dsh-stdio-agent`](../../packages/ui/stdio-agent) app and the [`@deepseek-ai/dsh-agent-core`](../../packages/core/agent-core) bundle it loads; the leaf wires the backends and model-facing optional tools:
|
||||
This example is a thin leaf `cordis.yml`: it picks the swappable backends, loads one app package, and adds product tools that are intentionally outside the shared spine. The spine (sessions, system-prompt, tools, agents, invariants, `agent-loop`) and the front-door cluster (console logger, JSONL persistence, readline UI, the pre-created `main` agent) live inside the [`@deepseek-ai/dsh-stdio-demo`](../../packages/examples/stdio-demo) app and the [`@deepseek-ai/dsh-agent-spine-demo`](../../packages/examples/agent-spine-demo) bundle it loads; the leaf wires the backends and model-facing optional tools:
|
||||
|
||||
| Entry | Demonstrates |
|
||||
|---|---|
|
||||
| `hmr` (`@cordisjs/plugin-hmr`) | the dev/demo edit-reload loop — a **leaf** entry (not baked into the app) because it is Loader-only and needs `node --expose-internals`, which `demo:repl` passes |
|
||||
| `llm-deepseek` | real `LlmAdapter` via config (`!!js process.env.…` secrets); swap one line to `@deepseek-ai/dsh-llm-pi-ai` for the library-backed twin |
|
||||
| `bash` (`dsh-bash-local`) | the executor implementation — the swappable half of the bash seam. The model-facing `bash`/`bash_output`/`bash_kill` tool schemas (`tool-bash`) come from `agent-core`, so only the executor is a leaf choice |
|
||||
| `stdio-agent` (`@deepseek-ai/dsh-stdio-agent`) | the app bundle: the agent-core spine + console logger + JSONL persistence + readline UI + a pre-created `main` agent. Its config carries the model, system prompt, `persistenceRoot` (`./.sessions`), and `resumeSessionId` — so persistence and the agent are configured here, not wired as separate leaf plugins |
|
||||
| `stdio-agent` (`@deepseek-ai/dsh-stdio-demo`) | the app bundle: the agent-core spine + console logger + JSONL persistence + readline UI + a pre-created `main` agent. Its config carries the model, system prompt, `persistenceRoot` (`./.sessions`), and `resumeSessionId` — so persistence and the agent are configured here, not wired as separate leaf plugins |
|
||||
| `subagent`, `subagent-spawn`, `subagent-fork` | the subagent provider registry plus the two in-process backends: a fresh child and a child seeded with the parent's completed-turn prefix |
|
||||
| `tool-subagent`, `tool-subagent-fork` | two model-facing `dsh-tool-subagent` loads, each bound to a different provider and exposed under a distinct tool name (`subagent`, `subagent_fork`) |
|
||||
| `tool-todo` | the model-facing `todo_write` tool; writes the whole task list to the session log and renders as a checklist in stdio |
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
path: ./cordis.yml
|
||||
patches:
|
||||
- id: stdio-agent
|
||||
name: '@deepseek-ai/dsh-stdio-agent'
|
||||
name: '@deepseek-ai/dsh-stdio-demo'
|
||||
config:
|
||||
provider: deepseek
|
||||
model: deepseek-v4-flash
|
||||
|
||||
@@ -14,9 +14,9 @@ flowchart LR
|
||||
cfg --> plugin_coding_llm_deepseek
|
||||
plugin_coding_bash["bash<br/>@deepseek-ai/dsh-bash-local"]
|
||||
cfg --> plugin_coding_bash
|
||||
plugin_coding_stdio_agent["stdio-agent<br/>@deepseek-ai/dsh-stdio-agent"]
|
||||
plugin_coding_stdio_agent["stdio-agent<br/>@deepseek-ai/dsh-stdio-demo"]
|
||||
cfg --> plugin_coding_stdio_agent
|
||||
plugin_coding_stdio_agent --> bundle_agent_core["@deepseek-ai/dsh-agent-core"]
|
||||
plugin_coding_stdio_agent --> bundle_agent_core["@deepseek-ai/dsh-agent-spine-demo"]
|
||||
plugin_coding_stdio_agent --> bundle_jsonl["@deepseek-ai/dsh-session-persistence-jsonl"]
|
||||
plugin_coding_stdio_agent --> frontdoor_stdio["readline UI<br/>console logger<br/>pre-created main agent"]
|
||||
bundle_agent_core --> spine_llm["ctx.llm"]
|
||||
@@ -54,7 +54,7 @@ flowchart LR
|
||||
| `hmr` | `@cordisjs/plugin-hmr` |
|
||||
| `llm-deepseek` | `@deepseek-ai/dsh-llm-deepseek` |
|
||||
| `bash` | `@deepseek-ai/dsh-bash-local` |
|
||||
| `stdio-agent` | `@deepseek-ai/dsh-stdio-agent` |
|
||||
| `stdio-agent` | `@deepseek-ai/dsh-stdio-demo` |
|
||||
| `compact-basic` | `@deepseek-ai/dsh-compact-basic` |
|
||||
| `subagent` | `@deepseek-ai/dsh-subagent` |
|
||||
| `subagent-spawn` | `@deepseek-ai/dsh-subagent-spawn` |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# REPL agent with swappable DeepSeek and local-bash backends. `dsh-stdio-agent`
|
||||
# REPL agent with swappable DeepSeek and local-bash backends. `dsh-stdio-demo`
|
||||
# supplies the agent-core spine, logging, JSONL persistence, readline UI, and `main` agent.
|
||||
# HMR remains a leaf because it requires Loader internals; `demo:repl` passes
|
||||
# `--expose-internals`. The app bin loads the gitignored root `.env`; this file
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
# The app bundle pre-creates the REPL's `main` agent.
|
||||
- id: stdio-agent
|
||||
name: '@deepseek-ai/dsh-stdio-agent'
|
||||
name: '@deepseek-ai/dsh-stdio-demo'
|
||||
config:
|
||||
provider: deepseek
|
||||
model: deepseek-v4-flash
|
||||
|
||||
@@ -8,7 +8,7 @@ import { LOADER_SMOKE_TEST_TIMEOUT_MS, runLoaderSmoke } from '@deepseek-ai/dsh-l
|
||||
* a prompt and assert the banner. No model or `run_code` turn runs.
|
||||
*/
|
||||
|
||||
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('../code-mode.cordis.yml', import.meta.url))
|
||||
const tsconfigPath = fileURLToPath(new URL('../../../tsconfig.json', import.meta.url))
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { LOADER_SMOKE_TEST_TIMEOUT_MS, runLoaderSmoke } from '@deepseek-ai/dsh-l
|
||||
* immediate EOF guarantees there is no model call.
|
||||
*/
|
||||
|
||||
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))
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ flowchart LR
|
||||
cfg --> plugin_cordis_web
|
||||
plugin_cordis_web_fetch_local["web-fetch-local<br/>@deepseek-ai/dsh-web-fetch-local"]
|
||||
cfg --> plugin_cordis_web_fetch_local
|
||||
plugin_cordis_stdio_agent["stdio-agent<br/>@deepseek-ai/dsh-stdio-agent"]
|
||||
plugin_cordis_stdio_agent["stdio-agent<br/>@deepseek-ai/dsh-stdio-demo"]
|
||||
cfg --> plugin_cordis_stdio_agent
|
||||
plugin_cordis_stdio_agent --> bundle_agent_core["@deepseek-ai/dsh-agent-core"]
|
||||
plugin_cordis_stdio_agent --> bundle_agent_core["@deepseek-ai/dsh-agent-spine-demo"]
|
||||
plugin_cordis_stdio_agent --> bundle_jsonl["@deepseek-ai/dsh-session-persistence-jsonl"]
|
||||
plugin_cordis_stdio_agent --> frontdoor_stdio["readline UI<br/>console logger<br/>pre-created main agent"]
|
||||
bundle_agent_core --> spine_llm["ctx.llm"]
|
||||
@@ -41,7 +41,7 @@ flowchart LR
|
||||
| `fs-local` | `@deepseek-ai/dsh-fs-local` |
|
||||
| `web` | `@deepseek-ai/dsh-web` |
|
||||
| `web-fetch-local` | `@deepseek-ai/dsh-web-fetch-local` |
|
||||
| `stdio-agent` | `@deepseek-ai/dsh-stdio-agent` |
|
||||
| `stdio-agent` | `@deepseek-ai/dsh-stdio-demo` |
|
||||
| `tool-cordis` | `@deepseek-ai/dsh-tool-cordis` |
|
||||
|
||||
Source config: [`examples/cordis-agent/cordis.yml`](cordis.yml).
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
# The app bundle pre-creates the self-referential demo's `main` agent.
|
||||
- id: stdio-agent
|
||||
name: '@deepseek-ai/dsh-stdio-agent'
|
||||
name: '@deepseek-ai/dsh-stdio-demo'
|
||||
config:
|
||||
provider: deepseek
|
||||
model: deepseek-v4-flash
|
||||
|
||||
@@ -8,7 +8,7 @@ import { LOADER_SMOKE_TEST_TIMEOUT_MS, runLoaderSmoke } from '@deepseek-ai/dsh-l
|
||||
* prompt and assert the banner. The dummy key never reaches a model call.
|
||||
*/
|
||||
|
||||
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))
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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).
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user