{"version":3,"file":"service/utils.mjs","sources":["../../../src/service/utils.ts"],"sourcesContent":["import {\n  AIResponseParseError,\n  extractJSONFromCodeBlock,\n} from '@/ai-model/service-caller';\nimport type { AIDescribeElementResponse } from '@/types';\nimport type { DumpMeta, PartialServiceDumpFromSDK, ServiceDump } from '@/types';\nimport { uuid } from '@midscene/shared/utils';\n\nexport function createServiceDump(\n  data: PartialServiceDumpFromSDK,\n): ServiceDump {\n  const baseData: DumpMeta = {\n    logTime: Date.now(),\n  };\n  const finalData: ServiceDump = {\n    logId: uuid(),\n    ...baseData,\n    ...data,\n  };\n\n  return finalData;\n}\n\nfunction readNextSignificantChar(input: string, startIndex: number) {\n  let index = startIndex;\n  while (index < input.length && /\\s/.test(input[index])) {\n    index += 1;\n  }\n  return input[index];\n}\n\nfunction extractPossiblyMalformedStringField(input: string, fieldName: string) {\n  const escapedFieldName = fieldName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n  const fieldStart = new RegExp(`\"${escapedFieldName}\"\\\\s*:\\\\s*\"`).exec(input);\n  if (!fieldStart) {\n    return undefined;\n  }\n\n  let index = fieldStart.index + fieldStart[0].length;\n  let escaped = false;\n  let valueForJsonParse = '';\n\n  for (; index < input.length; index += 1) {\n    const char = input[index];\n\n    if (escaped) {\n      valueForJsonParse += char;\n      escaped = false;\n      continue;\n    }\n\n    if (char === '\\\\') {\n      valueForJsonParse += char;\n      escaped = true;\n      continue;\n    }\n\n    if (char !== '\"') {\n      valueForJsonParse += char;\n      continue;\n    }\n\n    const nextSignificantChar = readNextSignificantChar(input, index + 1);\n    if (\n      nextSignificantChar === ',' ||\n      nextSignificantChar === '}' ||\n      nextSignificantChar === ']' ||\n      nextSignificantChar === undefined\n    ) {\n      try {\n        return JSON.parse(`\"${valueForJsonParse}\"`);\n      } catch {\n        return valueForJsonParse;\n      }\n    }\n\n    valueForJsonParse += '\\\\\"';\n  }\n\n  return undefined;\n}\n\nexport function recoverDescribeResponseFromParseError(\n  error: unknown,\n): Pick<AIDescribeElementResponse, 'description'> | undefined {\n  const message = error instanceof Error ? error.message : String(error);\n  const rawResponse =\n    error instanceof AIResponseParseError\n      ? error.rawResponse\n      : message.match(/Response -\\s*\\n\\s*([\\s\\S]*)$/)?.[1];\n\n  if (\n    !rawResponse ||\n    (!message.includes('failed to parse LLM response into JSON') &&\n      !(error instanceof AIResponseParseError))\n  ) {\n    return undefined;\n  }\n\n  const jsonLikeResponse = extractJSONFromCodeBlock(rawResponse);\n  const description = extractPossiblyMalformedStringField(\n    jsonLikeResponse,\n    'description',\n  )?.trim();\n\n  if (!description) {\n    return undefined;\n  }\n\n  return { description };\n}\n"],"names":["createServiceDump","data","baseData","Date","finalData","uuid","readNextSignificantChar","input","startIndex","index","extractPossiblyMalformedStringField","fieldName","escapedFieldName","fieldStart","RegExp","escaped","valueForJsonParse","char","nextSignificantChar","undefined","JSON","recoverDescribeResponseFromParseError","error","message","Error","String","rawResponse","AIResponseParseError","jsonLikeResponse","extractJSONFromCodeBlock","description"],"mappings":";;AAQO,SAASA,kBACdC,IAA+B;IAE/B,MAAMC,WAAqB;QACzB,SAASC,KAAK,GAAG;IACnB;IACA,MAAMC,YAAyB;QAC7B,OAAOC;QACP,GAAGH,QAAQ;QACX,GAAGD,IAAI;IACT;IAEA,OAAOG;AACT;AAEA,SAASE,wBAAwBC,KAAa,EAAEC,UAAkB;IAChE,IAAIC,QAAQD;IACZ,MAAOC,QAAQF,MAAM,MAAM,IAAI,KAAK,IAAI,CAACA,KAAK,CAACE,MAAM,EACnDA,SAAS;IAEX,OAAOF,KAAK,CAACE,MAAM;AACrB;AAEA,SAASC,oCAAoCH,KAAa,EAAEI,SAAiB;IAC3E,MAAMC,mBAAmBD,UAAU,OAAO,CAAC,uBAAuB;IAClE,MAAME,aAAa,IAAIC,OAAO,CAAC,CAAC,EAAEF,iBAAiB,WAAW,CAAC,EAAE,IAAI,CAACL;IACtE,IAAI,CAACM,YACH;IAGF,IAAIJ,QAAQI,WAAW,KAAK,GAAGA,UAAU,CAAC,EAAE,CAAC,MAAM;IACnD,IAAIE,UAAU;IACd,IAAIC,oBAAoB;IAExB,MAAOP,QAAQF,MAAM,MAAM,EAAEE,SAAS,EAAG;QACvC,MAAMQ,OAAOV,KAAK,CAACE,MAAM;QAEzB,IAAIM,SAAS;YACXC,qBAAqBC;YACrBF,UAAU;YACV;QACF;QAEA,IAAIE,AAAS,SAATA,MAAe;YACjBD,qBAAqBC;YACrBF,UAAU;YACV;QACF;QAEA,IAAIE,AAAS,QAATA,MAAc;YAChBD,qBAAqBC;YACrB;QACF;QAEA,MAAMC,sBAAsBZ,wBAAwBC,OAAOE,QAAQ;QACnE,IACES,AAAwB,QAAxBA,uBACAA,AAAwB,QAAxBA,uBACAA,AAAwB,QAAxBA,uBACAA,AAAwBC,WAAxBD,qBAEA,IAAI;YACF,OAAOE,KAAK,KAAK,CAAC,CAAC,CAAC,EAAEJ,kBAAkB,CAAC,CAAC;QAC5C,EAAE,OAAM;YACN,OAAOA;QACT;QAGFA,qBAAqB;IACvB;AAGF;AAEO,SAASK,sCACdC,KAAc;IAEd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAM,OAAO,GAAGG,OAAOH;IAChE,MAAMI,cACJJ,iBAAiBK,uBACbL,MAAM,WAAW,GACjBC,QAAQ,KAAK,CAAC,iCAAiC,CAAC,EAAE;IAExD,IACE,CAACG,eACA,CAACH,QAAQ,QAAQ,CAAC,6CACjB,CAAED,CAAAA,iBAAiBK,oBAAmB,GAExC;IAGF,MAAMC,mBAAmBC,yBAAyBH;IAClD,MAAMI,cAAcpB,oCAClBkB,kBACA,gBACC;IAEH,IAAI,CAACE,aACH;IAGF,OAAO;QAAEA;IAAY;AACvB"}