opencode-cursor-agent/docs/prd/2026-04-14-cursor-adapter.md

164 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## Research Inputs
N/A。這是個人工具不需要市場研究。
## Problem
我同時使用多個 CLI AI 工具Hermes Agent、OpenCode、Claude Code這些工具都支援自訂 API base URL 和 model。我的公司有 Cursor 帳號,透過 `agent login` 已在本機完成認證,可以使用 Cursor 提供的多種模型。
目前的問題是:每支 CLI 工具都需要自己買 API key 或設定 provider但我已經有 Cursor 帳號的額度可以用。我需要一個轉接器,讓這些 CLI 工具能透過 Cursor CLI 的 headless 模式來使用 Cursor 的模型,省去額外的 API 費用。
## Goals
- 本機跑一個 HTTP server提供 OpenAI-compatible API`/v1/chat/completions`
- 收到請求後spawn Cursor CLI 的 `agent` 子程序來執行
- 將 Cursor CLI 的 streaming JSON 輸出轉換成 OpenAI SSE 格式回傳
- 支援多種 Cursor 模型的選擇
- 零額外認證設定 — 直接使用本機已有的 Cursor 登入狀態
## Non Goals
- 不支援非 OpenAI format 的 CLI 工具
- 不做 API key 管理或多用戶認證
- 不做計量、追蹤、計費功能
- 不做模型負載平衡或 failover
- 不代理 Cursor IDE 的功能,只代理 headless CLI 模式
## Scope
本機 personal proxy server一個使用者本機部署。
### In Scope
- OpenAI-compatible API`/v1/chat/completions`、`/v1/models`
- SSE streaming response
- 模型選擇(透過 `--model` 參數傳給 Cursor CLI
- 簡單的 YAML config 檔設定
- 錯誤處理和 CLI 子程序生命週期管理
- health check endpoint
### Out of Scope
- 非 OpenAI format 支援
- 多用戶 / API key 管理
- 計量追蹤
- GUI 介面
- Docker 部署
## Success Metrics
- Hermes Agent、OpenCode、Claude Code 都能透過設定 base URL 指向此 proxy 來使用 Cursor 模型
- streaming 回應的延遲 < 2 不含模型思考時間
- proxy 啟動後零設定即可使用只需改 CLI 工具的 config
## User Stories
1. 作為使用者我想啟動 proxy server這樣我的 CLI 工具就能連到它
2. 作為使用者我想在 Hermes Agent 裡設定 `base_url = http://localhost:8976`這樣就能用 Cursor 的模型
3. 作為使用者我想在 CLI 工具裡指定 `model = claude-sonnet-4-20250514`proxy 會傳給 Cursor CLI
4. 作為使用者我想看到模型的思考過程即時串流到終端機上
5. 作為使用者我想透過 `/v1/models` 查看可用的模型列表
6. 作為使用者我想透過 config 檔設定 proxy port 和其他選項
## Functional Requirements
### FR1: OpenAI-Compatible API
- 支援 `POST /v1/chat/completions`
- 接受 OpenAI 格式的 request body`model`、`messages`、`stream`
- `stream: true` 回傳 SSE 格式的 `data: {...}\n\n` chunks
- `stream: false` 回傳完整的 JSON response
### FR2: Cursor CLI Integration
- 收到請求後組合 prompt messages 陣列
- spawn `agent -p "{prompt}" --model "{model}" --output-format stream-json` 子程序
- 讀取子程序的 stdout streaming JSON 輸出
- 管理子程序生命週期啟動執行結束超時 kill
### FR3: Streaming Response Conversion
- Cursor CLI `stream-json` 輸出轉換成 OpenAI SSE 格式
- 每個 SSE chunk 需包含 `id`、`object: "chat.completion.chunk"`、`choices[0].delta.content`
- 最後一個 chunk 需包含 `finish_reason: "stop"`
### FR4: Model Listing
- 支援 `GET /v1/models`回傳可用模型列表
- 模型列表從 Cursor CLI 取得`agent --list-models` config 定義
### FR5: Configuration
- YAML config 預設 `~/.cursor-adapter/config.yaml`
- 可設定portcursor_cli_pathdefault_modeltimeout
### FR6: Error Handling
- Cursor CLI 超時可設定預設 5 分鐘)→ 回傳 504
- Cursor CLI 錯誤 回傳 500 + 錯誤訊息
- 無效的 request body 回傳 400
- model 不存在 回傳 404
## Acceptance Criteria
### AC1: Basic Chat Completion
Given proxy 已啟動在 port 8976When 我用 curl 發送 `POST /v1/chat/completions` 帶上 `{"model": "claude-sonnet-4-20250514", "messages": [{"role": "user", "content": "hello"}], "stream": true}`Then 收到 SSE streaming response且內容為 Cursor CLI 的回應轉換成的 OpenAI 格式
### AC2: Streaming Display
Given CLI 工具連到 proxy 並發送 streaming 請求When 模型正在生成回應Then CLI 工具的終端機上即時顯示文字內容不需要等完整回應)。
### AC3: Model Selection
Given proxy 已啟動When 請求中指定 `model: "gpt-5.2"`Then proxy spawn Cursor CLI 時使用 `--model gpt-5.2`
### AC4: Health Check
Given proxy 已啟動When 發送 `GET /health`Then 回傳 `{"status": "ok", "cursor_cli": "available"}`
### AC5: Model Listing
Given proxy 已啟動When 發送 `GET /v1/models`Then 回傳 Cursor 可用的模型列表格式符合 OpenAI models API
## Edge Cases
- Cursor CLI 子程序意外崩潰 proxy 回傳 500清理資源
- 請求 timeout模型思考太久)→ proxy kill 子程序回傳 504
- 並發請求 每個請求 spawn 獨立的子程序
- Cursor CLI 未安裝或不在 PATH proxy 啟動時檢查啟動失敗時給明確錯誤
- Cursor CLI 未登入 proxy 回傳錯誤訊息提示先 `agent login`
- messages 陣列為空 回傳 400
- stream: false 需要等 Cursor CLI 完整輸出後才回傳
## Non Functional Requirements
### NFR1: Performance
- proxy 自身的 overhead < 500ms不含模型思考時間
- streaming 的第一個 token 延遲不超過 Cursor CLI 本身的延遲 + 200ms
### NFR2: Reliability
- 並發請求數 5個人使用
- 子程序超時後正確清理不留 zombie process
### NFR3: Usability
- 一行命令啟動`cursor-adapter` `cursor-adapter --port 8976`
- config 檔格式簡單有合理的預設值
- 啟動時顯示可用模型列表
## Risks
| Risk | Impact | Likelihood | Mitigation |
|------|--------|-----------|------------|
| Cursor CLI output format 變更 | High | Medium | 抽象輸出解析層方便適配 |
| Cursor CLI 不支援某些模型 | Medium | Low | 啟動時驗證模型可用性 |
| 並發子程序過多導致資源耗盡 | Medium | Low | 限制最大並發數 |
| Cursor headless 模式有限制 | High | Medium | 先用 headless 模式測試必要時 fallback ACP |
## Assumptions
- Cursor CLI 已安裝且在 PATH
- Cursor CLI 已透過 `agent login` 完成認證
- 使用者的 CLI 工具都支援 OpenAI-compatible API format
- 使用者只需要 `/v1/chat/completions` `/v1/models` 兩個 endpoint
## Dependencies
- Cursor CLI`agent` command
- Python 3.10+ Node.js 18+取決於實作語言選擇
## Open Questions
1. Cursor CLI `--output-format stream-json` 的確切 JSON schema 是什麼需要實際跑一次來確認
2. Cursor CLI 是否支援同時跑多個 headless 實例
3. 需要支援 function calling / tool use 目前 PRD 不含但如果 Cursor CLI 支援的話可以加