<!-- 文档分类: IMPL-RPT-002 | 阶段: 实现 | 原路径: docs/修复记录/kiro-连接修复-2026-06-05.md -->
# Kiro 连接修复（CW SDK 缺失 + 级联 404）

发布日期：2026-06-05 · 版本：v0.1.90

---

## 1. 现象

使用 Kiro 模型时报错，并连锁触发其它通道失败、最终重试预算耗尽：

```
真实失败原因:
 • Kiro [unavailable]: CW SDK not installed. Run: cd backend && npm install @aws/codewhisperer-streaming-client
 • kiro [timeout]: CW SDK not installed...
 • OpenAI [unknown]: Request failed with status code 404
 • api [unknown]: ...404...
 • Relay API (claude-sonnet-4-5-20250514) (404) [unavailable]: HTTP 404
 • relay_api [unavailable]: recent unavailable failure cached: HTTP 404 (cooldown 30s)
请求重试预算已用尽: 总尝试次数超限 (5/4)
[relay_api] HTTP 404 from https://api.trae.ai/v1/chat/completions | model=gpt-5.4-beta
```

表面看是"多个通道一起坏了"，实际是**单点缺失被级联放大**。

---

## 2. 根因

### 2.1 Kiro 适配器依赖一个从未安装的 SDK

Kiro 走的是 AWS CodeWhisperer 的**原生加密流式协议**（`GenerateAssistantResponse`），不是 OpenAI 兼容接口。适配器通过 `@aws/codewhisperer-streaming-client` 与之通信，并在 `_cwStreamParser.js` 里惰性加载该 SDK：

```javascript
// services/backend/src/services/gateway/adapters/_cwStreamParser.js
async function getCWModule() {
  // ...
  return await import('@aws/codewhisperer-streaming-client'); // 缺失时抛错
  // throw new Error('CW SDK not installed. Run: cd backend && npm install @aws/codewhisperer-streaming-client')
}
```

问题：该 SDK **既没有在 `package.json` 里声明为依赖，安装时也就不会被装进 `node_modules`**。于是 `getCWModule()` 每次都抛 `CW SDK not installed`，Kiro 通道直接 `unavailable`。

### 2.2 级联 failover 打到必然 404 的 OpenAI 通道

Kiro 不可用后，网关按级联策略 failover 到其它启用的通道。用户把 `RELAY_API_ENDPOINT` 配成了 `https://api.trae.ai/v1`——但 **Trae 的真实网关是加密原生协议（`adaptive-api.trae.ai`），不是 OpenAI 兼容**，对 `/v1/chat/completions` 一律返回 404（TLB 网关）。

于是每个 OpenAI 风格通道（relay_api / api / OpenAI）都撞上 404，叠加 30s 冷却与重试预算上限（5/4），最终"请求重试预算已用尽"。**Kiro 的单点缺失 → 级联到一组注定 404 的通道 → 整体失败**。

---

## 3. 修复

### 3.1 把 CW SDK 声明为常规依赖

`services/backend/package.json`：

```jsonc
"dependencies": {
  "@aws/codewhisperer-streaming-client": "^1.0.45",  // Kiro 原生流式协议 SDK
  // ...
}
```

该包是 AWS 公开发布的 npm 包，npmmirror 镜像已覆盖，国内安装无需访问 GitHub。声明为依赖后，常规 `npm install` 即可装好，`getCWModule()` 不再抛错。

### 3.2 引导期自愈（向后兼容老安装）

仅靠 `package.json` 只能覆盖**新装**用户；已经装过、`node_modules` 里没有 CW SDK 的**老安装**不会自动补齐。为此在首启引导器加入标记位守卫的自愈逻辑。

`platform/khy_platform/_bootstrap.py`：

```python
# Kiro CodeWhisperer SDK 修复标记：避免每次启动重复检查/安装
KIRO_CW_SDK_MARKER_FILE = ".khy_kiro_cw_sdk_fixed"

def _has_cw_sdk(node_modules: Path) -> bool:
    """Check if the Kiro CodeWhisperer streaming SDK is installed."""
    return _path_exists_safe(node_modules / "@aws" / "codewhisperer-streaming-client")

def _maybe_repair_kiro_cw_sdk(backend_dir: Path, marker: Path) -> None:
    """Self-heal: install the Kiro CW SDK if missing (marker-guarded, runs once)."""
    if marker.exists():
        return
    node_modules = backend_dir / "node_modules"
    if _has_cw_sdk(node_modules):
        _write_marker(marker, "ok")
        return
    # Stream the install so the user sees progress instead of a frozen prompt.
    rc = _run_npm_streaming(
        [npm_cmd, "install", "@aws/codewhisperer-streaming-client", "--no-audit", "--no-fund"],
        backend_dir, _NPM_TIMEOUT,
    )
    _write_marker(marker, "installed" if rc == 0 and _has_cw_sdk(node_modules) else "failed")
```

接入 `ensure_bootstrapped()` 的**两条路径**：

- **已引导分支**：在可选依赖修复之后调用 `_maybe_repair_kiro_cw_sdk(...)`，让老用户下次启动时补齐。
- **首次安装路径（step 6b）**：在 step 6 之后调用，保证全新安装也显式校验一次。

标记文件 `.khy_kiro_cw_sdk_fixed` 确保只在缺失时检查/安装一次，不拖慢每次启动。

> `_run_npm_streaming(...)` 是本版本新增的流式安装助手：用 `Popen` 逐行转发 `npm` 输出（`npm | ...`），看门狗线程每 5s 探活、静默 ≥15s 打印中文心跳（`仍在安装中（已用 N s）…`），超时则杀进程并抛 `TimeoutExpired`。解决了 Windows 非 TTY 下 `npm install` 长时间"看起来卡死"的问题。

### 3.3 配套消噪：删除所有 OpenAI 风格 `api.trae.ai` 端点

级联 404 的放大器是那些指向 `api.trae.ai/v1` 的 OpenAI 通道。把它们**全部移除**，让 Trae 只走原生协议端点 `adaptive-api.trae.ai`，未配置 OpenAI 兼容代理时优雅降级而非发出必然 404 的请求：

| 文件 | 改动 |
| --- | --- |
| `services/backend/src/services/multiFreeService.js` | Trae `baseUrl` 默认值 `https://api.trae.ai` → `''`（需显式 `TRAE_API_ENDPOINT`） |
| `services/backend/src/services/apiKeyPool.js` | `ENV_KEY_MAP.trae.default` → `''` |
| `services/backend/src/cli/handlers/gateway.js` | 两处 `defaultEndpoint: 'https://api.trae.ai/v1'` → `''` |
| `services/backend/src/services/gateway/adapters/traeAdapter.js` | 删除 JWT 回退盲加 `api.trae.ai/v1`，无候选端点时让上层降级 |
| `services/backend/src/services/gateway/adapters/relayApiAdapter.js` | 连通性探测加 `_probe` 标志，抑制探测期 4xx 噪音告警 |
| `services/ai-backend/src/services/gateway/adapters/traeAdapter.js` | （Docker-only 微服务）改为读 `TRAE_API_ENDPOINT`，未配置时优雅失败，不再硬编码 `api.trae.ai` |

保留的原生端点 `adaptive-api.trae.ai` 未动——那是 Trae 真正的网关。

---

## 4. 效果

- **Kiro 可用**：CW SDK 随安装到位（新装）或首启自愈（老装），不再 `CW SDK not installed`。
- **不再级联 404**：移除 `api.trae.ai` OpenAI 端点后，Kiro 失败不会再连锁触发一组注定 404 的通道，重试预算不被无谓耗尽。
- **安装可见**：`_run_npm_streaming` 让补装过程有进度与心跳，不再"看起来卡死"。

---

## 5. 验证

```bash
python3 -m py_compile platform/khy_platform/_bootstrap.py    # 引导器语法
node --check services/backend/src/services/multiFreeService.js
node --check services/backend/src/services/apiKeyPool.js
node --check services/backend/src/cli/handlers/gateway.js
node --check services/backend/src/services/gateway/adapters/traeAdapter.js
node --check services/backend/src/services/gateway/adapters/relayApiAdapter.js
node --check services/ai-backend/src/services/gateway/adapters/traeAdapter.js
# 全仓扫描：剩余 api.trae.ai 字样全部为解释性注释，无功能代码再使用裸 api.trae.ai
```

全部通过。

---

## 6. 涉及文件

- `services/backend/package.json` — 声明 CW SDK 依赖
- `platform/khy_platform/_bootstrap.py` — `KIRO_CW_SDK_MARKER_FILE` / `_has_cw_sdk` / `_maybe_repair_kiro_cw_sdk` / `_run_npm_streaming` + 两条接入路径
- `services/backend/src/services/gateway/adapters/_cwStreamParser.js` — 惰性加载点（错误信息来源，未改逻辑）
- `multiFreeService.js` / `apiKeyPool.js` / `cli/handlers/gateway.js` / `adapters/traeAdapter.js` / `adapters/relayApiAdapter.js` — 移除 OpenAI 风格 `api.trae.ai`
- `services/ai-backend/src/services/gateway/adapters/traeAdapter.js` — Docker-only 微服务同步消除硬编码 `api.trae.ai`
