{"version":3,"file":"ai-model/models/deepseek/locate-protocol.mjs","sources":["../../../../../src/ai-model/models/deepseek/locate-protocol.ts"],"sourcesContent":["import type {\n  ParsedLocateResponse,\n  StandardLocateProtocol,\n} from '../../model-adapter/locate-protocol';\nimport {\n  type LocateResultPromptSpec,\n  formatLocateExampleValue,\n} from '../../shared/model-locate-result';\n\nconst deepSeekRefBoxPattern =\n  /<(?:｜｜|\\|)ref(?:｜｜|\\|)>\\s*[\\s\\S]*?\\s*<(?:｜｜|\\|)\\/ref(?:｜｜|\\|)>\\s*<(?:｜｜|\\|)box(?:｜｜|\\|)>\\s*([\\s\\S]*?)\\s*<(?:｜｜|\\|)\\/box(?:｜｜|\\|)>/g;\n\nconst deepSeekPointPattern =\n  /^\\s*<(?:｜｜|\\|)point(?:｜｜|\\|)>\\s*([\\s\\S]*?)\\s*<(?:｜｜|\\|)\\/point(?:｜｜|\\|)>\\s*$/;\n\nconst deepSeekSearchAreaSystemPromptIntroduction = `## Role:\nYou are a GUI grounding agent.`;\n\nconst deepSeekElementSystemPromptIntroduction = `## Role:\nYou are a GUI click grounding agent.\n\n## Objective:\n- Identify the UI element in the screenshot that matches the user's description.\n- Return the center point of that element.`;\n\nconst buildDeepSeekElementResponseInstructions = (\n  promptSpec: LocateResultPromptSpec,\n) => `## Output Format:\nReturn exactly one ${promptSpec.resultNoun} using the following format, without any explanation or additional text:\n\n<｜｜point｜｜>[${promptSpec.resultValueSchema}]<｜｜/point｜｜>\n\nFor example:\n<｜｜point｜｜>[${formatLocateExampleValue(promptSpec.exampleValues[0])}]<｜｜/point｜｜>\n\nCoordinate values must be integers.\nCoordinate requirements: ${promptSpec.resultValueDescription}\nThe origin is the top-left of the full screenshot.`;\n\nconst buildDeepSeekSearchAreaResponseInstructions = (\n  promptSpec: LocateResultPromptSpec,\n) => {\n  const targetExampleValue = formatLocateExampleValue(\n    promptSpec.exampleValues[0],\n  );\n  const referenceExampleValue = formatLocateExampleValue(\n    promptSpec.exampleValues[1] ?? promptSpec.exampleValues[0],\n  );\n\n  return `## Objective:\n- Identify the target UI element in the screenshot.\n- Identify the reference elements that the description uses to select the target, such as an owner label, row value, column value, nearby text, or relative-position anchor.\n- Return a tight ${promptSpec.resultNoun} for the target first, followed by a tight ${promptSpec.resultNoun} for each reference element.\n\n## Reference Rules:\n- If the description explicitly identifies the target through another visible element, you MUST return that visible element as a reference, even if the target appears unique.\n- For descriptions like \"B in the row whose A is X\", B is the target and the visible X is a reference.\n- For descriptions like \"the icon next to label X\", the icon is the target and the visible X is a reference.\n- Do not return unrelated landmarks or alternative target candidates.\n\n## Output Format:\nReturn one or more ref-box pairs using the following format, without any explanation or additional text:\n\n<｜｜ref｜｜>target: concise target description<｜｜/ref｜｜><｜｜box｜｜>[${promptSpec.resultValueSchema}]<｜｜/box｜｜>\n<｜｜ref｜｜>reference: concise reference description<｜｜/ref｜｜><｜｜box｜｜>[${promptSpec.resultValueSchema}]<｜｜/box｜｜>\n\nFor example:\nIf the request is \"the edit icon in the row whose project name is Apollo\", return:\n<｜｜ref｜｜>target: edit icon<｜｜/ref｜｜><｜｜box｜｜>[${targetExampleValue}]<｜｜/box｜｜>\n<｜｜ref｜｜>reference: Apollo<｜｜/ref｜｜><｜｜box｜｜>[${referenceExampleValue}]<｜｜/box｜｜>\n\nThe first ref-box pair must represent the target element. Every remaining pair must represent a reference element needed to identify the target. If no reference element is needed, return only the target pair. Each pair must contain exactly one ${promptSpec.resultNoun}.\nCoordinate values must be integers.\nCoordinate requirements: ${promptSpec.resultValueDescription}\nThe origin is the top-left of the full screenshot.`;\n};\n\nexport function parseDeepSeekLocateOutput(\n  content: string,\n): ParsedLocateResponse {\n  const match = content.match(deepSeekPointPattern);\n  if (!match) {\n    throw new Error(\n      'DeepSeek element locate response does not contain a valid <｜｜point｜｜>value<｜｜/point｜｜> result',\n    );\n  }\n\n  return {\n    kind: 'located',\n    target: match[1],\n  };\n}\n\nexport function parseDeepSeekSearchAreaOutput(\n  content: string,\n): ParsedLocateResponse {\n  const rawBoxes = Array.from(\n    content.matchAll(deepSeekRefBoxPattern),\n    (match) => match[1],\n  );\n  if (rawBoxes.length === 0) {\n    throw new Error(\n      'DeepSeek search-area response does not contain a valid <｜｜ref｜｜>label<｜｜/ref｜｜><｜｜box｜｜>[[x1,y1,x2,y2]]<｜｜/box｜｜> result',\n    );\n  }\n\n  const [rawBbox, ...rawReferenceBboxes] = rawBoxes;\n  return {\n    kind: 'located',\n    target: rawBbox,\n    ...(rawReferenceBboxes.length > 0\n      ? { references: rawReferenceBboxes }\n      : {}),\n  };\n}\n\nexport const deepSeekElementLocateProtocol: StandardLocateProtocol = {\n  systemPromptIntroduction: deepSeekElementSystemPromptIntroduction,\n  buildResponseInstructions: buildDeepSeekElementResponseInstructions,\n  buildUserPrompt: (targetElementDescription) =>\n    `Locate the center point of the following UI element: ${targetElementDescription}`,\n  expectedJsonObjectResponse: false,\n  parseRawResponse: parseDeepSeekLocateOutput,\n};\n\nexport const deepSeekSearchAreaProtocol: StandardLocateProtocol = {\n  systemPromptIntroduction: deepSeekSearchAreaSystemPromptIntroduction,\n  buildResponseInstructions: buildDeepSeekSearchAreaResponseInstructions,\n  buildUserPrompt: (sectionDescription) =>\n    `Locate the target and the reference elements needed to distinguish it: ${sectionDescription}`,\n  expectedJsonObjectResponse: false,\n  parseRawResponse: parseDeepSeekSearchAreaOutput,\n};\n"],"names":["deepSeekRefBoxPattern","deepSeekPointPattern","deepSeekSearchAreaSystemPromptIntroduction","deepSeekElementSystemPromptIntroduction","buildDeepSeekElementResponseInstructions","promptSpec","formatLocateExampleValue","buildDeepSeekSearchAreaResponseInstructions","targetExampleValue","referenceExampleValue","parseDeepSeekLocateOutput","content","match","Error","parseDeepSeekSearchAreaOutput","rawBoxes","Array","rawBbox","rawReferenceBboxes","deepSeekElementLocateProtocol","targetElementDescription","deepSeekSearchAreaProtocol","sectionDescription"],"mappings":";AASA,MAAMA,wBACJ;AAEF,MAAMC,uBACJ;AAEF,MAAMC,6CAA6C,CAAC;8BACtB,CAAC;AAE/B,MAAMC,0CAA0C,CAAC;;;;;0CAKP,CAAC;AAE3C,MAAMC,2CAA2C,CAC/CC,aACG,CAAC;mBACa,EAAEA,WAAW,UAAU,CAAC;;YAE/B,EAAEA,WAAW,iBAAiB,CAAC;;;YAG/B,EAAEC,yBAAyBD,WAAW,aAAa,CAAC,EAAE,EAAE;;;yBAG3C,EAAEA,WAAW,sBAAsB,CAAC;kDACX,CAAC;AAEnD,MAAME,8CAA8C,CAClDF;IAEA,MAAMG,qBAAqBF,yBACzBD,WAAW,aAAa,CAAC,EAAE;IAE7B,MAAMI,wBAAwBH,yBAC5BD,WAAW,aAAa,CAAC,EAAE,IAAIA,WAAW,aAAa,CAAC,EAAE;IAG5D,OAAO,CAAC;;;iBAGO,EAAEA,WAAW,UAAU,CAAC,2CAA2C,EAAEA,WAAW,UAAU,CAAC;;;;;;;;;;;+DAW7C,EAAEA,WAAW,iBAAiB,CAAC;qEACzB,EAAEA,WAAW,iBAAiB,CAAC;;;;8CAItD,EAAEG,mBAAmB;8CACrB,EAAEC,sBAAsB;;oPAE8K,EAAEJ,WAAW,UAAU,CAAC;;yBAEnP,EAAEA,WAAW,sBAAsB,CAAC;kDACX,CAAC;AACnD;AAEO,SAASK,0BACdC,OAAe;IAEf,MAAMC,QAAQD,QAAQ,KAAK,CAACV;IAC5B,IAAI,CAACW,OACH,MAAM,IAAIC,MACR;IAIJ,OAAO;QACL,MAAM;QACN,QAAQD,KAAK,CAAC,EAAE;IAClB;AACF;AAEO,SAASE,8BACdH,OAAe;IAEf,MAAMI,WAAWC,MAAM,IAAI,CACzBL,QAAQ,QAAQ,CAACX,wBACjB,CAACY,QAAUA,KAAK,CAAC,EAAE;IAErB,IAAIG,AAAoB,MAApBA,SAAS,MAAM,EACjB,MAAM,IAAIF,MACR;IAIJ,MAAM,CAACI,SAAS,GAAGC,mBAAmB,GAAGH;IACzC,OAAO;QACL,MAAM;QACN,QAAQE;QACR,GAAIC,mBAAmB,MAAM,GAAG,IAC5B;YAAE,YAAYA;QAAmB,IACjC,CAAC,CAAC;IACR;AACF;AAEO,MAAMC,gCAAwD;IACnE,0BAA0BhB;IAC1B,2BAA2BC;IAC3B,iBAAiB,CAACgB,2BAChB,CAAC,qDAAqD,EAAEA,0BAA0B;IACpF,4BAA4B;IAC5B,kBAAkBV;AACpB;AAEO,MAAMW,6BAAqD;IAChE,0BAA0BnB;IAC1B,2BAA2BK;IAC3B,iBAAiB,CAACe,qBAChB,CAAC,uEAAuE,EAAEA,oBAAoB;IAChG,4BAA4B;IAC5B,kBAAkBR;AACpB"}