@midscene/core 1.10.1-beta-20260702031518.0 → 1.10.1

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.1-beta-20260702031518.0";
176
+ const getMidsceneVersion = ()=>"1.10.1";
177
177
  const parsePrompt = (prompt)=>{
178
178
  if ('string' == typeof prompt) return {
179
179
  textPrompt: prompt,
@@ -1,7 +1,34 @@
1
+ import { getDebug } from "@midscene/shared/logger";
1
2
  const MAX_ERROR_RESPONSE_BODY_LENGTH = 4000;
3
+ const MAX_FETCH_ERROR_LENGTH = 4000;
4
+ const debugOpenAIFetch = getDebug('ai:call');
5
+ function truncateText(text, maxLength) {
6
+ if (text.length <= maxLength) return text;
7
+ return `${text.slice(0, maxLength)}... [truncated, ${text.length} chars total]`;
8
+ }
2
9
  function truncateErrorResponseBody(body) {
3
- if (body.length <= MAX_ERROR_RESPONSE_BODY_LENGTH) return body;
4
- return `${body.slice(0, MAX_ERROR_RESPONSE_BODY_LENGTH)}... [truncated, ${body.length} chars total]`;
10
+ return truncateText(body, MAX_ERROR_RESPONSE_BODY_LENGTH);
11
+ }
12
+ function getErrorCode(error) {
13
+ if (!error || 'object' != typeof error) return;
14
+ const code = error.code;
15
+ return 'string' == typeof code ? code : void 0;
16
+ }
17
+ function formatErrorSummary(error) {
18
+ if (error instanceof Error) {
19
+ const code = getErrorCode(error);
20
+ const codeText = code ? ` [${code}]` : '';
21
+ return `${error.name}${codeText}: ${error.message}`;
22
+ }
23
+ return String(error);
24
+ }
25
+ function formatFetchErrorForReport(error) {
26
+ const details = [
27
+ formatErrorSummary(error)
28
+ ];
29
+ const cause = error && 'object' == typeof error ? error.cause : void 0;
30
+ if (void 0 !== cause) details.push(`Cause: ${formatErrorSummary(cause)}`);
31
+ return truncateText(details.join('\n'), MAX_FETCH_ERROR_LENGTH);
5
32
  }
6
33
  function getDefaultFetch() {
7
34
  if ('function' == typeof globalThis.fetch) return globalThis.fetch;
@@ -12,7 +39,19 @@ function wrapOpenAICompatibleFetch(context) {
12
39
  let attempt = 0;
13
40
  return async (input, init)=>{
14
41
  attempt += 1;
15
- const response = await baseFetch(input, init);
42
+ let response;
43
+ try {
44
+ response = await baseFetch(input, init);
45
+ } catch (error) {
46
+ const fetchErrorSummary = formatFetchErrorForReport(error);
47
+ debugOpenAIFetch('OpenAI-compatible fetch failed', fetchErrorSummary);
48
+ context.fetchErrors ??= [];
49
+ context.fetchErrors.push({
50
+ attempt,
51
+ error: fetchErrorSummary
52
+ });
53
+ throw error;
54
+ }
16
55
  if (!response.ok) {
17
56
  const rawResponseBody = await response.clone().text().catch(()=>void 0);
18
57
  if (void 0 !== rawResponseBody) {
@@ -27,10 +66,19 @@ function wrapOpenAICompatibleFetch(context) {
27
66
  };
28
67
  }
29
68
  function formatOpenAIAPIErrorDetails(_error, context) {
30
- if (!context.rawResponseBodies?.length) return '';
31
- if (1 === context.rawResponseBodies.length) return `\nOpenAI raw error response body: ${truncateErrorResponseBody(context.rawResponseBodies[0].body)}`;
32
- const details = context.rawResponseBodies.map(({ attempt, body })=>`Attempt ${attempt}: ${truncateErrorResponseBody(body)}`).join('\n');
33
- return `\nOpenAI raw error response bodies:\n${details}`;
69
+ const details = [];
70
+ if (context.rawResponseBodies?.length === 1) details.push(`OpenAI raw error response body: ${truncateErrorResponseBody(context.rawResponseBodies[0].body)}`);
71
+ else if (context.rawResponseBodies?.length) {
72
+ const rawResponseBodyDetails = context.rawResponseBodies.map(({ attempt, body })=>`Attempt ${attempt}: ${truncateErrorResponseBody(body)}`).join('\n');
73
+ details.push(`OpenAI raw error response bodies:\n${rawResponseBodyDetails}`);
74
+ }
75
+ if (context.fetchErrors?.length === 1) details.push(`OpenAI fetch error (attempt ${context.fetchErrors[0].attempt}): ${context.fetchErrors[0].error}`);
76
+ else if (context.fetchErrors?.length) {
77
+ const fetchErrorDetails = context.fetchErrors.map(({ attempt, error })=>`Attempt ${attempt}: ${error}`).join('\n');
78
+ details.push(`OpenAI fetch errors:\n${fetchErrorDetails}`);
79
+ }
80
+ if (!details.length) return '';
81
+ return `\n${details.join('\n')}`;
34
82
  }
35
83
  export { formatOpenAIAPIErrorDetails, wrapOpenAICompatibleFetch };
36
84
 
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/service-caller/openai-error.mjs","sources":["../../../../src/ai-model/service-caller/openai-error.ts"],"sourcesContent":["const MAX_ERROR_RESPONSE_BODY_LENGTH = 4000;\n\nexport interface OpenAIErrorResponseContext {\n rawResponseBodies?: Array<{\n attempt: number;\n body: string;\n }>;\n}\n\nfunction truncateErrorResponseBody(body: string): string {\n if (body.length <= MAX_ERROR_RESPONSE_BODY_LENGTH) {\n return body;\n }\n\n return `${body.slice(0, MAX_ERROR_RESPONSE_BODY_LENGTH)}... [truncated, ${body.length} chars total]`;\n}\n\n// Mirrors OpenAI SDK's default fetch selection:\n// openai@6.3.0 src/client.ts sets `this.fetch = options.fetch ?? Shims.getDefaultFetch()`,\n// and src/internal/shims.ts resolves that default to global `fetch`.\nfunction getDefaultFetch(): typeof fetch {\n if (typeof globalThis.fetch === 'function') {\n return globalThis.fetch;\n }\n\n throw new Error(\n '`fetch` is not defined as a global; check that the runtime provides globalThis.fetch or polyfill it before creating the OpenAI client',\n );\n}\n\nexport function wrapOpenAICompatibleFetch(\n context: OpenAIErrorResponseContext,\n): typeof fetch {\n const baseFetch = getDefaultFetch();\n let attempt = 0;\n\n return async (input, init) => {\n attempt += 1;\n const response = await baseFetch(input, init);\n\n if (!response.ok) {\n // OpenAI SDK only exposes the `error` field for JSON error responses.\n // Non-standard provider bodies like `{ err: 'xxx' }` would otherwise be\n // hidden from Midscene's final error message.\n const rawResponseBody = await response\n .clone()\n .text()\n .catch(() => undefined);\n\n if (rawResponseBody !== undefined) {\n context.rawResponseBodies ??= [];\n context.rawResponseBodies.push({\n attempt,\n body: rawResponseBody,\n });\n }\n }\n\n return response;\n };\n}\n\nexport function formatOpenAIAPIErrorDetails(\n _error: unknown,\n context: OpenAIErrorResponseContext,\n): string {\n if (!context.rawResponseBodies?.length) {\n return '';\n }\n\n if (context.rawResponseBodies.length === 1) {\n return `\\nOpenAI raw error response body: ${truncateErrorResponseBody(\n context.rawResponseBodies[0].body,\n )}`;\n }\n\n const details = context.rawResponseBodies\n .map(\n ({ attempt, body }) =>\n `Attempt ${attempt}: ${truncateErrorResponseBody(body)}`,\n )\n .join('\\n');\n\n return `\\nOpenAI raw error response bodies:\\n${details}`;\n}\n"],"names":["MAX_ERROR_RESPONSE_BODY_LENGTH","truncateErrorResponseBody","body","getDefaultFetch","globalThis","Error","wrapOpenAICompatibleFetch","context","baseFetch","attempt","input","init","response","rawResponseBody","undefined","formatOpenAIAPIErrorDetails","_error","details"],"mappings":"AAAA,MAAMA,iCAAiC;AASvC,SAASC,0BAA0BC,IAAY;IAC7C,IAAIA,KAAK,MAAM,IAAIF,gCACjB,OAAOE;IAGT,OAAO,GAAGA,KAAK,KAAK,CAAC,GAAGF,gCAAgC,gBAAgB,EAAEE,KAAK,MAAM,CAAC,aAAa,CAAC;AACtG;AAKA,SAASC;IACP,IAAI,AAA4B,cAA5B,OAAOC,WAAW,KAAK,EACzB,OAAOA,WAAW,KAAK;IAGzB,MAAM,IAAIC,MACR;AAEJ;AAEO,SAASC,0BACdC,OAAmC;IAEnC,MAAMC,YAAYL;IAClB,IAAIM,UAAU;IAEd,OAAO,OAAOC,OAAOC;QACnBF,WAAW;QACX,MAAMG,WAAW,MAAMJ,UAAUE,OAAOC;QAExC,IAAI,CAACC,SAAS,EAAE,EAAE;YAIhB,MAAMC,kBAAkB,MAAMD,SAC3B,KAAK,GACL,IAAI,GACJ,KAAK,CAAC,IAAME;YAEf,IAAID,AAAoBC,WAApBD,iBAA+B;gBACjCN,QAAQ,iBAAiB,KAAK,EAAE;gBAChCA,QAAQ,iBAAiB,CAAC,IAAI,CAAC;oBAC7BE;oBACA,MAAMI;gBACR;YACF;QACF;QAEA,OAAOD;IACT;AACF;AAEO,SAASG,4BACdC,MAAe,EACfT,OAAmC;IAEnC,IAAI,CAACA,QAAQ,iBAAiB,EAAE,QAC9B,OAAO;IAGT,IAAIA,AAAqC,MAArCA,QAAQ,iBAAiB,CAAC,MAAM,EAClC,OAAO,CAAC,kCAAkC,EAAEN,0BAC1CM,QAAQ,iBAAiB,CAAC,EAAE,CAAC,IAAI,GAChC;IAGL,MAAMU,UAAUV,QAAQ,iBAAiB,CACtC,GAAG,CACF,CAAC,EAAEE,OAAO,EAAEP,IAAI,EAAE,GAChB,CAAC,QAAQ,EAAEO,QAAQ,EAAE,EAAER,0BAA0BC,OAAO,EAE3D,IAAI,CAAC;IAER,OAAO,CAAC,qCAAqC,EAAEe,SAAS;AAC1D"}
1
+ {"version":3,"file":"ai-model/service-caller/openai-error.mjs","sources":["../../../../src/ai-model/service-caller/openai-error.ts"],"sourcesContent":["import { getDebug } from '@midscene/shared/logger';\n\nconst MAX_ERROR_RESPONSE_BODY_LENGTH = 4000;\nconst MAX_FETCH_ERROR_LENGTH = 4000;\n\nconst debugOpenAIFetch = getDebug('ai:call');\n\nexport interface OpenAIErrorResponseContext {\n rawResponseBodies?: Array<{\n attempt: number;\n body: string;\n }>;\n fetchErrors?: Array<{\n attempt: number;\n error: string;\n }>;\n}\n\nfunction truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) {\n return text;\n }\n\n return `${text.slice(0, maxLength)}... [truncated, ${text.length} chars total]`;\n}\n\nfunction truncateErrorResponseBody(body: string): string {\n return truncateText(body, MAX_ERROR_RESPONSE_BODY_LENGTH);\n}\n\nfunction getErrorCode(error: unknown): string | undefined {\n if (!error || typeof error !== 'object') {\n return undefined;\n }\n\n const code = (error as { code?: unknown }).code;\n return typeof code === 'string' ? code : undefined;\n}\n\nfunction formatErrorSummary(error: unknown): string {\n if (error instanceof Error) {\n const code = getErrorCode(error);\n const codeText = code ? ` [${code}]` : '';\n return `${error.name}${codeText}: ${error.message}`;\n }\n\n return String(error);\n}\n\nfunction formatFetchErrorForReport(error: unknown): string {\n const details = [formatErrorSummary(error)];\n const cause =\n error && typeof error === 'object'\n ? (error as { cause?: unknown }).cause\n : undefined;\n\n if (cause !== undefined) {\n details.push(`Cause: ${formatErrorSummary(cause)}`);\n }\n\n return truncateText(details.join('\\n'), MAX_FETCH_ERROR_LENGTH);\n}\n\n// Mirrors OpenAI SDK's default fetch selection:\n// openai@6.3.0 src/client.ts sets `this.fetch = options.fetch ?? Shims.getDefaultFetch()`,\n// and src/internal/shims.ts resolves that default to global `fetch`.\nfunction getDefaultFetch(): typeof fetch {\n if (typeof globalThis.fetch === 'function') {\n return globalThis.fetch;\n }\n\n throw new Error(\n '`fetch` is not defined as a global; check that the runtime provides globalThis.fetch or polyfill it before creating the OpenAI client',\n );\n}\n\nexport function wrapOpenAICompatibleFetch(\n context: OpenAIErrorResponseContext,\n): typeof fetch {\n const baseFetch = getDefaultFetch();\n let attempt = 0;\n\n return async (input, init) => {\n attempt += 1;\n let response: Response;\n try {\n response = await baseFetch(input, init);\n } catch (error) {\n const fetchErrorSummary = formatFetchErrorForReport(error);\n debugOpenAIFetch('OpenAI-compatible fetch failed', fetchErrorSummary);\n context.fetchErrors ??= [];\n context.fetchErrors.push({\n attempt,\n error: fetchErrorSummary,\n });\n throw error;\n }\n\n if (!response.ok) {\n // OpenAI SDK only exposes the `error` field for JSON error responses.\n // Non-standard provider bodies like `{ err: 'xxx' }` would otherwise be\n // hidden from Midscene's final error message.\n const rawResponseBody = await response\n .clone()\n .text()\n .catch(() => undefined);\n\n if (rawResponseBody !== undefined) {\n context.rawResponseBodies ??= [];\n context.rawResponseBodies.push({\n attempt,\n body: rawResponseBody,\n });\n }\n }\n\n return response;\n };\n}\n\nexport function formatOpenAIAPIErrorDetails(\n _error: unknown,\n context: OpenAIErrorResponseContext,\n): string {\n const details: string[] = [];\n\n if (context.rawResponseBodies?.length === 1) {\n details.push(\n `OpenAI raw error response body: ${truncateErrorResponseBody(\n context.rawResponseBodies[0].body,\n )}`,\n );\n } else if (context.rawResponseBodies?.length) {\n const rawResponseBodyDetails = context.rawResponseBodies\n .map(\n ({ attempt, body }) =>\n `Attempt ${attempt}: ${truncateErrorResponseBody(body)}`,\n )\n .join('\\n');\n\n details.push(\n `OpenAI raw error response bodies:\\n${rawResponseBodyDetails}`,\n );\n }\n\n if (context.fetchErrors?.length === 1) {\n details.push(\n `OpenAI fetch error (attempt ${context.fetchErrors[0].attempt}): ${context.fetchErrors[0].error}`,\n );\n } else if (context.fetchErrors?.length) {\n const fetchErrorDetails = context.fetchErrors\n .map(({ attempt, error }) => `Attempt ${attempt}: ${error}`)\n .join('\\n');\n\n details.push(`OpenAI fetch errors:\\n${fetchErrorDetails}`);\n }\n\n if (!details.length) {\n return '';\n }\n\n return `\\n${details.join('\\n')}`;\n}\n"],"names":["MAX_ERROR_RESPONSE_BODY_LENGTH","MAX_FETCH_ERROR_LENGTH","debugOpenAIFetch","getDebug","truncateText","text","maxLength","truncateErrorResponseBody","body","getErrorCode","error","code","undefined","formatErrorSummary","Error","codeText","String","formatFetchErrorForReport","details","cause","getDefaultFetch","globalThis","wrapOpenAICompatibleFetch","context","baseFetch","attempt","input","init","response","fetchErrorSummary","rawResponseBody","formatOpenAIAPIErrorDetails","_error","rawResponseBodyDetails","fetchErrorDetails"],"mappings":"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"}