Skip to content
This repository was archived by the owner on Aug 26, 2026. It is now read-only.

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

catpaw2api

将 CatPaw IDE 的 AI 能力反向代理为 OpenAI 兼容 API 服务,并自带额度自动管理。

这是什么?

catpaw2api 是一个 Go 编写的反向代理服务,它:

  1. 逆向了 CatPaw IDE 的内部 API(RSA+AES 加密、SSE 流式协议)
  2. 自动从 state.vscdb 读取认证 Token,无需手动复制
  3. 对外暴露标准 OpenAI API,可直接对接 ChatGPT 客户端、Cursor、Cherry Studio 等工具
  4. 模拟函数调用(Simulated Function Calling),让不支持 function calling 的后端也能完整支持工具调用
  5. 额度自动管理:定时查询剩余 credits,低于阈值时自动申请提额,无人值守持续运行

简而言之:你在 CatPaw IDE 里的 AI 额度 → 变成一个标准 OpenAI API → 任何支持 OpenAI API 的工具都能用,而且额度用完了会自动加。

特性

  • OpenAI 兼容/v1/chat/completions + /v1/models
  • 流式 & 非流式:同时支持 stream: true/false
  • 模拟函数调用:多层解析器,让 CatPaw 后端支持完整的 OpenAI function calling
  • 自动 Token 管理:从 state.vscdb 读取,每 5 分钟自动刷新
  • RSA+AES 加密:完整逆向 CatPaw 的混合加密机制(同时持有公钥和私钥,请求加密 + 响应解密)
  • 额度看门狗:后台定时查询余额,剩余 ≤ 阈值时自动调用 POST /api/user/addQuota 提额
  • 额度 Dashboard:可视化展示剩余/总额度、进度条、手动查询/提额按钮
  • 系统提示词覆盖:通过环境变量或 system 消息注入
  • CatPaw 格式中和:自动注入规则覆盖 CatPaw 专用的 {{ edit_1 }} 差异格式和文件路径代码块,确保第三方 IDE 兼容
  • 原生 SSE 解析:直接使用 CatPaw 返回的 OpenAI 格式 choices[].delta,无需手动计算增量
  • Token 用量传递usagefinish_reason 从 CatPaw SSE 原样透传
  • 多模型支持:glm-5.2, deepseek-v3.2, kimi-k2.6, LongCat-2.0 等 11 个模型
  • Request ID 追踪:每个请求注入 X-Request-ID
  • CORS 支持:前端直连无障碍

快速开始

编译

go build -o catpaw2api.exe .

运行

# 方式 1: 自动从 CatPaw IDE 的 state.vscdb 读取 Token(推荐)
./catpaw2api.exe

# 方式 2: 手动指定 Token
CATPAW_ACCESS_TOKEN=xxx CATPAW_MIS_ID=xxx ./catpaw2api.exe

# 方式 3: 指定 DB 路径 + 系统提示词 + API Key + 额度管理
CATPAW_DB_PATH=/path/to/state.vscdb \
SYSTEM_PROMPT="你是一个代码助手" \
API_KEY=mykey \
QUOTA_AUTO_APPLY=true \
QUOTA_WATCH_INTERVAL=120 \
QUOTA_THRESHOLD=50 \
./catpaw2api.exe

环境变量

变量 默认值 说明
PORT 8787 服务端口
API_KEY (空) API 密钥,为空则不鉴权
CATPAW_DB_PATH (自动检测) state.vscdb 路径
CATPAW_ACCESS_TOKEN (空) 手动指定 Token
CATPAW_MIS_ID (空) 手动指定 MIS ID
SYSTEM_PROMPT (空) 自定义系统提示词,自动注入为第一条 system 消息
LOG_LEVEL info 日志级别 (info/debug)
QUOTA_AUTO_APPLY true 是否启用额度自动提额
QUOTA_WATCH_INTERVAL 300 额度检查间隔(秒),默认 5 分钟
QUOTA_THRESHOLD 50 余额低于此值时自动提额

额度自动管理

CatPaw IDE 的免费额度是有限的,跑大量 API 请求时会很快耗尽。本服务内置了额度看门狗,自动管理额度:

工作原理

  1. 定时查询:后台 goroutine 每隔 QUOTA_WATCH_INTERVAL 秒调用 GET /api/user/limit 查询剩余额度
  2. 自动提额:当 modelRemaingCount ≤ QUOTA_THRESHOLD 时,自动调用 POST /api/user/addQuota 申请提额
  3. 结果展示:提额结果实时反映在 Dashboard 上

逆向的接口

接口 方法 用途
/api/user/limit GET 查询剩余/总额度
/api/user/addQuota POST 申请提额(剩余 ≤ 50 时可用)

这两个接口同样走 CatPaw 的 RSA+AES 加密通道,请求需加密、响应需解密。本服务通过持有的 RSA 私钥完成完整闭环。

Dashboard 额度面板

打开 http://localhost:8787/ 即可看到:

  • 剩余 / 总额 大字显示(低于阈值时变红)
  • 进度条 可视化额度消耗
  • 已用额度和百分比
  • 「查询额度」按钮 — 手动触发一次查询
  • 「申请提额」按钮 — 手动触发一次提额

手动 API 调用

# 查询当前额度
curl http://localhost:8787/api/quota

# 手动申请提额
curl -X POST http://localhost:8787/api/quota/apply

如何接入

1. 直接 curl 调用

# 流式请求
curl http://localhost:8787/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "model": "glm-5.2",
    "messages": [{"role": "user", "content": "Hello!"}],
    "stream": true
  }'

# 非流式请求
curl http://localhost:8787/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "model": "deepseek-v3.2",
    "messages": [
      {"role": "system", "content": "你是一个专业翻译"},
      {"role": "user", "content": "翻译: Hello World"}
    ],
    "stream": false
  }'

# 查看可用模型
curl http://localhost:8787/v1/models

2. 接入 Python (openai 库)

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8787/v1",
    api_key="YOUR_API_KEY"  # 如果未设置 API_KEY 则随意填
)

# 流式
stream = client.chat.completions.create(
    model="glm-5.2",
    messages=[{"role": "user", "content": "写一个快排"}],
    stream=True
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")

# 非流式
response = client.chat.completions.create(
    model="deepseek-v3.2",
    messages=[
        {"role": "system", "content": "你是代码专家"},
        {"role": "user", "content": "解释闭包"}
    ],
    stream=False
)
print(response.choices[0].message.content)

3. 接入 Cherry Studio / ChatBox / NextChat 等

设置项
API 地址 (Base URL) http://localhost:8787/v1
API Key 你设置的 API_KEY(未设则随意填)
模型名称 glm-5.2 / deepseek-v3.2 / kimi-k2.6

4. 接入 Cursor

Settings → Models → Override OpenAI Base URL → http://localhost:8787/v1

5. 系统提示词覆盖

两种方式:

方式 A: 环境变量全局覆盖

SYSTEM_PROMPT="你是一个 Rust 专家,所有回答必须用 Rust 实现" ./catpaw2api.exe

方式 B: 请求中直接传 system 消息

{
  "model": "glm-5.2",
  "messages": [
    {"role": "system", "content": "你的自定义系统提示词"},
    {"role": "user", "content": "你好"}
  ]
}

如果同时设置了 SYSTEM_PROMPT 环境变量和请求中的 system 消息,环境变量的会排在最前面。

模拟函数调用 (Simulated Function Calling)

CatPaw 后端原生不支持 OpenAI function calling,本代理通过提示词注入 + 多层解析器实现了完整的模拟函数调用。

工作原理

  1. 工具指令注入:当请求携带 tools 参数时,将工具定义作为 system 消息注入到 messages 数组开头(不放在 mrulesContent 中,避免 CatPaw 后端干扰)
  2. 多层解析器(按优先级 fallback):
层级 格式 示例
Layer 0 <function=Name> XML 风格 <function=read><parameter=file>test.py</parameter></function>
Layer 1 <tool_call> 标签 <tool_call>{"name":"read","arguments":{"file":"test.py"}}</tool_call>
Layer 2 <ToolName attr="val" /> 直接标签 <read file="test.py" />
Layer 2b <ToolName><param>value</param></ToolName> XML子标签 <read><file>test.py</file></read>
Layer 3 裸 JSON {"name":"read","arguments":{"file":"test.py"}}
Layer 4 bash 代码块 → 命令映射 ```bash\ncat test.py\n```
  1. 幻觉截断:检测到工具调用后,丢弃之后的所有文本(OpenAI 规范要求工具调用后不应有额外文本)
  2. 思考块处理:移除 <think></think> 标签但保留内容(模型有时把工具调用放在思考块内)

使用示例

response = client.chat.completions.create(
    model="glm-5.2",
    messages=[{"role": "user", "content": "读取 hello.py 的内容"}],
    tools=[{
        "type": "function",
        "function": {
            "name": "read_file",
            "description": "读取文件内容",
            "parameters": {
                "type": "object",
                "properties": {
                    "path": {"type": "string", "description": "文件路径"}
                },
                "required": ["path"]
            }
        }
    }]
)
# response.choices[0].message.tool_calls 将包含解析出的工具调用

已知限制

由于后端模型不支持原生 Function Calling,以下问题为模拟方案的固有限制: 1. 模型提前终止对话 模型输出前导语(如"让我查看这个文件")后直接 finish_reason=stop,未输出工具调用 JSON。对话中断,Agent 无法继续。对话超过 10 轮后高频出现。 2. 长对话返回空响应 对话累积超过 40 条消息后,模型返回完全空内容(content=""finish_reason 为空),所有重试均失败。疑似上下文超限或后端推理异常。 3. 模型编造工具结果(幻觉) 模型不输出工具调用 JSON,而是直接编造完整的工具执行结果(<toolcall_status>done</toolcall_result> + 假文件内容)。单次幻觉输出可达 14000+ 字符,耗时 100+ 秒。代理已实现早期检测+中断,但根因在后端。 4. 输出格式不统一 同一模型不同轮次输出的工具调用格式完全不同(裸 JSON / XML 标签 / bash 代码块 / 自然语言混合),解析器需覆盖所有变体,无法保证 100% 覆盖率。 5. 缓解措施(已实现)

  • 重试机制:解析失败时截断历史至最后 2 条 + 注入强制 JSON 指令,最多重试 3 次
  • 早期幻觉检测:SSE 累积过程中检测到幻觉标签立即中断,不等完整生成
  • 消息滑动窗口:保留第一条 system + 最近 11 条对话,单条超 4000 字符截断
  • 前导语清洗:检测到工具调用后丢弃其后所有幻觉文本

💡 建议:纯对话场景(无 tools)不受上述限制影响,体验等同于直接使用 CatPaw IDE。

支持的模型

模型名 modelType 思考链 图片
glm-5.2 75
glm-5.1 59
glm-5 46
glm-5v-turbo 60
deepseek-v3.2 9
kimi-k2.6 62
kimi-k2.5 41
LongCat-2.0 77
longcat-flash 22
MiniMax-M2.7 56
MiniMax-M2.5 48

API 端点

方法 路径 说明
POST /v1/chat/completions OpenAI 对话(流式 + 非流式 + 工具调用)
GET /v1/models 获取模型列表
GET /api/status 服务状态 JSON
GET /health 健康检查
GET / Dashboard 状态面板

技术细节

逆向的加密机制

CatPaw IDE 使用 RSA+AES 混合加密请求体:

  1. 生成随机 AES-128 密钥
  2. 用 AES-128-ECB (PKCS7) 加密请求体
  3. 将 AES 密钥转成 base64 字符串,用 RSA-OAEP (SHA1) 加密
  4. 发送加密体 + encrypted-key

逆向的认证流程

  • Token 存储:VS Code 的 globalState (state.vscdb)
  • Cookie 格式:1d47d6ff96_passportid=<token>; f32a546874_ssoid=<token>
  • 认证头:Catpaw-Auth: <token>
  • 租户:5282fa6645
  • 客户端环境:LOCAL_IDE

SSE 协议解析

CatPaw 的 SSE 同时返回两种内容表示:

  1. choices[].delta(优先使用):已是 OpenAI 格式的增量内容,直接透传
  2. content(fallback):累积全文,需要手动计算增量 最后一条数据带 finishReasonusage 字段,代理原样透传为 OpenAI 的 finish_reasonusage

CatPaw 格式中和

CatPaw 后端注入的系统提示词包含 IDE 专用格式指令({{ edit_1 }} 占位符、代码块带文件路径等), 这些格式在 Cursor / Cherry Studio 等第三方 IDE 中无法解析,导致对话异常结束。 代理通过 mrulesContent 字段自动注入覆盖规则,强制模型使用标准 Markdown 代码块格式, 确保所有 OpenAI 兼容客户端都能正常解析输出。

工具调用指令注入策略

工具定义通过 messages 数组中的 system 消息注入(而非 mrulesContent),原因:

  • CatPaw 后端对 mrulesContent 中的工具相关内容有特殊处理,可能导致 SSE 流提前终止
  • 注入到 messages 中可以绕过后端干扰,让模型完整输出工具调用 JSON

项目结构

catpaw2api/
├── main.go                      # 入口
├── config/constants.go          # CatPaw 协议常量、模型映射、请求头
├── auth/
│   ├── token_manager.go         # 从 state.vscdb 读取 + 自动刷新
│   └── http.go                  # HTTP 客户端
├── types/types.go               # OpenAI / CatPaw 数据结构
├── converter/
│   ├── openai.go                # OpenAI ↔ CatPaw 格式转换
│   ├── toolcall.go              # 模拟函数调用解析器(五层 fallback)
│   ├── toolcall_test.go         # 单元测试
│   └── toolcall_e2e_test.go     # 端到端测试
├── server/
│   ├── server.go                # HTTP 服务器 + 路由 + Dashboard
│   └── handlers.go              # 请求处理(流式/非流式/工具调用)
├── crypto/crypto.go             # RSA+AES 加密
├── catpaw_system_prompt.txt     # CatPaw 原始系统提示词(逆向参考)
├── go.mod / go.sum              # Go 模块定义
└── README.md                    # 你正在看的这个

License

MIT

About

CatPaw IDE AI → OpenAI-compatible API proxy with auto quota management

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages