diff --git a/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.i18n.yaml index 16a2f7752a..3a6b18cecf 100644 --- a/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.i18n.yaml @@ -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: a0f43751a17134f42e3f1a73879c79521fa7921b -2026-07-14-provider-routed-llm-adapters.zh.md: a8712166e74e323e3091251766fd26fefd0690d0 +2026-07-14-provider-routed-llm-adapters.md: 98205d18d07752e0cdba86d7cba80368d45fd816 +2026-07-14-provider-routed-llm-adapters.zh.md: c35225a86baf4c2d09732b5940abbc8046d365fb diff --git a/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.md b/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.md index a0f43751a1..98205d18d0 100644 --- a/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.md +++ b/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.md @@ -84,7 +84,6 @@ 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 diff --git a/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.zh.md b/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.zh.md index a8712166e7..c35225a86b 100644 --- a/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.zh.md +++ b/.agents/notes/implemented/architecture/2026-07-14-provider-routed-llm-adapters.zh.md @@ -84,7 +84,6 @@ 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 目标,并由仓库文档与类型等价门禁校验。 ## 风险 diff --git a/examples/tui-agent/README.md b/examples/tui-agent/README.md index fef7f99a91..a71eb848ab 100644 --- a/examples/tui-agent/README.md +++ b/examples/tui-agent/README.md @@ -13,14 +13,6 @@ 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. @@ -59,7 +51,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` | the default native adapter; `pi-ai-anthropic.cordis.yml` disables that owner and mounts an explicit library-backed Anthropic profile | +| `llm-deepseek` | the default native adapter | | `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 | diff --git a/examples/tui-agent/pi-ai-anthropic.cordis.yml b/examples/tui-agent/pi-ai-anthropic.cordis.yml deleted file mode 100644 index c1ec3b2968..0000000000 --- a/examples/tui-agent/pi-ai-anthropic.cordis.yml +++ /dev/null @@ -1,39 +0,0 @@ -# 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 diff --git a/examples/tui-agent/tests/tui-keyless-smoke.e2e.ts b/examples/tui-agent/tests/tui-keyless-smoke.e2e.ts index 79f0155cbd..169b582492 100644 --- a/examples/tui-agent/tests/tui-keyless-smoke.e2e.ts +++ b/examples/tui-agent/tests/tui-keyless-smoke.e2e.ts @@ -11,7 +11,6 @@ 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)) @@ -247,26 +246,6 @@ 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)', () => {