@midscene/core 1.12.9 → 1.12.10-beta-20260918061340.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.
- package/dist/es/agent/task-builder.mjs +1 -1
- package/dist/es/agent/task-builder.mjs.map +1 -1
- package/dist/es/agent/tasks.mjs +4 -4
- package/dist/es/agent/tasks.mjs.map +1 -1
- package/dist/es/agent/utils.mjs +1 -1
- package/dist/es/ai-model/model-adapter/chat-completion.mjs +8 -11
- package/dist/es/ai-model/model-adapter/chat-completion.mjs.map +1 -1
- package/dist/es/ai-model/model-adapter/resolve.mjs +10 -0
- package/dist/es/ai-model/model-adapter/resolve.mjs.map +1 -1
- package/dist/es/ai-model/model-adapter/responses.mjs +37 -0
- package/dist/es/ai-model/model-adapter/responses.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/temperature-with-semantic-retry.mjs +7 -0
- package/dist/es/ai-model/model-adapter/temperature-with-semantic-retry.mjs.map +1 -0
- package/dist/es/ai-model/models/gpt.mjs +68 -8
- package/dist/es/ai-model/models/gpt.mjs.map +1 -1
- package/dist/es/ai-model/models/registry.mjs +2 -2
- package/dist/es/ai-model/models/registry.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/call-ai.mjs +22 -13
- package/dist/es/ai-model/service-caller/call-ai.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/codex/call-codex.mjs +5 -1
- package/dist/es/ai-model/service-caller/codex/call-codex.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/index.mjs +1 -2
- package/dist/es/ai-model/service-caller/model-call.mjs +4 -4
- package/dist/es/ai-model/service-caller/model-call.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/openai/call-openai.mjs +13 -8
- package/dist/es/ai-model/service-caller/openai/call-openai.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/openai/chat-completion/chat-completion.mjs +12 -6
- package/dist/es/ai-model/service-caller/openai/chat-completion/chat-completion.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/openai/chat-completion/non-stream.mjs +9 -9
- package/dist/es/ai-model/service-caller/openai/chat-completion/non-stream.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/openai/chat-completion/stream.mjs +4 -8
- package/dist/es/ai-model/service-caller/openai/chat-completion/stream.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/openai/openai-client.mjs +3 -3
- package/dist/es/ai-model/service-caller/openai/openai-client.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/openai/responses/non-stream.mjs +21 -0
- package/dist/es/ai-model/service-caller/openai/responses/non-stream.mjs.map +1 -0
- package/dist/es/ai-model/service-caller/openai/responses/responses.mjs +60 -0
- package/dist/es/ai-model/service-caller/openai/responses/responses.mjs.map +1 -0
- package/dist/es/ai-model/service-caller/openai/responses/stream.mjs +56 -0
- package/dist/es/ai-model/service-caller/openai/responses/stream.mjs.map +1 -0
- package/dist/es/ai-model/service-caller/openai/responses/types.mjs +0 -0
- package/dist/es/ai-model/service-caller/openai/responses/utils.mjs +60 -0
- package/dist/es/ai-model/service-caller/openai/responses/utils.mjs.map +1 -0
- package/dist/es/ai-model/service-caller/utils.mjs +5 -4
- package/dist/es/ai-model/service-caller/utils.mjs.map +1 -1
- package/dist/es/ai-model/workflows/grounding/locate.mjs +6 -6
- package/dist/es/ai-model/workflows/grounding/locate.mjs.map +1 -1
- package/dist/es/ai-model/workflows/grounding/planning-action-locate.mjs +5 -5
- package/dist/es/ai-model/workflows/grounding/planning-action-locate.mjs.map +1 -1
- package/dist/es/ai-model/workflows/grounding/section-locate.mjs +5 -5
- package/dist/es/ai-model/workflows/grounding/section-locate.mjs.map +1 -1
- package/dist/es/ai-model/workflows/insight/extraction.mjs +3 -3
- package/dist/es/ai-model/workflows/insight/extraction.mjs.map +1 -1
- package/dist/es/ai-model/workflows/planning/custom-planning.mjs +3 -3
- package/dist/es/ai-model/workflows/planning/custom-planning.mjs.map +1 -1
- package/dist/es/ai-model/workflows/planning/standard-planning.mjs +4 -4
- package/dist/es/ai-model/workflows/planning/standard-planning.mjs.map +1 -1
- package/dist/es/report-html-template.mjs +1 -1
- package/dist/es/service/index.mjs +11 -11
- package/dist/es/service/index.mjs.map +1 -1
- package/dist/es/types.mjs.map +1 -1
- package/dist/es/utils.mjs +1 -1
- package/dist/lib/agent/task-builder.js +1 -1
- package/dist/lib/agent/task-builder.js.map +1 -1
- package/dist/lib/agent/tasks.js +4 -4
- package/dist/lib/agent/tasks.js.map +1 -1
- package/dist/lib/agent/utils.js +1 -1
- package/dist/lib/ai-model/model-adapter/chat-completion.js +8 -11
- package/dist/lib/ai-model/model-adapter/chat-completion.js.map +1 -1
- package/dist/lib/ai-model/model-adapter/resolve.js +10 -0
- package/dist/lib/ai-model/model-adapter/resolve.js.map +1 -1
- package/dist/lib/ai-model/model-adapter/responses.js +74 -0
- package/dist/lib/ai-model/model-adapter/responses.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/temperature-with-semantic-retry.js +41 -0
- package/dist/lib/ai-model/model-adapter/temperature-with-semantic-retry.js.map +1 -0
- package/dist/lib/ai-model/models/gpt.js +68 -8
- package/dist/lib/ai-model/models/gpt.js.map +1 -1
- package/dist/lib/ai-model/models/registry.js +2 -2
- package/dist/lib/ai-model/models/registry.js.map +1 -1
- package/dist/lib/ai-model/service-caller/call-ai.js +22 -13
- package/dist/lib/ai-model/service-caller/call-ai.js.map +1 -1
- package/dist/lib/ai-model/service-caller/codex/call-codex.js +5 -1
- package/dist/lib/ai-model/service-caller/codex/call-codex.js.map +1 -1
- package/dist/lib/ai-model/service-caller/index.js +0 -4
- package/dist/lib/ai-model/service-caller/model-call.js +4 -4
- package/dist/lib/ai-model/service-caller/model-call.js.map +1 -1
- package/dist/lib/ai-model/service-caller/openai/call-openai.js +12 -7
- package/dist/lib/ai-model/service-caller/openai/call-openai.js.map +1 -1
- package/dist/lib/ai-model/service-caller/openai/chat-completion/chat-completion.js +12 -6
- package/dist/lib/ai-model/service-caller/openai/chat-completion/chat-completion.js.map +1 -1
- package/dist/lib/ai-model/service-caller/openai/chat-completion/non-stream.js +9 -9
- package/dist/lib/ai-model/service-caller/openai/chat-completion/non-stream.js.map +1 -1
- package/dist/lib/ai-model/service-caller/openai/chat-completion/stream.js +4 -8
- package/dist/lib/ai-model/service-caller/openai/chat-completion/stream.js.map +1 -1
- package/dist/lib/ai-model/service-caller/openai/openai-client.js +5 -5
- package/dist/lib/ai-model/service-caller/openai/openai-client.js.map +1 -1
- package/dist/lib/ai-model/service-caller/openai/responses/non-stream.js +55 -0
- package/dist/lib/ai-model/service-caller/openai/responses/non-stream.js.map +1 -0
- package/dist/lib/ai-model/service-caller/openai/responses/responses.js +97 -0
- package/dist/lib/ai-model/service-caller/openai/responses/responses.js.map +1 -0
- package/dist/lib/ai-model/service-caller/openai/responses/stream.js +90 -0
- package/dist/lib/ai-model/service-caller/openai/responses/stream.js.map +1 -0
- package/dist/lib/ai-model/service-caller/openai/responses/types.js +20 -0
- package/dist/lib/ai-model/service-caller/openai/responses/types.js.map +1 -0
- package/dist/lib/ai-model/service-caller/openai/responses/utils.js +100 -0
- package/dist/lib/ai-model/service-caller/openai/responses/utils.js.map +1 -0
- package/dist/lib/ai-model/service-caller/utils.js +5 -4
- package/dist/lib/ai-model/service-caller/utils.js.map +1 -1
- package/dist/lib/ai-model/workflows/grounding/locate.js +6 -6
- package/dist/lib/ai-model/workflows/grounding/locate.js.map +1 -1
- package/dist/lib/ai-model/workflows/grounding/planning-action-locate.js +5 -5
- package/dist/lib/ai-model/workflows/grounding/planning-action-locate.js.map +1 -1
- package/dist/lib/ai-model/workflows/grounding/section-locate.js +5 -5
- package/dist/lib/ai-model/workflows/grounding/section-locate.js.map +1 -1
- package/dist/lib/ai-model/workflows/insight/extraction.js +3 -3
- package/dist/lib/ai-model/workflows/insight/extraction.js.map +1 -1
- package/dist/lib/ai-model/workflows/planning/custom-planning.js +3 -3
- package/dist/lib/ai-model/workflows/planning/custom-planning.js.map +1 -1
- package/dist/lib/ai-model/workflows/planning/standard-planning.js +4 -4
- package/dist/lib/ai-model/workflows/planning/standard-planning.js.map +1 -1
- package/dist/lib/report-html-template.js +1 -1
- package/dist/lib/service/index.js +11 -11
- package/dist/lib/service/index.js.map +1 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/utils.js +1 -1
- package/dist/types/ai-model/model-adapter/resolve.d.ts +4 -1
- package/dist/types/ai-model/model-adapter/responses.d.ts +3 -0
- package/dist/types/ai-model/model-adapter/temperature-with-semantic-retry.d.ts +5 -0
- package/dist/types/ai-model/model-adapter/types.d.ts +38 -13
- package/dist/types/ai-model/models/gpt.d.ts +13 -3
- package/dist/types/ai-model/models/registry.d.ts +12 -2
- package/dist/types/ai-model/service-caller/index.d.ts +0 -1
- package/dist/types/ai-model/service-caller/model-call.d.ts +3 -2
- package/dist/types/ai-model/service-caller/openai/call-openai.d.ts +9 -1
- package/dist/types/ai-model/service-caller/openai/chat-completion/chat-completion.d.ts +3 -4
- package/dist/types/ai-model/service-caller/openai/chat-completion/non-stream.d.ts +1 -1
- package/dist/types/ai-model/service-caller/openai/chat-completion/stream.d.ts +1 -1
- package/dist/types/ai-model/service-caller/openai/chat-completion/types.d.ts +5 -5
- package/dist/types/ai-model/service-caller/openai/openai-client.d.ts +2 -2
- package/dist/types/ai-model/service-caller/openai/responses/non-stream.d.ts +3 -0
- package/dist/types/ai-model/service-caller/openai/responses/responses.d.ts +7 -0
- package/dist/types/ai-model/service-caller/openai/responses/stream.d.ts +3 -0
- package/dist/types/ai-model/service-caller/openai/responses/types.d.ts +7 -0
- package/dist/types/ai-model/service-caller/openai/responses/utils.d.ts +7 -0
- package/dist/types/ai-model/service-caller/types.d.ts +3 -2
- package/dist/types/ai-model/service-caller/utils.d.ts +5 -3
- package/dist/types/ai-model/workflows/grounding/section-locate.d.ts +2 -1
- package/dist/types/ai-model/workflows/grounding/types.d.ts +3 -2
- package/dist/types/ai-model/workflows/insight/extraction.d.ts +1 -1
- package/dist/types/types.d.ts +11 -2
- package/package.json +2 -2
|
@@ -4,6 +4,7 @@ import { buildDefaultCodexAppServerParams } from "./codex-app-server.mjs";
|
|
|
4
4
|
import { resolveInsight } from "./insight.mjs";
|
|
5
5
|
import { resolveLocate } from "./locate.mjs";
|
|
6
6
|
import { resolveCustomPlanningDefinition, resolvePlanning } from "./planning.mjs";
|
|
7
|
+
import { resolveResponses } from "./responses.mjs";
|
|
7
8
|
function _define_property(obj, key, value) {
|
|
8
9
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
9
10
|
value: value,
|
|
@@ -14,6 +15,7 @@ function _define_property(obj, key, value) {
|
|
|
14
15
|
else obj[key] = value;
|
|
15
16
|
return obj;
|
|
16
17
|
}
|
|
18
|
+
const defaultImageDetail = (_input)=>void 0;
|
|
17
19
|
function resolveJsonParser(jsonParser) {
|
|
18
20
|
if (!jsonParser || 'lenient-json' === jsonParser) return parseModelResponseJson;
|
|
19
21
|
if ('function' == typeof jsonParser) return jsonParser;
|
|
@@ -26,16 +28,24 @@ function resolveImagePreprocess(imagePreprocess) {
|
|
|
26
28
|
}
|
|
27
29
|
class ResolvedModelAdapter {
|
|
28
30
|
constructor(config, modelFamily){
|
|
31
|
+
_define_property(this, "supportedApiTypes", void 0);
|
|
29
32
|
_define_property(this, "jsonParser", void 0);
|
|
30
33
|
_define_property(this, "chatCompletion", void 0);
|
|
34
|
+
_define_property(this, "resolveImageDetail", void 0);
|
|
35
|
+
_define_property(this, "responses", void 0);
|
|
31
36
|
_define_property(this, "buildCodexAppServerParams", void 0);
|
|
32
37
|
_define_property(this, "acceptBbox2dAlias", void 0);
|
|
33
38
|
_define_property(this, "imagePreprocess", void 0);
|
|
34
39
|
_define_property(this, "insight", void 0);
|
|
35
40
|
_define_property(this, "planning", void 0);
|
|
36
41
|
_define_property(this, "locate", void 0);
|
|
42
|
+
this.supportedApiTypes = config.supportedApiTypes ?? [
|
|
43
|
+
'chat-completion'
|
|
44
|
+
];
|
|
37
45
|
this.jsonParser = resolveJsonParser(config.jsonParser);
|
|
38
46
|
this.chatCompletion = resolveChatCompletion(config.chatCompletion);
|
|
47
|
+
this.resolveImageDetail = config.resolveImageDetail ?? defaultImageDetail;
|
|
48
|
+
this.responses = resolveResponses(config.responses);
|
|
39
49
|
this.buildCodexAppServerParams = config.buildCodexAppServerParams ?? buildDefaultCodexAppServerParams;
|
|
40
50
|
this.acceptBbox2dAlias = config.acceptBbox2dAlias ?? false;
|
|
41
51
|
this.imagePreprocess = resolveImagePreprocess(config.imagePreprocess);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/model-adapter/resolve.mjs","sources":["../../../../src/ai-model/model-adapter/resolve.ts"],"sourcesContent":["import { parseModelResponseJson } from '../shared/json';\nimport { resolveChatCompletion } from './chat-completion';\nimport { buildDefaultCodexAppServerParams } from './codex-app-server';\nimport { resolveInsight } from './insight';\nimport type { InsightAdapter } from './insight-protocol';\nimport { resolveLocate } from './locate';\nimport { resolveCustomPlanningDefinition, resolvePlanning } from './planning';\nimport type {\n BuildCodexAppServerParams,\n ChatCompletionAdapter,\n ImagePreprocessPolicy,\n JsonParser,\n LocateAdapter,\n ModelAdapter,\n ModelAdapterDefinition,\n PlanningAdapter,\n} from './types';\n\nfunction resolveJsonParser(\n jsonParser: ModelAdapterDefinition['jsonParser'],\n): JsonParser {\n if (!jsonParser || jsonParser === 'lenient-json') {\n return parseModelResponseJson;\n }\n\n if (typeof jsonParser === 'function') {\n return jsonParser;\n }\n\n throw new Error(`Unknown json parser preset: ${jsonParser}`);\n}\n\nfunction resolveImagePreprocess(\n imagePreprocess: ModelAdapterDefinition['imagePreprocess'],\n): ImagePreprocessPolicy {\n return {\n padBlockSize: imagePreprocess?.padBlockSize,\n };\n}\n\nexport class ResolvedModelAdapter implements ModelAdapter {\n readonly jsonParser: JsonParser;\n readonly chatCompletion: ChatCompletionAdapter;\n readonly buildCodexAppServerParams: BuildCodexAppServerParams;\n readonly acceptBbox2dAlias: boolean;\n readonly imagePreprocess: ImagePreprocessPolicy;\n readonly insight: InsightAdapter;\n readonly planning: PlanningAdapter;\n readonly locate: LocateAdapter;\n\n constructor(config: ModelAdapterDefinition, modelFamily: string) {\n this.jsonParser = resolveJsonParser(config.jsonParser);\n this.chatCompletion = resolveChatCompletion(config.chatCompletion);\n this.buildCodexAppServerParams =\n config.buildCodexAppServerParams ?? buildDefaultCodexAppServerParams;\n this.acceptBbox2dAlias = config.acceptBbox2dAlias ?? false;\n this.imagePreprocess = resolveImagePreprocess(config.imagePreprocess);\n this.insight = resolveInsight(config.insight, {\n jsonParser: this.jsonParser,\n });\n const customPlanner =\n config.planning?.kind === 'custom' ? config.planning.planner : undefined;\n const resolvedCustomPlanner = customPlanner\n ? resolveCustomPlanningDefinition(customPlanner)\n : undefined;\n this.locate = resolveLocate(\n config.locate,\n resolvedCustomPlanner,\n {\n jsonParser: this.jsonParser,\n },\n this.acceptBbox2dAlias,\n );\n this.planning = resolvePlanning(\n config.planning,\n resolvedCustomPlanner,\n { jsonParser: this.jsonParser },\n this.locate.kind === 'standard'\n ? this.locate.element.resultCodec\n : undefined,\n );\n }\n}\n"],"names":["resolveJsonParser","jsonParser","parseModelResponseJson","Error","resolveImagePreprocess","imagePreprocess","ResolvedModelAdapter","config","modelFamily","resolveChatCompletion","buildDefaultCodexAppServerParams","resolveInsight","customPlanner","
|
|
1
|
+
{"version":3,"file":"ai-model/model-adapter/resolve.mjs","sources":["../../../../src/ai-model/model-adapter/resolve.ts"],"sourcesContent":["import { parseModelResponseJson } from '../shared/json';\nimport { resolveChatCompletion } from './chat-completion';\nimport { buildDefaultCodexAppServerParams } from './codex-app-server';\nimport { resolveInsight } from './insight';\nimport type { InsightAdapter } from './insight-protocol';\nimport { resolveLocate } from './locate';\nimport { resolveCustomPlanningDefinition, resolvePlanning } from './planning';\nimport { resolveResponses } from './responses';\nimport type {\n BuildCodexAppServerParams,\n ChatCompletionAdapter,\n ImagePreprocessPolicy,\n JsonParser,\n LocateAdapter,\n ModelAdapter,\n ModelAdapterDefinition,\n PlanningAdapter,\n ResolveImageDetail,\n ResponsesAdapter,\n} from './types';\n\nconst defaultImageDetail = (_input: unknown) => undefined;\n\nfunction resolveJsonParser(\n jsonParser: ModelAdapterDefinition['jsonParser'],\n): JsonParser {\n if (!jsonParser || jsonParser === 'lenient-json') {\n return parseModelResponseJson;\n }\n\n if (typeof jsonParser === 'function') {\n return jsonParser;\n }\n\n throw new Error(`Unknown json parser preset: ${jsonParser}`);\n}\n\nfunction resolveImagePreprocess(\n imagePreprocess: ModelAdapterDefinition['imagePreprocess'],\n): ImagePreprocessPolicy {\n return {\n padBlockSize: imagePreprocess?.padBlockSize,\n };\n}\n\nexport class ResolvedModelAdapter implements ModelAdapter {\n readonly supportedApiTypes: ModelAdapter['supportedApiTypes'];\n readonly jsonParser: JsonParser;\n readonly chatCompletion: ChatCompletionAdapter;\n readonly resolveImageDetail: ResolveImageDetail;\n readonly responses: ResponsesAdapter;\n readonly buildCodexAppServerParams: BuildCodexAppServerParams;\n readonly acceptBbox2dAlias: boolean;\n readonly imagePreprocess: ImagePreprocessPolicy;\n readonly insight: InsightAdapter;\n readonly planning: PlanningAdapter;\n readonly locate: LocateAdapter;\n\n constructor(config: ModelAdapterDefinition, modelFamily: string) {\n this.supportedApiTypes = config.supportedApiTypes ?? ['chat-completion'];\n this.jsonParser = resolveJsonParser(config.jsonParser);\n this.chatCompletion = resolveChatCompletion(config.chatCompletion);\n this.resolveImageDetail = config.resolveImageDetail ?? defaultImageDetail;\n this.responses = resolveResponses(config.responses);\n this.buildCodexAppServerParams =\n config.buildCodexAppServerParams ?? buildDefaultCodexAppServerParams;\n this.acceptBbox2dAlias = config.acceptBbox2dAlias ?? false;\n this.imagePreprocess = resolveImagePreprocess(config.imagePreprocess);\n this.insight = resolveInsight(config.insight, {\n jsonParser: this.jsonParser,\n });\n const customPlanner =\n config.planning?.kind === 'custom' ? config.planning.planner : undefined;\n const resolvedCustomPlanner = customPlanner\n ? resolveCustomPlanningDefinition(customPlanner)\n : undefined;\n this.locate = resolveLocate(\n config.locate,\n resolvedCustomPlanner,\n {\n jsonParser: this.jsonParser,\n },\n this.acceptBbox2dAlias,\n );\n this.planning = resolvePlanning(\n config.planning,\n resolvedCustomPlanner,\n { jsonParser: this.jsonParser },\n this.locate.kind === 'standard'\n ? this.locate.element.resultCodec\n : undefined,\n );\n }\n}\n"],"names":["defaultImageDetail","_input","undefined","resolveJsonParser","jsonParser","parseModelResponseJson","Error","resolveImagePreprocess","imagePreprocess","ResolvedModelAdapter","config","modelFamily","resolveChatCompletion","resolveResponses","buildDefaultCodexAppServerParams","resolveInsight","customPlanner","resolvedCustomPlanner","resolveCustomPlanningDefinition","resolveLocate","resolvePlanning"],"mappings":";;;;;;;;;;;;;;;;;AAqBA,MAAMA,qBAAqB,CAACC,SAAoBC;AAEhD,SAASC,kBACPC,UAAgD;IAEhD,IAAI,CAACA,cAAcA,AAAe,mBAAfA,YACjB,OAAOC;IAGT,IAAI,AAAsB,cAAtB,OAAOD,YACT,OAAOA;IAGT,MAAM,IAAIE,MAAM,CAAC,4BAA4B,EAAEF,YAAY;AAC7D;AAEA,SAASG,uBACPC,eAA0D;IAE1D,OAAO;QACL,cAAcA,iBAAiB;IACjC;AACF;AAEO,MAAMC;IAaX,YAAYC,MAA8B,EAAEC,WAAmB,CAAE;QAZjE,uBAAS,qBAAT;QACA,uBAAS,cAAT;QACA,uBAAS,kBAAT;QACA,uBAAS,sBAAT;QACA,uBAAS,aAAT;QACA,uBAAS,6BAAT;QACA,uBAAS,qBAAT;QACA,uBAAS,mBAAT;QACA,uBAAS,WAAT;QACA,uBAAS,YAAT;QACA,uBAAS,UAAT;QAGE,IAAI,CAAC,iBAAiB,GAAGD,OAAO,iBAAiB,IAAI;YAAC;SAAkB;QACxE,IAAI,CAAC,UAAU,GAAGP,kBAAkBO,OAAO,UAAU;QACrD,IAAI,CAAC,cAAc,GAAGE,sBAAsBF,OAAO,cAAc;QACjE,IAAI,CAAC,kBAAkB,GAAGA,OAAO,kBAAkB,IAAIV;QACvD,IAAI,CAAC,SAAS,GAAGa,iBAAiBH,OAAO,SAAS;QAClD,IAAI,CAAC,yBAAyB,GAC5BA,OAAO,yBAAyB,IAAII;QACtC,IAAI,CAAC,iBAAiB,GAAGJ,OAAO,iBAAiB,IAAI;QACrD,IAAI,CAAC,eAAe,GAAGH,uBAAuBG,OAAO,eAAe;QACpE,IAAI,CAAC,OAAO,GAAGK,eAAeL,OAAO,OAAO,EAAE;YAC5C,YAAY,IAAI,CAAC,UAAU;QAC7B;QACA,MAAMM,gBACJN,OAAO,QAAQ,EAAE,SAAS,WAAWA,OAAO,QAAQ,CAAC,OAAO,GAAGR;QACjE,MAAMe,wBAAwBD,gBAC1BE,gCAAgCF,iBAChCd;QACJ,IAAI,CAAC,MAAM,GAAGiB,cACZT,OAAO,MAAM,EACbO,uBACA;YACE,YAAY,IAAI,CAAC,UAAU;QAC7B,GACA,IAAI,CAAC,iBAAiB;QAExB,IAAI,CAAC,QAAQ,GAAGG,gBACdV,OAAO,QAAQ,EACfO,uBACA;YAAE,YAAY,IAAI,CAAC,UAAU;QAAC,GAC9B,AAAqB,eAArB,IAAI,CAAC,MAAM,CAAC,IAAI,GACZ,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,GAC/Bf;IAER;AACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { getTemperatureWithSemanticRetry } from "./temperature-with-semantic-retry.mjs";
|
|
2
|
+
const midsceneResponsesDefaults = {
|
|
3
|
+
temperature: 0
|
|
4
|
+
};
|
|
5
|
+
const buildDefaultResponsesParams = ({ midsceneDefaults, userConfig })=>({
|
|
6
|
+
config: {
|
|
7
|
+
temperature: userConfig.temperature ?? midsceneDefaults.temperature
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
function resolveResponses(responses) {
|
|
11
|
+
const buildResponsesParams = responses?.buildResponsesParams ?? buildDefaultResponsesParams;
|
|
12
|
+
return {
|
|
13
|
+
unsupportedUserConfig: responses?.unsupportedUserConfig ?? [],
|
|
14
|
+
buildResponsesParams: (input)=>{
|
|
15
|
+
const context = {
|
|
16
|
+
...input,
|
|
17
|
+
userConfig: input.userConfig ?? {},
|
|
18
|
+
midsceneDefaults: midsceneResponsesDefaults
|
|
19
|
+
};
|
|
20
|
+
const params = buildResponsesParams(context);
|
|
21
|
+
return {
|
|
22
|
+
...params,
|
|
23
|
+
config: {
|
|
24
|
+
...params.config,
|
|
25
|
+
temperature: getTemperatureWithSemanticRetry({
|
|
26
|
+
temperature: params.config.temperature,
|
|
27
|
+
userTemperature: input.userConfig?.temperature,
|
|
28
|
+
semanticRetryAttempt: input.semanticRetryAttempt
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export { buildDefaultResponsesParams, resolveResponses };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=responses.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-model/model-adapter/responses.mjs","sources":["../../../../src/ai-model/model-adapter/responses.ts"],"sourcesContent":["import { getTemperatureWithSemanticRetry } from './temperature-with-semantic-retry';\nimport type {\n BuildResponsesParams,\n MidsceneResponsesDefaults,\n ModelAdapterDefinition,\n ResponsesAdapter,\n} from './types';\n\nconst midsceneResponsesDefaults: MidsceneResponsesDefaults = {\n temperature: 0,\n};\n\nexport const buildDefaultResponsesParams: BuildResponsesParams = ({\n midsceneDefaults,\n userConfig,\n}) => ({\n config: {\n temperature: userConfig.temperature ?? midsceneDefaults.temperature,\n },\n});\n\nexport function resolveResponses(\n responses: ModelAdapterDefinition['responses'],\n): ResponsesAdapter {\n const buildResponsesParams =\n responses?.buildResponsesParams ?? buildDefaultResponsesParams;\n return {\n unsupportedUserConfig: responses?.unsupportedUserConfig ?? [],\n buildResponsesParams: (input) => {\n const context = {\n ...input,\n userConfig: input.userConfig ?? {},\n midsceneDefaults: midsceneResponsesDefaults,\n };\n const params = buildResponsesParams(context);\n return {\n ...params,\n config: {\n ...params.config,\n temperature: getTemperatureWithSemanticRetry({\n temperature: params.config.temperature,\n userTemperature: input.userConfig?.temperature,\n semanticRetryAttempt: input.semanticRetryAttempt,\n }),\n },\n };\n },\n };\n}\n"],"names":["midsceneResponsesDefaults","buildDefaultResponsesParams","midsceneDefaults","userConfig","resolveResponses","responses","buildResponsesParams","input","context","params","getTemperatureWithSemanticRetry"],"mappings":";AAQA,MAAMA,4BAAuD;IAC3D,aAAa;AACf;AAEO,MAAMC,8BAAoD,CAAC,EAChEC,gBAAgB,EAChBC,UAAU,EACX,GAAM;QACL,QAAQ;YACN,aAAaA,WAAW,WAAW,IAAID,iBAAiB,WAAW;QACrE;IACF;AAEO,SAASE,iBACdC,SAA8C;IAE9C,MAAMC,uBACJD,WAAW,wBAAwBJ;IACrC,OAAO;QACL,uBAAuBI,WAAW,yBAAyB,EAAE;QAC7D,sBAAsB,CAACE;YACrB,MAAMC,UAAU;gBACd,GAAGD,KAAK;gBACR,YAAYA,MAAM,UAAU,IAAI,CAAC;gBACjC,kBAAkBP;YACpB;YACA,MAAMS,SAASH,qBAAqBE;YACpC,OAAO;gBACL,GAAGC,MAAM;gBACT,QAAQ;oBACN,GAAGA,OAAO,MAAM;oBAChB,aAAaC,gCAAgC;wBAC3C,aAAaD,OAAO,MAAM,CAAC,WAAW;wBACtC,iBAAiBF,MAAM,UAAU,EAAE;wBACnC,sBAAsBA,MAAM,oBAAoB;oBAClD;gBACF;YACF;QACF;IACF;AACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
function getTemperatureWithSemanticRetry({ temperature, userTemperature, semanticRetryAttempt = 0 }) {
|
|
2
|
+
if (semanticRetryAttempt > 0 && void 0 === userTemperature && 0 === temperature) return 0.2;
|
|
3
|
+
return temperature;
|
|
4
|
+
}
|
|
5
|
+
export { getTemperatureWithSemanticRetry };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=temperature-with-semantic-retry.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-model/model-adapter/temperature-with-semantic-retry.mjs","sources":["../../../../src/ai-model/model-adapter/temperature-with-semantic-retry.ts"],"sourcesContent":["export function getTemperatureWithSemanticRetry<T>({\n temperature,\n userTemperature,\n semanticRetryAttempt = 0,\n}: {\n temperature: T;\n userTemperature?: number;\n semanticRetryAttempt?: number;\n}): T | number {\n // Only perturb the default deterministic request after a semantic parse\n // failure: preserve an explicit user temperature, and avoid adding a\n // temperature to adapters whose normal parameters do not include one.\n if (\n semanticRetryAttempt > 0 &&\n userTemperature === undefined &&\n temperature === 0\n ) {\n return 0.2;\n }\n return temperature;\n}\n"],"names":["getTemperatureWithSemanticRetry","temperature","userTemperature","semanticRetryAttempt","undefined"],"mappings":"AAAO,SAASA,gCAAmC,EACjDC,WAAW,EACXC,eAAe,EACfC,uBAAuB,CAAC,EAKzB;IAIC,IACEA,uBAAuB,KACvBD,AAAoBE,WAApBF,mBACAD,AAAgB,MAAhBA,aAEA,OAAO;IAET,OAAOA;AACT"}
|
|
@@ -11,15 +11,54 @@ const resolveGpt6ReasoningEffort = ({ reasoningEnabled, reasoningEffort })=>{
|
|
|
11
11
|
const buildGpt5CodexAppServerParams = (input)=>({
|
|
12
12
|
config: {
|
|
13
13
|
effort: resolveGpt5ReasoningEffort(input.userConfig ?? {})
|
|
14
|
-
}
|
|
15
|
-
imageDetail: originalImageDetailForDefaultIntent(input)
|
|
14
|
+
}
|
|
16
15
|
});
|
|
17
16
|
const buildGpt6CodexAppServerParams = (input)=>({
|
|
18
17
|
config: {
|
|
19
18
|
effort: resolveGpt6ReasoningEffort(input.userConfig ?? {})
|
|
20
|
-
}
|
|
21
|
-
imageDetail: originalImageDetailForDefaultIntent(input)
|
|
19
|
+
}
|
|
22
20
|
});
|
|
21
|
+
const buildGpt5ResponsesParams = (input)=>{
|
|
22
|
+
const { midsceneDefaults, userConfig, expectedJsonObjectResponse } = input;
|
|
23
|
+
const commonOverrideConfig = {};
|
|
24
|
+
if (void 0 !== userConfig.temperature) commonOverrideConfig.temperature = userConfig.temperature;
|
|
25
|
+
if ('none' !== userConfig.responseFormat && expectedJsonObjectResponse) commonOverrideConfig.text = {
|
|
26
|
+
format: {
|
|
27
|
+
type: 'json_object'
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const effectiveReasoningEffort = resolveGpt5ReasoningEffort(userConfig);
|
|
31
|
+
return {
|
|
32
|
+
config: {
|
|
33
|
+
...midsceneDefaults,
|
|
34
|
+
...commonOverrideConfig,
|
|
35
|
+
reasoning: {
|
|
36
|
+
effort: effectiveReasoningEffort
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
const buildGpt6ResponsesParams = (input)=>{
|
|
42
|
+
const { midsceneDefaults, userConfig, expectedJsonObjectResponse } = input;
|
|
43
|
+
const { responseFormat } = userConfig;
|
|
44
|
+
const commonOverrideConfig = {};
|
|
45
|
+
commonOverrideConfig.temperature = void 0;
|
|
46
|
+
if ('none' !== responseFormat && expectedJsonObjectResponse) commonOverrideConfig.text = {
|
|
47
|
+
format: {
|
|
48
|
+
type: 'json_object'
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const effectiveReasoningEffort = resolveGpt6ReasoningEffort(userConfig);
|
|
52
|
+
return {
|
|
53
|
+
config: {
|
|
54
|
+
...midsceneDefaults,
|
|
55
|
+
...commonOverrideConfig,
|
|
56
|
+
reasoning: {
|
|
57
|
+
effort: effectiveReasoningEffort
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
};
|
|
23
62
|
const buildGpt5ChatCompletionParams = (input)=>{
|
|
24
63
|
const { midsceneDefaults, userConfig } = input;
|
|
25
64
|
const commonOverrideConfig = {};
|
|
@@ -55,13 +94,23 @@ const buildGpt6ChatCompletionParams = (input)=>{
|
|
|
55
94
|
};
|
|
56
95
|
const gptAdapters = {
|
|
57
96
|
'gpt-5': {
|
|
97
|
+
supportedApiTypes: [
|
|
98
|
+
'chat-completion',
|
|
99
|
+
'responses'
|
|
100
|
+
],
|
|
101
|
+
resolveImageDetail: originalImageDetailForDefaultIntent,
|
|
102
|
+
responses: {
|
|
103
|
+
unsupportedUserConfig: [
|
|
104
|
+
'reasoningBudget'
|
|
105
|
+
],
|
|
106
|
+
buildResponsesParams: buildGpt5ResponsesParams
|
|
107
|
+
},
|
|
58
108
|
buildCodexAppServerParams: buildGpt5CodexAppServerParams,
|
|
59
109
|
chatCompletion: {
|
|
60
110
|
unsupportedUserConfig: [
|
|
61
111
|
'reasoningBudget'
|
|
62
112
|
],
|
|
63
|
-
buildChatCompletionParams: buildGpt5ChatCompletionParams
|
|
64
|
-
resolveImageDetail: originalImageDetailForDefaultIntent
|
|
113
|
+
buildChatCompletionParams: buildGpt5ChatCompletionParams
|
|
65
114
|
},
|
|
66
115
|
locate: {
|
|
67
116
|
element: {
|
|
@@ -75,14 +124,25 @@ const gptAdapters = {
|
|
|
75
124
|
}
|
|
76
125
|
},
|
|
77
126
|
'gpt-6': {
|
|
127
|
+
supportedApiTypes: [
|
|
128
|
+
'chat-completion',
|
|
129
|
+
'responses'
|
|
130
|
+
],
|
|
131
|
+
resolveImageDetail: originalImageDetailForDefaultIntent,
|
|
132
|
+
responses: {
|
|
133
|
+
unsupportedUserConfig: [
|
|
134
|
+
'temperature',
|
|
135
|
+
'reasoningBudget'
|
|
136
|
+
],
|
|
137
|
+
buildResponsesParams: buildGpt6ResponsesParams
|
|
138
|
+
},
|
|
78
139
|
buildCodexAppServerParams: buildGpt6CodexAppServerParams,
|
|
79
140
|
chatCompletion: {
|
|
80
141
|
unsupportedUserConfig: [
|
|
81
142
|
'temperature',
|
|
82
143
|
'reasoningBudget'
|
|
83
144
|
],
|
|
84
|
-
buildChatCompletionParams: buildGpt6ChatCompletionParams
|
|
85
|
-
resolveImageDetail: originalImageDetailForDefaultIntent
|
|
145
|
+
buildChatCompletionParams: buildGpt6ChatCompletionParams
|
|
86
146
|
},
|
|
87
147
|
locate: {
|
|
88
148
|
element: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/models/gpt.mjs","sources":["../../../../src/ai-model/models/gpt.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n CodexAppServerCallInput,\n CodexAppServerParamsResult,\n
|
|
1
|
+
{"version":3,"file":"ai-model/models/gpt.mjs","sources":["../../../../src/ai-model/models/gpt.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n BuildResponsesParams,\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n CodexAppServerCallInput,\n CodexAppServerParamsResult,\n ModelAdapterDefinition,\n ReasoningInput,\n ResolveImageDetail,\n} from '../model-adapter/types';\nimport { isLocateIntent } from './utils/intent';\n\nconst originalImageDetailForDefaultIntent: ResolveImageDetail = (input) =>\n isLocateIntent(input.intent) || input.requiresOriginalImageDetail\n ? 'original'\n : undefined;\n\nconst resolveGpt5ReasoningEffort = ({\n reasoningEnabled,\n reasoningEffort,\n}: ReasoningInput): string | undefined => {\n if (reasoningEnabled === 'default') return undefined;\n return reasoningEnabled === true ? (reasoningEffort ?? 'medium') : 'none';\n};\n\n// Astra cannot disable reasoning; use its lowest effort when disabled.\nconst resolveGpt6ReasoningEffort = ({\n reasoningEnabled,\n reasoningEffort,\n}: ReasoningInput): string | undefined => {\n if (reasoningEnabled === 'default') return undefined;\n return reasoningEnabled === true ? (reasoningEffort ?? 'medium') : 'low';\n};\n\nconst buildGpt5CodexAppServerParams = (\n input: CodexAppServerCallInput,\n): CodexAppServerParamsResult => ({\n config: { effort: resolveGpt5ReasoningEffort(input.userConfig ?? {}) },\n});\n\nconst buildGpt6CodexAppServerParams = (\n input: CodexAppServerCallInput,\n): CodexAppServerParamsResult => ({\n config: { effort: resolveGpt6ReasoningEffort(input.userConfig ?? {}) },\n});\n\nconst buildGpt5ResponsesParams: BuildResponsesParams = (input) => {\n const { midsceneDefaults, userConfig, expectedJsonObjectResponse } = input;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n if (userConfig.responseFormat !== 'none' && expectedJsonObjectResponse) {\n commonOverrideConfig.text = { format: { type: 'json_object' } };\n }\n\n const effectiveReasoningEffort = resolveGpt5ReasoningEffort(userConfig);\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n reasoning: { effort: effectiveReasoningEffort },\n },\n };\n};\n\nconst buildGpt6ResponsesParams: BuildResponsesParams = (input) => {\n const { midsceneDefaults, userConfig, expectedJsonObjectResponse } = input;\n const { responseFormat } = userConfig;\n const commonOverrideConfig: Record<string, unknown> = {};\n // GPT-6 does not support temperature; omit it from the serialized request.\n commonOverrideConfig.temperature = undefined;\n if (responseFormat !== 'none' && expectedJsonObjectResponse) {\n commonOverrideConfig.text = { format: { type: 'json_object' } };\n }\n\n const effectiveReasoningEffort = resolveGpt6ReasoningEffort(userConfig);\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n reasoning: { effort: effectiveReasoningEffort },\n },\n };\n};\n\nconst buildGpt5ChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n // OpenAI Chat Completions JSON mode:\n // https://platform.openai.com/docs/guides/structured-outputs?api-mode=chat#json-mode\n if (\n input.userConfig.responseFormat !== 'none' &&\n input.expectedJsonObjectResponse\n ) {\n commonOverrideConfig.response_format = { type: 'json_object' };\n }\n\n const effectiveReasoningEffort = resolveGpt5ReasoningEffort(userConfig);\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n reasoning_effort: effectiveReasoningEffort,\n },\n };\n};\n\nconst buildGpt6ChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig, expectedJsonObjectResponse } = input;\n const { responseFormat } = userConfig;\n const commonOverrideConfig: Record<string, unknown> = {};\n // GPT-6 does not support temperature; omit it from the serialized request.\n commonOverrideConfig.temperature = undefined;\n if (responseFormat !== 'none' && expectedJsonObjectResponse) {\n commonOverrideConfig.response_format = { type: 'json_object' };\n }\n\n const effectiveReasoningEffort = resolveGpt6ReasoningEffort(userConfig);\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n reasoning_effort: effectiveReasoningEffort,\n },\n };\n};\n\nexport const gptAdapters = {\n 'gpt-5': {\n supportedApiTypes: ['chat-completion', 'responses'],\n resolveImageDetail: originalImageDetailForDefaultIntent,\n responses: {\n unsupportedUserConfig: ['reasoningBudget'],\n buildResponsesParams: buildGpt5ResponsesParams,\n },\n buildCodexAppServerParams: buildGpt5CodexAppServerParams,\n chatCompletion: {\n unsupportedUserConfig: ['reasoningBudget'],\n buildChatCompletionParams: buildGpt5ChatCompletionParams,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: { shape: 'bbox', order: 'xy' },\n },\n },\n },\n },\n 'gpt-6': {\n supportedApiTypes: ['chat-completion', 'responses'],\n resolveImageDetail: originalImageDetailForDefaultIntent,\n responses: {\n unsupportedUserConfig: ['temperature', 'reasoningBudget'],\n buildResponsesParams: buildGpt6ResponsesParams,\n },\n buildCodexAppServerParams: buildGpt6CodexAppServerParams,\n chatCompletion: {\n unsupportedUserConfig: ['temperature', 'reasoningBudget'],\n buildChatCompletionParams: buildGpt6ChatCompletionParams,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: { shape: 'bbox', order: 'xy' },\n },\n },\n },\n },\n} satisfies Pick<\n Record<TModelFamily, ModelAdapterDefinition>,\n 'gpt-5' | 'gpt-6'\n>;\n"],"names":["originalImageDetailForDefaultIntent","input","isLocateIntent","undefined","resolveGpt5ReasoningEffort","reasoningEnabled","reasoningEffort","resolveGpt6ReasoningEffort","buildGpt5CodexAppServerParams","buildGpt6CodexAppServerParams","buildGpt5ResponsesParams","midsceneDefaults","userConfig","expectedJsonObjectResponse","commonOverrideConfig","effectiveReasoningEffort","buildGpt6ResponsesParams","responseFormat","buildGpt5ChatCompletionParams","buildGpt6ChatCompletionParams","gptAdapters"],"mappings":"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"}
|
|
@@ -26,8 +26,8 @@ const MODEL_ADAPTER_CONFIGS = {
|
|
|
26
26
|
const modelAdapterCache = new Map();
|
|
27
27
|
const debugModelAdapter = getDebug('ai:model-adapter');
|
|
28
28
|
function debugAdapterUnsupportedUserConfig(modelFamily, adapter) {
|
|
29
|
-
if (0
|
|
30
|
-
debugModelAdapter(`model adapter "${modelFamily}" unsupportedUserConfig: ${JSON.stringify(adapter.
|
|
29
|
+
if (adapter.chatCompletion.unsupportedUserConfig.length > 0) debugModelAdapter(`model adapter "${modelFamily}" (chat-completion) unsupportedUserConfig: ${JSON.stringify(adapter.chatCompletion.unsupportedUserConfig)}`);
|
|
30
|
+
if (adapter.responses.unsupportedUserConfig.length > 0) debugModelAdapter(`model adapter "${modelFamily}" (responses) unsupportedUserConfig: ${JSON.stringify(adapter.responses.unsupportedUserConfig)}`);
|
|
31
31
|
}
|
|
32
32
|
function getModelAdapter(modelFamily) {
|
|
33
33
|
const cacheKey = modelFamily ?? 'default';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/models/registry.mjs","sources":["../../../../src/ai-model/models/registry.ts"],"sourcesContent":["import type { IModelConfig, TModelFamily } from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { ResolvedModelAdapter } from '../model-adapter/resolve';\nimport type {\n ModelAdapter,\n ModelAdapterDefinition,\n ModelRuntime,\n} from '../model-adapter/types';\nimport { autoGlmAdapters } from './auto-glm/adapter';\nimport { deepSeekAdapters } from './deepseek/adapter';\nimport { defaultOpenAICompatibleAdapterConfig } from './default';\nimport { doubaoAdapters } from './doubao';\nimport { geminiAdapters } from './gemini';\nimport { glmAdapters } from './glm';\nimport { gptAdapters } from './gpt';\nimport { kimiAdapters } from './kimi';\nimport { mimoAdapters } from './mimo';\nimport { qwenAdapters } from './qwen';\nimport { uiTarsAdapters } from './ui-tars/adapter';\n\nexport const MODEL_ADAPTER_CONFIGS = {\n ...qwenAdapters,\n ...deepSeekAdapters,\n ...doubaoAdapters,\n ...geminiAdapters,\n ...uiTarsAdapters,\n ...glmAdapters,\n ...autoGlmAdapters,\n ...gptAdapters,\n ...kimiAdapters,\n ...mimoAdapters,\n} satisfies Record<TModelFamily, ModelAdapterDefinition>;\n\ntype ModelAdapterCacheKey = TModelFamily | 'default';\n\nconst modelAdapterCache = new Map<ModelAdapterCacheKey, ModelAdapter>();\nconst debugModelAdapter = getDebug('ai:model-adapter');\n\nfunction debugAdapterUnsupportedUserConfig(\n modelFamily: ModelAdapterCacheKey,\n adapter: ModelAdapter,\n): void {\n if (adapter.chatCompletion.unsupportedUserConfig.length
|
|
1
|
+
{"version":3,"file":"ai-model/models/registry.mjs","sources":["../../../../src/ai-model/models/registry.ts"],"sourcesContent":["import type { IModelConfig, TModelFamily } from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { ResolvedModelAdapter } from '../model-adapter/resolve';\nimport type {\n ModelAdapter,\n ModelAdapterDefinition,\n ModelRuntime,\n} from '../model-adapter/types';\nimport { autoGlmAdapters } from './auto-glm/adapter';\nimport { deepSeekAdapters } from './deepseek/adapter';\nimport { defaultOpenAICompatibleAdapterConfig } from './default';\nimport { doubaoAdapters } from './doubao';\nimport { geminiAdapters } from './gemini';\nimport { glmAdapters } from './glm';\nimport { gptAdapters } from './gpt';\nimport { kimiAdapters } from './kimi';\nimport { mimoAdapters } from './mimo';\nimport { qwenAdapters } from './qwen';\nimport { uiTarsAdapters } from './ui-tars/adapter';\n\nexport const MODEL_ADAPTER_CONFIGS = {\n ...qwenAdapters,\n ...deepSeekAdapters,\n ...doubaoAdapters,\n ...geminiAdapters,\n ...uiTarsAdapters,\n ...glmAdapters,\n ...autoGlmAdapters,\n ...gptAdapters,\n ...kimiAdapters,\n ...mimoAdapters,\n} satisfies Record<TModelFamily, ModelAdapterDefinition>;\n\ntype ModelAdapterCacheKey = TModelFamily | 'default';\n\nconst modelAdapterCache = new Map<ModelAdapterCacheKey, ModelAdapter>();\nconst debugModelAdapter = getDebug('ai:model-adapter');\n\nfunction debugAdapterUnsupportedUserConfig(\n modelFamily: ModelAdapterCacheKey,\n adapter: ModelAdapter,\n): void {\n if (adapter.chatCompletion.unsupportedUserConfig.length > 0) {\n debugModelAdapter(\n `model adapter \"${modelFamily}\" (chat-completion) unsupportedUserConfig: ${JSON.stringify(adapter.chatCompletion.unsupportedUserConfig)}`,\n );\n }\n if (adapter.responses.unsupportedUserConfig.length > 0) {\n debugModelAdapter(\n `model adapter \"${modelFamily}\" (responses) unsupportedUserConfig: ${JSON.stringify(adapter.responses.unsupportedUserConfig)}`,\n );\n }\n}\n\nexport function getModelAdapter(modelFamily?: TModelFamily): ModelAdapter {\n const cacheKey: ModelAdapterCacheKey = modelFamily ?? 'default';\n let adapter = modelAdapterCache.get(cacheKey);\n if (adapter) {\n return adapter;\n }\n\n const config = modelFamily\n ? MODEL_ADAPTER_CONFIGS[modelFamily]\n : defaultOpenAICompatibleAdapterConfig;\n if (!config) {\n throw new Error(\n `No model adapter registered for modelFamily: ${modelFamily}`,\n );\n }\n\n adapter = new ResolvedModelAdapter(config, cacheKey);\n modelAdapterCache.set(cacheKey, adapter);\n debugAdapterUnsupportedUserConfig(cacheKey, adapter);\n\n return adapter;\n}\n\nexport function getModelRuntime(config: IModelConfig): ModelRuntime {\n return {\n config,\n adapter: getModelAdapter(config.modelFamily),\n };\n}\n"],"names":["MODEL_ADAPTER_CONFIGS","qwenAdapters","deepSeekAdapters","doubaoAdapters","geminiAdapters","uiTarsAdapters","glmAdapters","autoGlmAdapters","gptAdapters","kimiAdapters","mimoAdapters","modelAdapterCache","Map","debugModelAdapter","getDebug","debugAdapterUnsupportedUserConfig","modelFamily","adapter","JSON","getModelAdapter","cacheKey","config","defaultOpenAICompatibleAdapterConfig","Error","ResolvedModelAdapter","getModelRuntime"],"mappings":";;;;;;;;;;;;;AAoBO,MAAMA,wBAAwB;IACnC,GAAGC,YAAY;IACf,GAAGC,gBAAgB;IACnB,GAAGC,cAAc;IACjB,GAAGC,cAAc;IACjB,GAAGC,cAAc;IACjB,GAAGC,WAAW;IACd,GAAGC,eAAe;IAClB,GAAGC,WAAW;IACd,GAAGC,YAAY;IACf,GAAGC,YAAY;AACjB;AAIA,MAAMC,oBAAoB,IAAIC;AAC9B,MAAMC,oBAAoBC,SAAS;AAEnC,SAASC,kCACPC,WAAiC,EACjCC,OAAqB;IAErB,IAAIA,QAAQ,cAAc,CAAC,qBAAqB,CAAC,MAAM,GAAG,GACxDJ,kBACE,CAAC,eAAe,EAAEG,YAAY,2CAA2C,EAAEE,KAAK,SAAS,CAACD,QAAQ,cAAc,CAAC,qBAAqB,GAAG;IAG7I,IAAIA,QAAQ,SAAS,CAAC,qBAAqB,CAAC,MAAM,GAAG,GACnDJ,kBACE,CAAC,eAAe,EAAEG,YAAY,qCAAqC,EAAEE,KAAK,SAAS,CAACD,QAAQ,SAAS,CAAC,qBAAqB,GAAG;AAGpI;AAEO,SAASE,gBAAgBH,WAA0B;IACxD,MAAMI,WAAiCJ,eAAe;IACtD,IAAIC,UAAUN,kBAAkB,GAAG,CAACS;IACpC,IAAIH,SACF,OAAOA;IAGT,MAAMI,SAASL,cACXhB,qBAAqB,CAACgB,YAAY,GAClCM;IACJ,IAAI,CAACD,QACH,MAAM,IAAIE,MACR,CAAC,6CAA6C,EAAEP,aAAa;IAIjEC,UAAU,IAAIO,qBAAqBH,QAAQD;IAC3CT,kBAAkB,GAAG,CAACS,UAAUH;IAChCF,kCAAkCK,UAAUH;IAE5C,OAAOA;AACT;AAEO,SAASQ,gBAAgBJ,MAAoB;IAClD,OAAO;QACLA;QACA,SAASF,gBAAgBE,OAAO,WAAW;IAC7C;AACF"}
|
|
@@ -5,6 +5,7 @@ import { isCodexAppServerProvider } from "./codex/codex-app-server.mjs";
|
|
|
5
5
|
import { isModelCallRecordingEnabled, recordModelCallEvent } from "./model-call-recorder.mjs";
|
|
6
6
|
import { callOpenAI } from "./openai/call-openai.mjs";
|
|
7
7
|
import { prepareChatCompletion } from "./openai/chat-completion/chat-completion.mjs";
|
|
8
|
+
import { prepareResponses } from "./openai/responses/responses.mjs";
|
|
8
9
|
import { buildRequestAbortSignal, resolveEffectiveTimeoutMs, runWithAbortSignal, waitForRetry } from "./request-timeout.mjs";
|
|
9
10
|
import { appendAIRequestFailureSummary, buildUsageInfo, nextInternalCallId, normalizeRetryCount, toError } from "./utils.mjs";
|
|
10
11
|
function _define_property(obj, key, value) {
|
|
@@ -17,6 +18,7 @@ function _define_property(obj, key, value) {
|
|
|
17
18
|
else obj[key] = value;
|
|
18
19
|
return obj;
|
|
19
20
|
}
|
|
21
|
+
const DEFAULT_MODEL_API_TYPE = 'chat-completion';
|
|
20
22
|
async function callAI(messages, modelRuntime, options) {
|
|
21
23
|
options?.abortSignal?.throwIfAborted();
|
|
22
24
|
const isStreaming = options?.stream === true;
|
|
@@ -24,21 +26,27 @@ async function callAI(messages, modelRuntime, options) {
|
|
|
24
26
|
const executionId = modelRuntime.executionId ?? `unscoped-${uuid()}`;
|
|
25
27
|
const internalCallId = nextInternalCallId();
|
|
26
28
|
const { config: modelConfig } = modelRuntime;
|
|
27
|
-
const prepare = async ()=>
|
|
29
|
+
const prepare = async ()=>{
|
|
30
|
+
const input = {
|
|
31
|
+
messages,
|
|
32
|
+
modelRuntime,
|
|
33
|
+
options
|
|
34
|
+
};
|
|
35
|
+
if (isCodexAppServerProvider(modelConfig.openaiBaseURL)) return {
|
|
28
36
|
protocol: 'codex',
|
|
29
|
-
input: prepareCodexCall(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
input: prepareCodexCall(input)
|
|
38
|
+
};
|
|
39
|
+
const apiType = modelConfig.apiType ?? DEFAULT_MODEL_API_TYPE;
|
|
40
|
+
assert(modelRuntime.adapter.supportedApiTypes.includes(apiType), `Model adapter "${modelConfig.modelFamily ?? 'default'}" does not support API type "${apiType}"`);
|
|
41
|
+
if ('responses' === apiType) return {
|
|
42
|
+
protocol: 'responses',
|
|
43
|
+
input: await prepareResponses(input)
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
35
46
|
protocol: 'chat-completion',
|
|
36
|
-
input: await prepareChatCompletion(
|
|
37
|
-
messages,
|
|
38
|
-
modelRuntime,
|
|
39
|
-
options
|
|
40
|
-
})
|
|
47
|
+
input: await prepareChatCompletion(input)
|
|
41
48
|
};
|
|
49
|
+
};
|
|
42
50
|
const prepared = options?.abortSignal ? await runWithAbortSignal(options.abortSignal, prepare) : await prepare();
|
|
43
51
|
const result = await callModelWithRetry({
|
|
44
52
|
messages,
|
|
@@ -50,6 +58,7 @@ async function callAI(messages, modelRuntime, options) {
|
|
|
50
58
|
});
|
|
51
59
|
const { rawUsage, timeCost, totalTimeCost, retryCount, requestId, responseModelName, ...response } = result;
|
|
52
60
|
const usage = buildUsageInfo({
|
|
61
|
+
apiType: prepared.protocol,
|
|
53
62
|
usageData: rawUsage,
|
|
54
63
|
timeCost,
|
|
55
64
|
totalTimeCost,
|
|
@@ -145,7 +154,7 @@ async function callModelOnce({ messages, modelRuntime, options, executionId, int
|
|
|
145
154
|
} : options
|
|
146
155
|
};
|
|
147
156
|
try {
|
|
148
|
-
return await runWithAbortSignal(requestSignal, ()=>'codex' === prepared.protocol ? callCodex(context, prepared.input) : callOpenAI(context, prepared
|
|
157
|
+
return await runWithAbortSignal(requestSignal, ()=>'codex' === prepared.protocol ? callCodex(context, prepared.input) : callOpenAI(context, prepared));
|
|
149
158
|
} catch (error) {
|
|
150
159
|
options?.abortSignal?.throwIfAborted();
|
|
151
160
|
const lastError = toError(error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/service-caller/call-ai.mjs","sources":["../../../../src/ai-model/service-caller/call-ai.ts"],"sourcesContent":["import { getDebug } from '@midscene/shared/logger';\nimport { assert, uuid } from '@midscene/shared/utils';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport type { ModelRuntime } from '../models';\nimport { callCodex, prepareCodexCall } from './codex/call-codex';\nimport { isCodexAppServerProvider } from './codex/codex-app-server';\nimport {\n isModelCallRecordingEnabled,\n recordModelCallEvent,\n} from './model-call-recorder';\nimport { callOpenAI } from './openai/call-openai';\nimport { prepareChatCompletion } from './openai/chat-completion/chat-completion';\nimport {\n buildRequestAbortSignal,\n resolveEffectiveTimeoutMs,\n runWithAbortSignal,\n waitForRetry,\n} from './request-timeout';\nimport type {\n AICallResult,\n CallAIOptions,\n ModelCallContext,\n ModelCallResult,\n} from './types';\nimport {\n appendAIRequestFailureSummary,\n buildUsageInfo,\n nextInternalCallId,\n normalizeRetryCount,\n toError,\n} from './utils';\n\nexport async function callAI(\n messages: ChatCompletionMessageParam[],\n modelRuntime: ModelRuntime,\n options?: CallAIOptions,\n): Promise<AICallResult> {\n options?.abortSignal?.throwIfAborted();\n const isStreaming = options?.stream === true;\n if (isStreaming) {\n assert(\n typeof options?.onChunk === 'function',\n 'onChunk is required when stream is true',\n );\n }\n\n // Low-level callers without a TaskRunner still need a stable ID for the\n // lifetime of this model call (including its network retries).\n const executionId = modelRuntime.executionId ?? `unscoped-${uuid()}`;\n\n // Stable internal ID for this call, used by the agent to deduplicate usage\n // across the onUsage callback and the task-dump-based collectUsageMetrics()\n // path when the provider does not return a request_id.\n const internalCallId = nextInternalCallId();\n\n const { config: modelConfig } = modelRuntime;\n\n const prepare = async (): Promise<PreparedModelInput> =>\n isCodexAppServerProvider(modelConfig.openaiBaseURL)\n ? {\n protocol: 'codex',\n input: prepareCodexCall({ messages, modelRuntime, options }),\n }\n : {\n protocol: 'chat-completion',\n input: await prepareChatCompletion({\n messages,\n modelRuntime,\n options,\n }),\n };\n\n const prepared = options?.abortSignal\n ? await runWithAbortSignal(options.abortSignal, prepare)\n : await prepare();\n\n const result = await callModelWithRetry({\n messages,\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n });\n\n const {\n rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n ...response\n } = result;\n\n const usage = buildUsageInfo({\n usageData: rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n modelName: modelConfig.modelName,\n modelDescription: modelConfig.modelDescription,\n slot: modelConfig.slot,\n internalCallId,\n });\n\n const debugProfileStats = getDebug('ai:profile:stats');\n const debugProfileDetail = getDebug('ai:profile:detail');\n debugProfileStats(\n `model, ${modelConfig.modelName}, mode, ${modelConfig.modelFamily || 'default'}, streaming, ${response.isStreamed}, prompt-tokens, ${usage?.prompt_tokens ?? ''}, completion-tokens, ${usage?.completion_tokens ?? ''}, total-tokens, ${usage?.total_tokens ?? ''}, cached-input, ${usage?.cached_input ?? ''}, cost-ms, ${timeCost ?? ''}, requestId, ${requestId ?? ''}, slot, ${modelConfig.slot}, configured-temperature, ${modelConfig.temperature ?? ''}`,\n );\n debugProfileDetail(`model usage detail: ${JSON.stringify(usage)}`);\n\n if (usage && modelRuntime.onUsage) {\n modelRuntime.onUsage(usage);\n }\n return { ...response, usage };\n}\n\ntype PreparedModelInput =\n | { protocol: 'codex'; input: ReturnType<typeof prepareCodexCall> }\n | {\n protocol: 'chat-completion';\n input: Awaited<ReturnType<typeof prepareChatCompletion>>;\n };\n\ntype ModelCallInput = {\n messages: ChatCompletionMessageParam[];\n modelRuntime: ModelRuntime;\n options?: CallAIOptions;\n executionId: string;\n internalCallId: string;\n prepared: PreparedModelInput;\n};\n\n/** Carries the original failure across the retry boundary without replaying output. */\nclass NonRetryableModelCallError extends Error {\n readonly cause: Error;\n\n constructor(cause: Error) {\n super(cause.message, { cause });\n this.cause = cause;\n }\n}\n\nasync function callModelWithRetry(\n input: ModelCallInput,\n): Promise<ModelCallResult & { totalTimeCost: number; retryCount: number }> {\n const startTime = Date.now();\n const {\n modelRuntime: { config },\n options,\n } = input;\n const maxAttempts = normalizeRetryCount(config.retryCount) + 1;\n const retryInterval = config.retryInterval ?? 2000;\n const attemptErrors: Array<{ attempt: number; error: unknown }> = [];\n\n for (let attempt = 1; ; attempt++) {\n options?.abortSignal?.throwIfAborted();\n try {\n const result = await callModelOnce(input, attempt);\n return {\n ...result,\n totalTimeCost: Date.now() - startTime,\n retryCount: attempt - 1,\n };\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n if (error instanceof NonRetryableModelCallError) {\n throw error.cause;\n }\n const lastError = toError(error);\n attemptErrors.push({ attempt, error: lastError });\n if (attempt === maxAttempts) {\n throw appendAIRequestFailureSummary(\n lastError,\n attemptErrors,\n maxAttempts,\n );\n }\n getDebug('ai:call', { console: true })(\n `AI call failed (attempt ${attempt}/${maxAttempts}), retrying in ${retryInterval}ms... Error: ${lastError.message}`,\n );\n }\n await waitForRetry(retryInterval, options?.abortSignal);\n }\n}\n\nasync function callModelOnce(\n {\n messages,\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n }: ModelCallInput,\n attempt: number,\n): Promise<ModelCallResult> {\n const { config: modelConfig } = modelRuntime;\n const recordEvent = isModelCallRecordingEnabled()\n ? (event: Record<string, unknown>) => {\n void recordModelCallEvent({\n executionId,\n callId: internalCallId,\n semanticRetryAttempt: options?.semanticRetryAttempt,\n slot: modelConfig.slot,\n intent: modelConfig.intent,\n modelFamily: modelConfig.modelFamily,\n ...event,\n attempt,\n });\n }\n : undefined;\n const effectiveTimeoutMs = resolveEffectiveTimeoutMs(modelConfig.timeout);\n const { signal: requestSignal, cleanup } = buildRequestAbortSignal(\n effectiveTimeoutMs,\n options?.abortSignal,\n );\n let deliveredChunk = false;\n const onChunk = options?.onChunk;\n const context: ModelCallContext = {\n messages,\n modelRuntime,\n executionId,\n recordEvent,\n requestSignal,\n effectiveTimeoutMs,\n options: onChunk\n ? {\n ...options,\n onChunk: (chunk) => {\n requestSignal.throwIfAborted();\n deliveredChunk = true;\n onChunk(chunk);\n },\n }\n : options,\n };\n try {\n return await runWithAbortSignal(requestSignal, () =>\n prepared.protocol === 'codex'\n ? callCodex(context, prepared.input)\n : callOpenAI(context, prepared.input),\n );\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n const lastError = toError(error);\n if (deliveredChunk) {\n throw new NonRetryableModelCallError(lastError);\n }\n throw lastError;\n } finally {\n cleanup();\n }\n}\n"],"names":["callAI","messages","modelRuntime","options","isStreaming","assert","executionId","uuid","internalCallId","nextInternalCallId","modelConfig","prepare","isCodexAppServerProvider","prepareCodexCall","prepareChatCompletion","prepared","runWithAbortSignal","result","callModelWithRetry","rawUsage","timeCost","totalTimeCost","retryCount","requestId","responseModelName","response","usage","buildUsageInfo","debugProfileStats","getDebug","debugProfileDetail","JSON","NonRetryableModelCallError","Error","cause","input","startTime","Date","config","maxAttempts","normalizeRetryCount","retryInterval","attemptErrors","attempt","callModelOnce","error","lastError","toError","appendAIRequestFailureSummary","waitForRetry","recordEvent","isModelCallRecordingEnabled","event","recordModelCallEvent","undefined","effectiveTimeoutMs","resolveEffectiveTimeoutMs","requestSignal","cleanup","buildRequestAbortSignal","deliveredChunk","onChunk","context","chunk","callCodex","callOpenAI"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-model/service-caller/call-ai.mjs","sources":["../../../../src/ai-model/service-caller/call-ai.ts"],"sourcesContent":["import { getDebug } from '@midscene/shared/logger';\nimport { assert, uuid } from '@midscene/shared/utils';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport type { ModelRuntime } from '../models';\nimport { callCodex, prepareCodexCall } from './codex/call-codex';\nimport { isCodexAppServerProvider } from './codex/codex-app-server';\nimport {\n isModelCallRecordingEnabled,\n recordModelCallEvent,\n} from './model-call-recorder';\nimport { type PreparedOpenAIInput, callOpenAI } from './openai/call-openai';\nimport { prepareChatCompletion } from './openai/chat-completion/chat-completion';\nimport { prepareResponses } from './openai/responses/responses';\nimport {\n buildRequestAbortSignal,\n resolveEffectiveTimeoutMs,\n runWithAbortSignal,\n waitForRetry,\n} from './request-timeout';\nimport type {\n AICallResult,\n CallAIOptions,\n ModelCallContext,\n ModelCallResult,\n} from './types';\nimport {\n appendAIRequestFailureSummary,\n buildUsageInfo,\n nextInternalCallId,\n normalizeRetryCount,\n toError,\n} from './utils';\n\nconst DEFAULT_MODEL_API_TYPE = 'chat-completion';\n\nexport async function callAI(\n messages: ChatCompletionMessageParam[],\n modelRuntime: ModelRuntime,\n options?: CallAIOptions,\n): Promise<AICallResult> {\n options?.abortSignal?.throwIfAborted();\n const isStreaming = options?.stream === true;\n if (isStreaming) {\n assert(\n typeof options?.onChunk === 'function',\n 'onChunk is required when stream is true',\n );\n }\n\n // Low-level callers without a TaskRunner still need a stable ID for the\n // lifetime of this model call (including its network retries).\n const executionId = modelRuntime.executionId ?? `unscoped-${uuid()}`;\n\n // Stable internal ID for this call, used by the agent to deduplicate usage\n // across the onUsage callback and the task-dump-based collectUsageMetrics()\n // path when the provider does not return a request_id.\n const internalCallId = nextInternalCallId();\n\n const { config: modelConfig } = modelRuntime;\n\n const prepare = async (): Promise<PreparedModelInput> => {\n const input = { messages, modelRuntime, options };\n if (isCodexAppServerProvider(modelConfig.openaiBaseURL)) {\n return { protocol: 'codex', input: prepareCodexCall(input) };\n }\n const apiType = modelConfig.apiType ?? DEFAULT_MODEL_API_TYPE;\n\n assert(\n modelRuntime.adapter.supportedApiTypes.includes(apiType),\n `Model adapter \"${modelConfig.modelFamily ?? 'default'}\" does not support API type \"${apiType}\"`,\n );\n if (apiType === 'responses') {\n return { protocol: 'responses', input: await prepareResponses(input) };\n }\n return {\n protocol: 'chat-completion',\n input: await prepareChatCompletion(input),\n };\n };\n\n const prepared = options?.abortSignal\n ? await runWithAbortSignal(options.abortSignal, prepare)\n : await prepare();\n\n const result = await callModelWithRetry({\n messages,\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n });\n\n const {\n rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n ...response\n } = result;\n\n const usage = buildUsageInfo({\n apiType: prepared.protocol,\n usageData: rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n modelName: modelConfig.modelName,\n modelDescription: modelConfig.modelDescription,\n slot: modelConfig.slot,\n internalCallId,\n });\n\n const debugProfileStats = getDebug('ai:profile:stats');\n const debugProfileDetail = getDebug('ai:profile:detail');\n debugProfileStats(\n `model, ${modelConfig.modelName}, mode, ${modelConfig.modelFamily || 'default'}, streaming, ${response.isStreamed}, prompt-tokens, ${usage?.prompt_tokens ?? ''}, completion-tokens, ${usage?.completion_tokens ?? ''}, total-tokens, ${usage?.total_tokens ?? ''}, cached-input, ${usage?.cached_input ?? ''}, cost-ms, ${timeCost ?? ''}, requestId, ${requestId ?? ''}, slot, ${modelConfig.slot}, configured-temperature, ${modelConfig.temperature ?? ''}`,\n );\n debugProfileDetail(`model usage detail: ${JSON.stringify(usage)}`);\n\n if (usage && modelRuntime.onUsage) {\n modelRuntime.onUsage(usage);\n }\n return { ...response, usage };\n}\n\ntype PreparedModelInput =\n | { protocol: 'codex'; input: ReturnType<typeof prepareCodexCall> }\n | PreparedOpenAIInput;\n\ntype ModelCallInput = {\n messages: ChatCompletionMessageParam[];\n modelRuntime: ModelRuntime;\n options?: CallAIOptions;\n executionId: string;\n internalCallId: string;\n prepared: PreparedModelInput;\n};\n\n/** Carries the original failure across the retry boundary without replaying output. */\nclass NonRetryableModelCallError extends Error {\n readonly cause: Error;\n\n constructor(cause: Error) {\n super(cause.message, { cause });\n this.cause = cause;\n }\n}\n\nasync function callModelWithRetry(\n input: ModelCallInput,\n): Promise<ModelCallResult & { totalTimeCost: number; retryCount: number }> {\n const startTime = Date.now();\n const {\n modelRuntime: { config },\n options,\n } = input;\n const maxAttempts = normalizeRetryCount(config.retryCount) + 1;\n const retryInterval = config.retryInterval ?? 2000;\n const attemptErrors: Array<{ attempt: number; error: unknown }> = [];\n\n for (let attempt = 1; ; attempt++) {\n options?.abortSignal?.throwIfAborted();\n try {\n const result = await callModelOnce(input, attempt);\n return {\n ...result,\n totalTimeCost: Date.now() - startTime,\n retryCount: attempt - 1,\n };\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n if (error instanceof NonRetryableModelCallError) {\n throw error.cause;\n }\n const lastError = toError(error);\n attemptErrors.push({ attempt, error: lastError });\n if (attempt === maxAttempts) {\n throw appendAIRequestFailureSummary(\n lastError,\n attemptErrors,\n maxAttempts,\n );\n }\n getDebug('ai:call', { console: true })(\n `AI call failed (attempt ${attempt}/${maxAttempts}), retrying in ${retryInterval}ms... Error: ${lastError.message}`,\n );\n }\n await waitForRetry(retryInterval, options?.abortSignal);\n }\n}\n\nasync function callModelOnce(\n {\n messages,\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n }: ModelCallInput,\n attempt: number,\n): Promise<ModelCallResult> {\n const { config: modelConfig } = modelRuntime;\n const recordEvent = isModelCallRecordingEnabled()\n ? (event: Record<string, unknown>) => {\n void recordModelCallEvent({\n executionId,\n callId: internalCallId,\n semanticRetryAttempt: options?.semanticRetryAttempt,\n slot: modelConfig.slot,\n intent: modelConfig.intent,\n modelFamily: modelConfig.modelFamily,\n ...event,\n attempt,\n });\n }\n : undefined;\n const effectiveTimeoutMs = resolveEffectiveTimeoutMs(modelConfig.timeout);\n const { signal: requestSignal, cleanup } = buildRequestAbortSignal(\n effectiveTimeoutMs,\n options?.abortSignal,\n );\n let deliveredChunk = false;\n const onChunk = options?.onChunk;\n const context: ModelCallContext = {\n messages,\n modelRuntime,\n executionId,\n recordEvent,\n requestSignal,\n effectiveTimeoutMs,\n options: onChunk\n ? {\n ...options,\n onChunk: (chunk) => {\n requestSignal.throwIfAborted();\n deliveredChunk = true;\n onChunk(chunk);\n },\n }\n : options,\n };\n try {\n return await runWithAbortSignal(requestSignal, () =>\n prepared.protocol === 'codex'\n ? callCodex(context, prepared.input)\n : callOpenAI(context, prepared),\n );\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n const lastError = toError(error);\n if (deliveredChunk) {\n throw new NonRetryableModelCallError(lastError);\n }\n throw lastError;\n } finally {\n cleanup();\n }\n}\n"],"names":["DEFAULT_MODEL_API_TYPE","callAI","messages","modelRuntime","options","isStreaming","assert","executionId","uuid","internalCallId","nextInternalCallId","modelConfig","prepare","input","isCodexAppServerProvider","prepareCodexCall","apiType","prepareResponses","prepareChatCompletion","prepared","runWithAbortSignal","result","callModelWithRetry","rawUsage","timeCost","totalTimeCost","retryCount","requestId","responseModelName","response","usage","buildUsageInfo","debugProfileStats","getDebug","debugProfileDetail","JSON","NonRetryableModelCallError","Error","cause","startTime","Date","config","maxAttempts","normalizeRetryCount","retryInterval","attemptErrors","attempt","callModelOnce","error","lastError","toError","appendAIRequestFailureSummary","waitForRetry","recordEvent","isModelCallRecordingEnabled","event","recordModelCallEvent","undefined","effectiveTimeoutMs","resolveEffectiveTimeoutMs","requestSignal","cleanup","buildRequestAbortSignal","deliveredChunk","onChunk","context","chunk","callCodex","callOpenAI"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { applyImageDetail } from "../utils.mjs";
|
|
|
2
2
|
import { callAIWithCodexAppServer } from "./codex-app-server.mjs";
|
|
3
3
|
const prepareCodexCall = ({ messages, modelRuntime, options })=>{
|
|
4
4
|
const { config: modelConfig, adapter } = modelRuntime;
|
|
5
|
-
const { config
|
|
5
|
+
const { config } = adapter.buildCodexAppServerParams({
|
|
6
6
|
intent: modelConfig.intent,
|
|
7
7
|
userConfig: {
|
|
8
8
|
reasoningEnabled: modelConfig.reasoningEnabled,
|
|
@@ -11,6 +11,10 @@ const prepareCodexCall = ({ messages, modelRuntime, options })=>{
|
|
|
11
11
|
},
|
|
12
12
|
requiresOriginalImageDetail: options?.requiresOriginalImageDetail
|
|
13
13
|
});
|
|
14
|
+
const imageDetail = adapter.resolveImageDetail({
|
|
15
|
+
intent: modelConfig.intent,
|
|
16
|
+
requiresOriginalImageDetail: options?.requiresOriginalImageDetail
|
|
17
|
+
});
|
|
14
18
|
const messagesWithImageDetail = applyImageDetail({
|
|
15
19
|
imageDetail,
|
|
16
20
|
messages
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/service-caller/codex/call-codex.mjs","sources":["../../../../../src/ai-model/service-caller/codex/call-codex.ts"],"sourcesContent":["import type { ModelCallContext, ModelCallResult } from '../types';\nimport { applyImageDetail } from '../utils';\nimport {\n type CodexAppServerRecordEvent,\n callAIWithCodexAppServer,\n} from './codex-app-server';\n\nexport const prepareCodexCall = ({\n messages,\n modelRuntime,\n options,\n}: Pick<ModelCallContext, 'messages' | 'modelRuntime' | 'options'>) => {\n const { config: modelConfig, adapter } = modelRuntime;\n const { config
|
|
1
|
+
{"version":3,"file":"ai-model/service-caller/codex/call-codex.mjs","sources":["../../../../../src/ai-model/service-caller/codex/call-codex.ts"],"sourcesContent":["import type { ModelCallContext, ModelCallResult } from '../types';\nimport { applyImageDetail } from '../utils';\nimport {\n type CodexAppServerRecordEvent,\n callAIWithCodexAppServer,\n} from './codex-app-server';\n\nexport const prepareCodexCall = ({\n messages,\n modelRuntime,\n options,\n}: Pick<ModelCallContext, 'messages' | 'modelRuntime' | 'options'>) => {\n const { config: modelConfig, adapter } = modelRuntime;\n const { config } = adapter.buildCodexAppServerParams({\n intent: modelConfig.intent,\n userConfig: {\n reasoningEnabled: modelConfig.reasoningEnabled,\n reasoningEffort: modelConfig.reasoningEffort,\n reasoningBudget: modelConfig.reasoningBudget,\n },\n requiresOriginalImageDetail: options?.requiresOriginalImageDetail,\n });\n const imageDetail = adapter.resolveImageDetail({\n intent: modelConfig.intent,\n requiresOriginalImageDetail: options?.requiresOriginalImageDetail,\n });\n const messagesWithImageDetail = applyImageDetail({ imageDetail, messages });\n return { messages: messagesWithImageDetail, requestParams: config };\n};\n\nexport const callCodex = async (\n { modelRuntime, options, recordEvent, requestSignal }: ModelCallContext,\n { messages, requestParams }: ReturnType<typeof prepareCodexCall>,\n): Promise<ModelCallResult> => {\n const { config: modelConfig } = modelRuntime;\n let protocolChunkSequence = 0;\n const codexStartTime = Date.now();\n const recordCodexEvent = recordEvent\n ? (event: CodexAppServerRecordEvent) => {\n if (event.type === 'chunk') {\n protocolChunkSequence += 1;\n recordEvent({\n ...event,\n attempt: 1,\n sequence: protocolChunkSequence,\n provider: 'codex-app-server',\n });\n return;\n }\n\n recordEvent({\n ...event,\n attempt: 1,\n provider: 'codex-app-server',\n });\n }\n : undefined;\n\n try {\n const codexResult = await callAIWithCodexAppServer(messages, modelConfig, {\n stream: options?.stream,\n onChunk: options?.onChunk,\n params: requestParams,\n abortSignal: requestSignal,\n onRecordEvent: recordCodexEvent,\n });\n requestSignal.throwIfAborted();\n const { protocolMetadata, usage: rawUsage, ...response } = codexResult;\n const timeCost = Date.now() - codexStartTime;\n recordEvent?.({\n type: 'response',\n attempt: 1,\n provider: 'codex-app-server',\n final: {\n content: response.content,\n reasoningContent: response.reasoning_content,\n usage: rawUsage,\n timeCost,\n protocol: protocolMetadata,\n },\n });\n return {\n ...response,\n rawUsage,\n timeCost,\n requestId: protocolMetadata.turnId,\n };\n } catch (error) {\n recordEvent?.({\n type: 'error',\n attempt: 1,\n provider: 'codex-app-server',\n error:\n error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : String(error),\n });\n throw error;\n }\n};\n"],"names":["prepareCodexCall","messages","modelRuntime","options","modelConfig","adapter","config","imageDetail","messagesWithImageDetail","applyImageDetail","callCodex","recordEvent","requestSignal","requestParams","protocolChunkSequence","codexStartTime","Date","recordCodexEvent","event","undefined","codexResult","callAIWithCodexAppServer","protocolMetadata","rawUsage","response","timeCost","error","Error","String"],"mappings":";;AAOO,MAAMA,mBAAmB,CAAC,EAC/BC,QAAQ,EACRC,YAAY,EACZC,OAAO,EACyD;IAChE,MAAM,EAAE,QAAQC,WAAW,EAAEC,OAAO,EAAE,GAAGH;IACzC,MAAM,EAAEI,MAAM,EAAE,GAAGD,QAAQ,yBAAyB,CAAC;QACnD,QAAQD,YAAY,MAAM;QAC1B,YAAY;YACV,kBAAkBA,YAAY,gBAAgB;YAC9C,iBAAiBA,YAAY,eAAe;YAC5C,iBAAiBA,YAAY,eAAe;QAC9C;QACA,6BAA6BD,SAAS;IACxC;IACA,MAAMI,cAAcF,QAAQ,kBAAkB,CAAC;QAC7C,QAAQD,YAAY,MAAM;QAC1B,6BAA6BD,SAAS;IACxC;IACA,MAAMK,0BAA0BC,iBAAiB;QAAEF;QAAaN;IAAS;IACzE,OAAO;QAAE,UAAUO;QAAyB,eAAeF;IAAO;AACpE;AAEO,MAAMI,YAAY,OACvB,EAAER,YAAY,EAAEC,OAAO,EAAEQ,WAAW,EAAEC,aAAa,EAAoB,EACvE,EAAEX,QAAQ,EAAEY,aAAa,EAAuC;IAEhE,MAAM,EAAE,QAAQT,WAAW,EAAE,GAAGF;IAChC,IAAIY,wBAAwB;IAC5B,MAAMC,iBAAiBC,KAAK,GAAG;IAC/B,MAAMC,mBAAmBN,cACrB,CAACO;QACC,IAAIA,AAAe,YAAfA,MAAM,IAAI,EAAc;YAC1BJ,yBAAyB;YACzBH,YAAY;gBACV,GAAGO,KAAK;gBACR,SAAS;gBACT,UAAUJ;gBACV,UAAU;YACZ;YACA;QACF;QAEAH,YAAY;YACV,GAAGO,KAAK;YACR,SAAS;YACT,UAAU;QACZ;IACF,IACAC;IAEJ,IAAI;QACF,MAAMC,cAAc,MAAMC,yBAAyBpB,UAAUG,aAAa;YACxE,QAAQD,SAAS;YACjB,SAASA,SAAS;YAClB,QAAQU;YACR,aAAaD;YACb,eAAeK;QACjB;QACAL,cAAc,cAAc;QAC5B,MAAM,EAAEU,gBAAgB,EAAE,OAAOC,QAAQ,EAAE,GAAGC,UAAU,GAAGJ;QAC3D,MAAMK,WAAWT,KAAK,GAAG,KAAKD;QAC9BJ,cAAc;YACZ,MAAM;YACN,SAAS;YACT,UAAU;YACV,OAAO;gBACL,SAASa,SAAS,OAAO;gBACzB,kBAAkBA,SAAS,iBAAiB;gBAC5C,OAAOD;gBACPE;gBACA,UAAUH;YACZ;QACF;QACA,OAAO;YACL,GAAGE,QAAQ;YACXD;YACAE;YACA,WAAWH,iBAAiB,MAAM;QACpC;IACF,EAAE,OAAOI,OAAO;QACdf,cAAc;YACZ,MAAM;YACN,SAAS;YACT,UAAU;YACV,OACEe,iBAAiBC,QACb;gBACE,MAAMD,MAAM,IAAI;gBAChB,SAASA,MAAM,OAAO;gBACtB,OAAOA,MAAM,KAAK;YACpB,IACAE,OAAOF;QACf;QACA,MAAMA;IACR;AACF"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { callAIWithObjectResponse, callAIWithStringResponse, parseAIObjectResponse } from "./model-call.mjs";
|
|
2
2
|
import { callAI } from "./call-ai.mjs";
|
|
3
|
-
import { createChatClient } from "./openai/openai-client.mjs";
|
|
4
3
|
import { AIResponseParseError, INTERNAL_CALL_ID_FIELD } from "./utils.mjs";
|
|
5
4
|
import { extractJSONFromCodeBlock, parseModelResponseJson } from "../shared/json.mjs";
|
|
6
|
-
export { AIResponseParseError, INTERNAL_CALL_ID_FIELD, callAI, callAIWithObjectResponse, callAIWithStringResponse,
|
|
5
|
+
export { AIResponseParseError, INTERNAL_CALL_ID_FIELD, callAI, callAIWithObjectResponse, callAIWithStringResponse, extractJSONFromCodeBlock, parseAIObjectResponse, parseModelResponseJson };
|
|
@@ -15,7 +15,7 @@ function parseAIObjectResponse(response, modelRuntime, jsonParserSource = 'gener
|
|
|
15
15
|
contentString: response.content,
|
|
16
16
|
usage: response.usage,
|
|
17
17
|
reasoning_content: response.reasoning_content,
|
|
18
|
-
|
|
18
|
+
rawAssistantOutput: response.rawAssistantOutput
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
async function callAIWithObjectResponse(messages, modelRuntime, options) {
|
|
@@ -29,7 +29,7 @@ async function callAIWithObjectResponse(messages, modelRuntime, options) {
|
|
|
29
29
|
parseResponse: (response)=>parseAIObjectResponse(response, modelRuntime, options?.jsonParserSource),
|
|
30
30
|
toParseError: (error, response)=>{
|
|
31
31
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
32
|
-
return new AIResponseParseError(errorMessage, response.content, response.usage, response.
|
|
32
|
+
return new AIResponseParseError(errorMessage, response.content, response.usage, response.rawAssistantOutput, response.reasoning_content);
|
|
33
33
|
},
|
|
34
34
|
parseRetryTimes: options?.retryTimes ?? modelConfig.retryCount,
|
|
35
35
|
parseRetryInterval: options?.retryInterval ?? modelConfig.retryInterval,
|
|
@@ -37,11 +37,11 @@ async function callAIWithObjectResponse(messages, modelRuntime, options) {
|
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
39
|
async function callAIWithStringResponse(msgs, modelRuntime, options) {
|
|
40
|
-
const { content, usage,
|
|
40
|
+
const { content, usage, rawAssistantOutput } = await callAI(msgs, modelRuntime, options);
|
|
41
41
|
return {
|
|
42
42
|
content,
|
|
43
43
|
usage,
|
|
44
|
-
|
|
44
|
+
rawAssistantOutput
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
export { callAIWithObjectResponse, callAIWithStringResponse, parseAIObjectResponse };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/service-caller/model-call.mjs","sources":["../../../../src/ai-model/service-caller/model-call.ts"],"sourcesContent":["import type { AIUsageInfo } from '@/types';\nimport { assert } from '@midscene/shared/utils';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport type { ModelRuntime } from '../models';\nimport { type JsonParserSource, assertJsonObject } from '../shared/json';\nimport { callAI } from './call-ai';\nimport {\n callAiAndParseWithRetry,\n withSemanticRetryFeedback,\n} from './semantic-retry';\nimport type { CallAIOptions } from './types';\nimport type { AIArgs } from './types';\nimport { AIResponseParseError } from './utils';\n\nexport type AIObjectResponse<T> = {\n // TODO: `content` is a misleading name here because this is already the parsed object response. Consider renaming it to `object` or `data`.\n content: T;\n contentString: string;\n usage?: AIUsageInfo;\n reasoning_content?: string;\n
|
|
1
|
+
{"version":3,"file":"ai-model/service-caller/model-call.mjs","sources":["../../../../src/ai-model/service-caller/model-call.ts"],"sourcesContent":["import type { RawAssistantOutput } from '@/types';\nimport type { AIUsageInfo } from '@/types';\nimport { assert } from '@midscene/shared/utils';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport type { ModelRuntime } from '../models';\nimport { type JsonParserSource, assertJsonObject } from '../shared/json';\nimport { callAI } from './call-ai';\nimport {\n callAiAndParseWithRetry,\n withSemanticRetryFeedback,\n} from './semantic-retry';\nimport type { CallAIOptions } from './types';\nimport type { AIArgs } from './types';\nimport { AIResponseParseError } from './utils';\n\nexport type AIObjectResponse<T> = {\n // TODO: `content` is a misleading name here because this is already the parsed object response. Consider renaming it to `object` or `data`.\n content: T;\n contentString: string;\n usage?: AIUsageInfo;\n reasoning_content?: string;\n rawAssistantOutput?: RawAssistantOutput;\n};\n\nexport function parseAIObjectResponse<T>(\n response: Awaited<ReturnType<typeof callAI>>,\n modelRuntime: ModelRuntime,\n jsonParserSource: JsonParserSource = 'generic-object',\n): AIObjectResponse<T> {\n const { adapter } = modelRuntime;\n assert(response, 'empty response');\n const jsonContent = adapter.jsonParser(response.content, {\n source: jsonParserSource,\n });\n assertJsonObject(jsonContent);\n return {\n content: jsonContent as T,\n contentString: response.content,\n usage: response.usage,\n reasoning_content: response.reasoning_content,\n rawAssistantOutput: response.rawAssistantOutput,\n };\n}\n\nexport async function callAIWithObjectResponse<T>(\n messages: ChatCompletionMessageParam[],\n modelRuntime: ModelRuntime,\n options?: {\n abortSignal?: AbortSignal;\n jsonParserSource?: JsonParserSource;\n retryTimes?: number;\n retryInterval?: number;\n },\n): Promise<AIObjectResponse<T>> {\n const { config: modelConfig } = modelRuntime;\n return callAiAndParseWithRetry({\n callAi: (retryAttempt, previousParseError) =>\n callAI(\n withSemanticRetryFeedback(messages, previousParseError),\n modelRuntime,\n {\n abortSignal: options?.abortSignal,\n expectedJsonObjectResponse: true,\n semanticRetryAttempt: retryAttempt,\n },\n ),\n parseResponse: (response) =>\n parseAIObjectResponse<T>(\n response,\n modelRuntime,\n options?.jsonParserSource,\n ),\n toParseError: (error, response) => {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n return new AIResponseParseError(\n errorMessage,\n response.content,\n response.usage,\n response.rawAssistantOutput,\n response.reasoning_content,\n );\n },\n parseRetryTimes: options?.retryTimes ?? modelConfig.retryCount,\n parseRetryInterval: options?.retryInterval ?? modelConfig.retryInterval,\n abortSignal: options?.abortSignal,\n });\n}\n\nexport async function callAIWithStringResponse(\n msgs: AIArgs,\n modelRuntime: ModelRuntime,\n options?: Pick<CallAIOptions, 'abortSignal' | 'requiresOriginalImageDetail'>,\n): Promise<{\n content: string;\n usage?: AIUsageInfo;\n rawAssistantOutput?: RawAssistantOutput;\n}> {\n const { content, usage, rawAssistantOutput } = await callAI(\n msgs,\n modelRuntime,\n options,\n );\n return { content, usage, rawAssistantOutput };\n}\n"],"names":["parseAIObjectResponse","response","modelRuntime","jsonParserSource","adapter","assert","jsonContent","assertJsonObject","callAIWithObjectResponse","messages","options","modelConfig","callAiAndParseWithRetry","retryAttempt","previousParseError","callAI","withSemanticRetryFeedback","error","errorMessage","Error","String","AIResponseParseError","callAIWithStringResponse","msgs","content","usage","rawAssistantOutput"],"mappings":";;;;;AAwBO,SAASA,sBACdC,QAA4C,EAC5CC,YAA0B,EAC1BC,mBAAqC,gBAAgB;IAErD,MAAM,EAAEC,OAAO,EAAE,GAAGF;IACpBG,OAAOJ,UAAU;IACjB,MAAMK,cAAcF,QAAQ,UAAU,CAACH,SAAS,OAAO,EAAE;QACvD,QAAQE;IACV;IACAI,iBAAiBD;IACjB,OAAO;QACL,SAASA;QACT,eAAeL,SAAS,OAAO;QAC/B,OAAOA,SAAS,KAAK;QACrB,mBAAmBA,SAAS,iBAAiB;QAC7C,oBAAoBA,SAAS,kBAAkB;IACjD;AACF;AAEO,eAAeO,yBACpBC,QAAsC,EACtCP,YAA0B,EAC1BQ,OAKC;IAED,MAAM,EAAE,QAAQC,WAAW,EAAE,GAAGT;IAChC,OAAOU,wBAAwB;QAC7B,QAAQ,CAACC,cAAcC,qBACrBC,OACEC,0BAA0BP,UAAUK,qBACpCZ,cACA;gBACE,aAAaQ,SAAS;gBACtB,4BAA4B;gBAC5B,sBAAsBG;YACxB;QAEJ,eAAe,CAACZ,WACdD,sBACEC,UACAC,cACAQ,SAAS;QAEb,cAAc,CAACO,OAAOhB;YACpB,MAAMiB,eACJD,iBAAiBE,QAAQF,MAAM,OAAO,GAAGG,OAAOH;YAClD,OAAO,IAAII,qBACTH,cACAjB,SAAS,OAAO,EAChBA,SAAS,KAAK,EACdA,SAAS,kBAAkB,EAC3BA,SAAS,iBAAiB;QAE9B;QACA,iBAAiBS,SAAS,cAAcC,YAAY,UAAU;QAC9D,oBAAoBD,SAAS,iBAAiBC,YAAY,aAAa;QACvE,aAAaD,SAAS;IACxB;AACF;AAEO,eAAeY,yBACpBC,IAAY,EACZrB,YAA0B,EAC1BQ,OAA4E;IAM5E,MAAM,EAAEc,OAAO,EAAEC,KAAK,EAAEC,kBAAkB,EAAE,GAAG,MAAMX,OACnDQ,MACArB,cACAQ;IAEF,OAAO;QAAEc;QAASC;QAAOC;IAAmB;AAC9C"}
|