{"version":3,"file":"ai-model/models/auto-glm/parser.mjs","sources":["../../../../../src/ai-model/models/auto-glm/parser.ts"],"sourcesContent":["import { getDebug } from '@midscene/shared/logger';\nimport type { AutoGLMParsedAction } from './actions';\n\nconst debug = getDebug('auto-glm-parser');\n\n// Do not rely on regex extraction here; regex can fail on malformed input.\n// Bad Case: finish(message=\"Finished! Now There is a contact whose name is \\\"Tom\\\" in the list.\")\nexport const extractValueAfter = (src: string, key: string): string => {\n  const idx = src.indexOf(key);\n  if (idx === -1) {\n    throw new Error(`Missing key ${key} in action payload ${src}`);\n  }\n  let rest = src.slice(idx + key.length).trim();\n  if (rest.endsWith('\")')) {\n    rest = rest.slice(0, -2);\n  }\n  return rest;\n};\n\nexport function parseAutoGLMPlanningAction(response: {\n  think: string;\n  content: string;\n}): AutoGLMParsedAction {\n  debug('Parsing action:', response);\n  let trimmedResponse = '';\n  try {\n    trimmedResponse = response.content.trim();\n\n    if (\n      trimmedResponse.startsWith('do(action=\"Type\"') ||\n      trimmedResponse.startsWith('do(action=\"Type_Name\"')\n    ) {\n      const text = extractValueAfter(trimmedResponse, 'text=\"');\n      return {\n        _metadata: 'do',\n        action: 'Type',\n        text,\n        think: response.think,\n      } as AutoGLMParsedAction;\n    }\n\n    if (trimmedResponse.startsWith('finish(message=')) {\n      let message = extractValueAfter(trimmedResponse, 'finish(message=\"');\n      if (message.endsWith(')')) message = message.slice(0, -1);\n      return {\n        _metadata: 'finish',\n        message,\n        think: response.think,\n      } as AutoGLMParsedAction;\n    }\n\n    if (trimmedResponse.startsWith('do(')) {\n      const actionMatch = trimmedResponse.match(/do\\(action=\"([^\"]+)\"/);\n      if (!actionMatch)\n        throw new Error(\n          `Failed to extract action type from do() call; raw=\"${trimmedResponse}\"`,\n        );\n      const actionType = actionMatch[1];\n\n      const baseAction = { _metadata: 'do' as const, think: response.think };\n      switch (actionType) {\n        case 'Tap': {\n          const elementMatch = trimmedResponse.match(/element=\\[(\\d+),(\\d+)\\]/);\n          if (!elementMatch)\n            throw new Error(\n              `Failed to extract element coordinates for Tap; raw=\"${trimmedResponse}\"`,\n            );\n          return {\n            ...baseAction,\n            action: 'Tap',\n            element: [Number(elementMatch[1]), Number(elementMatch[2])],\n          } as AutoGLMParsedAction;\n        }\n        case 'Double Tap': {\n          const elementMatch = trimmedResponse.match(/element=\\[(\\d+),(\\d+)\\]/);\n          if (!elementMatch)\n            throw new Error(\n              `Failed to extract element coordinates for Double Tap; raw=\"${trimmedResponse}\"`,\n            );\n          return {\n            ...baseAction,\n            action: 'Double Tap',\n            element: [Number(elementMatch[1]), Number(elementMatch[2])],\n          } as AutoGLMParsedAction;\n        }\n        case 'Swipe': {\n          const startMatch = trimmedResponse.match(/start=\\[(\\d+),(\\d+)\\]/);\n          const endMatch = trimmedResponse.match(/end=\\[(\\d+),(\\d+)\\]/);\n          if (!startMatch || !endMatch)\n            throw new Error(\n              `Failed to extract start/end coordinates for Swipe; raw=\"${trimmedResponse}\"`,\n            );\n          return {\n            ...baseAction,\n            action: 'Swipe',\n            start: [Number(startMatch[1]), Number(startMatch[2])],\n            end: [Number(endMatch[1]), Number(endMatch[2])],\n          } as AutoGLMParsedAction;\n        }\n        case 'Long Press': {\n          const elementMatch = trimmedResponse.match(/element=\\[(\\d+),(\\d+)\\]/);\n          if (!elementMatch)\n            throw new Error(\n              `Failed to extract element coordinates for Long Press; raw=\"${trimmedResponse}\"`,\n            );\n          return {\n            ...baseAction,\n            action: 'Long Press',\n            element: [Number(elementMatch[1]), Number(elementMatch[2])],\n          } as AutoGLMParsedAction;\n        }\n        case 'Launch': {\n          const app = extractValueAfter(trimmedResponse, 'app=\"');\n          return {\n            ...baseAction,\n            action: 'Launch',\n            app,\n          } as AutoGLMParsedAction;\n        }\n        case 'Back': {\n          return { ...baseAction, action: 'Back' } as AutoGLMParsedAction;\n        }\n        case 'Home': {\n          return { ...baseAction, action: 'Home' } as AutoGLMParsedAction;\n        }\n        case 'Wait': {\n          const durationMatch = trimmedResponse.match(\n            /duration=(?:[\"\\[])?(\\d+)/,\n          );\n          if (!durationMatch) {\n            throw new Error(\n              `Failed to extract duration for Wait; raw=\"${trimmedResponse}\"`,\n            );\n          }\n          const seconds = Number.parseInt(durationMatch[1], 10);\n          const durationMs = seconds * 1000;\n          return {\n            ...baseAction,\n            action: 'Wait',\n            durationMs,\n          } as AutoGLMParsedAction;\n        }\n        case 'Interact': {\n          return { ...baseAction, action: 'Interact' } as AutoGLMParsedAction;\n        }\n        case 'Call_API': {\n          const instruction = extractValueAfter(\n            trimmedResponse,\n            'instruction=\"',\n          );\n          return {\n            ...baseAction,\n            action: 'Call_API',\n            instruction,\n          } as AutoGLMParsedAction;\n        }\n        case 'Take_over': {\n          const message = extractValueAfter(trimmedResponse, 'message=\"');\n          return {\n            ...baseAction,\n            action: 'Take_over',\n            message,\n          } as AutoGLMParsedAction;\n        }\n        case 'Note': {\n          const message = extractValueAfter(trimmedResponse, 'message=\"');\n          return {\n            ...baseAction,\n            action: 'Note',\n            message,\n          } as AutoGLMParsedAction;\n        }\n        default:\n          throw new Error(\n            `Unknown action type: ${actionType}; raw=\"${trimmedResponse}\"`,\n          );\n      }\n    }\n    throw new Error(`Failed to parse action: ${trimmedResponse}`);\n  } catch (error) {\n    const errorMessage = error instanceof Error ? error.message : String(error);\n    throw new Error(\n      `Failed to parse action: ${errorMessage}; raw=\"${trimmedResponse}\"`,\n    );\n  }\n}\n\nexport function parseAutoGLMResponse(content: string): {\n  think: string;\n  content: string;\n} {\n  let parsedResponse: { think: string; content: string };\n\n  if (content.includes('finish(message=')) {\n    const parts = content.split('finish(message=');\n    const think = parts[0].trim();\n    const actionContent = `finish(message=${parts[1]}`;\n    parsedResponse = { think, content: actionContent };\n  } else if (content.includes('do(action=')) {\n    const parts = content.split('do(action=');\n    const think = parts[0].trim();\n    const actionContent = `do(action=${parts[1]}`;\n    parsedResponse = { think, content: actionContent };\n  } else if (content.includes('<answer>')) {\n    const parts = content.split('<answer>');\n    const think = parts[0]\n      .replace(/<think>/g, '')\n      .replace(/<\\/think>/g, '')\n      .trim();\n    const actionContent = parts[1].replace(/<\\/answer>/g, '').trim();\n    parsedResponse = { think, content: actionContent };\n  } else {\n    parsedResponse = { think: '', content };\n  }\n\n  debug('autoGLM rawResponse:', content);\n  debug('thinking in response:', parsedResponse.think);\n  debug('action in response:', parsedResponse.content);\n  return parsedResponse;\n}\n\nexport function parseAutoGLMPlanningResponse(content: string): {\n  response: ReturnType<typeof parseAutoGLMResponse>;\n  action: AutoGLMParsedAction;\n} {\n  const response = parseAutoGLMResponse(content);\n  const action = parseAutoGLMPlanningAction(response);\n  return { response, action };\n}\n"],"names":["debug","getDebug","extractValueAfter","src","key","idx","Error","rest","parseAutoGLMPlanningAction","response","trimmedResponse","text","message","actionMatch","actionType","baseAction","elementMatch","Number","startMatch","endMatch","app","durationMatch","seconds","durationMs","instruction","error","errorMessage","String","parseAutoGLMResponse","content","parsedResponse","parts","think","actionContent","parseAutoGLMPlanningResponse","action"],"mappings":"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"}