@midscene/core 1.10.8-beta-20260724035136.0 → 1.10.8
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/agent.mjs +66 -26
- package/dist/es/agent/agent.mjs.map +1 -1
- package/dist/es/agent/file-chooser.mjs +82 -0
- package/dist/es/agent/file-chooser.mjs.map +1 -0
- package/dist/es/agent/prompt-context.mjs +12 -1
- package/dist/es/agent/prompt-context.mjs.map +1 -1
- package/dist/es/agent/task-builder.mjs +11 -2
- package/dist/es/agent/task-builder.mjs.map +1 -1
- package/dist/es/agent/tasks.mjs +4 -16
- package/dist/es/agent/tasks.mjs.map +1 -1
- package/dist/es/agent/ui-utils.mjs +1 -0
- package/dist/es/agent/ui-utils.mjs.map +1 -1
- package/dist/es/agent/utils.mjs +1 -1
- package/dist/es/ai-model/inspect.mjs +1 -1
- package/dist/es/ai-model/inspect.mjs.map +1 -1
- package/dist/es/ai-model/llm-planning.mjs +2 -1
- package/dist/es/ai-model/llm-planning.mjs.map +1 -1
- package/dist/es/ai-model/model-adapter/chat-completion.mjs +3 -1
- package/dist/es/ai-model/model-adapter/chat-completion.mjs.map +1 -1
- package/dist/es/ai-model/models/kimi.mjs +35 -0
- package/dist/es/ai-model/models/kimi.mjs.map +1 -1
- package/dist/es/ai-model/prompt/extraction.mjs +4 -2
- package/dist/es/ai-model/prompt/extraction.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/codex-app-server.mjs +22 -14
- package/dist/es/ai-model/service-caller/codex-app-server.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/index.mjs +15 -14
- package/dist/es/ai-model/service-caller/index.mjs.map +1 -1
- package/dist/es/ai-model/workflows/planning/custom-planning.mjs.map +1 -1
- package/dist/es/device/index.mjs +21 -1
- package/dist/es/device/index.mjs.map +1 -1
- package/dist/es/report.mjs +1 -0
- package/dist/es/report.mjs.map +1 -1
- package/dist/es/types.mjs.map +1 -1
- package/dist/es/utils.mjs +2 -2
- package/dist/es/yaml/utils.mjs +9 -1
- package/dist/es/yaml/utils.mjs.map +1 -1
- package/dist/lib/agent/agent.js +63 -23
- package/dist/lib/agent/agent.js.map +1 -1
- package/dist/lib/agent/file-chooser.js +125 -0
- package/dist/lib/agent/file-chooser.js.map +1 -0
- package/dist/lib/agent/prompt-context.js +14 -0
- package/dist/lib/agent/prompt-context.js.map +1 -1
- package/dist/lib/agent/task-builder.js +11 -2
- package/dist/lib/agent/task-builder.js.map +1 -1
- package/dist/lib/agent/tasks.js +6 -18
- package/dist/lib/agent/tasks.js.map +1 -1
- package/dist/lib/agent/ui-utils.js +1 -0
- package/dist/lib/agent/ui-utils.js.map +1 -1
- package/dist/lib/agent/utils.js +1 -1
- package/dist/lib/ai-model/inspect.js +1 -1
- package/dist/lib/ai-model/inspect.js.map +1 -1
- package/dist/lib/ai-model/llm-planning.js +2 -1
- package/dist/lib/ai-model/llm-planning.js.map +1 -1
- package/dist/lib/ai-model/model-adapter/chat-completion.js +3 -1
- package/dist/lib/ai-model/model-adapter/chat-completion.js.map +1 -1
- package/dist/lib/ai-model/models/kimi.js +35 -0
- package/dist/lib/ai-model/models/kimi.js.map +1 -1
- package/dist/lib/ai-model/prompt/extraction.js +4 -2
- package/dist/lib/ai-model/prompt/extraction.js.map +1 -1
- package/dist/lib/ai-model/service-caller/codex-app-server.js +22 -14
- package/dist/lib/ai-model/service-caller/codex-app-server.js.map +1 -1
- package/dist/lib/ai-model/service-caller/index.js +15 -14
- package/dist/lib/ai-model/service-caller/index.js.map +1 -1
- package/dist/lib/ai-model/workflows/planning/custom-planning.js.map +1 -1
- package/dist/lib/device/index.js +27 -1
- package/dist/lib/device/index.js.map +1 -1
- package/dist/lib/report.js +1 -0
- package/dist/lib/report.js.map +1 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/utils.js +2 -2
- package/dist/lib/yaml/utils.js +9 -1
- package/dist/lib/yaml/utils.js.map +1 -1
- package/dist/types/agent/agent.d.ts +5 -2
- package/dist/types/agent/file-chooser.d.ts +19 -0
- package/dist/types/agent/prompt-context.d.ts +1 -0
- package/dist/types/agent/tasks.d.ts +1 -1
- package/dist/types/ai-model/model-adapter/types.d.ts +9 -0
- package/dist/types/ai-model/models/kimi.d.ts +18 -0
- package/dist/types/ai-model/models/registry.d.ts +18 -0
- package/dist/types/ai-model/prompt/extraction.d.ts +1 -1
- package/dist/types/ai-model/service-caller/codex-app-server.d.ts +5 -1
- package/dist/types/device/device-options.d.ts +7 -0
- package/dist/types/device/index.d.ts +11 -0
- package/dist/types/types.d.ts +6 -4
- package/dist/types/yaml.d.ts +9 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/prompt/extraction.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/prompt/extraction.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { AIDataExtractionResponse, ServiceExtractParam } from '@/types';\nimport { getPreferredLanguage } from '@midscene/shared/env';\nimport { parseModelResponseJson } from '../service-caller/json';\nimport { extractXMLTag } from './util';\n\nexport function buildTypeQueryDemandValue(\n type: 'Boolean' | 'Number' | 'String' | 'Assert' | 'WaitFor',\n demand: ServiceExtractParam,\n) {\n const currentScreenshotConstraint =\n 'based on the current screenshot and its contents if provided, unless the user explicitly asks to compare with reference images';\n\n if (type === 'Assert') {\n return `Boolean, ${currentScreenshotConstraint}, whether the following statement is true: ${demand}`;\n }\n\n if (type === 'WaitFor') {\n return `Boolean, the user wants to do some 'wait for' operation. ${currentScreenshotConstraint}, please check whether the following statement is true: ${demand}`;\n }\n\n return `${type}, ${currentScreenshotConstraint}, ${demand}`;\n}\n\n/**\n * Parse XML response from LLM and convert to AIDataExtractionResponse\n */\nexport function parseXMLExtractionResponse<T>(\n xmlString: string,\n): AIDataExtractionResponse<T> {\n // Keep the internal field named `thought`, but ask models to emit\n // <observation>. Gemini may only return <thought>-named content when\n // thinking summaries are enabled.\n const thought = extractXMLTag(xmlString, 'observation');\n const dataJsonStr = extractXMLTag(xmlString, 'data-json');\n const errorsStr = extractXMLTag(xmlString, 'errors');\n\n // Parse data-json (required)\n if (!dataJsonStr) {\n throw new Error('Missing required field: data-json');\n }\n\n let data: T;\n try {\n data = parseModelResponseJson(dataJsonStr, {\n source: 'generic-object',\n requireObject: false,\n }) as T;\n } catch (e) {\n throw new Error(`Failed to parse data-json: ${e}`);\n }\n\n // Parse errors (optional)\n let errors: string[] | undefined;\n if (errorsStr) {\n try {\n const parsedErrors = parseModelResponseJson(errorsStr, {\n source: 'generic-object',\n requireObject: false,\n });\n if (Array.isArray(parsedErrors)) {\n errors = parsedErrors;\n }\n } catch (e) {\n // If errors parsing fails, just ignore it\n }\n }\n\n return {\n ...(thought ? { thought } : {}),\n data,\n ...(errors && errors.length > 0 ? { errors } : {}),\n };\n}\n\nexport function systemPromptToExtract(options?: {\n screenshotIncluded?: boolean;\n referenceImagesIncluded?: boolean;\n}) {\n const preferredLanguage = getPreferredLanguage();\n const screenshotIncluded = options?.screenshotIncluded ?? true;\n const referenceImagesIncluded = options?.referenceImagesIncluded ?? false;\n\n const contextPrompts = [\n \"The user will give you data requirements in <DATA_DEMAND>. You need to understand the user's requirements and extract the data satisfying the <DATA_DEMAND>.\",\n ];\n\n if (screenshotIncluded) {\n contextPrompts.push(\n 'The user will provide a current screenshot to evaluate, and may provide its contents. Base your answer on the current screenshot and its contents when provided. Treat them as the primary source of truth for what is currently visible or true.',\n );\n } else {\n contextPrompts.push(\n 'The user will not provide a current screenshot. Use only the supplied page contents and other inputs, and do not infer unsupported visual details.',\n );\n }\n\n if (referenceImagesIncluded) {\n const referenceImagesPrompt =\n 'Reference images are supporting context only unless <DATA_DEMAND> explicitly asks for comparison, matching, or reasoning about them.';\n contextPrompts.push(\n screenshotIncluded\n ? `${referenceImagesPrompt} Do not conclude that something exists in the current screenshot solely because it appears in a reference image; when they conflict, trust the current screenshot and its contents.`\n : `${referenceImagesPrompt} Do not treat reference images as direct evidence of the current state unless the demand explicitly asks you to use them that way.`,\n );\n }\n const contextPrompt = contextPrompts.join('\\n\\n');\n\n return `\nYou are a versatile professional in software UI design and testing. Your outstanding contributions will impact the user experience of billions of users.\n\n${contextPrompt}\n\nIf a key specifies a JSON data type (such as Number, String, Boolean, Object, Array), ensure the returned value strictly matches that data type.\n\nWhen DATA_DEMAND is a JSON object, the keys in your response must exactly match the keys in DATA_DEMAND. Do not rename, translate, or substitute any key.\n\n\nReturn in the following XML format:\n<observation>brief evidence observed for the extraction, less than 300 words. Use ${preferredLanguage} in this field.</observation>\n<data-json>the extracted data as JSON. Make sure both the value and scheme meet the DATA_DEMAND. If you want to write some description in this field, use the same language as the DATA_DEMAND.</data-json>\n<errors>optional error messages as JSON array, e.g., [\"error1\", \"error2\"]</errors>\n\n# Example 1\nFor example, if the DATA_DEMAND is:\n\n<DATA_DEMAND>\n{\n \"name\": \"name shows on the left panel, string\",\n \"age\": \"age shows on the right panel, number\",\n \"isAdmin\": \"if the user is admin, boolean\"\n}\n</DATA_DEMAND>\n\nBy viewing the screenshot and page contents, you can extract the following data:\n\n<observation>According to the screenshot, i can see ...</observation>\n<data-json>\n{\n \"name\": \"John\",\n \"age\": 30,\n \"isAdmin\": true\n}\n</data-json>\n\n# Example 2\nIf the DATA_DEMAND is:\n\n<DATA_DEMAND>\nthe todo items list, string[]\n</DATA_DEMAND>\n\nBy viewing the screenshot and page contents, you can extract the following data:\n\n<observation>According to the screenshot, i can see ...</observation>\n<data-json>\n[\"todo 1\", \"todo 2\", \"todo 3\"]\n</data-json>\n\n# Example 3\nIf the DATA_DEMAND is:\n\n<DATA_DEMAND>\nthe page title, string\n</DATA_DEMAND>\n\nBy viewing the screenshot and page contents, you can extract the following data:\n\n<observation>According to the screenshot, i can see ...</observation>\n<data-json>\n\"todo list\"\n</data-json>\n\n# Example 4\nIf the DATA_DEMAND is:\n\n<DATA_DEMAND>\n{\n \"StatementIsTruthy\": \"Boolean, is it currently the SMS page?\"\n}\n</DATA_DEMAND>\n\nBy viewing the screenshot and page contents, you can extract the following data:\n\n<observation>According to the screenshot, i can see ...</observation>\n<data-json>\n{ \"StatementIsTruthy\": true }\n</data-json>\n`;\n}\n\nexport const extractDataQueryPrompt = (\n pageDescription: string,\n dataQuery: string | Record<string, string>,\n) => {\n let dataQueryText = '';\n if (typeof dataQuery === 'string') {\n dataQueryText = dataQuery;\n } else {\n dataQueryText = JSON.stringify(dataQuery, null, 2);\n }\n\n return `\n<PageDescription>\n${pageDescription}\n</PageDescription>\n\n<DATA_DEMAND>\n${dataQueryText}\n</DATA_DEMAND>\n `;\n};\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","buildTypeQueryDemandValue","type","demand","currentScreenshotConstraint","parseXMLExtractionResponse","xmlString","thought","extractXMLTag","dataJsonStr","errorsStr","Error","data","parseModelResponseJson","e","errors","parsedErrors","Array","systemPromptToExtract","options","preferredLanguage","getPreferredLanguage","screenshotIncluded","referenceImagesIncluded","contextPrompts","referenceImagesPrompt","contextPrompt","extractDataQueryPrompt","pageDescription","dataQuery","dataQueryText","JSON"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-model/prompt/extraction.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/prompt/extraction.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { AIDataExtractionResponse, ServiceExtractParam } from '@/types';\nimport { getPreferredLanguage } from '@midscene/shared/env';\nimport { parseModelResponseJson } from '../service-caller/json';\nimport { extractXMLTag } from './util';\n\nexport function buildTypeQueryDemandValue(\n type: 'Boolean' | 'Number' | 'String' | 'Assert' | 'WaitFor',\n demand: ServiceExtractParam,\n) {\n const currentScreenshotConstraint =\n 'based on the current screenshot and its contents if provided, unless the user explicitly asks to compare with reference images';\n\n if (type === 'Assert') {\n return `Boolean, ${currentScreenshotConstraint}, whether the following statement is true: ${demand}`;\n }\n\n if (type === 'WaitFor') {\n return `Boolean, the user wants to do some 'wait for' operation. ${currentScreenshotConstraint}, please check whether the following statement is true: ${demand}`;\n }\n\n return `${type}, ${currentScreenshotConstraint}, ${demand}`;\n}\n\n/**\n * Parse XML response from LLM and convert to AIDataExtractionResponse\n */\nexport function parseXMLExtractionResponse<T>(\n xmlString: string,\n): AIDataExtractionResponse<T> {\n // Keep the internal field named `thought`, but ask models to emit\n // <observation>. Gemini may only return <thought>-named content when\n // thinking summaries are enabled.\n const thought = extractXMLTag(xmlString, 'observation');\n const dataJsonStr = extractXMLTag(xmlString, 'data-json');\n const errorsStr = extractXMLTag(xmlString, 'errors');\n\n // Parse data-json (required)\n if (!dataJsonStr) {\n throw new Error('Missing required field: data-json');\n }\n\n let data: T;\n try {\n data = parseModelResponseJson(dataJsonStr, {\n source: 'generic-object',\n requireObject: false,\n }) as T;\n } catch (e) {\n throw new Error(`Failed to parse data-json: ${e}`);\n }\n\n // Parse errors (optional)\n let errors: string[] | undefined;\n if (errorsStr) {\n try {\n const parsedErrors = parseModelResponseJson(errorsStr, {\n source: 'generic-object',\n requireObject: false,\n });\n if (Array.isArray(parsedErrors)) {\n errors = parsedErrors;\n }\n } catch (e) {\n // If errors parsing fails, just ignore it\n }\n }\n\n return {\n ...(thought ? { thought } : {}),\n data,\n ...(errors && errors.length > 0 ? { errors } : {}),\n };\n}\n\nexport function systemPromptToExtract(options?: {\n screenshotIncluded?: boolean;\n referenceImagesIncluded?: boolean;\n}) {\n const preferredLanguage = getPreferredLanguage();\n const screenshotIncluded = options?.screenshotIncluded ?? true;\n const referenceImagesIncluded = options?.referenceImagesIncluded ?? false;\n\n const contextPrompts = [\n \"The user will give you data requirements in <DATA_DEMAND>. You need to understand the user's requirements and extract the data satisfying the <DATA_DEMAND>.\",\n ];\n\n if (screenshotIncluded) {\n contextPrompts.push(\n 'The user will provide a current screenshot to evaluate, and may provide its contents. Base your answer on the current screenshot and its contents when provided. Treat them as the primary source of truth for what is currently visible or true.',\n );\n } else {\n contextPrompts.push(\n 'The user will not provide a current screenshot. Use only the supplied page contents and other inputs, and do not infer unsupported visual details.',\n );\n }\n\n if (referenceImagesIncluded) {\n const referenceImagesPrompt =\n 'Reference images are supporting context only unless <DATA_DEMAND> explicitly asks for comparison, matching, or reasoning about them.';\n contextPrompts.push(\n screenshotIncluded\n ? `${referenceImagesPrompt} Do not conclude that something exists in the current screenshot solely because it appears in a reference image; when they conflict, trust the current screenshot and its contents.`\n : `${referenceImagesPrompt} Do not treat reference images as direct evidence of the current state unless the demand explicitly asks you to use them that way.`,\n );\n }\n const contextPrompt = contextPrompts.join('\\n\\n');\n\n return `\nYou are a versatile professional in software UI design and testing. Your outstanding contributions will impact the user experience of billions of users.\n\n${contextPrompt}\n\nIf a key specifies a JSON data type (such as Number, String, Boolean, Object, Array), ensure the returned value strictly matches that data type.\n\nWhen DATA_DEMAND is a JSON object, the keys in your response must exactly match the keys in DATA_DEMAND. Do not rename, translate, or substitute any key.\n\n\nReturn in the following XML format:\n<observation>brief evidence observed for the extraction, less than 300 words. Use ${preferredLanguage} in this field.</observation>\n<data-json>the extracted data as JSON. Make sure both the value and scheme meet the DATA_DEMAND. If you want to write some description in this field, use the same language as the DATA_DEMAND.</data-json>\n<errors>optional error messages as JSON array, e.g., [\"error1\", \"error2\"]</errors>\n\n# Example 1\nFor example, if the DATA_DEMAND is:\n\n<DATA_DEMAND>\n{\n \"name\": \"name shows on the left panel, string\",\n \"age\": \"age shows on the right panel, number\",\n \"isAdmin\": \"if the user is admin, boolean\"\n}\n</DATA_DEMAND>\n\nBy viewing the screenshot and page contents, you can extract the following data:\n\n<observation>According to the screenshot, i can see ...</observation>\n<data-json>\n{\n \"name\": \"John\",\n \"age\": 30,\n \"isAdmin\": true\n}\n</data-json>\n\n# Example 2\nIf the DATA_DEMAND is:\n\n<DATA_DEMAND>\nthe todo items list, string[]\n</DATA_DEMAND>\n\nBy viewing the screenshot and page contents, you can extract the following data:\n\n<observation>According to the screenshot, i can see ...</observation>\n<data-json>\n[\"todo 1\", \"todo 2\", \"todo 3\"]\n</data-json>\n\n# Example 3\nIf the DATA_DEMAND is:\n\n<DATA_DEMAND>\nthe page title, string\n</DATA_DEMAND>\n\nBy viewing the screenshot and page contents, you can extract the following data:\n\n<observation>According to the screenshot, i can see ...</observation>\n<data-json>\n\"todo list\"\n</data-json>\n\n# Example 4\nIf the DATA_DEMAND is:\n\n<DATA_DEMAND>\n{\n \"StatementIsTruthy\": \"Boolean, is it currently the SMS page?\"\n}\n</DATA_DEMAND>\n\nBy viewing the screenshot and page contents, you can extract the following data:\n\n<observation>According to the screenshot, i can see ...</observation>\n<data-json>\n{ \"StatementIsTruthy\": true }\n</data-json>\n`;\n}\n\nexport const extractDataQueryPrompt = (\n pageDescription: string,\n dataQuery: string | Record<string, string>,\n context?: string,\n) => {\n let dataQueryText = '';\n if (typeof dataQuery === 'string') {\n dataQueryText = dataQuery;\n } else {\n dataQueryText = JSON.stringify(dataQuery, null, 2);\n }\n\n const trimmedContext = context?.trim();\n const contextSection = trimmedContext\n ? `\\n<CONTEXT>\\n${trimmedContext}\\n</CONTEXT>\\n`\n : '';\n\n return `\n<PageDescription>\n${pageDescription}\n</PageDescription>\n${contextSection}\n<DATA_DEMAND>\n${dataQueryText}\n</DATA_DEMAND>\n `;\n};\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","buildTypeQueryDemandValue","type","demand","currentScreenshotConstraint","parseXMLExtractionResponse","xmlString","thought","extractXMLTag","dataJsonStr","errorsStr","Error","data","parseModelResponseJson","e","errors","parsedErrors","Array","systemPromptToExtract","options","preferredLanguage","getPreferredLanguage","screenshotIncluded","referenceImagesIncluded","contextPrompts","referenceImagesPrompt","contextPrompt","extractDataQueryPrompt","pageDescription","dataQuery","context","dataQueryText","JSON","trimmedContext","contextSection"],"mappings":"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"}
|
|
@@ -85,6 +85,7 @@ const toNonEmptyString = (value)=>{
|
|
|
85
85
|
const trimmed = value.trim();
|
|
86
86
|
return trimmed || void 0;
|
|
87
87
|
};
|
|
88
|
+
const toCodexImageDetail = (value)=>'auto' === value || 'low' === value || 'high' === value || 'original' === value ? value : void 0;
|
|
88
89
|
const normalizeCodexLocalImagePath = (imageUrl, platform = process.platform)=>{
|
|
89
90
|
if (!imageUrl.startsWith('file://')) return imageUrl;
|
|
90
91
|
try {
|
|
@@ -113,7 +114,7 @@ const extractTextFromMessage = (message)=>{
|
|
|
113
114
|
}).filter(Boolean).join('\n');
|
|
114
115
|
return '';
|
|
115
116
|
};
|
|
116
|
-
const extractImageInputs = (message)=>{
|
|
117
|
+
const extractImageInputs = (message, imageDetailOverride)=>{
|
|
117
118
|
const content = message.content;
|
|
118
119
|
if (!Array.isArray(content)) return [];
|
|
119
120
|
const inputs = [];
|
|
@@ -121,32 +122,37 @@ const extractImageInputs = (message)=>{
|
|
|
121
122
|
if (!part || 'object' != typeof part) continue;
|
|
122
123
|
const partType = String(part.type || '');
|
|
123
124
|
const imageUrl = 'image_url' === partType ? toNonEmptyString(part.image_url?.url) : 'input_image' === partType ? toNonEmptyString(part.image_url || part.url) : void 0;
|
|
125
|
+
const imageDetail = imageDetailOverride ?? toCodexImageDetail('image_url' === partType ? part.image_url?.detail : part.detail);
|
|
124
126
|
if (imageUrl) {
|
|
125
127
|
if (imageUrl.startsWith('/') || imageUrl.startsWith('./') || imageUrl.startsWith('../') || imageUrl.startsWith('file://')) {
|
|
126
128
|
const path = imageUrl.startsWith('file://') ? normalizeCodexLocalImagePath(imageUrl) : imageUrl;
|
|
127
129
|
inputs.push({
|
|
128
130
|
type: 'localImage',
|
|
129
|
-
path
|
|
131
|
+
path,
|
|
132
|
+
...imageDetail ? {
|
|
133
|
+
detail: imageDetail
|
|
134
|
+
} : {}
|
|
130
135
|
});
|
|
131
136
|
continue;
|
|
132
137
|
}
|
|
133
138
|
inputs.push({
|
|
134
139
|
type: 'image',
|
|
135
|
-
url: imageUrl
|
|
140
|
+
url: imageUrl,
|
|
141
|
+
...imageDetail ? {
|
|
142
|
+
detail: imageDetail
|
|
143
|
+
} : {}
|
|
136
144
|
});
|
|
137
145
|
}
|
|
138
146
|
}
|
|
139
147
|
return inputs;
|
|
140
148
|
};
|
|
141
149
|
const resolveCodexReasoningEffort = ({ reasoningEnabled, modelConfig })=>{
|
|
142
|
-
if (true
|
|
143
|
-
if (false === reasoningEnabled) return 'none';
|
|
144
|
-
if ('default' === reasoningEnabled) return;
|
|
150
|
+
if (true !== reasoningEnabled) return 'none';
|
|
145
151
|
const normalized = modelConfig.reasoningEffort?.trim().toLowerCase();
|
|
146
152
|
if ('none' === normalized || 'minimal' === normalized || 'low' === normalized || 'medium' === normalized || 'high' === normalized || 'xhigh' === normalized) return normalized;
|
|
147
|
-
return '
|
|
153
|
+
return 'medium';
|
|
148
154
|
};
|
|
149
|
-
const buildCodexTurnPayloadFromMessages = (messages)=>{
|
|
155
|
+
const buildCodexTurnPayloadFromMessages = (messages, imageDetailOverride)=>{
|
|
150
156
|
const developerInstructionParts = [];
|
|
151
157
|
const transcriptParts = [];
|
|
152
158
|
const imageInputs = [];
|
|
@@ -160,7 +166,7 @@ const buildCodexTurnPayloadFromMessages = (messages)=>{
|
|
|
160
166
|
const roleTag = role.toUpperCase();
|
|
161
167
|
if (text.trim()) transcriptParts.push(`[${roleTag}]\n${text.trim()}`);
|
|
162
168
|
else transcriptParts.push(`[${roleTag}]\n(no text content)`);
|
|
163
|
-
if ('user' === role) imageInputs.push(...extractImageInputs(message));
|
|
169
|
+
if ('user' === role) imageInputs.push(...extractImageInputs(message, imageDetailOverride));
|
|
164
170
|
}
|
|
165
171
|
const fullTranscript = transcriptParts.join('\n\n');
|
|
166
172
|
const transcriptText = (fullTranscript.length > CODEX_TEXT_INPUT_MAX_LENGTH ? fullTranscript.slice(-CODEX_TEXT_INPUT_MAX_LENGTH) : fullTranscript) || 'Please answer the latest user request.';
|
|
@@ -208,12 +214,12 @@ class CodexAppServerConnection {
|
|
|
208
214
|
isClosed() {
|
|
209
215
|
return this.closed;
|
|
210
216
|
}
|
|
211
|
-
async runTurn({ messages, modelConfig, stream, onChunk, reasoningEnabled, abortSignal }) {
|
|
217
|
+
async runTurn({ messages, modelConfig, stream, onChunk, reasoningEnabled, abortSignal, imageDetail }) {
|
|
212
218
|
const startTime = Date.now();
|
|
213
219
|
const timeoutMs = modelConfig.timeout || CODEX_DEFAULT_TIMEOUT_MS;
|
|
214
220
|
const deadlineAt = Date.now() + timeoutMs;
|
|
215
221
|
const isStreaming = !!(stream && onChunk);
|
|
216
|
-
const { developerInstructions, input } = buildCodexTurnPayloadFromMessages(messages);
|
|
222
|
+
const { developerInstructions, input } = buildCodexTurnPayloadFromMessages(messages, imageDetail);
|
|
217
223
|
const effort = resolveCodexReasoningEffort({
|
|
218
224
|
reasoningEnabled,
|
|
219
225
|
modelConfig
|
|
@@ -551,7 +557,7 @@ class CodexAppServerConnection {
|
|
|
551
557
|
}
|
|
552
558
|
}
|
|
553
559
|
class CodexAppServerConnectionManager {
|
|
554
|
-
async runTurn({ messages, modelConfig, stream, onChunk, reasoningEnabled, abortSignal }) {
|
|
560
|
+
async runTurn({ messages, modelConfig, stream, onChunk, reasoningEnabled, abortSignal, imageDetail }) {
|
|
555
561
|
return this.runner.run(async ()=>{
|
|
556
562
|
const connection = await this.getConnection();
|
|
557
563
|
try {
|
|
@@ -561,7 +567,8 @@ class CodexAppServerConnectionManager {
|
|
|
561
567
|
stream,
|
|
562
568
|
onChunk,
|
|
563
569
|
reasoningEnabled,
|
|
564
|
-
abortSignal
|
|
570
|
+
abortSignal,
|
|
571
|
+
imageDetail
|
|
565
572
|
});
|
|
566
573
|
} catch (error) {
|
|
567
574
|
if (connection.isClosed() || !isAbortError(error)) await this.resetConnection();
|
|
@@ -600,7 +607,8 @@ async function callAIWithCodexAppServer(messages, modelConfig, options) {
|
|
|
600
607
|
stream: options?.stream,
|
|
601
608
|
onChunk: options?.onChunk,
|
|
602
609
|
reasoningEnabled: options?.reasoningEnabled,
|
|
603
|
-
abortSignal: options?.abortSignal
|
|
610
|
+
abortSignal: options?.abortSignal,
|
|
611
|
+
imageDetail: options?.imageDetail
|
|
604
612
|
});
|
|
605
613
|
}
|
|
606
614
|
async function __shutdownCodexAppServerForTests() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/service-caller/codex-app-server.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/service-caller/codex-app-server.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type {\n AIUsageInfo,\n CodeGenerationChunk,\n StreamingCallback,\n} from '@/types';\nimport type {\n IModelConfig,\n TModelReasoningEnabled,\n} from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { ifInBrowser } from '@midscene/shared/utils';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\n\nconst CODEX_PROVIDER_SCHEME = 'codex://';\nconst CODEX_DEFAULT_TIMEOUT_MS = 10 * 60 * 1000;\nconst CODEX_DEFAULT_PROCESS_START_TIMEOUT_MS = 15 * 1000;\nconst CODEX_DEFAULT_CLEANUP_TIMEOUT_MS = 8 * 1000;\nconst CODEX_TEXT_INPUT_MAX_LENGTH = 256 * 1024;\n\nconst debugCodex = getDebug('ai:call:codex');\nconst warnCodex = getDebug('ai:call:codex', { console: true });\n\ntype CodexReasoningEffort =\n | 'none'\n | 'minimal'\n | 'low'\n | 'medium'\n | 'high'\n | 'xhigh';\n\ntype JsonRpcRequest = {\n id: string | number;\n method: string;\n params?: unknown;\n};\n\ntype JsonRpcResponse = {\n id: string | number;\n result?: unknown;\n error?: {\n code?: number;\n message?: string;\n data?: unknown;\n };\n};\n\ntype JsonRpcNotification = {\n method: string;\n params?: Record<string, any>;\n};\n\ntype JsonRpcMessage = JsonRpcRequest | JsonRpcResponse | JsonRpcNotification;\n\ntype CodexTextInput = {\n type: 'text';\n text: string;\n text_elements: any[];\n};\n\ntype CodexImageInput = {\n type: 'image';\n url: string;\n};\n\ntype CodexLocalImageInput = {\n type: 'localImage';\n path: string;\n};\n\ntype CodexTurnInput = CodexTextInput | CodexImageInput | CodexLocalImageInput;\n\ntype CodexTurnResult = {\n content: string;\n reasoning_content?: string;\n usage?: AIUsageInfo;\n isStreamed: boolean;\n};\n\ntype CodexTurnStartResponse = {\n turn?: {\n id?: string;\n };\n};\n\ntype CodexThreadStartResponse = {\n thread?: {\n id?: string;\n };\n};\n\ntype CodexUsageNotification = {\n threadId?: string;\n turnId?: string;\n tokenUsage?: {\n total?: {\n totalTokens?: number;\n inputTokens?: number;\n cachedInputTokens?: number;\n outputTokens?: number;\n reasoningOutputTokens?: number;\n };\n last?: {\n totalTokens?: number;\n inputTokens?: number;\n cachedInputTokens?: number;\n outputTokens?: number;\n reasoningOutputTokens?: number;\n };\n };\n};\n\nclass SerializedRunner {\n private tail: Promise<void> = Promise.resolve();\n\n async run<T>(work: () => Promise<T>): Promise<T> {\n const previous = this.tail;\n let release!: () => void;\n this.tail = new Promise<void>((resolve) => {\n release = resolve;\n });\n\n await previous;\n try {\n return await work();\n } finally {\n release();\n }\n }\n}\n\nexport const isCodexAppServerProvider = (baseURL?: string): boolean => {\n if (!baseURL) return false;\n return baseURL.trim().toLowerCase().startsWith(CODEX_PROVIDER_SCHEME);\n};\n\nconst isAbortError = (error: unknown): boolean => {\n if (!error) return false;\n if (error instanceof Error && error.name === 'AbortError') return true;\n const message =\n error instanceof Error ? error.message : String(error ?? 'unknown error');\n return /aborted|abort/i.test(message);\n};\n\nconst toNonEmptyString = (value: unknown): string | undefined => {\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return trimmed || undefined;\n};\n\nexport const normalizeCodexLocalImagePath = (\n imageUrl: string,\n platform: NodeJS.Platform = process.platform,\n): string => {\n if (!imageUrl.startsWith('file://')) {\n return imageUrl;\n }\n\n try {\n const parsed = new URL(imageUrl);\n const pathname = decodeURIComponent(parsed.pathname);\n const host = parsed.hostname.toLowerCase();\n\n if (platform === 'win32') {\n const windowsPath = pathname\n .replace(/\\//g, '\\\\')\n .replace(/^\\\\([A-Za-z]:)/, '$1');\n\n if (host && host !== 'localhost') {\n return `\\\\\\\\${parsed.hostname}${windowsPath}`;\n }\n\n return windowsPath;\n }\n\n if (host && host !== 'localhost') {\n return `//${parsed.hostname}${pathname}`;\n }\n\n return pathname;\n } catch {\n return decodeURIComponent(imageUrl.slice('file://'.length));\n }\n};\n\nconst extractTextFromMessage = (\n message: ChatCompletionMessageParam,\n): string => {\n const content = (message as any).content;\n if (typeof content === 'string') {\n return content;\n }\n\n if (Array.isArray(content)) {\n return content\n .map((part) => {\n if (!part || typeof part !== 'object') return '';\n\n if (part.type === 'text' && typeof part.text === 'string') {\n return part.text;\n }\n\n if (part.type === 'input_text' && typeof part.text === 'string') {\n return part.text;\n }\n\n return '';\n })\n .filter(Boolean)\n .join('\\n');\n }\n\n return '';\n};\n\nconst extractImageInputs = (\n message: ChatCompletionMessageParam,\n): Array<CodexImageInput | CodexLocalImageInput> => {\n const content = (message as any).content;\n if (!Array.isArray(content)) return [];\n\n const inputs: Array<CodexImageInput | CodexLocalImageInput> = [];\n for (const part of content) {\n if (!part || typeof part !== 'object') continue;\n\n const partType = String(part.type || '');\n const imageUrl =\n partType === 'image_url'\n ? toNonEmptyString(part.image_url?.url)\n : partType === 'input_image'\n ? toNonEmptyString(part.image_url || part.url)\n : undefined;\n\n if (!imageUrl) continue;\n\n if (\n imageUrl.startsWith('/') ||\n imageUrl.startsWith('./') ||\n imageUrl.startsWith('../') ||\n imageUrl.startsWith('file://')\n ) {\n const path = imageUrl.startsWith('file://')\n ? normalizeCodexLocalImagePath(imageUrl)\n : imageUrl;\n\n inputs.push({\n type: 'localImage',\n path,\n });\n continue;\n }\n\n inputs.push({\n type: 'image',\n url: imageUrl,\n });\n }\n\n return inputs;\n};\n\nexport const resolveCodexReasoningEffort = ({\n reasoningEnabled,\n modelConfig,\n}: {\n reasoningEnabled?: TModelReasoningEnabled;\n modelConfig: IModelConfig;\n}): CodexReasoningEffort | undefined => {\n if (reasoningEnabled === true) return 'high';\n if (reasoningEnabled === false) return 'none';\n if (reasoningEnabled === 'default') return undefined;\n\n const normalized = modelConfig.reasoningEffort?.trim().toLowerCase();\n if (\n normalized === 'none' ||\n normalized === 'minimal' ||\n normalized === 'low' ||\n normalized === 'medium' ||\n normalized === 'high' ||\n normalized === 'xhigh'\n ) {\n return normalized;\n }\n\n return 'none';\n};\n\nexport const buildCodexTurnPayloadFromMessages = (\n messages: ChatCompletionMessageParam[],\n): {\n developerInstructions?: string;\n input: CodexTurnInput[];\n} => {\n const developerInstructionParts: string[] = [];\n const transcriptParts: string[] = [];\n const imageInputs: Array<CodexImageInput | CodexLocalImageInput> = [];\n\n for (const message of messages) {\n const role = String((message as any).role || 'user');\n const text = extractTextFromMessage(message);\n\n if (role === 'system') {\n if (text.trim()) developerInstructionParts.push(text.trim());\n continue;\n }\n\n const roleTag = role.toUpperCase();\n if (text.trim()) {\n transcriptParts.push(`[${roleTag}]\\n${text.trim()}`);\n } else {\n transcriptParts.push(`[${roleTag}]\\n(no text content)`);\n }\n\n if (role === 'user') {\n imageInputs.push(...extractImageInputs(message));\n }\n }\n\n const fullTranscript = transcriptParts.join('\\n\\n');\n const transcriptText =\n (fullTranscript.length > CODEX_TEXT_INPUT_MAX_LENGTH\n ? fullTranscript.slice(-CODEX_TEXT_INPUT_MAX_LENGTH)\n : fullTranscript) || 'Please answer the latest user request.';\n\n const input: CodexTurnInput[] = [\n {\n type: 'text',\n text: transcriptText,\n text_elements: [],\n },\n ...imageInputs,\n ];\n\n const developerInstructions = developerInstructionParts.length\n ? developerInstructionParts.join('\\n\\n')\n : undefined;\n\n return {\n developerInstructions,\n input,\n };\n};\n\nclass CodexAppServerConnection {\n private child: any;\n private lineReader: any;\n private pendingMessages: JsonRpcMessage[] = [];\n private lineBuffer: string[] = [];\n private nextRequestId = 1;\n private closed = false;\n private lastExitCode: number | null = null;\n private processErrorMessage: string | null = null;\n private stderrBuffer = '';\n\n private constructor(child: any, lineReader: any) {\n this.child = child;\n this.lineReader = lineReader;\n }\n\n static async create(): Promise<CodexAppServerConnection> {\n if (ifInBrowser) {\n throw new Error(\n 'codex app-server provider is not supported in browser runtime',\n );\n }\n\n const childProcessModuleName = 'node:child_process';\n const readlineModuleName = 'node:readline';\n const { spawn } = await import(childProcessModuleName);\n const readline = await import(readlineModuleName);\n\n const child = spawn('codex', ['app-server'], {\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n if (!child.stdin || !child.stdout || !child.stderr) {\n throw new Error('failed to start codex app-server: stdio unavailable');\n }\n\n const lineReader = readline.createInterface({\n input: child.stdout,\n crlfDelay: Number.POSITIVE_INFINITY,\n });\n const connection = new CodexAppServerConnection(child, lineReader);\n connection.detachFromEventLoop();\n connection.attachProcessListeners();\n await connection.initializeHandshake();\n\n return connection;\n }\n\n isClosed(): boolean {\n return this.closed;\n }\n\n async runTurn({\n messages,\n modelConfig,\n stream,\n onChunk,\n reasoningEnabled,\n abortSignal,\n }: {\n messages: ChatCompletionMessageParam[];\n modelConfig: IModelConfig;\n stream?: boolean;\n onChunk?: StreamingCallback;\n reasoningEnabled?: TModelReasoningEnabled;\n abortSignal?: AbortSignal;\n }): Promise<CodexTurnResult> {\n const startTime = Date.now();\n const timeoutMs = modelConfig.timeout || CODEX_DEFAULT_TIMEOUT_MS;\n const deadlineAt = Date.now() + timeoutMs;\n const isStreaming = !!(stream && onChunk);\n\n const { developerInstructions, input } =\n buildCodexTurnPayloadFromMessages(messages);\n const effort = resolveCodexReasoningEffort({\n reasoningEnabled,\n modelConfig,\n });\n\n let threadId: string | undefined;\n let turnId: string | undefined;\n let latestErrorMessage: string | undefined;\n let accumulatedText = '';\n let accumulatedReasoning = '';\n let latestUsage: AIUsageInfo | undefined;\n\n const emitChunk = ({\n content,\n reasoning,\n isComplete,\n usage,\n }: {\n content: string;\n reasoning: string;\n isComplete: boolean;\n usage?: AIUsageInfo;\n }) => {\n if (!isStreaming || !onChunk) return;\n const chunk: CodeGenerationChunk = {\n content,\n reasoning_content: reasoning,\n accumulated: accumulatedText,\n isComplete,\n usage,\n };\n onChunk(chunk);\n };\n\n try {\n const threadStartResponse = await this.request<CodexThreadStartResponse>({\n method: 'thread/start',\n params: {\n model: modelConfig.modelName,\n cwd: process.cwd(),\n approvalPolicy: 'never',\n sandbox: 'read-only',\n ephemeral: true,\n experimentalRawEvents: false,\n persistExtendedHistory: false,\n developerInstructions: developerInstructions || null,\n },\n deadlineAt,\n abortSignal,\n });\n\n threadId = threadStartResponse?.thread?.id;\n if (!threadId) {\n throw new Error('thread/start did not return a thread id');\n }\n\n const turnStartResponse = await this.request<CodexTurnStartResponse>({\n method: 'turn/start',\n params: {\n threadId,\n input,\n effort,\n },\n deadlineAt,\n abortSignal,\n });\n\n turnId = turnStartResponse?.turn?.id;\n if (!turnId) {\n throw new Error('turn/start did not return a turn id');\n }\n\n let turnStatus: string | undefined;\n while (!turnStatus) {\n const message = await this.nextMessage({ deadlineAt, abortSignal });\n\n if (this.isResponseMessage(message)) {\n // No concurrent requests in adapter runtime.\n continue;\n }\n\n if (this.isRequestMessage(message)) {\n await this.respondToServerRequest(message);\n continue;\n }\n\n const notification = message as JsonRpcNotification;\n const method = notification.method;\n const params = notification.params || {};\n\n if (method === 'error') {\n const messageText =\n params.error?.message ||\n params.message ||\n 'codex app-server reported turn error';\n latestErrorMessage = String(messageText);\n continue;\n }\n\n if (\n method === 'item/agentMessage/delta' &&\n params.threadId === threadId &&\n params.turnId === turnId\n ) {\n const delta = String(params.delta || '');\n if (delta) {\n accumulatedText += delta;\n emitChunk({\n content: delta,\n reasoning: '',\n isComplete: false,\n });\n }\n continue;\n }\n\n if (\n (method === 'item/reasoning/summaryTextDelta' ||\n method === 'item/reasoning/textDelta') &&\n params.threadId === threadId &&\n params.turnId === turnId\n ) {\n const delta = String(params.delta || '');\n if (delta) {\n accumulatedReasoning += delta;\n emitChunk({\n content: '',\n reasoning: delta,\n isComplete: false,\n });\n }\n continue;\n }\n\n if (\n method === 'item/completed' &&\n params.threadId === threadId &&\n params.turnId === turnId &&\n params.item?.type === 'agentMessage' &&\n typeof params.item?.text === 'string' &&\n !accumulatedText\n ) {\n accumulatedText = params.item.text;\n continue;\n }\n\n if (\n method === 'thread/tokenUsage/updated' &&\n params.threadId === threadId &&\n params.turnId === turnId\n ) {\n latestUsage = this.mapUsage({\n usage: params as CodexUsageNotification,\n modelConfig,\n turnId,\n startTime,\n });\n continue;\n }\n\n if (\n method === 'turn/completed' &&\n params.threadId === threadId &&\n params.turn?.id === turnId\n ) {\n turnStatus = String(params.turn.status || '');\n latestErrorMessage =\n params.turn?.error?.message || latestErrorMessage || undefined;\n break;\n }\n }\n\n if (turnStatus !== 'completed') {\n throw new Error(\n latestErrorMessage ||\n `codex turn finished with status \"${turnStatus || 'unknown'}\"`,\n );\n }\n\n if (isStreaming) {\n emitChunk({\n content: '',\n reasoning: '',\n isComplete: true,\n usage: latestUsage,\n });\n }\n\n return {\n content: accumulatedText,\n reasoning_content: accumulatedReasoning || undefined,\n usage: latestUsage,\n isStreamed: isStreaming,\n };\n } catch (error) {\n if (isAbortError(error) && threadId && turnId) {\n await this.request({\n method: 'turn/interrupt',\n params: {\n threadId,\n turnId,\n },\n deadlineAt: Date.now() + 5_000,\n }).catch(() => {});\n }\n throw error;\n } finally {\n if (threadId) {\n await this.request({\n method: 'thread/unsubscribe',\n params: { threadId },\n deadlineAt: Date.now() + CODEX_DEFAULT_CLEANUP_TIMEOUT_MS,\n }).catch((error) => {\n warnCodex(\n `failed to unsubscribe codex thread ${threadId}: ${String(error)}`,\n );\n });\n }\n }\n }\n\n async dispose(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n\n try {\n this.lineReader?.close?.();\n } catch {}\n\n try {\n this.child?.stdin?.end?.();\n } catch {}\n\n try {\n this.child?.kill?.();\n } catch {}\n }\n\n private attachProcessListeners() {\n this.lineReader.on('line', (line: string) => {\n this.lineBuffer.push(line);\n });\n\n this.child.stderr.on('data', (chunk: Buffer | string) => {\n const text = Buffer.isBuffer(chunk)\n ? chunk.toString('utf8')\n : String(chunk);\n this.stderrBuffer += text;\n if (this.stderrBuffer.length > 8192) {\n this.stderrBuffer = this.stderrBuffer.slice(-8192);\n }\n });\n\n this.child.on('exit', (code: number | null) => {\n this.closed = true;\n this.lastExitCode = code;\n });\n\n this.child.on('error', (error: Error) => {\n this.closed = true;\n this.processErrorMessage = error.message;\n });\n }\n\n /**\n * Keep codex process reusable but let short-lived callers exit naturally.\n * Without unref, one-shot scripts/tests that call AI once can hang.\n */\n private detachFromEventLoop() {\n this.child.unref?.();\n this.child.stdin?.unref?.();\n this.child.stdout?.unref?.();\n this.child.stderr?.unref?.();\n }\n\n private async initializeHandshake() {\n const deadlineAt = Date.now() + CODEX_DEFAULT_PROCESS_START_TIMEOUT_MS;\n await this.request({\n method: 'initialize',\n params: {\n clientInfo: {\n name: 'midscene_codex_provider',\n title: 'Midscene Codex Provider',\n version: '1.0.0',\n },\n capabilities: {\n experimentalApi: false,\n },\n },\n deadlineAt,\n });\n await this.sendMessage({\n method: 'initialized',\n });\n }\n\n private mapUsage({\n usage,\n modelConfig,\n turnId,\n startTime,\n }: {\n usage: CodexUsageNotification;\n modelConfig: IModelConfig;\n turnId: string;\n startTime: number;\n }): AIUsageInfo | undefined {\n const tokenUsage = usage.tokenUsage;\n const picked = tokenUsage?.last || tokenUsage?.total;\n if (!picked) return undefined;\n\n return {\n ...picked,\n prompt_tokens: picked.inputTokens ?? 0,\n completion_tokens: picked.outputTokens ?? 0,\n total_tokens: picked.totalTokens ?? 0,\n cached_input: picked.cachedInputTokens ?? 0,\n time_cost: Date.now() - startTime,\n model_name: modelConfig.modelName,\n model_description: modelConfig.modelDescription,\n response_model_name: undefined,\n slot: modelConfig.slot,\n intent: undefined,\n request_id: turnId,\n } satisfies AIUsageInfo;\n }\n\n private isRequestMessage(message: JsonRpcMessage): message is JsonRpcRequest {\n return (\n typeof (message as any)?.method === 'string' &&\n (message as any)?.id !== undefined\n );\n }\n\n private isResponseMessage(\n message: JsonRpcMessage,\n ): message is JsonRpcResponse {\n return (\n (message as any)?.id !== undefined &&\n ((message as any)?.result !== undefined ||\n (message as any)?.error !== undefined) &&\n typeof (message as any)?.method !== 'string'\n );\n }\n\n private async request<T = unknown>({\n method,\n params,\n deadlineAt,\n abortSignal,\n }: {\n method: string;\n params: unknown;\n deadlineAt?: number;\n abortSignal?: AbortSignal;\n }): Promise<T> {\n const requestId = this.nextRequestId++;\n\n await this.sendMessage({\n id: requestId,\n method,\n params,\n });\n\n while (true) {\n const message = await this.nextMessage({\n deadlineAt,\n abortSignal,\n includePending: false,\n });\n\n if (this.isResponseMessage(message) && message.id === requestId) {\n if (message.error) {\n throw new Error(\n `codex app-server ${method} failed: ${\n message.error.message || 'unknown error'\n }`,\n );\n }\n return (message.result || {}) as T;\n }\n\n if (this.isRequestMessage(message)) {\n await this.respondToServerRequest(message);\n continue;\n }\n\n // Keep unmatched notifications/other responses for later stream handling.\n this.pendingMessages.push(message);\n }\n }\n\n private async respondToServerRequest(request: JsonRpcRequest): Promise<void> {\n const requestId = request.id;\n const method = request.method;\n\n let result: unknown = {};\n if (method === 'item/commandExecution/requestApproval') {\n result = { decision: 'decline' };\n } else if (method === 'item/fileChange/requestApproval') {\n result = { decision: 'decline' };\n } else if (method === 'mcpServer/elicitation/request') {\n result = { action: 'cancel', content: null };\n } else if (method === 'item/tool/requestUserInput') {\n result = { answers: [] };\n } else {\n await this.sendMessage({\n id: requestId,\n error: {\n code: -32601,\n message: `unsupported server request: ${method}`,\n },\n });\n return;\n }\n\n await this.sendMessage({\n id: requestId,\n result,\n });\n }\n\n private async nextMessage({\n deadlineAt,\n abortSignal,\n includePending = true,\n }: {\n deadlineAt?: number;\n abortSignal?: AbortSignal;\n includePending?: boolean;\n }): Promise<JsonRpcMessage> {\n if (includePending && this.pendingMessages.length) {\n return this.pendingMessages.shift() as JsonRpcMessage;\n }\n\n while (true) {\n if (abortSignal?.aborted) {\n throw new Error('codex app-server request aborted');\n }\n\n if (deadlineAt && Date.now() > deadlineAt) {\n throw new Error('codex app-server request timed out');\n }\n\n if (this.lineBuffer.length) {\n const line = this.lineBuffer.shift()!;\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n let parsed: JsonRpcMessage;\n try {\n parsed = JSON.parse(trimmed);\n } catch (error) {\n warnCodex(\n `ignored non-JSON message from codex app-server: ${trimmed}`,\n );\n continue;\n }\n\n return parsed;\n }\n\n if (this.closed) {\n throw this.createClosedConnectionError();\n }\n\n await new Promise((resolve) => setTimeout(resolve, 20));\n }\n }\n\n private async sendMessage(payload: Record<string, unknown>): Promise<void> {\n if (this.closed) {\n throw this.createClosedConnectionError();\n }\n\n const line = JSON.stringify(payload);\n await new Promise<void>((resolve, reject) => {\n this.child.stdin.write(`${line}\\n`, (error: Error | null | undefined) => {\n if (error) {\n reject(\n new Error(\n `failed writing to codex app-server stdin: ${error.message}`,\n ),\n );\n return;\n }\n resolve();\n });\n });\n }\n\n private createClosedConnectionError(): Error {\n const stderr = this.stderrBuffer.trim();\n if (this.processErrorMessage) {\n return new Error(\n stderr\n ? `codex app-server process error: ${this.processErrorMessage}. stderr=${stderr}`\n : `codex app-server process error: ${this.processErrorMessage}`,\n );\n }\n\n return new Error(\n stderr\n ? `codex app-server connection closed (exitCode=${this.lastExitCode}). stderr=${stderr}`\n : `codex app-server connection closed (exitCode=${this.lastExitCode})`,\n );\n }\n}\n\nclass CodexAppServerConnectionManager {\n private connection: CodexAppServerConnection | null = null;\n private runner = new SerializedRunner();\n\n async runTurn({\n messages,\n modelConfig,\n stream,\n onChunk,\n reasoningEnabled,\n abortSignal,\n }: {\n messages: ChatCompletionMessageParam[];\n modelConfig: IModelConfig;\n stream?: boolean;\n onChunk?: StreamingCallback;\n reasoningEnabled?: TModelReasoningEnabled;\n abortSignal?: AbortSignal;\n }): Promise<CodexTurnResult> {\n return this.runner.run(async () => {\n const connection = await this.getConnection();\n try {\n return await connection.runTurn({\n messages,\n modelConfig,\n stream,\n onChunk,\n reasoningEnabled,\n abortSignal,\n });\n } catch (error) {\n if (connection.isClosed() || !isAbortError(error)) {\n await this.resetConnection();\n }\n throw error;\n }\n });\n }\n\n async shutdownForTests(): Promise<void> {\n await this.resetConnection();\n }\n\n private async getConnection(): Promise<CodexAppServerConnection> {\n if (!this.connection || this.connection.isClosed()) {\n this.connection = await CodexAppServerConnection.create();\n debugCodex('started long-lived codex app-server connection');\n }\n return this.connection;\n }\n\n private async resetConnection(): Promise<void> {\n if (!this.connection) return;\n const staleConnection = this.connection;\n this.connection = null;\n await staleConnection.dispose();\n debugCodex('reset codex app-server connection');\n }\n}\n\nconst codexConnectionManager = new CodexAppServerConnectionManager();\n\nexport async function callAIWithCodexAppServer(\n messages: ChatCompletionMessageParam[],\n modelConfig: IModelConfig,\n options?: {\n stream?: boolean;\n onChunk?: StreamingCallback;\n reasoningEnabled?: TModelReasoningEnabled;\n abortSignal?: AbortSignal;\n },\n): Promise<CodexTurnResult> {\n if (ifInBrowser) {\n throw new Error(\n 'codex app-server provider is not supported in browser runtime',\n );\n }\n\n return codexConnectionManager.runTurn({\n messages,\n modelConfig,\n stream: options?.stream,\n onChunk: options?.onChunk,\n reasoningEnabled: options?.reasoningEnabled,\n abortSignal: options?.abortSignal,\n });\n}\n\nexport async function __shutdownCodexAppServerForTests() {\n await codexConnectionManager.shutdownForTests();\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","CODEX_PROVIDER_SCHEME","CODEX_DEFAULT_TIMEOUT_MS","CODEX_DEFAULT_PROCESS_START_TIMEOUT_MS","CODEX_DEFAULT_CLEANUP_TIMEOUT_MS","CODEX_TEXT_INPUT_MAX_LENGTH","debugCodex","getDebug","warnCodex","SerializedRunner","work","previous","release","Promise","resolve","isCodexAppServerProvider","baseURL","isAbortError","error","Error","message","String","toNonEmptyString","value","trimmed","undefined","normalizeCodexLocalImagePath","imageUrl","platform","process","parsed","URL","pathname","decodeURIComponent","host","windowsPath","extractTextFromMessage","content","Array","part","Boolean","extractImageInputs","inputs","partType","path","resolveCodexReasoningEffort","reasoningEnabled","modelConfig","normalized","buildCodexTurnPayloadFromMessages","messages","developerInstructionParts","transcriptParts","imageInputs","role","text","roleTag","fullTranscript","transcriptText","input","developerInstructions","CodexAppServerConnection","ifInBrowser","childProcessModuleName","readlineModuleName","spawn","readline","child","lineReader","Number","connection","stream","onChunk","abortSignal","startTime","Date","timeoutMs","deadlineAt","isStreaming","effort","threadId","turnId","latestErrorMessage","accumulatedText","accumulatedReasoning","latestUsage","emitChunk","reasoning","isComplete","usage","chunk","threadStartResponse","turnStartResponse","turnStatus","notification","method","params","messageText","delta","line","Buffer","code","tokenUsage","picked","requestId","request","result","includePending","JSON","setTimeout","payload","reject","stderr","CodexAppServerConnectionManager","staleConnection","codexConnectionManager","callAIWithCodexAppServer","options","__shutdownCodexAppServerForTests"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-model/service-caller/codex-app-server.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/service-caller/codex-app-server.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type {\n AIUsageInfo,\n CodeGenerationChunk,\n StreamingCallback,\n} from '@/types';\nimport type {\n IModelConfig,\n TModelReasoningEnabled,\n} from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { ifInBrowser } from '@midscene/shared/utils';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\n\nconst CODEX_PROVIDER_SCHEME = 'codex://';\nconst CODEX_DEFAULT_TIMEOUT_MS = 10 * 60 * 1000;\nconst CODEX_DEFAULT_PROCESS_START_TIMEOUT_MS = 15 * 1000;\nconst CODEX_DEFAULT_CLEANUP_TIMEOUT_MS = 8 * 1000;\nconst CODEX_TEXT_INPUT_MAX_LENGTH = 256 * 1024;\n\nconst debugCodex = getDebug('ai:call:codex');\nconst warnCodex = getDebug('ai:call:codex', { console: true });\n\ntype CodexReasoningEffort =\n | 'none'\n | 'minimal'\n | 'low'\n | 'medium'\n | 'high'\n | 'xhigh';\n\ntype JsonRpcRequest = {\n id: string | number;\n method: string;\n params?: unknown;\n};\n\ntype JsonRpcResponse = {\n id: string | number;\n result?: unknown;\n error?: {\n code?: number;\n message?: string;\n data?: unknown;\n };\n};\n\ntype JsonRpcNotification = {\n method: string;\n params?: Record<string, any>;\n};\n\ntype JsonRpcMessage = JsonRpcRequest | JsonRpcResponse | JsonRpcNotification;\n\ntype CodexTextInput = {\n type: 'text';\n text: string;\n text_elements: any[];\n};\n\n// Codex app-server v2 accepts `detail` on both image input variants:\n// https://github.com/openai/codex/blob/main/codex-rs/app-server-protocol/src/protocol/v2/turn.rs#L276-L329\n// Codex has also reported `original` as a supported value in production:\n// https://github.com/openai/codex/issues/24797\ntype CodexImageInput = {\n type: 'image';\n url: string;\n detail?: CodexImageDetail;\n};\n\ntype CodexLocalImageInput = {\n type: 'localImage';\n path: string;\n detail?: CodexImageDetail;\n};\n\ntype CodexTurnInput = CodexTextInput | CodexImageInput | CodexLocalImageInput;\n\ntype CodexImageDetail = 'auto' | 'low' | 'high' | 'original';\n\ntype CodexTurnResult = {\n content: string;\n reasoning_content?: string;\n usage?: AIUsageInfo;\n isStreamed: boolean;\n};\n\ntype CodexTurnStartResponse = {\n turn?: {\n id?: string;\n };\n};\n\ntype CodexThreadStartResponse = {\n thread?: {\n id?: string;\n };\n};\n\ntype CodexUsageNotification = {\n threadId?: string;\n turnId?: string;\n tokenUsage?: {\n total?: {\n totalTokens?: number;\n inputTokens?: number;\n cachedInputTokens?: number;\n outputTokens?: number;\n reasoningOutputTokens?: number;\n };\n last?: {\n totalTokens?: number;\n inputTokens?: number;\n cachedInputTokens?: number;\n outputTokens?: number;\n reasoningOutputTokens?: number;\n };\n };\n};\n\nclass SerializedRunner {\n private tail: Promise<void> = Promise.resolve();\n\n async run<T>(work: () => Promise<T>): Promise<T> {\n const previous = this.tail;\n let release!: () => void;\n this.tail = new Promise<void>((resolve) => {\n release = resolve;\n });\n\n await previous;\n try {\n return await work();\n } finally {\n release();\n }\n }\n}\n\nexport const isCodexAppServerProvider = (baseURL?: string): boolean => {\n if (!baseURL) return false;\n return baseURL.trim().toLowerCase().startsWith(CODEX_PROVIDER_SCHEME);\n};\n\nconst isAbortError = (error: unknown): boolean => {\n if (!error) return false;\n if (error instanceof Error && error.name === 'AbortError') return true;\n const message =\n error instanceof Error ? error.message : String(error ?? 'unknown error');\n return /aborted|abort/i.test(message);\n};\n\nconst toNonEmptyString = (value: unknown): string | undefined => {\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return trimmed || undefined;\n};\n\nconst toCodexImageDetail = (value: unknown): CodexImageDetail | undefined =>\n value === 'auto' ||\n value === 'low' ||\n value === 'high' ||\n value === 'original'\n ? value\n : undefined;\n\nexport const normalizeCodexLocalImagePath = (\n imageUrl: string,\n platform: NodeJS.Platform = process.platform,\n): string => {\n if (!imageUrl.startsWith('file://')) {\n return imageUrl;\n }\n\n try {\n const parsed = new URL(imageUrl);\n const pathname = decodeURIComponent(parsed.pathname);\n const host = parsed.hostname.toLowerCase();\n\n if (platform === 'win32') {\n const windowsPath = pathname\n .replace(/\\//g, '\\\\')\n .replace(/^\\\\([A-Za-z]:)/, '$1');\n\n if (host && host !== 'localhost') {\n return `\\\\\\\\${parsed.hostname}${windowsPath}`;\n }\n\n return windowsPath;\n }\n\n if (host && host !== 'localhost') {\n return `//${parsed.hostname}${pathname}`;\n }\n\n return pathname;\n } catch {\n return decodeURIComponent(imageUrl.slice('file://'.length));\n }\n};\n\nconst extractTextFromMessage = (\n message: ChatCompletionMessageParam,\n): string => {\n const content = (message as any).content;\n if (typeof content === 'string') {\n return content;\n }\n\n if (Array.isArray(content)) {\n return content\n .map((part) => {\n if (!part || typeof part !== 'object') return '';\n\n if (part.type === 'text' && typeof part.text === 'string') {\n return part.text;\n }\n\n if (part.type === 'input_text' && typeof part.text === 'string') {\n return part.text;\n }\n\n return '';\n })\n .filter(Boolean)\n .join('\\n');\n }\n\n return '';\n};\n\nconst extractImageInputs = (\n message: ChatCompletionMessageParam,\n imageDetailOverride?: CodexImageDetail,\n): Array<CodexImageInput | CodexLocalImageInput> => {\n const content = (message as any).content;\n if (!Array.isArray(content)) return [];\n\n const inputs: Array<CodexImageInput | CodexLocalImageInput> = [];\n for (const part of content) {\n if (!part || typeof part !== 'object') continue;\n\n const partType = String(part.type || '');\n const imageUrl =\n partType === 'image_url'\n ? toNonEmptyString(part.image_url?.url)\n : partType === 'input_image'\n ? toNonEmptyString(part.image_url || part.url)\n : undefined;\n const imageDetail =\n imageDetailOverride ??\n toCodexImageDetail(\n partType === 'image_url' ? part.image_url?.detail : part.detail,\n );\n\n if (!imageUrl) continue;\n\n if (\n imageUrl.startsWith('/') ||\n imageUrl.startsWith('./') ||\n imageUrl.startsWith('../') ||\n imageUrl.startsWith('file://')\n ) {\n const path = imageUrl.startsWith('file://')\n ? normalizeCodexLocalImagePath(imageUrl)\n : imageUrl;\n\n inputs.push({\n type: 'localImage',\n path,\n ...(imageDetail ? { detail: imageDetail } : {}),\n });\n continue;\n }\n\n inputs.push({\n type: 'image',\n url: imageUrl,\n ...(imageDetail ? { detail: imageDetail } : {}),\n });\n }\n\n return inputs;\n};\n\nexport const resolveCodexReasoningEffort = ({\n reasoningEnabled,\n modelConfig,\n}: {\n reasoningEnabled?: TModelReasoningEnabled;\n modelConfig: IModelConfig;\n}): CodexReasoningEffort | undefined => {\n if (reasoningEnabled !== true) return 'none';\n\n const normalized = modelConfig.reasoningEffort?.trim().toLowerCase();\n if (\n normalized === 'none' ||\n normalized === 'minimal' ||\n normalized === 'low' ||\n normalized === 'medium' ||\n normalized === 'high' ||\n normalized === 'xhigh'\n ) {\n return normalized;\n }\n\n return 'medium';\n};\n\nexport const buildCodexTurnPayloadFromMessages = (\n messages: ChatCompletionMessageParam[],\n imageDetailOverride?: CodexImageDetail,\n): {\n developerInstructions?: string;\n input: CodexTurnInput[];\n} => {\n const developerInstructionParts: string[] = [];\n const transcriptParts: string[] = [];\n const imageInputs: Array<CodexImageInput | CodexLocalImageInput> = [];\n\n for (const message of messages) {\n const role = String((message as any).role || 'user');\n const text = extractTextFromMessage(message);\n\n if (role === 'system') {\n if (text.trim()) developerInstructionParts.push(text.trim());\n continue;\n }\n\n const roleTag = role.toUpperCase();\n if (text.trim()) {\n transcriptParts.push(`[${roleTag}]\\n${text.trim()}`);\n } else {\n transcriptParts.push(`[${roleTag}]\\n(no text content)`);\n }\n\n if (role === 'user') {\n imageInputs.push(...extractImageInputs(message, imageDetailOverride));\n }\n }\n\n const fullTranscript = transcriptParts.join('\\n\\n');\n const transcriptText =\n (fullTranscript.length > CODEX_TEXT_INPUT_MAX_LENGTH\n ? fullTranscript.slice(-CODEX_TEXT_INPUT_MAX_LENGTH)\n : fullTranscript) || 'Please answer the latest user request.';\n\n const input: CodexTurnInput[] = [\n {\n type: 'text',\n text: transcriptText,\n text_elements: [],\n },\n ...imageInputs,\n ];\n\n const developerInstructions = developerInstructionParts.length\n ? developerInstructionParts.join('\\n\\n')\n : undefined;\n\n return {\n developerInstructions,\n input,\n };\n};\n\nclass CodexAppServerConnection {\n private child: any;\n private lineReader: any;\n private pendingMessages: JsonRpcMessage[] = [];\n private lineBuffer: string[] = [];\n private nextRequestId = 1;\n private closed = false;\n private lastExitCode: number | null = null;\n private processErrorMessage: string | null = null;\n private stderrBuffer = '';\n\n private constructor(child: any, lineReader: any) {\n this.child = child;\n this.lineReader = lineReader;\n }\n\n static async create(): Promise<CodexAppServerConnection> {\n if (ifInBrowser) {\n throw new Error(\n 'codex app-server provider is not supported in browser runtime',\n );\n }\n\n const childProcessModuleName = 'node:child_process';\n const readlineModuleName = 'node:readline';\n const { spawn } = await import(childProcessModuleName);\n const readline = await import(readlineModuleName);\n\n const child = spawn('codex', ['app-server'], {\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n if (!child.stdin || !child.stdout || !child.stderr) {\n throw new Error('failed to start codex app-server: stdio unavailable');\n }\n\n const lineReader = readline.createInterface({\n input: child.stdout,\n crlfDelay: Number.POSITIVE_INFINITY,\n });\n const connection = new CodexAppServerConnection(child, lineReader);\n connection.detachFromEventLoop();\n connection.attachProcessListeners();\n await connection.initializeHandshake();\n\n return connection;\n }\n\n isClosed(): boolean {\n return this.closed;\n }\n\n async runTurn({\n messages,\n modelConfig,\n stream,\n onChunk,\n reasoningEnabled,\n abortSignal,\n imageDetail,\n }: {\n messages: ChatCompletionMessageParam[];\n modelConfig: IModelConfig;\n stream?: boolean;\n onChunk?: StreamingCallback;\n reasoningEnabled?: TModelReasoningEnabled;\n abortSignal?: AbortSignal;\n imageDetail?: CodexImageDetail;\n }): Promise<CodexTurnResult> {\n const startTime = Date.now();\n const timeoutMs = modelConfig.timeout || CODEX_DEFAULT_TIMEOUT_MS;\n const deadlineAt = Date.now() + timeoutMs;\n const isStreaming = !!(stream && onChunk);\n\n const { developerInstructions, input } = buildCodexTurnPayloadFromMessages(\n messages,\n imageDetail,\n );\n const effort = resolveCodexReasoningEffort({\n reasoningEnabled,\n modelConfig,\n });\n\n let threadId: string | undefined;\n let turnId: string | undefined;\n let latestErrorMessage: string | undefined;\n let accumulatedText = '';\n let accumulatedReasoning = '';\n let latestUsage: AIUsageInfo | undefined;\n\n const emitChunk = ({\n content,\n reasoning,\n isComplete,\n usage,\n }: {\n content: string;\n reasoning: string;\n isComplete: boolean;\n usage?: AIUsageInfo;\n }) => {\n if (!isStreaming || !onChunk) return;\n const chunk: CodeGenerationChunk = {\n content,\n reasoning_content: reasoning,\n accumulated: accumulatedText,\n isComplete,\n usage,\n };\n onChunk(chunk);\n };\n\n try {\n const threadStartResponse = await this.request<CodexThreadStartResponse>({\n method: 'thread/start',\n params: {\n model: modelConfig.modelName,\n cwd: process.cwd(),\n approvalPolicy: 'never',\n sandbox: 'read-only',\n ephemeral: true,\n experimentalRawEvents: false,\n persistExtendedHistory: false,\n developerInstructions: developerInstructions || null,\n },\n deadlineAt,\n abortSignal,\n });\n\n threadId = threadStartResponse?.thread?.id;\n if (!threadId) {\n throw new Error('thread/start did not return a thread id');\n }\n\n const turnStartResponse = await this.request<CodexTurnStartResponse>({\n method: 'turn/start',\n params: {\n threadId,\n input,\n effort,\n },\n deadlineAt,\n abortSignal,\n });\n\n turnId = turnStartResponse?.turn?.id;\n if (!turnId) {\n throw new Error('turn/start did not return a turn id');\n }\n\n let turnStatus: string | undefined;\n while (!turnStatus) {\n const message = await this.nextMessage({ deadlineAt, abortSignal });\n\n if (this.isResponseMessage(message)) {\n // No concurrent requests in adapter runtime.\n continue;\n }\n\n if (this.isRequestMessage(message)) {\n await this.respondToServerRequest(message);\n continue;\n }\n\n const notification = message as JsonRpcNotification;\n const method = notification.method;\n const params = notification.params || {};\n\n if (method === 'error') {\n const messageText =\n params.error?.message ||\n params.message ||\n 'codex app-server reported turn error';\n latestErrorMessage = String(messageText);\n continue;\n }\n\n if (\n method === 'item/agentMessage/delta' &&\n params.threadId === threadId &&\n params.turnId === turnId\n ) {\n const delta = String(params.delta || '');\n if (delta) {\n accumulatedText += delta;\n emitChunk({\n content: delta,\n reasoning: '',\n isComplete: false,\n });\n }\n continue;\n }\n\n if (\n (method === 'item/reasoning/summaryTextDelta' ||\n method === 'item/reasoning/textDelta') &&\n params.threadId === threadId &&\n params.turnId === turnId\n ) {\n const delta = String(params.delta || '');\n if (delta) {\n accumulatedReasoning += delta;\n emitChunk({\n content: '',\n reasoning: delta,\n isComplete: false,\n });\n }\n continue;\n }\n\n if (\n method === 'item/completed' &&\n params.threadId === threadId &&\n params.turnId === turnId &&\n params.item?.type === 'agentMessage' &&\n typeof params.item?.text === 'string' &&\n !accumulatedText\n ) {\n accumulatedText = params.item.text;\n continue;\n }\n\n if (\n method === 'thread/tokenUsage/updated' &&\n params.threadId === threadId &&\n params.turnId === turnId\n ) {\n latestUsage = this.mapUsage({\n usage: params as CodexUsageNotification,\n modelConfig,\n turnId,\n startTime,\n });\n continue;\n }\n\n if (\n method === 'turn/completed' &&\n params.threadId === threadId &&\n params.turn?.id === turnId\n ) {\n turnStatus = String(params.turn.status || '');\n latestErrorMessage =\n params.turn?.error?.message || latestErrorMessage || undefined;\n break;\n }\n }\n\n if (turnStatus !== 'completed') {\n throw new Error(\n latestErrorMessage ||\n `codex turn finished with status \"${turnStatus || 'unknown'}\"`,\n );\n }\n\n if (isStreaming) {\n emitChunk({\n content: '',\n reasoning: '',\n isComplete: true,\n usage: latestUsage,\n });\n }\n\n return {\n content: accumulatedText,\n reasoning_content: accumulatedReasoning || undefined,\n usage: latestUsage,\n isStreamed: isStreaming,\n };\n } catch (error) {\n if (isAbortError(error) && threadId && turnId) {\n await this.request({\n method: 'turn/interrupt',\n params: {\n threadId,\n turnId,\n },\n deadlineAt: Date.now() + 5_000,\n }).catch(() => {});\n }\n throw error;\n } finally {\n if (threadId) {\n await this.request({\n method: 'thread/unsubscribe',\n params: { threadId },\n deadlineAt: Date.now() + CODEX_DEFAULT_CLEANUP_TIMEOUT_MS,\n }).catch((error) => {\n warnCodex(\n `failed to unsubscribe codex thread ${threadId}: ${String(error)}`,\n );\n });\n }\n }\n }\n\n async dispose(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n\n try {\n this.lineReader?.close?.();\n } catch {}\n\n try {\n this.child?.stdin?.end?.();\n } catch {}\n\n try {\n this.child?.kill?.();\n } catch {}\n }\n\n private attachProcessListeners() {\n this.lineReader.on('line', (line: string) => {\n this.lineBuffer.push(line);\n });\n\n this.child.stderr.on('data', (chunk: Buffer | string) => {\n const text = Buffer.isBuffer(chunk)\n ? chunk.toString('utf8')\n : String(chunk);\n this.stderrBuffer += text;\n if (this.stderrBuffer.length > 8192) {\n this.stderrBuffer = this.stderrBuffer.slice(-8192);\n }\n });\n\n this.child.on('exit', (code: number | null) => {\n this.closed = true;\n this.lastExitCode = code;\n });\n\n this.child.on('error', (error: Error) => {\n this.closed = true;\n this.processErrorMessage = error.message;\n });\n }\n\n /**\n * Keep codex process reusable but let short-lived callers exit naturally.\n * Without unref, one-shot scripts/tests that call AI once can hang.\n */\n private detachFromEventLoop() {\n this.child.unref?.();\n this.child.stdin?.unref?.();\n this.child.stdout?.unref?.();\n this.child.stderr?.unref?.();\n }\n\n private async initializeHandshake() {\n const deadlineAt = Date.now() + CODEX_DEFAULT_PROCESS_START_TIMEOUT_MS;\n await this.request({\n method: 'initialize',\n params: {\n clientInfo: {\n name: 'midscene_codex_provider',\n title: 'Midscene Codex Provider',\n version: '1.0.0',\n },\n capabilities: {\n experimentalApi: false,\n },\n },\n deadlineAt,\n });\n await this.sendMessage({\n method: 'initialized',\n });\n }\n\n private mapUsage({\n usage,\n modelConfig,\n turnId,\n startTime,\n }: {\n usage: CodexUsageNotification;\n modelConfig: IModelConfig;\n turnId: string;\n startTime: number;\n }): AIUsageInfo | undefined {\n const tokenUsage = usage.tokenUsage;\n const picked = tokenUsage?.last || tokenUsage?.total;\n if (!picked) return undefined;\n\n return {\n ...picked,\n prompt_tokens: picked.inputTokens ?? 0,\n completion_tokens: picked.outputTokens ?? 0,\n total_tokens: picked.totalTokens ?? 0,\n cached_input: picked.cachedInputTokens ?? 0,\n time_cost: Date.now() - startTime,\n model_name: modelConfig.modelName,\n model_description: modelConfig.modelDescription,\n response_model_name: undefined,\n slot: modelConfig.slot,\n intent: undefined,\n request_id: turnId,\n } satisfies AIUsageInfo;\n }\n\n private isRequestMessage(message: JsonRpcMessage): message is JsonRpcRequest {\n return (\n typeof (message as any)?.method === 'string' &&\n (message as any)?.id !== undefined\n );\n }\n\n private isResponseMessage(\n message: JsonRpcMessage,\n ): message is JsonRpcResponse {\n return (\n (message as any)?.id !== undefined &&\n ((message as any)?.result !== undefined ||\n (message as any)?.error !== undefined) &&\n typeof (message as any)?.method !== 'string'\n );\n }\n\n private async request<T = unknown>({\n method,\n params,\n deadlineAt,\n abortSignal,\n }: {\n method: string;\n params: unknown;\n deadlineAt?: number;\n abortSignal?: AbortSignal;\n }): Promise<T> {\n const requestId = this.nextRequestId++;\n\n await this.sendMessage({\n id: requestId,\n method,\n params,\n });\n\n while (true) {\n const message = await this.nextMessage({\n deadlineAt,\n abortSignal,\n includePending: false,\n });\n\n if (this.isResponseMessage(message) && message.id === requestId) {\n if (message.error) {\n throw new Error(\n `codex app-server ${method} failed: ${\n message.error.message || 'unknown error'\n }`,\n );\n }\n return (message.result || {}) as T;\n }\n\n if (this.isRequestMessage(message)) {\n await this.respondToServerRequest(message);\n continue;\n }\n\n // Keep unmatched notifications/other responses for later stream handling.\n this.pendingMessages.push(message);\n }\n }\n\n private async respondToServerRequest(request: JsonRpcRequest): Promise<void> {\n const requestId = request.id;\n const method = request.method;\n\n let result: unknown = {};\n if (method === 'item/commandExecution/requestApproval') {\n result = { decision: 'decline' };\n } else if (method === 'item/fileChange/requestApproval') {\n result = { decision: 'decline' };\n } else if (method === 'mcpServer/elicitation/request') {\n result = { action: 'cancel', content: null };\n } else if (method === 'item/tool/requestUserInput') {\n result = { answers: [] };\n } else {\n await this.sendMessage({\n id: requestId,\n error: {\n code: -32601,\n message: `unsupported server request: ${method}`,\n },\n });\n return;\n }\n\n await this.sendMessage({\n id: requestId,\n result,\n });\n }\n\n private async nextMessage({\n deadlineAt,\n abortSignal,\n includePending = true,\n }: {\n deadlineAt?: number;\n abortSignal?: AbortSignal;\n includePending?: boolean;\n }): Promise<JsonRpcMessage> {\n if (includePending && this.pendingMessages.length) {\n return this.pendingMessages.shift() as JsonRpcMessage;\n }\n\n while (true) {\n if (abortSignal?.aborted) {\n throw new Error('codex app-server request aborted');\n }\n\n if (deadlineAt && Date.now() > deadlineAt) {\n throw new Error('codex app-server request timed out');\n }\n\n if (this.lineBuffer.length) {\n const line = this.lineBuffer.shift()!;\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n let parsed: JsonRpcMessage;\n try {\n parsed = JSON.parse(trimmed);\n } catch (error) {\n warnCodex(\n `ignored non-JSON message from codex app-server: ${trimmed}`,\n );\n continue;\n }\n\n return parsed;\n }\n\n if (this.closed) {\n throw this.createClosedConnectionError();\n }\n\n await new Promise((resolve) => setTimeout(resolve, 20));\n }\n }\n\n private async sendMessage(payload: Record<string, unknown>): Promise<void> {\n if (this.closed) {\n throw this.createClosedConnectionError();\n }\n\n const line = JSON.stringify(payload);\n await new Promise<void>((resolve, reject) => {\n this.child.stdin.write(`${line}\\n`, (error: Error | null | undefined) => {\n if (error) {\n reject(\n new Error(\n `failed writing to codex app-server stdin: ${error.message}`,\n ),\n );\n return;\n }\n resolve();\n });\n });\n }\n\n private createClosedConnectionError(): Error {\n const stderr = this.stderrBuffer.trim();\n if (this.processErrorMessage) {\n return new Error(\n stderr\n ? `codex app-server process error: ${this.processErrorMessage}. stderr=${stderr}`\n : `codex app-server process error: ${this.processErrorMessage}`,\n );\n }\n\n return new Error(\n stderr\n ? `codex app-server connection closed (exitCode=${this.lastExitCode}). stderr=${stderr}`\n : `codex app-server connection closed (exitCode=${this.lastExitCode})`,\n );\n }\n}\n\nclass CodexAppServerConnectionManager {\n private connection: CodexAppServerConnection | null = null;\n private runner = new SerializedRunner();\n\n async runTurn({\n messages,\n modelConfig,\n stream,\n onChunk,\n reasoningEnabled,\n abortSignal,\n imageDetail,\n }: {\n messages: ChatCompletionMessageParam[];\n modelConfig: IModelConfig;\n stream?: boolean;\n onChunk?: StreamingCallback;\n reasoningEnabled?: TModelReasoningEnabled;\n abortSignal?: AbortSignal;\n imageDetail?: CodexImageDetail;\n }): Promise<CodexTurnResult> {\n return this.runner.run(async () => {\n const connection = await this.getConnection();\n try {\n return await connection.runTurn({\n messages,\n modelConfig,\n stream,\n onChunk,\n reasoningEnabled,\n abortSignal,\n imageDetail,\n });\n } catch (error) {\n if (connection.isClosed() || !isAbortError(error)) {\n await this.resetConnection();\n }\n throw error;\n }\n });\n }\n\n async shutdownForTests(): Promise<void> {\n await this.resetConnection();\n }\n\n private async getConnection(): Promise<CodexAppServerConnection> {\n if (!this.connection || this.connection.isClosed()) {\n this.connection = await CodexAppServerConnection.create();\n debugCodex('started long-lived codex app-server connection');\n }\n return this.connection;\n }\n\n private async resetConnection(): Promise<void> {\n if (!this.connection) return;\n const staleConnection = this.connection;\n this.connection = null;\n await staleConnection.dispose();\n debugCodex('reset codex app-server connection');\n }\n}\n\nconst codexConnectionManager = new CodexAppServerConnectionManager();\n\nexport async function callAIWithCodexAppServer(\n messages: ChatCompletionMessageParam[],\n modelConfig: IModelConfig,\n options?: {\n stream?: boolean;\n onChunk?: StreamingCallback;\n reasoningEnabled?: TModelReasoningEnabled;\n abortSignal?: AbortSignal;\n imageDetail?: CodexImageDetail;\n },\n): Promise<CodexTurnResult> {\n if (ifInBrowser) {\n throw new Error(\n 'codex app-server provider is not supported in browser runtime',\n );\n }\n\n return codexConnectionManager.runTurn({\n messages,\n modelConfig,\n stream: options?.stream,\n onChunk: options?.onChunk,\n reasoningEnabled: options?.reasoningEnabled,\n abortSignal: options?.abortSignal,\n imageDetail: options?.imageDetail,\n });\n}\n\nexport async function __shutdownCodexAppServerForTests() {\n await codexConnectionManager.shutdownForTests();\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","CODEX_PROVIDER_SCHEME","CODEX_DEFAULT_TIMEOUT_MS","CODEX_DEFAULT_PROCESS_START_TIMEOUT_MS","CODEX_DEFAULT_CLEANUP_TIMEOUT_MS","CODEX_TEXT_INPUT_MAX_LENGTH","debugCodex","getDebug","warnCodex","SerializedRunner","work","previous","release","Promise","resolve","isCodexAppServerProvider","baseURL","isAbortError","error","Error","message","String","toNonEmptyString","value","trimmed","undefined","toCodexImageDetail","normalizeCodexLocalImagePath","imageUrl","platform","process","parsed","URL","pathname","decodeURIComponent","host","windowsPath","extractTextFromMessage","content","Array","part","Boolean","extractImageInputs","imageDetailOverride","inputs","partType","imageDetail","path","resolveCodexReasoningEffort","reasoningEnabled","modelConfig","normalized","buildCodexTurnPayloadFromMessages","messages","developerInstructionParts","transcriptParts","imageInputs","role","text","roleTag","fullTranscript","transcriptText","input","developerInstructions","CodexAppServerConnection","ifInBrowser","childProcessModuleName","readlineModuleName","spawn","readline","child","lineReader","Number","connection","stream","onChunk","abortSignal","startTime","Date","timeoutMs","deadlineAt","isStreaming","effort","threadId","turnId","latestErrorMessage","accumulatedText","accumulatedReasoning","latestUsage","emitChunk","reasoning","isComplete","usage","chunk","threadStartResponse","turnStartResponse","turnStatus","notification","method","params","messageText","delta","line","Buffer","code","tokenUsage","picked","requestId","request","result","includePending","JSON","setTimeout","payload","reject","stderr","CodexAppServerConnectionManager","staleConnection","codexConnectionManager","callAIWithCodexAppServer","options","__shutdownCodexAppServerForTests"],"mappings":"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"}
|
|
@@ -224,12 +224,26 @@ async function createChatClient({ modelConfig }) {
|
|
|
224
224
|
async function callAI(messages, modelRuntime, options) {
|
|
225
225
|
const { config: modelConfig, adapter } = modelRuntime;
|
|
226
226
|
const internalCallId = nextInternalCallId();
|
|
227
|
+
const chatCompletionInput = {
|
|
228
|
+
intent: modelConfig.intent,
|
|
229
|
+
userConfig: {
|
|
230
|
+
temperature: modelConfig.temperature,
|
|
231
|
+
reasoningEnabled: modelConfig.reasoningEnabled,
|
|
232
|
+
reasoningEffort: modelConfig.reasoningEffort,
|
|
233
|
+
reasoningBudget: modelConfig.reasoningBudget,
|
|
234
|
+
responseFormat: modelConfig.responseFormat
|
|
235
|
+
},
|
|
236
|
+
requiresOriginalImageDetail: options?.requiresOriginalImageDetail,
|
|
237
|
+
expectedJsonObjectResponse: options?.expectedJsonObjectResponse
|
|
238
|
+
};
|
|
239
|
+
const imageDetail = adapter.chatCompletion.resolveImageDetail(chatCompletionInput);
|
|
227
240
|
if ((0, external_codex_app_server_js_namespaceObject.isCodexAppServerProvider)(modelConfig.openaiBaseURL)) {
|
|
228
241
|
const codexResult = await (0, external_codex_app_server_js_namespaceObject.callAIWithCodexAppServer)(messages, modelConfig, {
|
|
229
242
|
stream: options?.stream,
|
|
230
243
|
onChunk: options?.onChunk,
|
|
231
244
|
reasoningEnabled: modelConfig.reasoningEnabled,
|
|
232
|
-
abortSignal: options?.abortSignal
|
|
245
|
+
abortSignal: options?.abortSignal,
|
|
246
|
+
imageDetail
|
|
233
247
|
});
|
|
234
248
|
if (codexResult.usage) {
|
|
235
249
|
codexResult.usage[INTERNAL_CALL_ID_FIELD] = internalCallId;
|
|
@@ -250,18 +264,6 @@ async function callAI(messages, modelRuntime, options) {
|
|
|
250
264
|
const debugProfileDetail = (0, logger_namespaceObject.getDebug)('ai:profile:detail');
|
|
251
265
|
const startTime = Date.now();
|
|
252
266
|
const isStreaming = options?.stream && options?.onChunk;
|
|
253
|
-
const chatCompletionInput = {
|
|
254
|
-
intent: modelConfig.intent,
|
|
255
|
-
userConfig: {
|
|
256
|
-
temperature: modelConfig.temperature,
|
|
257
|
-
reasoningEnabled: modelConfig.reasoningEnabled,
|
|
258
|
-
reasoningEffort: modelConfig.reasoningEffort,
|
|
259
|
-
reasoningBudget: modelConfig.reasoningBudget,
|
|
260
|
-
responseFormat: modelConfig.responseFormat
|
|
261
|
-
},
|
|
262
|
-
requiresOriginalImageDetail: options?.requiresOriginalImageDetail,
|
|
263
|
-
expectedJsonObjectResponse: options?.expectedJsonObjectResponse
|
|
264
|
-
};
|
|
265
267
|
const { config: adapterChatCompletionParams } = adapter.chatCompletion.buildChatCompletionParams(chatCompletionInput);
|
|
266
268
|
debugCall(`adapter chat completion params: ${stringifyForDebug({
|
|
267
269
|
config: adapterChatCompletionParams
|
|
@@ -307,7 +309,6 @@ async function callAI(messages, modelRuntime, options) {
|
|
|
307
309
|
...extraBody ?? {}
|
|
308
310
|
};
|
|
309
311
|
const temperature = requestConfig.temperature;
|
|
310
|
-
const imageDetail = adapter.chatCompletion.resolveImageDetail(chatCompletionInput);
|
|
311
312
|
const messagesWithImageDetail = (()=>{
|
|
312
313
|
if (!imageDetail) return messages;
|
|
313
314
|
return messages.map((msg)=>{
|