Kiro Gateway 配置指南

# Kiro Gateway 配置指南

## 前置要求

- **Python 3.10+**
- **uv**(Python 包管理器)— 未安装请先执行:
  ```bash
  pip install uv
  # 或 macOS/Linux
  curl -LsSf https://astral.sh/uv/install.sh | sh
  ```
- **Kiro IDE 已登录**(用于提供认证凭证)

---

## 第一步:安装依赖

```bash
# 克隆项目
git clone https://github.com/jwadow/kiro-gateway.git
cd kiro-gateway

# Pin Python 版本(确保环境一致性)
uv python pin 3.10

# 创建虚拟环境并安装依赖
uv venv
uv pip install -r requirements.txt
```

---

## 第二步:创建启动脚本

项目默认不包含启动脚本,手动创建 `bin/start.sh`:

```bash
mkdir -p bin

cat > bin/start.sh << 'EOF'
#!/usr/bin/env bash
# Start kiro-gateway using uv
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"

cd "$PROJECT_ROOT"
exec uv run python main.py "$@"
EOF

chmod +x bin/start.sh
```

验证脚本已创建:

```bash
ls -la bin/start.sh
```

---

## 第三步:配置 .env

复制模板文件:

```bash
cp .env.example .env
```

编辑 `.env`,完成以下配置:

### 必填:API Key

自己设定一个密码,用于保护 gateway 接口。客户端连接时需要填写这个值。

```bash
PROXY_API_KEY="your-secret-password"
```

### 必填:Kiro 认证(四选一)

**方式 A:Kiro IDE 凭证文件(推荐)**

Kiro IDE 登录后会在本地生成凭证文件,填写其路径:

```bash
KIRO_CREDS_FILE="~/.aws/sso/cache/kiro-auth-token.json"
```

**方式 B:直接填写 refresh token**

从 Kiro IDE 网络请求中抓取 refresh token:

```bash
REFRESH_TOKEN="your_kiro_refresh_token_here"
```

**方式 C:kiro-cli SQLite 数据库**

```bash
KIRO_CLI_DB_FILE="~/.local/share/kiro-cli/data.sqlite3"
```

**方式 D:AWS SSO 缓存文件**

```bash
KIRO_CREDS_FILE="~/.aws/sso/cache/your-sso-cache-file.json"
```

### 推荐:代理(国内网络必填)

```bash
VPN_PROXY_URL="http://127.0.0.1:1082"
# 或 SOCKS5
# VPN_PROXY_URL="socks5://127.0.0.1:1080"
```

### 推荐:开启多账号故障转移

```bash
ACCOUNT_SYSTEM=true
```

开启后首次启动时,gateway 会自动将 `.env` 中的认证配置迁移到 `credentials.json`,后续通过 `credentials.json` 管理账号。

### 推荐:关闭 gateway 内容干预行为

gateway 默认开启了几个会主动修改请求/响应内容的功能。如果你使用的 agent 系统(如 Claude Code、自建 agent)自己管理这些逻辑,建议全部关闭,让 gateway 做纯粹的协议转发:

```bash
WEB_SEARCH_ENABLED=false
FAKE_REASONING=false
TRUNCATION_RECOVERY=false
```

> 详细说明见 [附录 C:gateway 内容干预行为](#附录-c-gateway-内容干预行为)。

---

## 第四步:启动服务

```bash
# 默认端口 8000
./bin/start.sh

# 指定端口
# ./bin/start.sh --port 9000
```

启动成功后日志中会显示:

```
INFO  | Kiro Gateway started on http://0.0.0.0:8000
```

验证服务正常运行:

```bash
curl http://localhost:8000/health
```

---

## 第五步:连接客户端

在 Claude Code、Cursor 等客户端中填写:

| 字段 | 值 |
|------|----|
| API Base URL | `http://localhost:8000` |
| API Key | `.env` 中 `PROXY_API_KEY` 的值 |
| API 格式 | OpenAI 或 Anthropic 均可 |

- Anthropic 端点:`POST http://localhost:8000/v1/messages`
- OpenAI 端点:`POST http://localhost:8000/v1/chat/completions`

---

## 附录 A:多账号配置

开启 `ACCOUNT_SYSTEM=true` 并首次启动后,编辑自动生成的 `credentials.json` 添加更多账号:

```json
[
  {
    "type": "json",
    "path": "~/.aws/sso/cache/kiro-auth-token.json",
    "comment": "主账号"
  },
  {
    "type": "refresh_token",
    "refresh_token": "eyJhbGci...",
    "profile_arn": "arn:aws:codewhisperer:us-east-1:...",
    "comment": "备用账号"
  }
]
```

支持的账号类型:

| `type` | 说明 |
|--------|------|
| `json` | Kiro IDE 凭证文件,或指向包含多个凭证文件的文件夹 |
| `refresh_token` | 直接填写 refresh token 字符串 |
| `sqlite` | kiro-cli SQLite 数据库,或指向包含多个数据库的文件夹 |

每个账号支持的可选参数:

```json
{
  "enabled": true,             // false 可临时禁用该账号
  "region": "us-east-1",      // SSO 认证区域
  "api_region": "us-east-1",  // Q API 区域
  "profile_arn": "arn:..."    // CodeWhisperer profile ARN
}
```

**故障转移行为:**

- 主账号出现 429 / 5xx / 网络超时 → 自动切换到下一个账号
- 故障账号进入冷却期(指数退避:1分钟 → 2分钟 → 4分钟 → ... 最长1天)
- 冷却期内仍有 10% 概率被重试,防止永久卡死
- 致命错误(400、401)直接返回客户端,不触发切换

---

## 附录 B:其他配置项

### 调试日志

遇到问题时开启,日志保存在 `debug_logs/` 目录:

```bash
DEBUG_MODE=errors   # 只保存失败请求(推荐)
# DEBUG_MODE=all    # 保存所有请求
```

### 服务器监听设置

```bash
SERVER_HOST="127.0.0.1"  # 仅允许本机访问(默认 0.0.0.0 监听所有网卡)
SERVER_PORT="8000"
```

---

## 附录 C:gateway 内容干预行为

gateway 默认开启了几个会主动修改请求或响应内容的功能。理解这些行为有助于判断是否需要关闭它们。

### FAKE_REASONING — 思考过程注入

**默认:开启**

Kiro API 底层是 Claude,支持扩展思考,但 Kiro 没有暴露对应的 API 参数。gateway 通过 prompt 工程绕过这个限制:在每条用户消息前自动插入以下内容:

```
<thinking_mode>enabled</thinking_mode>
<max_thinking_length>16000</max_thinking_length>
<thinking_instruction>Think in English...</thinking_instruction>

[用户原始消息]
```

模型收到这些标签后会在回答前输出 `<thinking>...</thinking>` 推理过程,gateway 再将其解析并转换为 OpenAI 的 `reasoning_content` 字段返回。

**`FAKE_REASONING_BUDGET_CAP`** 控制思考 token 的上限。由于思考内容消耗的是**输出 token**(不是独立配额),预算过大会导致模型把所有输出都用于思考,正文反而为空。建议设为总输出 token 的一半左右:

```bash
FAKE_REASONING_BUDGET_CAP=16000
```

**关闭后的效果:**
- 消息原样转发,模型不会有思考过程
- 即使客户端请求了 `thinking` 参数,Kiro API 也不支持,同样不会生效
- 响应速度更快,输出 token 全部用于正文

**建议:** 如果你的 agent 系统自己管理推理策略,或不需要思考过程,关闭可以获得更干净、更快的响应:

```bash
FAKE_REASONING=false
```

---

### WEB_SEARCH_ENABLED — 网络搜索工具注入

**默认:开启**

gateway 会在每个请求的工具列表里自动追加一个 `web_search` 工具定义。模型决定调用时,gateway 拦截该调用,转而请求 Kiro 内置的 MCP 搜索 API,再把结果注入回响应流。

**关闭后的效果:**
- 工具列表不再被修改,请求原样转发
- 如果你的 agent 系统自己声明了搜索工具并自己执行,这是正确的做法——agent 可以使用任意搜索服务(Tavily、Bing 等),结果也完全由 agent 控制

**建议:** 使用 agent 系统时关闭,由 agent 自己管理搜索能力:

```bash
WEB_SEARCH_ENABLED=false
```

---

### TRUNCATION_RECOVERY — 截断恢复通知

**默认:开启**

Kiro API 有时会在流传输中途截断响应(比如模型生成大文件时写到一半就断了)。

**截断检测原理:** Kiro API 在每次正常完成的响应末尾会发送一个 `contextUsagePercentage` 事件(表示本次请求消耗了多少上下文窗口)。gateway 以这个事件作为"正常结束"的信号——如果流结束了但没有收到这个事件,且已有内容输出,就判定为截断。工具调用的截断则通过 JSON 完整性检测:如果工具参数的 JSON 括号不匹配(有开括号没有闭括号),说明参数被截断。

开启后,gateway 检测到截断时会在下一轮请求中自动插入一条系统通知:

```
[System Notice] Your previous response was truncated by the API due to output limits.
Please adapt your approach (e.g., split large outputs into smaller parts).
```

模型看到这条消息后可以调整策略,比如把大文件拆成多次写入。

**关闭后的效果:**
- 截断照样发生,但不插入任何通知
- 模型不知道自己被截断,会继续正常对话,用户看到不完整的结果

**建议:** 如果你的 agent 系统自己有截断检测和重试逻辑,关闭可以避免 gateway 插入的通知消息干扰 agent 的上下文管理:

```bash
TRUNCATION_RECOVERY=false
```

---

### AUTO_TRIM_PAYLOAD — 超限 Payload 静默裁剪

**默认:关闭**

Kiro API 拒绝超过约 615KB 的请求体,返回一个很不友好的 "Improperly formed request" 错误,完全看不出是 payload 太大导致的。

**关闭时(默认):** 超限时 gateway 返回清晰的错误信息,由调用方自行处理:

```
Request payload too large (XXX bytes > 600000 bytes limit).
Please reduce conversation history or tool definitions.
```

**开启时:** gateway 自动从对话历史里删除最旧的消息对,直到 payload 缩小到限制内,然后继续发请求。用户无感知,但最旧的上下文被静默丢弃,调用方不知道这件事发生过。

**建议:** agent 系统通常自己管理上下文窗口,如果 gateway 在背后静默删消息,agent 的上下文状态和实际发出去的请求会不一致,可能导致难以排查的问题。保持关闭,让 agent 自己响应超限错误:

```bash
# AUTO_TRIM_PAYLOAD=false  # 默认已关闭,无需显式设置
```