Improve: Add optional max_width to get_screenshot

The get_screenshot tool inherited the MFC thumbnail-preview profile, capping
the frame at 1024px wide (1280 on 4K source), which is too small for AI
vision/OCR of dense UI. Add an optional max_width argument that overrides the
width (clamped to the client's 64..1920 limit) while keeping the RTT-adaptive
jpegQuality. Omitted or 0 keeps the existing thumbnail profile; 1920 yields
near-native resolution (full 1080p on a 1080p source, 1920 wide on 4K). Sync
the design doc.

Co-Authored-By: deepseek-v4-pro
This commit is contained in:
yuanyuanxiang
2026-08-19 13:41:38 +02:00
parent 61089e5fae
commit c6c6e1d5ef
2 changed files with 37 additions and 1 deletions

View File

@@ -271,6 +271,7 @@ Web 是长连接子链接可长驻MCP 是**一次性 request/response**。
- 复用现有双击预览机制 `COMMAND_SCREEN_PREVIEW_REQ`(247)→`TOKEN_SCREEN_PREVIEW_RSP`(248)`common/commands.h:416-455`,单帧 JPEG`ScreenPreviewReq`/`ScreenPreviewRspHeader``ctx->Send2Client` 发请求、主连接回响应,**不建子链接、不弹框**。 - 复用现有双击预览机制 `COMMAND_SCREEN_PREVIEW_REQ`(247)→`TOKEN_SCREEN_PREVIEW_RSP`(248)`common/commands.h:416-455`,单帧 JPEG`ScreenPreviewReq`/`ScreenPreviewRspHeader``ctx->Send2Client` 发请求、主连接回响应,**不建子链接、不弹框**。
- 复用 MFC 预览的 RTT/FRP 自适应参数挑选 `ChooseScreenPreviewParams` + `SendScreenPreviewRequest`,不重复实现 `GetTargetQualityLevel` - 复用 MFC 预览的 RTT/FRP 自适应参数挑选 `ChooseScreenPreviewParams` + `SendScreenPreviewRequest`,不重复实现 `GetTargetQualityLevel`
- **可选 `max_width` 参数**:缺省/0 沿用缩略图档位(最大 10244K 源屏高档 1280`max_width`>0 覆盖宽度并钳制到客户端上限 `[64,1920]`(客户端 `CaptureAndEncodePreview` 硬钳制),供 AI 视觉/OCR 场景请求接近原分辨率1080p 源屏传 1920 即原分辨率4K 源屏最多 1920`jpegQuality` 仍沿用档位自适应值。
- **请求关联**`ScreenPreviewReq.reqId` 提供关联MCP 用独立 16 位 reqId 发生器(`NextPreviewReqId`,跳过 0+ `SetPendingReqId` 登记期望值,`TakePreviewResponse` 只接受「挂起命中 + reqId 一致」的响应,过期/他途MFC 预览并发)响应原样回落到 MFC 路径。 - **请求关联**`ScreenPreviewReq.reqId` 提供关联MCP 用独立 16 位 reqId 发生器(`NextPreviewReqId`,跳过 0+ `SetPendingReqId` 登记期望值,`TakePreviewResponse` 只接受「挂起命中 + reqId 一致」的响应,过期/他途MFC 预览并发)响应原样回落到 MFC 路径。
- 客户端能力位 `CLIENT_CAP_SCREEN_PREVIEW`(0x0004仅 Windows 客户端声明):非 Windows 主机返回 `-32005`「不支持」。 - 客户端能力位 `CLIENT_CAP_SCREEN_PREVIEW`(0x0004仅 Windows 客户端声明):非 Windows 主机返回 `-32005`「不支持」。
- 返回结构:`content[0] = {type:"image", data: base64(JPEG), mimeType:"image/jpeg"}` + `structuredContent.image = {mimeType,width,height,bytes}`(元数据,不含 base64避免二次膨胀 - 返回结构:`content[0] = {type:"image", data: base64(JPEG), mimeType:"image/jpeg"}` + `structuredContent.image = {mimeType,width,height,bytes}`(元数据,不含 base64避免二次膨胀

View File

@@ -587,6 +587,29 @@ Json::Value BuildScreenshotOutputSchema() {
return schema; return schema;
} }
// get_screenshot 的 inputSchemaid 必填max_width 可选)
Json::Value BuildGetScreenshotInputSchema() {
Json::Value props(Json::objectValue);
Json::Value idProp(Json::objectValue);
idProp["type"] = "string";
idProp["description"] = u8"主机 id取 list_online_hosts / search_hosts 返回的 id 字段";
props["id"] = idProp;
Json::Value mwProp(Json::objectValue);
mwProp["type"] = "integer";
mwProp["description"] = u8"期望图片最大宽度(像素,钳制到 64~1920。省略或传 0 时沿用 RTT 自适应缩略图档位(最大 1024传 1920 可拿到接近原分辨率1080p 源屏即原分辨率4K 源屏最多 1920供 AI 视觉/OCR 场景提升清晰度。";
props["max_width"] = mwProp;
Json::Value schema(Json::objectValue);
schema["type"] = "object";
schema["properties"] = props;
Json::Value required(Json::arrayValue);
required.append("id");
schema["required"] = required;
return schema;
}
// list_files 的 inputSchemaid 必填path 可选path 缺省/空 = 列盘) // list_files 的 inputSchemaid 必填path 可选path 缺省/空 = 列盘)
Json::Value BuildListFilesInputSchema() { Json::Value BuildListFilesInputSchema() {
Json::Value props(Json::objectValue); Json::Value props(Json::objectValue);
@@ -752,7 +775,7 @@ std::string BuildToolsListResult(const Json::Value& id) {
tool["name"] = "get_screenshot"; tool["name"] = "get_screenshot";
tool["description"] = u8"截取指定在线主机的一帧屏幕,返回 base64 编码的 JPEG 图片image 对象含 mimeType/data/width/height。仅 Windows 客户端支持(能力位 CLIENT_CAP_SCREEN_PREVIEW主连接 RPC、一次性返回。"; tool["description"] = u8"截取指定在线主机的一帧屏幕,返回 base64 编码的 JPEG 图片image 对象含 mimeType/data/width/height。仅 Windows 客户端支持(能力位 CLIENT_CAP_SCREEN_PREVIEW主连接 RPC、一次性返回。";
tool["inputSchema"] = BuildGetHostDetailInputSchema(); // 复用 { id } 必填 schema tool["inputSchema"] = BuildGetScreenshotInputSchema(); // { id } 必填 + max_width 可选
tool["outputSchema"] = BuildScreenshotOutputSchema(); tool["outputSchema"] = BuildScreenshotOutputSchema();
tools.append(tool); tools.append(tool);
@@ -1061,6 +1084,18 @@ std::string BuildGetScreenshot(const Json::Value& id, const Json::Value& args, C
WORD maxWidth = 0; WORD maxWidth = 0;
BYTE quality = 0; BYTE quality = 0;
parent->ChooseScreenPreviewParams(ctx, maxWidth, quality); parent->ChooseScreenPreviewParams(ctx, maxWidth, quality);
// 可选 max_width缺省/0 沿用缩略图档位;>0 覆盖宽度(钳制到客户端上限 [64,1920]
// 供 AI 视觉/OCR 场景请求接近原分辨率的大图。jpegQuality 仍沿用档位自适应值。
if (args.isMember("max_width") && args["max_width"].isInt()) {
int mw = args["max_width"].asInt();
if (mw > 0) {
if (mw < 64) mw = 64;
if (mw > 1920) mw = 1920;
maxWidth = (WORD)mw;
}
}
parent->SendScreenPreviewRequest(ctx, reqId, maxWidth, quality); parent->SendScreenPreviewRequest(ctx, reqId, maxWidth, quality);
std::vector<BYTE> data; std::vector<BYTE> data;