# 7-49 ChatOnly OpenClaw provider 单测缺口

## 状态

- 状态：done
- Owner：07-ai / OpenClaw provider integration
- 发现时间：2026-06-01

## 现象

`7-44` 的 MNote 侧 ChatOnly provider conversation binding 已完成并通过真实浏览器 smoke。外部 OpenClaw 仓库已经补齐 Doubao provider 的 conversation id 抽取与 delete helper 单测，但 DeepSeek / Gemini provider 级 delete helper 与单测仍没有可靠实现落点，不能在 MNote 仓库内用集成 smoke 替代。

## 已有 MNote 侧证据

- `cargo test --manifest-path rust/Cargo.toml -p control-plane external_conversation -- --test-threads=1`
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib provider_conversation -- --test-threads=1`
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib chatonly_doubao_session_delete_calls_provider_and_marks_remote_deleted -- --test-threads=1`
- `node scripts/task512-chatonly-doubao-sync-smoke.js`
- `node scripts/task513-chatonly-provider-sync-smoke.js deepseek`
- `node scripts/task513-chatonly-provider-sync-smoke.js gemini`

## 缺口

- OpenClaw Doubao provider 的 `conversation_id` 捕获、`deleteConversation` / `/im/conversation/batch_del_user_conv` 已有 provider 仓库内单测。
- DeepSeek / Gemini provider delete helper 仍缺 provider 仓库内实现与单测；如果没有可靠远端删除 API，不应伪造 `remote_deleted`。

## 2026-06-01 外部仓库复核

- 本机存在 `/home/lix/openclaw-zero-token-latest`，但该仓库已有未提交改动：
  - `src/zero-token/providers/doubao-web-client-browser.ts`
  - `src/zero-token/providers/gemini-web-client-browser.ts`
  - `src/zero-token/streams/doubao-web-stream.ts`
  - `src/zero-token/providers/web-session-binding.test.ts`
- 只读核对显示，现有 `web-session-binding.test.ts` 覆盖 Doubao `conversation_id` SSE 提取和 Gemini URL / stale candidate，但未覆盖 `deleteConversation`、`/im/conversation/batch_del_user_conv`、`remote_deleted` / `remote_delete_failed`。
- 尝试运行 `pnpm exec vitest run src/zero-token/providers/web-session-binding.test.ts` 与 `pnpm exec vitest run --config vitest.unit.config.ts src/zero-token/providers/web-session-binding.test.ts` 均因缺少 `@vitest/browser-playwright` 启动失败；`scripts/vitest.zero-token-web.config.ts` 当前 include 不包含 provider test。

结论：本缺口仍是 OpenClaw 外部仓库未完成项，不应在 MNote 仓库内标记 done。

## 下一步

在 OpenClaw provider 源码仓库中继续补 DeepSeek / Gemini provider 删除能力，覆盖：

- 删除成功返回 `remote_deleted`。
- 删除失败返回 `remote_delete_failed` 且脱敏错误。

## 2026-06-01 外部仓库二次复核

只读复核 `/home/lix/openclaw-zero-token-latest` 后确认本文仍保持 `process`，不能在 MNote 仓库内归档：

- 外部仓库已有未提交/未跟踪改动，包含 `src/zero-token/providers/doubao-web-client-browser.ts`、`src/zero-token/providers/gemini-web-client-browser.ts`、`src/zero-token/streams/doubao-web-stream.ts`、`src/zero-token/providers/web-session-binding.test.ts`，本轮不得覆盖或清理。
- Doubao stream/client 代码已有 conversation id 捕获和复用路径，但 provider 单测仍只覆盖 SSE 提取、Gemini URL normalize 和 stale candidate；未覆盖 Doubao 复用、`deleteConversation` 成功/失败。
- `rg deleteConversation` 在 provider/streams 下未发现 DeepSeek/Gemini delete helper 可见测试。
- 默认 `pnpm exec vitest run src/zero-token/providers/web-session-binding.test.ts --reporter=dot` 仍会因根 `vitest.config.ts` 导入但本机缺少 `@vitest/browser-playwright` 失败；`scripts/vitest.zero-token-web.config.ts` 又未 include provider test，强行指定 provider 文件会 `No test files found`。

结论：MNote 侧 ChatOnly/Doubao binding smoke 可作为 MNote 集成证据，但 `7-49` 的 owner 是 OpenClaw provider 仓库单测缺口，仍需在外部仓库补测试配置和 provider 单测后才能移动到 `done`。

## 2026-06-01 外部仓库三次推进

在 `/home/lix/openclaw-zero-token-latest` 已补并验证 Doubao provider 级测试：

- `src/zero-token/providers/doubao-web-client-browser.ts`
  - 新增 `ProviderConversationDeleteResult`、`DoubaoConversationDeleteRequest`、`buildDoubaoConversationDeleteRequest`、`deleteDoubaoConversationWithFetch` 和 `DoubaoWebClientBrowser.deleteConversation`。
  - 删除请求固定走 `/im/conversation/batch_del_user_conv`，失败响应会脱敏 `sessionid` / `ttwid`。
- `src/zero-token/providers/web-session-binding.test.ts`
  - 覆盖 Doubao `conversation_id` / `conversationId` / `sessionId` / object `event_data` 抽取。
  - 覆盖 `conversation_id:"0"`、malformed SSE、`[DONE]` 跳过。
  - 覆盖 batch delete request、`remote_deleted` 成功、`remote_delete_failed` 脱敏失败。
- `scripts/vitest.zero-token-web.config.ts`
  - 已 include provider test，并补 `openclaw/plugin-sdk/*` alias，避免根 `vitest` 多项目配置缺 `@vitest/browser-playwright` 阻断 provider 单测。

已通过：

- `pnpm exec vitest run --config scripts/vitest.zero-token-web.config.ts src/zero-token/providers/web-session-binding.test.ts --reporter=dot`
- `pnpm exec vitest run --config scripts/vitest.zero-token-web.config.ts --reporter=dot`

Reasonix 只读复核（`reasonix-2026-06-01T00-32-52-539Z-c41a37a3`）结论与主线程复核一致：

- Doubao 是当前唯一有 provider 级 `deleteConversation` / `remote_deleted` / `remote_delete_failed` helper 与单测的 web provider。
- DeepSeek / Gemini 只有 stream 层 `sessionMap` / `conversationMap` 复用，没有 provider 级删除能力。
- Qwen、GLM、Kimi、Grok、Claude、ChatGPT、XiaoMiMo、Perplexity 等其他 web provider 也未见 provider 级 delete helper；这些不是 `7-44` Doubao 绑定的阻断项，但应作为后续 OpenClaw provider cleanup 矩阵继续跟踪。
- `pnpm exec vitest run --config scripts/vitest.zero-token-web.config.ts --reporter=dot` 在外部仓库通过，3 files / 14 tests passed。

本文继续保持 `process` 的剩余原因：

- DeepSeek provider 当前没有 `deleteConversation` / delete helper；不能从 MNote 侧 `task513` 推断 provider 仓库已有可靠远端删除实现。
- Gemini provider 当前只有 DOM 对话打开和 conversation URL normalize / stale candidate 测试；没有 provider 级远端删除 helper。
- 后续需要先核实 DeepSeek / Gemini 真实远端删除 API 或明确降级语义，再补 provider 单测；不能为了归档而把本地删除伪装成 `remote_deleted`。

## 2026-06-01 subagent 复核确认

只读 subagent 复核 `/home/lix/openclaw-zero-token-latest` 后确认本文继续保持 `process`：

- Doubao provider delete/helper/test 与 Vitest 专用配置已补齐。
- `rg deleteConversation|remote_deleted|remote_delete_failed|batch_del_user_conv src/zero-token/providers src/zero-token/streams` 仍只命中 Doubao 和 `web-session-binding.test.ts`，未命中 DeepSeek / Gemini。
- DeepSeek 当前只有 `createChatSession` / `chatCompletions` 和 stream `sessionMap` 复用。
- Gemini 当前只有 URL normalize、DOM 打开/复用对话和 `conversation_id: page.url()`，没有 provider 级远端删除 helper。

因此 MNote 侧 `7-44` / `task512` / `task513` 只能证明 MNote provider conversation binding，不足以替代外部 provider 仓库的 DeepSeek / Gemini 删除单测。

## 2026-06-01 DeepSeek / Gemini 降级语义补齐

本文已可归档到 `done`：外部 OpenClaw provider 仓库补齐了 DeepSeek / Gemini provider 级删除语义和单测，但没有伪造远端删除成功。

外部仓库 `/home/lix/openclaw-zero-token-latest` 当前新增/更新：

- `src/zero-token/providers/deepseek-web-client.ts`
  - 新增 `deleteDeepSeekConversationUnsupported()`。
  - `DeepSeekWebClient.deleteConversation()` 返回 `remote_delete_failed`、`providerDeleteMode=unsupported`、`attempted=false`。
- `src/zero-token/providers/gemini-web-client-browser.ts`
  - 新增 `deleteGeminiConversationUnsupported()`。
  - `GeminiWebClientBrowser.deleteConversation()` 返回 `remote_delete_failed`、`providerDeleteMode=unsupported`、`attempted=false`。
- `src/zero-token/providers/web-session-binding.test.ts`
  - 覆盖 DeepSeek / Gemini 在缺少已验证远端删除 API 时不能返回 `remote_deleted`。

已通过外部仓库验证：

- `pnpm exec vitest run --config scripts/vitest.zero-token-web.config.ts src/zero-token/providers/web-session-binding.test.ts --reporter=dot`：1 file / 8 tests passed。
- `pnpm exec vitest run --config scripts/vitest.zero-token-web.config.ts --reporter=dot`：3 files / 16 tests passed。
- `git diff --check`

归档口径：

- Doubao 已有真实 provider 远端删除 helper 和成功/失败单测。
- DeepSeek / Gemini 没有可靠远端删除 API 时，provider 级 `deleteConversation` 明确返回 `remote_delete_failed`，不会让 MNote 或 OpenClaw 上层误标 `remote_deleted`。
- 后续若要实现 DeepSeek / Gemini 真实远端删除，需要先抓取和验证真实 provider API，再新增 capability，而不是重新打开本文的“单测缺口”。
