mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
feat(tui): add pi-ai Anthropic example
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-07-14-provider-routed-llm-adapters.md: 98205d18d07752e0cdba86d7cba80368d45fd816
|
||||
2026-07-14-provider-routed-llm-adapters.zh.md: c35225a86baf4c2d09732b5940abbc8046d365fb
|
||||
2026-07-14-provider-routed-llm-adapters.md: a0f43751a17134f42e3f1a73879c79521fa7921b
|
||||
2026-07-14-provider-routed-llm-adapters.zh.md: a8712166e74e323e3091251766fd26fefd0690d0
|
||||
|
||||
@@ -84,6 +84,7 @@ The on-disk session format remains the pre-release pinned version `0`, with no c
|
||||
|
||||
- Unit coverage exercises registry conflicts, request reconstruction, session validation, profile resolution, single-attempt option forwarding, native API selection including OpenAI Responses, conversion, replay validation, error mapping, caller cancellation, idle-timeout transport termination, content rewrites, and same-instance versus different-instance replay dispatch.
|
||||
- Keyless loop/session tests and ACP snapshots exercise durable provider/model metadata, resume and fork propagation, workflow/subagent overrides, and unchanged user-visible transcripts; the key-gated DeepSeek e2e retains real provider streaming and tool follow-up coverage.
|
||||
- The TUI's `pi-ai-anthropic.cordis.yml` overlay disables the native provider owner, mounts an explicit Anthropic profile over deployment-supplied credentials and endpoint, and selects a catalog model. Its keyless PTY smoke opens `/model`, observes the profile's default reasoning effort, and selects the next adapter-advertised effort without provider I/O.
|
||||
- Public JSDoc, package READMEs, architecture and core-data-structure docs, generated catalogs, examples, session fixtures, and Python SDK pairs use provider/model targets consistently and are checked by the repository documentation and type-equivalence gates.
|
||||
|
||||
## Risks
|
||||
|
||||
@@ -84,6 +84,7 @@ JSON-RPC 运行时显式接收 provider 与 model。仅当 `deepseek` 提供方
|
||||
|
||||
- 单元测试覆盖注册表冲突、请求重建、会话验证、配置解析、单次请求的选项转发、包括 OpenAI Responses 在内的原生 API 选择、转换、回放验证、错误映射、调用方取消、空闲超时导致的传输终止、内容重写,以及同一实例与不同实例间的回放分发。
|
||||
- 无密钥的 agent loop/会话测试和 ACP 快照覆盖持久化 provider/model 元数据、恢复与 fork 传播、工作流/subagent 覆盖,以及不变的用户可见 transcript(文本记录);密钥门控的 DeepSeek e2e 测试保留真实提供方的流式输出与工具后续调用覆盖率。
|
||||
- TUI 的 `pi-ai-anthropic.cordis.yml` 覆盖配置会禁用原生提供方所有者,在部署提供的凭据和端点之上挂载显式 Anthropic 配置,并选择一个目录模型。其无密钥 PTY 冒烟测试会打开 `/model`,观察该配置的默认推理级别,并在不执行提供方 I/O 的情况下选择适配器公布的下一个推理级别。
|
||||
- 公共 JSDoc、package README、架构与核心数据结构文档、生成目录、示例、会话 fixture(测试前置数据)和 Python SDK 配对文档统一使用 provider/model 目标,并由仓库文档与类型等价门禁校验。
|
||||
|
||||
## 风险
|
||||
|
||||
@@ -13,6 +13,14 @@ pnpm run demo:tui
|
||||
|
||||
Both the demo script and the installable `dsh` CLI ([`apps/cli`](../../apps/cli/README.md)) boot this example's `cordis.yml` as the shipped default config; `dsh` additionally applies the personal overlay from `~/.dsh` and uses the invoking directory as the workspace.
|
||||
|
||||
### Anthropic-compatible pi-ai route
|
||||
|
||||
The checked-in `pi-ai-anthropic.cordis.yml` overlay disables the native DeepSeek adapter, mounts one explicit `anthropic` profile through `dsh-llm-pi-ai`, and selects `claude-sonnet-4-6` with `high` reasoning by default. It deliberately reuses `DEEPSEEK_API_KEY` and `DEEPSEEK_BASE_URL` for a deployment whose private endpoint accepts the Anthropic Messages protocol; a DeepSeek Chat Completions endpoint is not interchangeable. Run it from the repository root:
|
||||
|
||||
```sh
|
||||
pnpm run demo:tui --config examples/tui-agent/pi-ai-anthropic.cordis.yml
|
||||
```
|
||||
|
||||
Type a coding task. The agent works through the `read`/`write`/`edit` filesystem tools for ordinary file operations and `bash` (+ the generic `task_output` / `task_list` / `task_kill` for background tasks) for shell commands, searches, and test runs, each in a fresh `bash -c` (the system prompt tells the model to pass `workdir` instead of `cd`). Both the fs tools and bash resolve relative paths against the session workspace. It can also delegate with `subagent`/`subagent_fork`.
|
||||
|
||||
The `todo_write` task tracker is opt-in and not in the shipped config: add `@deepseek-ai/dsh-tool-todo` to `cordis.yml` (or a personal-config overlay under `~/.dsh`) to expose it. Once loaded, the model records a whole-list plan to the session log and the TUI renders it.
|
||||
@@ -51,7 +59,7 @@ This example is a thin leaf `cordis.yml`: it picks the swappable backends, loads
|
||||
| Entry | Demonstrates |
|
||||
|---|---|
|
||||
| `hmr` (`@cordisjs/plugin-hmr`) | the dev/demo edit-reload loop — a **leaf** entry (not baked into the app) because it depends on the Loader's internal module access |
|
||||
| `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 |
|
||||
| `llm-deepseek` | the default native adapter; `pi-ai-anthropic.cordis.yml` disables that owner and mounts an explicit library-backed Anthropic profile |
|
||||
| `bash` (`dsh-bash-local`) | the executor implementation — the swappable half of the bash seam. The model-facing `bash` schema (`tool-bash`) and generic `task_*` controls (`tool-tasks`) come from `dsh-agent-spine-demo`, so only the executor is a leaf choice |
|
||||
| `tui-agent` (`@deepseek-ai/dsh-tui-demo`) | the app bundle: the agent-spine demo + JSONL persistence + the pi-tui channel + a pre-created `main` agent |
|
||||
| `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 |
|
||||
|
||||
39
examples/tui-agent/pi-ai-anthropic.cordis.yml
Normal file
39
examples/tui-agent/pi-ai-anthropic.cordis.yml
Normal file
@@ -0,0 +1,39 @@
|
||||
# Replace the native DeepSeek adapter with pi-ai's Anthropic route. The
|
||||
# configured endpoint must implement the Anthropic Messages protocol even
|
||||
# though this deployment reuses the repository's DeepSeek-named environment
|
||||
# variables.
|
||||
- id: base
|
||||
name: '@cordisjs/plugin-include'
|
||||
config:
|
||||
path: ./cordis.yml
|
||||
patches:
|
||||
- id: llm-deepseek
|
||||
name: '@deepseek-ai/dsh-llm-deepseek'
|
||||
disabled: true
|
||||
- id: tui-agent
|
||||
name: '@deepseek-ai/dsh-tui-demo'
|
||||
config:
|
||||
provider: anthropic
|
||||
model: claude-sonnet-4-6
|
||||
resumeSessionId: !!js "typeof resumeSessionId === 'string' ? resumeSessionId : undefined"
|
||||
persistenceRoot: './.sessions'
|
||||
resumeCommand: 'dsh --config examples/tui-agent/pi-ai-anthropic.cordis.yml --resume {session}'
|
||||
workspaceContext:
|
||||
maxBytes: 65536
|
||||
ui:
|
||||
showReasoning: true
|
||||
maxToolOutputLines: 6
|
||||
persona: |
|
||||
You are a coding agent powered by the {{model}} model.
|
||||
|
||||
Verify your work by running the code or tests. Keep answers brief and
|
||||
factual.
|
||||
- insert:
|
||||
- id: llm-pi-ai
|
||||
name: '@deepseek-ai/dsh-llm-pi-ai'
|
||||
config:
|
||||
providers:
|
||||
- provider: anthropic
|
||||
apiKey: !!js process.env.DEEPSEEK_API_KEY
|
||||
baseURL: !!js process.env.DEEPSEEK_BASE_URL
|
||||
reasoning: high
|
||||
@@ -11,6 +11,7 @@ import { runTuiPtySmoke, type TuiPtySmokeOptions } from './pty-harness.ts'
|
||||
const dshBinScript = fileURLToPath(new URL('../../../apps/cli/src/bin.ts', import.meta.url))
|
||||
const configPath = fileURLToPath(new URL('../cordis.yml', import.meta.url))
|
||||
const codeModeConfigPath = fileURLToPath(new URL('../code-mode.cordis.yml', import.meta.url))
|
||||
const piAiAnthropicConfigPath = fileURLToPath(new URL('../pi-ai-anthropic.cordis.yml', import.meta.url))
|
||||
const scriptedConfigPath = fileURLToPath(new URL('./fixtures/tui-scripted.cordis.yml', import.meta.url))
|
||||
const tsconfigPath = fileURLToPath(new URL('../../../tsconfig.json', import.meta.url))
|
||||
|
||||
@@ -246,6 +247,26 @@ describe('tui-agent keyless smoke (real Loader tree in a PTY)', () => {
|
||||
expect(output).toContain('\u001B[?2004l')
|
||||
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
||||
|
||||
it('boots the pi-ai Anthropic overlay and selects an advertised reasoning effort', async () => {
|
||||
const output = await smoke({
|
||||
label: 'tui-agent pi-ai anthropic',
|
||||
tempDirPrefix: 'tui-agent-pi-ai-anthropic-',
|
||||
configPath: piAiAnthropicConfigPath,
|
||||
env: {
|
||||
DEEPSEEK_API_KEY: 'keyless-tui-no-call',
|
||||
DEEPSEEK_BASE_URL: 'http://127.0.0.1:1',
|
||||
},
|
||||
actions: [
|
||||
{ waitFor: 'main-session-', send: '/model\r' },
|
||||
{ waitFor: 'Claude Sonnet 4.6 — High — current', send: '\x1b[Z\r' },
|
||||
{ waitFor: 'Reasoning effort: Max.', send: '/exit\r' },
|
||||
],
|
||||
})
|
||||
expect(output).toContain('anthropic/claude-sonnet-4-6')
|
||||
expect(output).toContain('Reasoning effort: Max.')
|
||||
expect(output).toContain('\u001B[?2004l')
|
||||
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
||||
|
||||
})
|
||||
|
||||
describe('dsh CLI keyless smoke (apps/cli through the same PTY)', () => {
|
||||
|
||||
Reference in New Issue
Block a user