Files

1 line
50 KiB
JSON
Raw Permalink 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.
{"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"}}}}