{"repo": "3243138509/preppro", "files": {"docs/protocol.md": {"a2753dd35b8fcf963cd117e73ca4154cdc7d42df": {"t": 1785674069.6171732, "n": 7117, "h": "8032c63fe7e1fb95", "c": "# TCP 协议(当前实现)\n\n## 1. 传输帧格式\n\n## 协议变更日志\n\n- 协议变更对照(v1.0 -> 当前):`docs/protocol-changelog.md`\n\n使用长度前缀帧:\n\n- 前 4 字节:无符号大端整数 `length`\n- 后续 `length` 字节:UTF-8 JSON\n\n示意:\n\n```text\n| 4 bytes length (big-endian) | UTF-8 JSON payload |\n```\n\n服务端限制:\n\n- 单帧最大长度 `RC_MAX_FRAME_SIZE`(默认 12 MiB)\n- `length <= 0` 或超过上限会直接报错并断开本次处理\n\n## 2. 连接与鉴权\n\n连接建立后,服务端要求第一条业务消息必须是 `AUTH`。\n\n### 客户端 -> 服务端\n\n```json\n{\n \"type\": \"AUTH\",\n \"password\": \"changeme\"\n}\n```\n\n### 服务端 -> 客户端\n\n```json\n{\n \"type\": \"AUTH_OK\"\n}\n```\n\n注意:当前实现只要求先发送 `AUTH`,并不会校验 `password` 是否正确。\n\n如果未先鉴权就发送其他消息,返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_AUTH_REQUIRED\",\n \"message\": \"auth required\"\n}\n```\n\n## 3. 通用错误格式\n\n```json\n{\n \"type\": \"ERROR\",\n \"requestId\": \"uuid-string (可选)\",\n \"code\": \"ERROR_XXX\",\n \"message\": \"错误描述\"\n}\n```\n\n## 4. 截图相关\n\n### 4.1 请求截图\n\n客户端发送:\n\n```json\n{\n \"type\": \"CAPTURE\",\n \"requestId\": \"uuid-string\",\n \"quality\": 75,\n \"displayId\": 1\n}\n```\n\n字段说明:\n\n- `quality` 范围会被服务端钳制到 30~95\n- `displayId` 默认 1\n\n成功返回:\n\n```json\n{\n \"type\": \"IMAGE\",\n \"requestId\": \"uuid-string\",\n \"displayId\": 1,\n \"format\": \"jpeg\",\n \"width\": 1920,\n \"height\": 1080,\n \"imageBase64\": \"...\"\n}\n```\n\n失败返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"requestId\": \"uuid-string\",\n \"code\": \"ERROR_CAPTURE\",\n \"message\": \"capture failed (displayId=1)\"\n}\n```\n\n### 4.2 获取显示器列表\n\n客户端发送:\n\n```json\n{\n \"type\": \"LIST_DISPLAYS\"\n}\n```\n\n成功返回:\n\n```json\n{\n \"type\": \"DISPLAYS\",\n \"displays\": [\n {\n \"id\": 1,\n \"left\": 0,\n \"top\": 0,\n \"width\": 1920,\n \"height\": 1080\n }\n ]\n}\n```\n\n失败返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_DISPLAYS\",\n \"message\": \"list displays failed\"\n}\n```\n\n## 5. 解析相关\n\n### 5.1 图片解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_IMAGE\",\n \"requestId\": \"uuid-string\",\n \"imageBase64\": \"...\",\n \"prompt\": \"可选,额外提示词\",\n \"analysisMode\": \"可选,qa 或 code\",\n \"targetLanguage\": \"可选,代码模式下的目标语言,如 Python / Java / C++\"\n}\n```\n\n字段说明:\n\n- `analysisMode` 默认为 `qa`\n- `analysisMode=code` 时,服务端会切换到编程题代码生成提示词\n- `targetLanguage` 仅在 `analysisMode=code` 时生效;为空时默认按 `Python` 处理\n- `prompt` 不再承担完整主提示词职责,只作为附加要求拼接到服务端内置提示词后面\n\n成功返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...模型输出...\",\n \"ocrText\": \"...OCR 文本(可能为空)...\",\n \"modelNotice\": \"...模型提示(可能为空)...\",\n \"agentRoute\": \"可选,agent 模式下为 qa 或 code\",\n \"improvementOptions\": [\"可选,agent 模式动态改进项\"],\n \"executionReport\": {\n \"success\": true,\n \"summary\": \"可选,代码运行/编译检查摘要\",\n \"returnCode\": 0\n }\n}\n```\n\n可能错误码:\n\n- `ERROR_ANALYZE_INPUT`:`imageBase64` 为空\n- `ERROR_OCR`:OCR 过程失败\n- `ERROR_OCR_EMPTY`:要求 OCR 非空但结果为空\n- `ERROR_ANALYZE`:模型分析失败\n\n### 5.2 文本解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"需要解析的文本\",\n \"prompt\": \"可选,额外提示词\",\n \"analysisMode\": \"可选,qa 或 code\",\n \"targetLanguage\": \"可选,代码模式下的目标语言,如 Python / Java / C++\"\n}\n```\n\n当 `analysisMode=code` 时,服务端会先识别题目中的输入输出、约束与边界,再输出对应语言的可提交代码。\n\n成功返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...模型输出...\",\n \"ocrText\": \"\",\n \"modelNotice\": \"...模型提示(可能为空)...\",\n \"agentRoute\": \"可选,agent 模式下为 qa 或 code\",\n \"improvementOptions\": [\"可选,agent 模式动态改进项\"],\n \"executionReport\": {\n \"success\": true,\n \"summary\": \"可选,代码运行/编译检查摘要\",\n \"returnCode\": 0\n }\n}\n```\n\n可能错误码:\n\n- `ERROR_ANALYZE_TEXT_INPUT`\n- `ERROR_ANALYZE`\n\n### 5.3 Agent 解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_AGENT\",\n \"requestId\": \"uuid-string\",\n \"imageBase64\": \"可选,图片解析时提供\",\n \"text\": \"可选,文本解析时提供\",\n \"prompt\": \"可选,附加提示\",\n \"targetLanguage\": \"可选,代码路线下语言偏好,如 Python / Java / C++\",\n \"routeHint\": \"可选,客户端本地分类结果 qa 或 code\",\n \"improvementRequest\": \"可选,用户在手机端选择的改进项\",\n \"currentText\": \"可选,当前结果文本,供二次优化使用\"\n}\n```\n\n字段说明:\n\n- `imageBase64` 与 `text` 至少提供一个\n- 服务端会先基于 OCR/文本判断路线(`qa` 或 `code`)\n- 若 `routeHint` 传入且值为 `qa|code`,服务端优先采用该路线;否则回退服务端分类\n- 当路线为 `code` 且 `targetLanguage=Python` 时,服务端会尝试本地运行校验\n- `improvementRequest` 存在时,服务端会在当前结果基础上做定向优化\n\n成功返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...Agent 输出...\",\n \"ocrText\": \"...OCR 文本(可能为空)...\",\n \"modelNotice\": \"\",\n \"agentRoute\": \"qa | code\",\n \"improvementOptions\": [\n \"优化边界条件处理\",\n \"优化可读性\"\n ],\n \"executionReport\": {\n \"success\": true,\n \"summary\": \"Python 代码运行通过。\",\n \"returnCode\": 0\n }\n}\n```\n\n可能错误码:\n\n- `ERROR_ANALYZE_AGENT_INPUT`\n- `ERROR_OCR`\n- `ERROR_OCR_EMPTY`\n- `ERROR_ANALYZE`\n\n## 6. 剪贴板相关\n\n### 6.1 订阅剪贴板推送\n\n客户端发送:\n\n```json\n{\n \"type\": \"SUBSCRIBE_CLIPBOARD\"\n}\n```\n\n服务端检测到电脑端剪贴板变化后推送:\n\n```json\n{\n \"type\": \"CLIPBOARD_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"剪贴板文本(按上限截断)\"\n}\n```\n\n注意:当前实现中,进入 `SUBSCRIBE_CLIPBOARD` 后该连接会持续轮询并推送,不再处理同连接上的其他请求。建议为订阅使用独立连接。\n\n### 6.2 设置电脑端剪贴板\n\n客户端发送:\n\n```json\n{\n \"type\": \"SET_CLIPBOARD_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"要写入的文本\"\n}\n```\n\n成功返回:\n\n```json\n{\n \"type\": \"CLIPBOARD_SET_OK\",\n \"requestId\": \"uuid-string\"\n}\n```\n\n可能错误码:\n\n- `ERROR_CLIPBOARD_INPUT`\n- `ERROR_CLIPBOARD_SET`\n\n## 7. 模型配置相关\n\n### 7.0 同步手机端模型配置(推荐)\n\n客户端发送:\n\n```json\n{\n \"type\": \"SYNC_MODEL_SETTINGS\",\n \"requestId\": \"uuid-string\",\n \"profiles\": [\n {\n \"apiUrl\": \"https://api.deepseek.com\",\n \"apiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\"\n }\n ],\n \"activeIndex\": 0\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_SETTINGS\",\n \"requestId\": \"uuid-string\",\n \"profiles\": [\n {\n \"apiUrl\": \"https://api.deepseek.com\",\n \"apiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\"\n }\n ],\n \"activeIndex\": 0\n}\n```\n\n说明:\n\n- 推荐由手机端本地持久化 `apiUrl/apiKey/modelName`,每次连接后调用该接口同步到电脑端运行时。\n- 当前实现中,这次同步默认不会写入电脑端 `model_profiles.json`,用于避免因电脑端升级覆盖导致模型配置丢失。\n- 失败错误码:`ERROR_SYNC_MODEL_SETTINGS`\n\n### 7.1 获取模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"GET_MODEL_SETTINGS\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_SETTINGS\",\n \"profiles\": [\n {\n \"apiUrl\": \"https://api.deepseek.com\",\n \"apiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\"\n }\n ],\n \"activeIndex\": 0\n}\n```\n\n### 7.2 检测可用模型名\n\n客户端发送:\n\n```json\n{\n \"type\": \"DETECT_MODELS\",\n \"requestId\": \"uuid-string\",\n \"modelApiUrl\": \"https://api.deepseek.com\",\n \"modelApiKey\": \"sk-...\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_NAMES\",\n \"requestId\": \"uuid-string\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"]\n}\n```\n\n失败错误码:`ERROR_DETECT_MODELS`\n\n### 7.3 新增模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"ADD_MODEL_SETTING\",\n \"requestId\": \"uuid-string\",\n \"modelApiUrl\": \"https://api.deepseek.com\",\n \"modelApiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\",\n \"setActive\": true\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_ADD_MODEL_SETTING`\n\n### 7.4 切换当前模型\n\n客户端发送:\n\n```json\n{\n \"type\": \"SET_ACTIVE_MODEL\",\n \"requestId\": \"uuid-string\",\n \"index\": 1\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_SET_ACTIVE_MODEL`\n\n### 7.5 删除模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"DELETE_MODEL_SETTING\",\n \"requestId\": \"uuid-string\",\n \"index\": 1\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_DELETE_MODEL_SETTING`\n\n## 8. 未知消息类型\n\n当 `type` 未被支持时返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_UNKNOWN_TYPE\",\n \"message\": \"unknown message type: XXX\"\n}\n```\n\n## 9. 客户端实现建议(基于当前服务端)\n\n- 每个连接先发 `AUTH`,收到 `AUTH_OK` 后再发其他请求。\n- `SUBSCRIBE_CLIPBOARD` 使用独立连接。\n- `CAPTURE`、`ANALYZE_IMAGE` 建议携带 `requestId` 以便对应响应。\n- 单条消息体尽量控制在 12 MiB 内(或与服务端 `RC_MAX_FRAME_SIZE` 保持一致)。\n"}, "9aabb640d24e51cd22ef64b5de9a2134573e6d29": {"t": 1785764434.961498, "n": 7117, "h": "8032c63fe7e1fb95", "c": "# TCP 协议(当前实现)\n\n## 1. 传输帧格式\n\n## 协议变更日志\n\n- 协议变更对照(v1.0 -> 当前):`docs/protocol-changelog.md`\n\n使用长度前缀帧:\n\n- 前 4 字节:无符号大端整数 `length`\n- 后续 `length` 字节:UTF-8 JSON\n\n示意:\n\n```text\n| 4 bytes length (big-endian) | UTF-8 JSON payload |\n```\n\n服务端限制:\n\n- 单帧最大长度 `RC_MAX_FRAME_SIZE`(默认 12 MiB)\n- `length <= 0` 或超过上限会直接报错并断开本次处理\n\n## 2. 连接与鉴权\n\n连接建立后,服务端要求第一条业务消息必须是 `AUTH`。\n\n### 客户端 -> 服务端\n\n```json\n{\n \"type\": \"AUTH\",\n \"password\": \"changeme\"\n}\n```\n\n### 服务端 -> 客户端\n\n```json\n{\n \"type\": \"AUTH_OK\"\n}\n```\n\n注意:当前实现只要求先发送 `AUTH`,并不会校验 `password` 是否正确。\n\n如果未先鉴权就发送其他消息,返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_AUTH_REQUIRED\",\n \"message\": \"auth required\"\n}\n```\n\n## 3. 通用错误格式\n\n```json\n{\n \"type\": \"ERROR\",\n \"requestId\": \"uuid-string (可选)\",\n \"code\": \"ERROR_XXX\",\n \"message\": \"错误描述\"\n}\n```\n\n## 4. 截图相关\n\n### 4.1 请求截图\n\n客户端发送:\n\n```json\n{\n \"type\": \"CAPTURE\",\n \"requestId\": \"uuid-string\",\n \"quality\": 75,\n \"displayId\": 1\n}\n```\n\n字段说明:\n\n- `quality` 范围会被服务端钳制到 30~95\n- `displayId` 默认 1\n\n成功返回:\n\n```json\n{\n \"type\": \"IMAGE\",\n \"requestId\": \"uuid-string\",\n \"displayId\": 1,\n \"format\": \"jpeg\",\n \"width\": 1920,\n \"height\": 1080,\n \"imageBase64\": \"...\"\n}\n```\n\n失败返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"requestId\": \"uuid-string\",\n \"code\": \"ERROR_CAPTURE\",\n \"message\": \"capture failed (displayId=1)\"\n}\n```\n\n### 4.2 获取显示器列表\n\n客户端发送:\n\n```json\n{\n \"type\": \"LIST_DISPLAYS\"\n}\n```\n\n成功返回:\n\n```json\n{\n \"type\": \"DISPLAYS\",\n \"displays\": [\n {\n \"id\": 1,\n \"left\": 0,\n \"top\": 0,\n \"width\": 1920,\n \"height\": 1080\n }\n ]\n}\n```\n\n失败返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_DISPLAYS\",\n \"message\": \"list displays failed\"\n}\n```\n\n## 5. 解析相关\n\n### 5.1 图片解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_IMAGE\",\n \"requestId\": \"uuid-string\",\n \"imageBase64\": \"...\",\n \"prompt\": \"可选,额外提示词\",\n \"analysisMode\": \"可选,qa 或 code\",\n \"targetLanguage\": \"可选,代码模式下的目标语言,如 Python / Java / C++\"\n}\n```\n\n字段说明:\n\n- `analysisMode` 默认为 `qa`\n- `analysisMode=code` 时,服务端会切换到编程题代码生成提示词\n- `targetLanguage` 仅在 `analysisMode=code` 时生效;为空时默认按 `Python` 处理\n- `prompt` 不再承担完整主提示词职责,只作为附加要求拼接到服务端内置提示词后面\n\n成功返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...模型输出...\",\n \"ocrText\": \"...OCR 文本(可能为空)...\",\n \"modelNotice\": \"...模型提示(可能为空)...\",\n \"agentRoute\": \"可选,agent 模式下为 qa 或 code\",\n \"improvementOptions\": [\"可选,agent 模式动态改进项\"],\n \"executionReport\": {\n \"success\": true,\n \"summary\": \"可选,代码运行/编译检查摘要\",\n \"returnCode\": 0\n }\n}\n```\n\n可能错误码:\n\n- `ERROR_ANALYZE_INPUT`:`imageBase64` 为空\n- `ERROR_OCR`:OCR 过程失败\n- `ERROR_OCR_EMPTY`:要求 OCR 非空但结果为空\n- `ERROR_ANALYZE`:模型分析失败\n\n### 5.2 文本解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"需要解析的文本\",\n \"prompt\": \"可选,额外提示词\",\n \"analysisMode\": \"可选,qa 或 code\",\n \"targetLanguage\": \"可选,代码模式下的目标语言,如 Python / Java / C++\"\n}\n```\n\n当 `analysisMode=code` 时,服务端会先识别题目中的输入输出、约束与边界,再输出对应语言的可提交代码。\n\n成功返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...模型输出...\",\n \"ocrText\": \"\",\n \"modelNotice\": \"...模型提示(可能为空)...\",\n \"agentRoute\": \"可选,agent 模式下为 qa 或 code\",\n \"improvementOptions\": [\"可选,agent 模式动态改进项\"],\n \"executionReport\": {\n \"success\": true,\n \"summary\": \"可选,代码运行/编译检查摘要\",\n \"returnCode\": 0\n }\n}\n```\n\n可能错误码:\n\n- `ERROR_ANALYZE_TEXT_INPUT`\n- `ERROR_ANALYZE`\n\n### 5.3 Agent 解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_AGENT\",\n \"requestId\": \"uuid-string\",\n \"imageBase64\": \"可选,图片解析时提供\",\n \"text\": \"可选,文本解析时提供\",\n \"prompt\": \"可选,附加提示\",\n \"targetLanguage\": \"可选,代码路线下语言偏好,如 Python / Java / C++\",\n \"routeHint\": \"可选,客户端本地分类结果 qa 或 code\",\n \"improvementRequest\": \"可选,用户在手机端选择的改进项\",\n \"currentText\": \"可选,当前结果文本,供二次优化使用\"\n}\n```\n\n字段说明:\n\n- `imageBase64` 与 `text` 至少提供一个\n- 服务端会先基于 OCR/文本判断路线(`qa` 或 `code`)\n- 若 `routeHint` 传入且值为 `qa|code`,服务端优先采用该路线;否则回退服务端分类\n- 当路线为 `code` 且 `targetLanguage=Python` 时,服务端会尝试本地运行校验\n- `improvementRequest` 存在时,服务端会在当前结果基础上做定向优化\n\n成功返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...Agent 输出...\",\n \"ocrText\": \"...OCR 文本(可能为空)...\",\n \"modelNotice\": \"\",\n \"agentRoute\": \"qa | code\",\n \"improvementOptions\": [\n \"优化边界条件处理\",\n \"优化可读性\"\n ],\n \"executionReport\": {\n \"success\": true,\n \"summary\": \"Python 代码运行通过。\",\n \"returnCode\": 0\n }\n}\n```\n\n可能错误码:\n\n- `ERROR_ANALYZE_AGENT_INPUT`\n- `ERROR_OCR`\n- `ERROR_OCR_EMPTY`\n- `ERROR_ANALYZE`\n\n## 6. 剪贴板相关\n\n### 6.1 订阅剪贴板推送\n\n客户端发送:\n\n```json\n{\n \"type\": \"SUBSCRIBE_CLIPBOARD\"\n}\n```\n\n服务端检测到电脑端剪贴板变化后推送:\n\n```json\n{\n \"type\": \"CLIPBOARD_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"剪贴板文本(按上限截断)\"\n}\n```\n\n注意:当前实现中,进入 `SUBSCRIBE_CLIPBOARD` 后该连接会持续轮询并推送,不再处理同连接上的其他请求。建议为订阅使用独立连接。\n\n### 6.2 设置电脑端剪贴板\n\n客户端发送:\n\n```json\n{\n \"type\": \"SET_CLIPBOARD_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"要写入的文本\"\n}\n```\n\n成功返回:\n\n```json\n{\n \"type\": \"CLIPBOARD_SET_OK\",\n \"requestId\": \"uuid-string\"\n}\n```\n\n可能错误码:\n\n- `ERROR_CLIPBOARD_INPUT`\n- `ERROR_CLIPBOARD_SET`\n\n## 7. 模型配置相关\n\n### 7.0 同步手机端模型配置(推荐)\n\n客户端发送:\n\n```json\n{\n \"type\": \"SYNC_MODEL_SETTINGS\",\n \"requestId\": \"uuid-string\",\n \"profiles\": [\n {\n \"apiUrl\": \"https://api.deepseek.com\",\n \"apiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\"\n }\n ],\n \"activeIndex\": 0\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_SETTINGS\",\n \"requestId\": \"uuid-string\",\n \"profiles\": [\n {\n \"apiUrl\": \"https://api.deepseek.com\",\n \"apiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\"\n }\n ],\n \"activeIndex\": 0\n}\n```\n\n说明:\n\n- 推荐由手机端本地持久化 `apiUrl/apiKey/modelName`,每次连接后调用该接口同步到电脑端运行时。\n- 当前实现中,这次同步默认不会写入电脑端 `model_profiles.json`,用于避免因电脑端升级覆盖导致模型配置丢失。\n- 失败错误码:`ERROR_SYNC_MODEL_SETTINGS`\n\n### 7.1 获取模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"GET_MODEL_SETTINGS\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_SETTINGS\",\n \"profiles\": [\n {\n \"apiUrl\": \"https://api.deepseek.com\",\n \"apiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\"\n }\n ],\n \"activeIndex\": 0\n}\n```\n\n### 7.2 检测可用模型名\n\n客户端发送:\n\n```json\n{\n \"type\": \"DETECT_MODELS\",\n \"requestId\": \"uuid-string\",\n \"modelApiUrl\": \"https://api.deepseek.com\",\n \"modelApiKey\": \"sk-...\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_NAMES\",\n \"requestId\": \"uuid-string\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"]\n}\n```\n\n失败错误码:`ERROR_DETECT_MODELS`\n\n### 7.3 新增模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"ADD_MODEL_SETTING\",\n \"requestId\": \"uuid-string\",\n \"modelApiUrl\": \"https://api.deepseek.com\",\n \"modelApiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\",\n \"setActive\": true\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_ADD_MODEL_SETTING`\n\n### 7.4 切换当前模型\n\n客户端发送:\n\n```json\n{\n \"type\": \"SET_ACTIVE_MODEL\",\n \"requestId\": \"uuid-string\",\n \"index\": 1\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_SET_ACTIVE_MODEL`\n\n### 7.5 删除模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"DELETE_MODEL_SETTING\",\n \"requestId\": \"uuid-string\",\n \"index\": 1\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_DELETE_MODEL_SETTING`\n\n## 8. 未知消息类型\n\n当 `type` 未被支持时返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_UNKNOWN_TYPE\",\n \"message\": \"unknown message type: XXX\"\n}\n```\n\n## 9. 客户端实现建议(基于当前服务端)\n\n- 每个连接先发 `AUTH`,收到 `AUTH_OK` 后再发其他请求。\n- `SUBSCRIBE_CLIPBOARD` 使用独立连接。\n- `CAPTURE`、`ANALYZE_IMAGE` 建议携带 `requestId` 以便对应响应。\n- 单条消息体尽量控制在 12 MiB 内(或与服务端 `RC_MAX_FRAME_SIZE` 保持一致)。\n"}, "b3d05a49584b91a4dce9eeed082e5ad883470814": {"t": 1785764436.2397223, "n": 6440, "h": "1dd492e19349b63f", "c": "# TCP 协议(当前实现)\n\n## 1. 传输帧格式\n\n## 协议变更日志\n\n- 协议变更对照(v1.0 -> 当前):`docs/protocol-changelog.md`\n\n使用长度前缀帧:\n\n- 前 4 字节:无符号大端整数 `length`\n- 后续 `length` 字节:UTF-8 JSON\n\n示意:\n\n```text\n| 4 bytes length (big-endian) | UTF-8 JSON payload |\n```\n\n服务端限制:\n\n- 单帧最大长度 `RC_MAX_FRAME_SIZE`(默认 12 MiB)\n- `length <= 0` 或超过上限会直接报错并断开本次处理\n\n## 2. 连接与鉴权\n\n连接建立后,服务端要求第一条业务消息必须是 `AUTH`。\n\n### 客户端 -> 服务端\n\n```json\n{\n \"type\": \"AUTH\",\n \"password\": \"changeme\"\n}\n```\n\n### 服务端 -> 客户端\n\n```json\n{\n \"type\": \"AUTH_OK\"\n}\n```\n\n注意:当前实现只要求先发送 `AUTH`,并不会校验 `password` 是否正确。\n\n如果未先鉴权就发送其他消息,返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_AUTH_REQUIRED\",\n \"message\": \"auth required\"\n}\n```\n\n## 3. 通用错误格式\n\n```json\n{\n \"type\": \"ERROR\",\n \"requestId\": \"uuid-string (可选)\",\n \"code\": \"ERROR_XXX\",\n \"message\": \"错误描述\"\n}\n```\n\n## 4. 截图相关\n\n### 4.1 请求截图\n\n客户端发送:\n\n```json\n{\n \"type\": \"CAPTURE\",\n \"requestId\": \"uuid-string\",\n \"quality\": 75,\n \"displayId\": 1\n}\n```\n\n字段说明:\n\n- `quality` 范围会被服务端钳制到 30~95\n- `displayId` 默认 1\n\n成功返回:\n\n```json\n{\n \"type\": \"IMAGE\",\n \"requestId\": \"uuid-string\",\n \"displayId\": 1,\n \"format\": \"jpeg\",\n \"width\": 1920,\n \"height\": 1080,\n \"imageBase64\": \"...\"\n}\n```\n\n失败返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"requestId\": \"uuid-string\",\n \"code\": \"ERROR_CAPTURE\",\n \"message\": \"capture failed (displayId=1)\"\n}\n```\n\n### 4.2 获取显示器列表\n\n客户端发送:\n\n```json\n{\n \"type\": \"LIST_DISPLAYS\"\n}\n```\n\n成功返回:\n\n```json\n{\n \"type\": \"DISPLAYS\",\n \"displays\": [\n {\n \"id\": 1,\n \"left\": 0,\n \"top\": 0,\n \"width\": 1920,\n \"height\": 1080\n }\n ]\n}\n```\n\n失败返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_DISPLAYS\",\n \"message\": \"list displays failed\"\n}\n```\n\n## 5. 解析相关\n\n### 5.1 图片解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_IMAGE\",\n \"requestId\": \"uuid-string\",\n \"imageBase64\": \"...\",\n \"prompt\": \"可选,额外提示词\",\n \"analysisMode\": \"可选,qa 或 code\",\n \"targetLanguage\": \"可选,代码模式下的目标语言,如 Python / Java / C++\"\n}\n```\n\n字段说明:\n\n- `analysisMode` 默认为 `qa`\n- `analysisMode=code` 时,服务端会切换到编程题代码生成提示词\n- `targetLanguage` 仅在 `analysisMode=code` 时生效;为空时默认按 `Python` 处理\n- `prompt` 不再承担完整主提示词职责,只作为附加要求拼接到服务端内置提示词后面\n\n成功返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...模型输出...\",\n \"ocrText\": \"...OCR 文本(可能为空)...\",\n \"modelNotice\": \"...模型提示(可能为空)...\",\n \"agentRoute\": \"可选,agent 模式下为 qa 或 code\",\n \"improvementOptions\": [\"可选,agent 模式动态改进项\"],\n \"executionReport\": {\n \"success\": true,\n \"summary\": \"可选,代码运行/编译检查摘要\",\n \"returnCode\": 0\n }\n}\n```\n\n可能错误码:\n\n- `ERROR_ANALYZE_INPUT`:`imageBase64` 为空\n- `ERROR_OCR`:OCR 过程失败\n- `ERROR_OCR_EMPTY`:要求 OCR 非空但结果为空\n- `ERROR_ANALYZE`:模型分析失败\n\n### 5.2 文本解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"需要解析的文本\",\n \"prompt\": \"可选,额外提示词\",\n \"analysisMode\": \"可选,qa 或 code\",\n \"targetLanguage\": \"可选,代码模式下的目标语言,如 Python / Java / C++\"\n}\n```\n\n当 `analysisMode=code` 时,服务端会先识别题目中的输入输出、约束与边界,再输出对应语言的可提交代码。\n\n成功返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...模型输出...\",\n \"ocrText\": \"\",\n \"modelNotice\": \"...模型提示(可能为空)...\",\n \"agentRoute\": \"可选,agent 模式下为 qa 或 code\",\n \"improvementOptions\": [\"可选,agent 模式动态改进项\"],\n \"executionReport\": {\n \"success\": true,\n \"summary\": \"可选,代码运行/编译检查摘要\",\n \"returnCode\": 0\n }\n}\n```\n\n可能错误码:\n\n- `ERROR_ANALYZE_TEXT_INPUT`\n- `ERROR_ANALYZE`\n\n### 5.3 Agent 解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_AGENT\",\n \"requestId\": \"uuid-string\",\n \"imageBase64\": \"可选,图片解析时提供\",\n \"text\": \"可选,文本解析时提供\",\n \"prompt\": \"可选,附加提示\",\n \"targetLanguage\": \"可选,代码路线下语言偏好,如 Python / Java / C++\",\n \"routeHint\": \"可选,客户端本地分类结果 qa 或 code\",\n \"improvementRequest\": \"可选,用户在手机端选择的改进项\",\n \"currentText\": \"可选,当前结果文本,供二次优化使用\"\n}\n```\n\n字段说明:\n\n- `imageBase64` 与 `text` 至少提供一个\n- 服务端会先基于 OCR/文本判断路线(`qa` 或 `code`)\n- 若 `routeHint` 传入且值为 `qa|code`,服务端优先采用该路线;否则回退服务端分类\n- 当路线为 `code` 且 `targetLanguage=Python` 时,服务端会尝试本地运行校验\n- `improvementRequest` 存在时,服务端会在当前结果基础上做定向优化\n\n成功返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...Agent 输出...\",\n \"ocrText\": \"...OCR 文本(可能为空)...\",\n \"modelNotice\": \"\",\n \"agentRoute\": \"qa | code\",\n \"improvementOptions\": [\n \"优化边界条件处理\",\n \"优化可读性\"\n ],\n \"executionReport\": {\n \"success\": true,\n \"summary\": \"Python 代码运行通过。\",\n \"returnCode\": 0\n }\n}\n```\n\n可能错误码:\n\n- `ERROR_ANALYZE_AGENT_INPUT`\n- `ERROR_OCR`\n- `ERROR_OCR_EMPTY`\n- `ERROR_ANALYZE`\n\n## 6. 剪贴板相关\n\n### 6.1 订阅剪贴板推送\n\n客户端发送:\n\n```json\n{\n \"type\": \"SUBSCRIBE_CLIPBOARD\"\n}\n```\n\n服务端检测到电脑端剪贴板变化后推送:\n\n```json\n{\n \"type\": \"CLIPBOARD_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"剪贴板文本(按上限截断)\"\n}\n```\n\n注意:当前实现中,进入 `SUBSCRIBE_CLIPBOARD` 后该连接会持续轮询并推送,不再处理同连接上的其他请求。建议为订阅使用独立连接。\n\n### 6.2 设置电脑端剪贴板\n\n客户端发送:\n\n```json\n{\n \"type\": \"SET_CLIPBOARD_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"要写入的文本\"\n}\n```\n\n成功返回:\n\n```json\n{\n \"type\": \"CLIPBOARD_SET_OK\",\n \"requestId\": \"uuid-string\"\n}\n```\n\n可能错误码:\n\n- `ERROR_CLIPBOARD_INPUT`\n- `ERROR_CLIPBOARD_SET`\n\n## 7. 模型配置相关\n\n### 7.1 获取模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"GET_MODEL_SETTINGS\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_SETTINGS\",\n \"profiles\": [\n {\n \"apiUrl\": \"https://api.deepseek.com\",\n \"apiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\"\n }\n ],\n \"activeIndex\": 0\n}\n```\n\n### 7.2 检测可用模型名\n\n客户端发送:\n\n```json\n{\n \"type\": \"DETECT_MODELS\",\n \"requestId\": \"uuid-string\",\n \"modelApiUrl\": \"https://api.deepseek.com\",\n \"modelApiKey\": \"sk-...\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_NAMES\",\n \"requestId\": \"uuid-string\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"]\n}\n```\n\n失败错误码:`ERROR_DETECT_MODELS`\n\n### 7.3 新增模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"ADD_MODEL_SETTING\",\n \"requestId\": \"uuid-string\",\n \"modelApiUrl\": \"https://api.deepseek.com\",\n \"modelApiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\",\n \"setActive\": true\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_ADD_MODEL_SETTING`\n\n### 7.4 切换当前模型\n\n客户端发送:\n\n```json\n{\n \"type\": \"SET_ACTIVE_MODEL\",\n \"requestId\": \"uuid-string\",\n \"index\": 1\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_SET_ACTIVE_MODEL`\n\n### 7.5 删除模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"DELETE_MODEL_SETTING\",\n \"requestId\": \"uuid-string\",\n \"index\": 1\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_DELETE_MODEL_SETTING`\n\n## 8. 未知消息类型\n\n当 `type` 未被支持时返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_UNKNOWN_TYPE\",\n \"message\": \"unknown message type: XXX\"\n}\n```\n\n## 9. 客户端实现建议(基于当前服务端)\n\n- 每个连接先发 `AUTH`,收到 `AUTH_OK` 后再发其他请求。\n- `SUBSCRIBE_CLIPBOARD` 使用独立连接。\n- `CAPTURE`、`ANALYZE_IMAGE` 建议携带 `requestId` 以便对应响应。\n- 单条消息体尽量控制在 12 MiB 内(或与服务端 `RC_MAX_FRAME_SIZE` 保持一致)。\n"}, "adc70836756e7d25b15b657b83cbf3aa9fad6ead": {"t": 1785764437.5204804, "n": 5026, "h": "ffe6d87b97065db5", "c": "# TCP 协议(当前实现)\n\n## 1. 传输帧格式\n\n## 协议变更日志\n\n- 协议变更对照(v1.0 -> 当前):`docs/protocol-changelog.md`\n\n使用长度前缀帧:\n\n- 前 4 字节:无符号大端整数 `length`\n- 后续 `length` 字节:UTF-8 JSON\n\n示意:\n\n```text\n| 4 bytes length (big-endian) | UTF-8 JSON payload |\n```\n\n服务端限制:\n\n- 单帧最大长度 `RC_MAX_FRAME_SIZE`(默认 12 MiB)\n- `length <= 0` 或超过上限会直接报错并断开本次处理\n\n## 2. 连接与鉴权\n\n连接建立后,服务端要求第一条业务消息必须是 `AUTH`。\n\n### 客户端 -> 服务端\n\n```json\n{\n \"type\": \"AUTH\",\n \"password\": \"changeme\"\n}\n```\n\n### 服务端 -> 客户端\n\n```json\n{\n \"type\": \"AUTH_OK\"\n}\n```\n\n注意:当前实现只要求先发送 `AUTH`,并不会校验 `password` 是否正确。\n\n如果未先鉴权就发送其他消息,返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_AUTH_REQUIRED\",\n \"message\": \"auth required\"\n}\n```\n\n## 3. 通用错误格式\n\n```json\n{\n \"type\": \"ERROR\",\n \"requestId\": \"uuid-string (可选)\",\n \"code\": \"ERROR_XXX\",\n \"message\": \"错误描述\"\n}\n```\n\n## 4. 截图相关\n\n### 4.1 请求截图\n\n客户端发送:\n\n```json\n{\n \"type\": \"CAPTURE\",\n \"requestId\": \"uuid-string\",\n \"quality\": 75,\n \"displayId\": 1\n}\n```\n\n字段说明:\n\n- `quality` 范围会被服务端钳制到 30~95\n- `displayId` 默认 1\n\n成功返回:\n\n```json\n{\n \"type\": \"IMAGE\",\n \"requestId\": \"uuid-string\",\n \"displayId\": 1,\n \"format\": \"jpeg\",\n \"width\": 1920,\n \"height\": 1080,\n \"imageBase64\": \"...\"\n}\n```\n\n失败返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"requestId\": \"uuid-string\",\n \"code\": \"ERROR_CAPTURE\",\n \"message\": \"capture failed (displayId=1)\"\n}\n```\n\n### 4.2 获取显示器列表\n\n客户端发送:\n\n```json\n{\n \"type\": \"LIST_DISPLAYS\"\n}\n```\n\n成功返回:\n\n```json\n{\n \"type\": \"DISPLAYS\",\n \"displays\": [\n {\n \"id\": 1,\n \"left\": 0,\n \"top\": 0,\n \"width\": 1920,\n \"height\": 1080\n }\n ]\n}\n```\n\n失败返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_DISPLAYS\",\n \"message\": \"list displays failed\"\n}\n```\n\n## 5. 解析相关\n\n### 5.1 图片解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_IMAGE\",\n \"requestId\": \"uuid-string\",\n \"imageBase64\": \"...\",\n \"prompt\": \"可选,额外提示词\",\n \"analysisMode\": \"可选,qa 或 code\",\n \"targetLanguage\": \"可选,代码模式下的目标语言,如 Python / Java / C++\"\n}\n```\n\n字段说明:\n\n- `analysisMode` 默认为 `qa`\n- `analysisMode=code` 时,服务端会切换到编程题代码生成提示词\n- `targetLanguage` 仅在 `analysisMode=code` 时生效;为空时默认按 `Python` 处理\n- `prompt` 不再承担完整主提示词职责,只作为附加要求拼接到服务端内置提示词后面\n\n成功返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...模型输出...\",\n \"ocrText\": \"...OCR 文本(可能为空)...\",\n \"modelNotice\": \"...模型提示(可能为空)...\"\n}\n```\n\n可能错误码:\n\n- `ERROR_ANALYZE_INPUT`:`imageBase64` 为空\n- `ERROR_OCR`:OCR 过程失败\n- `ERROR_OCR_EMPTY`:要求 OCR 非空但结果为空\n- `ERROR_ANALYZE`:模型分析失败\n\n### 5.2 文本解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"需要解析的文本\",\n \"prompt\": \"可选,额外提示词\",\n \"analysisMode\": \"可选,qa 或 code\",\n \"targetLanguage\": \"可选,代码模式下的目标语言,如 Python / Java / C++\"\n}\n```\n\n当 `analysisMode=code` 时,服务端会先识别题目中的输入输出、约束与边界,再输出对应语言的可提交代码。\n\n成功返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...模型输出...\",\n \"ocrText\": \"\",\n \"modelNotice\": \"...模型提示(可能为空)...\"\n}\n```\n\n可能错误码:\n\n- `ERROR_ANALYZE_TEXT_INPUT`\n- `ERROR_ANALYZE`\n\n## 6. 剪贴板相关\n\n### 6.1 订阅剪贴板推送\n\n客户端发送:\n\n```json\n{\n \"type\": \"SUBSCRIBE_CLIPBOARD\"\n}\n```\n\n服务端检测到电脑端剪贴板变化后推送:\n\n```json\n{\n \"type\": \"CLIPBOARD_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"剪贴板文本(按上限截断)\"\n}\n```\n\n注意:当前实现中,进入 `SUBSCRIBE_CLIPBOARD` 后该连接会持续轮询并推送,不再处理同连接上的其他请求。建议为订阅使用独立连接。\n\n### 6.2 设置电脑端剪贴板\n\n客户端发送:\n\n```json\n{\n \"type\": \"SET_CLIPBOARD_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"要写入的文本\"\n}\n```\n\n成功返回:\n\n```json\n{\n \"type\": \"CLIPBOARD_SET_OK\",\n \"requestId\": \"uuid-string\"\n}\n```\n\n可能错误码:\n\n- `ERROR_CLIPBOARD_INPUT`\n- `ERROR_CLIPBOARD_SET`\n\n## 7. 模型配置相关\n\n### 7.1 获取模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"GET_MODEL_SETTINGS\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_SETTINGS\",\n \"profiles\": [\n {\n \"apiUrl\": \"https://api.deepseek.com\",\n \"apiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\"\n }\n ],\n \"activeIndex\": 0\n}\n```\n\n### 7.2 检测可用模型名\n\n客户端发送:\n\n```json\n{\n \"type\": \"DETECT_MODELS\",\n \"requestId\": \"uuid-string\",\n \"modelApiUrl\": \"https://api.deepseek.com\",\n \"modelApiKey\": \"sk-...\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_NAMES\",\n \"requestId\": \"uuid-string\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"]\n}\n```\n\n失败错误码:`ERROR_DETECT_MODELS`\n\n### 7.3 新增模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"ADD_MODEL_SETTING\",\n \"requestId\": \"uuid-string\",\n \"modelApiUrl\": \"https://api.deepseek.com\",\n \"modelApiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\",\n \"setActive\": true\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_ADD_MODEL_SETTING`\n\n### 7.4 切换当前模型\n\n客户端发送:\n\n```json\n{\n \"type\": \"SET_ACTIVE_MODEL\",\n \"requestId\": \"uuid-string\",\n \"index\": 1\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_SET_ACTIVE_MODEL`\n\n### 7.5 删除模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"DELETE_MODEL_SETTING\",\n \"requestId\": \"uuid-string\",\n \"index\": 1\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_DELETE_MODEL_SETTING`\n\n## 8. 未知消息类型\n\n当 `type` 未被支持时返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_UNKNOWN_TYPE\",\n \"message\": \"unknown message type: XXX\"\n}\n```\n\n## 9. 客户端实现建议(基于当前服务端)\n\n- 每个连接先发 `AUTH`,收到 `AUTH_OK` 后再发其他请求。\n- `SUBSCRIBE_CLIPBOARD` 使用独立连接。\n- `CAPTURE`、`ANALYZE_IMAGE` 建议携带 `requestId` 以便对应响应。\n- 单条消息体尽量控制在 12 MiB 内(或与服务端 `RC_MAX_FRAME_SIZE` 保持一致)。\n"}, "9ebcc7a4a7cbb76155920c7eac149a0def3294db": {"t": 1785764439.7325044, "n": 4594, "h": "8e18c211b9181bb0", "c": "# TCP 协议(当前实现)\n\n## 1. 传输帧格式\n\n## 协议变更日志\n\n- 协议变更对照(v1.0 -> 当前):`docs/protocol-changelog.md`\n\n使用长度前缀帧:\n\n- 前 4 字节:无符号大端整数 `length`\n- 后续 `length` 字节:UTF-8 JSON\n\n示意:\n\n```text\n| 4 bytes length (big-endian) | UTF-8 JSON payload |\n```\n\n服务端限制:\n\n- 单帧最大长度 `RC_MAX_FRAME_SIZE`(默认 12 MiB)\n- `length <= 0` 或超过上限会直接报错并断开本次处理\n\n## 2. 连接与鉴权\n\n连接建立后,服务端要求第一条业务消息必须是 `AUTH`。\n\n### 客户端 -> 服务端\n\n```json\n{\n \"type\": \"AUTH\",\n \"password\": \"changeme\"\n}\n```\n\n### 服务端 -> 客户端\n\n```json\n{\n \"type\": \"AUTH_OK\"\n}\n```\n\n注意:当前实现只要求先发送 `AUTH`,并不会校验 `password` 是否正确。\n\n如果未先鉴权就发送其他消息,返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_AUTH_REQUIRED\",\n \"message\": \"auth required\"\n}\n```\n\n## 3. 通用错误格式\n\n```json\n{\n \"type\": \"ERROR\",\n \"requestId\": \"uuid-string (可选)\",\n \"code\": \"ERROR_XXX\",\n \"message\": \"错误描述\"\n}\n```\n\n## 4. 截图相关\n\n### 4.1 请求截图\n\n客户端发送:\n\n```json\n{\n \"type\": \"CAPTURE\",\n \"requestId\": \"uuid-string\",\n \"quality\": 75,\n \"displayId\": 1\n}\n```\n\n字段说明:\n\n- `quality` 范围会被服务端钳制到 30~95\n- `displayId` 默认 1\n\n成功返回:\n\n```json\n{\n \"type\": \"IMAGE\",\n \"requestId\": \"uuid-string\",\n \"displayId\": 1,\n \"format\": \"jpeg\",\n \"width\": 1920,\n \"height\": 1080,\n \"imageBase64\": \"...\"\n}\n```\n\n失败返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"requestId\": \"uuid-string\",\n \"code\": \"ERROR_CAPTURE\",\n \"message\": \"capture failed (displayId=1)\"\n}\n```\n\n### 4.2 获取显示器列表\n\n客户端发送:\n\n```json\n{\n \"type\": \"LIST_DISPLAYS\"\n}\n```\n\n成功返回:\n\n```json\n{\n \"type\": \"DISPLAYS\",\n \"displays\": [\n {\n \"id\": 1,\n \"left\": 0,\n \"top\": 0,\n \"width\": 1920,\n \"height\": 1080\n }\n ]\n}\n```\n\n失败返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_DISPLAYS\",\n \"message\": \"list displays failed\"\n}\n```\n\n## 5. 解析相关\n\n### 5.1 图片解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_IMAGE\",\n \"requestId\": \"uuid-string\",\n \"imageBase64\": \"...\",\n \"prompt\": \"可选,自定义提示词\"\n}\n```\n\n成功返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...模型输出...\",\n \"ocrText\": \"...OCR 文本(可能为空)...\",\n \"modelNotice\": \"...模型提示(可能为空)...\"\n}\n```\n\n可能错误码:\n\n- `ERROR_ANALYZE_INPUT`:`imageBase64` 为空\n- `ERROR_OCR`:OCR 过程失败\n- `ERROR_OCR_EMPTY`:要求 OCR 非空但结果为空\n- `ERROR_ANALYZE`:模型分析失败\n\n### 5.2 文本解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"需要解析的文本\",\n \"prompt\": \"可选,自定义提示词\"\n}\n```\n\n成功返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...模型输出...\",\n \"ocrText\": \"\",\n \"modelNotice\": \"...模型提示(可能为空)...\"\n}\n```\n\n可能错误码:\n\n- `ERROR_ANALYZE_TEXT_INPUT`\n- `ERROR_ANALYZE`\n\n## 6. 剪贴板相关\n\n### 6.1 订阅剪贴板推送\n\n客户端发送:\n\n```json\n{\n \"type\": \"SUBSCRIBE_CLIPBOARD\"\n}\n```\n\n服务端检测到电脑端剪贴板变化后推送:\n\n```json\n{\n \"type\": \"CLIPBOARD_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"剪贴板文本(按上限截断)\"\n}\n```\n\n注意:当前实现中,进入 `SUBSCRIBE_CLIPBOARD` 后该连接会持续轮询并推送,不再处理同连接上的其他请求。建议为订阅使用独立连接。\n\n### 6.2 设置电脑端剪贴板\n\n客户端发送:\n\n```json\n{\n \"type\": \"SET_CLIPBOARD_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"要写入的文本\"\n}\n```\n\n成功返回:\n\n```json\n{\n \"type\": \"CLIPBOARD_SET_OK\",\n \"requestId\": \"uuid-string\"\n}\n```\n\n可能错误码:\n\n- `ERROR_CLIPBOARD_INPUT`\n- `ERROR_CLIPBOARD_SET`\n\n## 7. 模型配置相关\n\n### 7.1 获取模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"GET_MODEL_SETTINGS\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_SETTINGS\",\n \"profiles\": [\n {\n \"apiUrl\": \"https://api.deepseek.com\",\n \"apiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\"\n }\n ],\n \"activeIndex\": 0\n}\n```\n\n### 7.2 检测可用模型名\n\n客户端发送:\n\n```json\n{\n \"type\": \"DETECT_MODELS\",\n \"requestId\": \"uuid-string\",\n \"modelApiUrl\": \"https://api.deepseek.com\",\n \"modelApiKey\": \"sk-...\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_NAMES\",\n \"requestId\": \"uuid-string\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"]\n}\n```\n\n失败错误码:`ERROR_DETECT_MODELS`\n\n### 7.3 新增模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"ADD_MODEL_SETTING\",\n \"requestId\": \"uuid-string\",\n \"modelApiUrl\": \"https://api.deepseek.com\",\n \"modelApiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\",\n \"setActive\": true\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_ADD_MODEL_SETTING`\n\n### 7.4 切换当前模型\n\n客户端发送:\n\n```json\n{\n \"type\": \"SET_ACTIVE_MODEL\",\n \"requestId\": \"uuid-string\",\n \"index\": 1\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_SET_ACTIVE_MODEL`\n\n### 7.5 删除模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"DELETE_MODEL_SETTING\",\n \"requestId\": \"uuid-string\",\n \"index\": 1\n}\n```\n\n服务端返回 `MODEL_SETTINGS`。\n\n失败错误码:`ERROR_DELETE_MODEL_SETTING`\n\n## 8. 未知消息类型\n\n当 `type` 未被支持时返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_UNKNOWN_TYPE\",\n \"message\": \"unknown message type: XXX\"\n}\n```\n\n## 9. 客户端实现建议(基于当前服务端)\n\n- 每个连接先发 `AUTH`,收到 `AUTH_OK` 后再发其他请求。\n- `SUBSCRIBE_CLIPBOARD` 使用独立连接。\n- `CAPTURE`、`ANALYZE_IMAGE` 建议携带 `requestId` 以便对应响应。\n- 单条消息体尽量控制在 12 MiB 内(或与服务端 `RC_MAX_FRAME_SIZE` 保持一致)。\n"}, "91e5ea812263e8ecba1ca025e65c4e9d0bfcc379": {"t": 1785764441.1169696, "n": 3464, "h": "f1791b1e7821e9ef", "c": "# TCP 协议(MVP)\n\n采用长度前缀帧:\n\n- 每个帧以 4 字节无符号大端整数 `length` 开头。\n- 后续 `length` 字节为 UTF-8 JSON 文本。\n- 对于图片响应,JSON 中包含 Base64 图片内容(MVP 简化实现)。\n\n## 通用字段\n\n```json\n{\n \"type\": \"AUTH|CAPTURE|LIST_DISPLAYS|DISPLAYS|ANALYZE_IMAGE|ANALYZE_RESULT|IMAGE|ERROR\",\n \"requestId\": \"uuid-string\"\n}\n```\n\n## 鉴权\n\n客户端发送:\n\n```json\n{\n \"type\": \"AUTH\",\n \"password\": \"changeme\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"AUTH_OK\"\n}\n```\n\n失败:\n\n```json\n{\n \"type\": \"ERROR\",\n \"code\": \"ERROR_AUTH\",\n \"message\": \"invalid password\"\n}\n```\n\n## 截图请求\n\n客户端发送:\n\n```json\n{\n \"type\": \"CAPTURE\",\n \"requestId\": \"uuid-string\",\n \"quality\": 75,\n \"displayId\": 1\n}\n```\n\n服务端成功返回:\n\n```json\n{\n \"type\": \"IMAGE\",\n \"requestId\": \"uuid-string\",\n \"displayId\": 1,\n \"format\": \"jpeg\",\n \"width\": 1920,\n \"height\": 1080,\n \"imageBase64\": \"...\"\n}\n\n## 显示器列表请求\n\n客户端发送:\n\n```json\n{\n \"type\": \"LIST_DISPLAYS\"\n}\n```\n\n## 上传图片并解析\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_IMAGE\",\n \"requestId\": \"uuid-string\",\n \"imageBase64\": \"...\",\n \"prompt\": \"请用简洁中文描述这张图里的主要内容,并列出关键元素。\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...模型解析结果...\",\n \"ocrText\": \"...上传前 OCR 扫描提取文本(可为空)...\",\n \"modelNotice\": \"已自动切换模型:xxx(可为空)\"\n}\n```\n\n说明:\n\n- 服务端在调用视觉模型前,会先执行一次 OCR 扫描(可通过服务端配置关闭)。\n- 当 `RC_OCR_REQUIRED=true` 且 OCR 结果为空时,服务端会拒绝上传并返回错误。\n\nOCR 相关错误:\n\n```json\n{\n \"type\": \"ERROR\",\n \"requestId\": \"uuid-string\",\n \"code\": \"ERROR_OCR|ERROR_OCR_EMPTY\",\n \"message\": \"...\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"DISPLAYS\",\n \"displays\": [\n {\n \"id\": 1,\n \"left\": 0,\n \"top\": 0,\n \"width\": 1920,\n \"height\": 1080\n },\n {\n \"id\": 2,\n \"left\": 1920,\n \"top\": 0,\n \"width\": 2560,\n \"height\": 1440\n }\n ]\n}\n```\n```\n\n失败返回:\n\n```json\n{\n \"type\": \"ERROR\",\n \"requestId\": \"uuid-string\",\n \"code\": \"ERROR_CAPTURE\",\n \"message\": \"capture failed\"\n}\n```\n\n## 超时与重试建议\n\n- 客户端读超时:8 秒。\n- 连接失败可重试 1~2 次。\n- 单连接串行请求(MVP),避免并发复杂度。\n\n## 文本解析请求\n\n客户端发送:\n\n```json\n{\n \"type\": \"ANALYZE_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"需要解析的文本\",\n \"prompt\": \"可选,自定义提示词\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"ANALYZE_RESULT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"...模型解析结果...\",\n \"ocrText\": \"\"\n}\n```\n\n## 剪贴板订阅推送\n\n客户端发送:\n\n```json\n{\n \"type\": \"SUBSCRIBE_CLIPBOARD\"\n}\n```\n\n服务端在检测到电脑端剪贴板文本变化后,主动推送:\n\n```json\n{\n \"type\": \"CLIPBOARD_TEXT\",\n \"requestId\": \"uuid-string\",\n \"text\": \"当前复制文本\"\n}\n```\n\n## 模型设置与检测\n\n### 获取模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"GET_MODEL_SETTINGS\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_SETTINGS\",\n \"activeIndex\": 0,\n \"profiles\": [\n {\n \"apiUrl\": \"https://api.deepseek.com\",\n \"apiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\"\n }\n ]\n}\n```\n\n### 检测可用模型名\n\n客户端发送:\n\n```json\n{\n \"type\": \"DETECT_MODELS\",\n \"requestId\": \"uuid-string\",\n \"modelApiUrl\": \"https://api.deepseek.com\",\n \"modelApiKey\": \"sk-...\"\n}\n```\n\n服务端返回:\n\n```json\n{\n \"type\": \"MODEL_NAMES\",\n \"requestId\": \"uuid-string\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"]\n}\n```\n\n### 新增模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"ADD_MODEL_SETTING\",\n \"requestId\": \"uuid-string\",\n \"modelApiUrl\": \"https://api.deepseek.com\",\n \"modelApiKey\": \"sk-...\",\n \"modelName\": \"deepseek-chat\",\n \"setActive\": true\n}\n```\n\n服务端返回同 `MODEL_SETTINGS`。\n\n### 切换当前模型\n\n客户端发送:\n\n```json\n{\n \"type\": \"SET_ACTIVE_MODEL\",\n \"requestId\": \"uuid-string\",\n \"index\": 1\n}\n```\n\n服务端返回同 `MODEL_SETTINGS`。\n\n### 删除模型配置\n\n客户端发送:\n\n```json\n{\n \"type\": \"DELETE_MODEL_SETTING\",\n \"requestId\": \"uuid-string\",\n \"index\": 1\n}\n```\n\n服务端返回同 `MODEL_SETTINGS`。\n"}}}}