@midscene/core 1.10.4 → 1.10.5-beta-20260714101501.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -173,7 +173,7 @@ async function matchElementFromCache(context, cacheEntry, cachePrompt, cacheable
173
173
  return;
174
174
  }
175
175
  }
176
- const getMidsceneVersion = ()=>"1.10.4";
176
+ const getMidsceneVersion = ()=>"1.10.5-beta-20260714101501.0";
177
177
  const parsePrompt = (prompt)=>{
178
178
  if ('string' == typeof prompt) return {
179
179
  textPrompt: prompt,
@@ -26,8 +26,52 @@ function trimParsedJsonStrings(obj, context = {}) {
26
26
  if ('string' == typeof obj) return obj.trim();
27
27
  return obj;
28
28
  }
29
- function repairKnownJsonIssues(jsonBlock, _rawResponse) {
30
- return jsonBlock;
29
+ function findNextNonWhitespaceChar(text, startIndex) {
30
+ for(let index = startIndex; index < text.length; index++){
31
+ const char = text[index];
32
+ if (!/\s/.test(char)) return char;
33
+ }
34
+ }
35
+ function escapeBareQuotesInsideJsonStrings(jsonBlock) {
36
+ let repaired = '';
37
+ let inString = false;
38
+ let escaped = false;
39
+ let changed = false;
40
+ for(let index = 0; index < jsonBlock.length; index++){
41
+ const char = jsonBlock[index];
42
+ if (!inString) {
43
+ if ('"' === char) inString = true;
44
+ repaired += char;
45
+ continue;
46
+ }
47
+ if (escaped) {
48
+ repaired += char;
49
+ escaped = false;
50
+ continue;
51
+ }
52
+ if ('\\' === char) {
53
+ repaired += char;
54
+ escaped = true;
55
+ continue;
56
+ }
57
+ if ('"' === char) {
58
+ const nextNonWhitespaceChar = findNextNonWhitespaceChar(jsonBlock, index + 1);
59
+ const isStringTerminator = void 0 === nextNonWhitespaceChar || ':' === nextNonWhitespaceChar || ',' === nextNonWhitespaceChar || '}' === nextNonWhitespaceChar || ']' === nextNonWhitespaceChar;
60
+ if (isStringTerminator) {
61
+ inString = false;
62
+ repaired += char;
63
+ } else {
64
+ repaired += '\\"';
65
+ changed = true;
66
+ }
67
+ continue;
68
+ }
69
+ repaired += char;
70
+ }
71
+ return changed ? repaired : jsonBlock;
72
+ }
73
+ function repairKnownJsonIssues(jsonBlock, _rawResponse, _context) {
74
+ return escapeBareQuotesInsideJsonStrings(jsonBlock);
31
75
  }
32
76
  function assertJsonObject(parsed) {
33
77
  if (!parsed || 'object' != typeof parsed || Array.isArray(parsed)) throw new Error(`expected parsed LLM response to be a JSON object, got ${JSON.stringify(parsed)}`);
@@ -47,7 +91,7 @@ function parseModelResponseJson(raw, context) {
47
91
  parsedObj = parseJsonWithRepair(cleanJsonString);
48
92
  if (requireObject) assertJsonObject(parsedObj);
49
93
  } catch (e1) {
50
- const code = repairKnownJsonIssues(cleanJsonString, raw);
94
+ const code = repairKnownJsonIssues(cleanJsonString, raw, context);
51
95
  if (code === cleanJsonString) throw new Error(`failed to parse LLM response into JSON. Error - ${String(e1)}. Response - \n ${raw}`);
52
96
  try {
53
97
  parsedObj = parseJsonWithRepair(code);
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/service-caller/json.mjs","sources":["../../../../src/ai-model/service-caller/json.ts"],"sourcesContent":["import { jsonrepair } from 'jsonrepair';\n\n/**\n * Extract the JSON portion from a model response.\n *\n * This mainly handles fenced JSON like ```json { ... } ``` by removing the\n * fence. If that does not produce a JSON object, it falls back to a greedy regex\n * that extracts from the first \"{\" to the last \"}\". If that still fails, the\n * original response is returned.\n *\n * Expected model responses are JSON objects, possibly wrapped in markdown\n * fences. Natural language mixed with JSON, or arrays like\n * [{\"type\":\"Tap\"}, {\"type\":\"Hover\"}], are outside the supported contract and\n * are not reliably recoverable.\n *\n * This legacy extractor is also used by extraction responses that can be any\n * JSON value. In those cases, arrays/strings/numbers have no object braces and\n * pass through unchanged.\n */\nexport function extractJSONFromCodeBlock(response: string) {\n try {\n // First, try to match a JSON object directly in the response\n const jsonMatch = response.match(/^\\s*(\\{[\\s\\S]*\\})\\s*$/);\n if (jsonMatch) {\n return jsonMatch[1];\n }\n\n // If no direct JSON object is found, try to extract JSON from a code block\n const codeBlockMatch = response.match(\n /```(?:json)?\\s*(\\{[\\s\\S]*?\\})\\s*```/,\n );\n if (codeBlockMatch) {\n return codeBlockMatch[1];\n }\n\n // If no code block is found, try to find a JSON-like structure in the text\n const jsonLikeMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonLikeMatch) {\n return jsonLikeMatch[0];\n }\n } catch {}\n // If no JSON-like structure is found, return the original response\n return response;\n}\n\nexport type JsonParserSource =\n | 'generic-object'\n | 'planning-action-param'\n | 'locate'\n | 'section-locator';\n\nexport interface JsonParserContext {\n source: JsonParserSource;\n preserveStringValueKeys?: string[];\n requireObject?: boolean;\n}\n\nexport type JsonParser = (raw: string, context?: JsonParserContext) => unknown;\n\n/**\n * Trim whitespace in parsed JSON by normalizing:\n * 1. All object keys (e.g., \" prompt \" -> \"prompt\")\n * 2. All string values (e.g., \" Tap \" -> \"Tap\")\n * This handles LLM output that may include leading/trailing spaces.\n */\nfunction trimParsedJsonStrings(\n obj: any,\n context: Pick<JsonParserContext, 'preserveStringValueKeys'> = {},\n): any {\n // Handle null and undefined\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n // Handle arrays - recursively normalize each element\n if (Array.isArray(obj)) {\n return obj.map((item) => trimParsedJsonStrings(item, context));\n }\n\n // Handle objects\n if (typeof obj === 'object') {\n const normalized: any = {};\n\n for (const [key, value] of Object.entries(obj)) {\n // Trim the key to remove leading/trailing spaces\n const trimmedKey = key.trim();\n const preserveStringValue =\n context.preserveStringValueKeys?.includes(trimmedKey) ?? false;\n\n const normalizedValue =\n typeof value === 'string'\n ? preserveStringValue\n ? value\n : value.trim()\n : trimParsedJsonStrings(value, context);\n\n normalized[trimmedKey] = normalizedValue;\n }\n\n return normalized;\n }\n\n // Handle primitive strings\n if (typeof obj === 'string') {\n return obj.trim();\n }\n\n // Return other primitives as-is\n return obj;\n}\n\nfunction repairKnownJsonIssues(\n jsonBlock: string,\n _rawResponse: string,\n): string {\n // TODO: Add project-specific repairs that jsonrepair cannot handle.\n return jsonBlock;\n}\n\nfunction assertJsonObject(\n parsed: unknown,\n): asserts parsed is Record<string, unknown> {\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error(\n `expected parsed LLM response to be a JSON object, got ${JSON.stringify(\n parsed,\n )}`,\n );\n }\n}\n\nfunction parseJsonWithRepair(jsonStr: string) {\n try {\n return JSON.parse(jsonStr);\n } catch {\n return JSON.parse(jsonrepair(jsonStr));\n }\n}\n\nexport function parseModelResponseJson(\n raw: string,\n context?: JsonParserContext,\n) {\n const cleanJsonString = extractJSONFromCodeBlock(raw);\n const requireObject = context?.requireObject ?? true;\n\n let parsedObj: unknown;\n\n try {\n parsedObj = parseJsonWithRepair(cleanJsonString);\n if (requireObject) {\n assertJsonObject(parsedObj);\n }\n } catch (e1) {\n const code = repairKnownJsonIssues(cleanJsonString, raw);\n if (code === cleanJsonString) {\n throw new Error(\n `failed to parse LLM response into JSON. Error - ${String(\n e1,\n )}. Response - \\n ${raw}`,\n );\n }\n\n try {\n parsedObj = parseJsonWithRepair(code);\n if (requireObject) {\n assertJsonObject(parsedObj);\n }\n } catch (e2) {\n throw new Error(\n `failed to parse LLM response into JSON. First error - ${String(\n e1,\n )}. Second error - ${String(e2)}. Response - \\n ${raw}`,\n );\n }\n }\n\n return trimParsedJsonStrings(parsedObj, context);\n}\n"],"names":["extractJSONFromCodeBlock","response","jsonMatch","codeBlockMatch","jsonLikeMatch","trimParsedJsonStrings","obj","context","Array","item","normalized","key","value","Object","trimmedKey","preserveStringValue","normalizedValue","repairKnownJsonIssues","jsonBlock","_rawResponse","assertJsonObject","parsed","Error","JSON","parseJsonWithRepair","jsonStr","jsonrepair","parseModelResponseJson","raw","cleanJsonString","requireObject","parsedObj","e1","code","String","e2"],"mappings":";AAmBO,SAASA,yBAAyBC,QAAgB;IACvD,IAAI;QAEF,MAAMC,YAAYD,SAAS,KAAK,CAAC;QACjC,IAAIC,WACF,OAAOA,SAAS,CAAC,EAAE;QAIrB,MAAMC,iBAAiBF,SAAS,KAAK,CACnC;QAEF,IAAIE,gBACF,OAAOA,cAAc,CAAC,EAAE;QAI1B,MAAMC,gBAAgBH,SAAS,KAAK,CAAC;QACrC,IAAIG,eACF,OAAOA,aAAa,CAAC,EAAE;IAE3B,EAAE,OAAM,CAAC;IAET,OAAOH;AACT;AAsBA,SAASI,sBACPC,GAAQ,EACRC,UAA8D,CAAC,CAAC;IAGhE,IAAID,QAAAA,KACF,OAAOA;IAIT,IAAIE,MAAM,OAAO,CAACF,MAChB,OAAOA,IAAI,GAAG,CAAC,CAACG,OAASJ,sBAAsBI,MAAMF;IAIvD,IAAI,AAAe,YAAf,OAAOD,KAAkB;QAC3B,MAAMI,aAAkB,CAAC;QAEzB,KAAK,MAAM,CAACC,KAAKC,MAAM,IAAIC,OAAO,OAAO,CAACP,KAAM;YAE9C,MAAMQ,aAAaH,IAAI,IAAI;YAC3B,MAAMI,sBACJR,QAAQ,uBAAuB,EAAE,SAASO,eAAe;YAE3D,MAAME,kBACJ,AAAiB,YAAjB,OAAOJ,QACHG,sBACEH,QACAA,MAAM,IAAI,KACZP,sBAAsBO,OAAOL;YAEnCG,UAAU,CAACI,WAAW,GAAGE;QAC3B;QAEA,OAAON;IACT;IAGA,IAAI,AAAe,YAAf,OAAOJ,KACT,OAAOA,IAAI,IAAI;IAIjB,OAAOA;AACT;AAEA,SAASW,sBACPC,SAAiB,EACjBC,YAAoB;IAGpB,OAAOD;AACT;AAEA,SAASE,iBACPC,MAAe;IAEf,IAAI,CAACA,UAAU,AAAkB,YAAlB,OAAOA,UAAuBb,MAAM,OAAO,CAACa,SACzD,MAAM,IAAIC,MACR,CAAC,sDAAsD,EAAEC,KAAK,SAAS,CACrEF,SACC;AAGT;AAEA,SAASG,oBAAoBC,OAAe;IAC1C,IAAI;QACF,OAAOF,KAAK,KAAK,CAACE;IACpB,EAAE,OAAM;QACN,OAAOF,KAAK,KAAK,CAACG,WAAWD;IAC/B;AACF;AAEO,SAASE,uBACdC,GAAW,EACXrB,OAA2B;IAE3B,MAAMsB,kBAAkB7B,yBAAyB4B;IACjD,MAAME,gBAAgBvB,SAAS,iBAAiB;IAEhD,IAAIwB;IAEJ,IAAI;QACFA,YAAYP,oBAAoBK;QAChC,IAAIC,eACFV,iBAAiBW;IAErB,EAAE,OAAOC,IAAI;QACX,MAAMC,OAAOhB,sBAAsBY,iBAAiBD;QACpD,IAAIK,SAASJ,iBACX,MAAM,IAAIP,MACR,CAAC,gDAAgD,EAAEY,OACjDF,IACA,gBAAgB,EAAEJ,KAAK;QAI7B,IAAI;YACFG,YAAYP,oBAAoBS;YAChC,IAAIH,eACFV,iBAAiBW;QAErB,EAAE,OAAOI,IAAI;YACX,MAAM,IAAIb,MACR,CAAC,sDAAsD,EAAEY,OACvDF,IACA,iBAAiB,EAAEE,OAAOC,IAAI,gBAAgB,EAAEP,KAAK;QAE3D;IACF;IAEA,OAAOvB,sBAAsB0B,WAAWxB;AAC1C"}
1
+ {"version":3,"file":"ai-model/service-caller/json.mjs","sources":["../../../../src/ai-model/service-caller/json.ts"],"sourcesContent":["import { jsonrepair } from 'jsonrepair';\n\n/**\n * Extract the JSON portion from a model response.\n *\n * This mainly handles fenced JSON like ```json { ... } ``` by removing the\n * fence. If that does not produce a JSON object, it falls back to a greedy regex\n * that extracts from the first \"{\" to the last \"}\". If that still fails, the\n * original response is returned.\n *\n * Expected model responses are JSON objects, possibly wrapped in markdown\n * fences. Natural language mixed with JSON, or arrays like\n * [{\"type\":\"Tap\"}, {\"type\":\"Hover\"}], are outside the supported contract and\n * are not reliably recoverable.\n *\n * This legacy extractor is also used by extraction responses that can be any\n * JSON value. In those cases, arrays/strings/numbers have no object braces and\n * pass through unchanged.\n */\nexport function extractJSONFromCodeBlock(response: string) {\n try {\n // First, try to match a JSON object directly in the response\n const jsonMatch = response.match(/^\\s*(\\{[\\s\\S]*\\})\\s*$/);\n if (jsonMatch) {\n return jsonMatch[1];\n }\n\n // If no direct JSON object is found, try to extract JSON from a code block\n const codeBlockMatch = response.match(\n /```(?:json)?\\s*(\\{[\\s\\S]*?\\})\\s*```/,\n );\n if (codeBlockMatch) {\n return codeBlockMatch[1];\n }\n\n // If no code block is found, try to find a JSON-like structure in the text\n const jsonLikeMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonLikeMatch) {\n return jsonLikeMatch[0];\n }\n } catch {}\n // If no JSON-like structure is found, return the original response\n return response;\n}\n\nexport type JsonParserSource =\n | 'generic-object'\n | 'planning-action-param'\n | 'locate'\n | 'section-locator';\n\nexport interface JsonParserContext {\n source: JsonParserSource;\n preserveStringValueKeys?: string[];\n requireObject?: boolean;\n}\n\nexport type JsonParser = (raw: string, context?: JsonParserContext) => unknown;\n\n/**\n * Trim whitespace in parsed JSON by normalizing:\n * 1. All object keys (e.g., \" prompt \" -> \"prompt\")\n * 2. All string values (e.g., \" Tap \" -> \"Tap\")\n * This handles LLM output that may include leading/trailing spaces.\n */\nfunction trimParsedJsonStrings(\n obj: any,\n context: Pick<JsonParserContext, 'preserveStringValueKeys'> = {},\n): any {\n // Handle null and undefined\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n // Handle arrays - recursively normalize each element\n if (Array.isArray(obj)) {\n return obj.map((item) => trimParsedJsonStrings(item, context));\n }\n\n // Handle objects\n if (typeof obj === 'object') {\n const normalized: any = {};\n\n for (const [key, value] of Object.entries(obj)) {\n // Trim the key to remove leading/trailing spaces\n const trimmedKey = key.trim();\n const preserveStringValue =\n context.preserveStringValueKeys?.includes(trimmedKey) ?? false;\n\n const normalizedValue =\n typeof value === 'string'\n ? preserveStringValue\n ? value\n : value.trim()\n : trimParsedJsonStrings(value, context);\n\n normalized[trimmedKey] = normalizedValue;\n }\n\n return normalized;\n }\n\n // Handle primitive strings\n if (typeof obj === 'string') {\n return obj.trim();\n }\n\n // Return other primitives as-is\n return obj;\n}\n\nfunction findNextNonWhitespaceChar(text: string, startIndex: number) {\n for (let index = startIndex; index < text.length; index++) {\n const char = text[index];\n if (!/\\s/.test(char)) {\n return char;\n }\n }\n return undefined;\n}\n\nfunction escapeBareQuotesInsideJsonStrings(jsonBlock: string) {\n let repaired = '';\n let inString = false;\n let escaped = false;\n let changed = false;\n\n for (let index = 0; index < jsonBlock.length; index++) {\n const char = jsonBlock[index];\n\n if (!inString) {\n if (char === '\"') {\n inString = true;\n }\n repaired += char;\n continue;\n }\n\n if (escaped) {\n repaired += char;\n escaped = false;\n continue;\n }\n\n if (char === '\\\\') {\n repaired += char;\n escaped = true;\n continue;\n }\n\n if (char === '\"') {\n const nextNonWhitespaceChar = findNextNonWhitespaceChar(\n jsonBlock,\n index + 1,\n );\n const isStringTerminator =\n nextNonWhitespaceChar === undefined ||\n nextNonWhitespaceChar === ':' ||\n nextNonWhitespaceChar === ',' ||\n nextNonWhitespaceChar === '}' ||\n nextNonWhitespaceChar === ']';\n\n if (isStringTerminator) {\n inString = false;\n repaired += char;\n } else {\n repaired += '\\\\\"';\n changed = true;\n }\n continue;\n }\n\n repaired += char;\n }\n\n return changed ? repaired : jsonBlock;\n}\n\nfunction repairKnownJsonIssues(\n jsonBlock: string,\n _rawResponse: string,\n _context?: JsonParserContext,\n): string {\n return escapeBareQuotesInsideJsonStrings(jsonBlock);\n}\n\nfunction assertJsonObject(\n parsed: unknown,\n): asserts parsed is Record<string, unknown> {\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error(\n `expected parsed LLM response to be a JSON object, got ${JSON.stringify(\n parsed,\n )}`,\n );\n }\n}\n\nfunction parseJsonWithRepair(jsonStr: string) {\n try {\n return JSON.parse(jsonStr);\n } catch {\n return JSON.parse(jsonrepair(jsonStr));\n }\n}\n\nexport function parseModelResponseJson(\n raw: string,\n context?: JsonParserContext,\n) {\n const cleanJsonString = extractJSONFromCodeBlock(raw);\n const requireObject = context?.requireObject ?? true;\n\n let parsedObj: unknown;\n\n try {\n parsedObj = parseJsonWithRepair(cleanJsonString);\n if (requireObject) {\n assertJsonObject(parsedObj);\n }\n } catch (e1) {\n const code = repairKnownJsonIssues(cleanJsonString, raw, context);\n if (code === cleanJsonString) {\n throw new Error(\n `failed to parse LLM response into JSON. Error - ${String(\n e1,\n )}. Response - \\n ${raw}`,\n );\n }\n\n try {\n parsedObj = parseJsonWithRepair(code);\n if (requireObject) {\n assertJsonObject(parsedObj);\n }\n } catch (e2) {\n throw new Error(\n `failed to parse LLM response into JSON. First error - ${String(\n e1,\n )}. Second error - ${String(e2)}. Response - \\n ${raw}`,\n );\n }\n }\n\n return trimParsedJsonStrings(parsedObj, context);\n}\n"],"names":["extractJSONFromCodeBlock","response","jsonMatch","codeBlockMatch","jsonLikeMatch","trimParsedJsonStrings","obj","context","Array","item","normalized","key","value","Object","trimmedKey","preserveStringValue","normalizedValue","findNextNonWhitespaceChar","text","startIndex","index","char","escapeBareQuotesInsideJsonStrings","jsonBlock","repaired","inString","escaped","changed","nextNonWhitespaceChar","isStringTerminator","undefined","repairKnownJsonIssues","_rawResponse","_context","assertJsonObject","parsed","Error","JSON","parseJsonWithRepair","jsonStr","jsonrepair","parseModelResponseJson","raw","cleanJsonString","requireObject","parsedObj","e1","code","String","e2"],"mappings":"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"}