@aiscene/core 9.0.0 → 9.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/agent/tasks.mjs +5 -1
- package/dist/es/agent/tasks.mjs.map +1 -1
- package/dist/es/agent/utils.mjs +1 -1
- package/dist/es/index.mjs +2 -2
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/report-generator.mjs.map +1 -1
- package/dist/es/types.mjs +20 -1
- package/dist/es/types.mjs.map +1 -1
- package/dist/es/utils.mjs +2 -2
- package/dist/lib/agent/agent.js +1 -1
- package/dist/lib/agent/agent.js.map +1 -1
- package/dist/lib/agent/execution-session.js +1 -1
- package/dist/lib/agent/execution-session.js.map +1 -1
- package/dist/lib/agent/index.js +1 -1
- package/dist/lib/agent/index.js.map +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/task-cache.js +1 -1
- package/dist/lib/agent/task-cache.js.map +1 -1
- package/dist/lib/agent/tasks.js +5 -1
- package/dist/lib/agent/tasks.js.map +1 -1
- package/dist/lib/agent/ui-utils.js +1 -1
- package/dist/lib/agent/ui-utils.js.map +1 -1
- package/dist/lib/agent/usage-intent.js +1 -1
- package/dist/lib/agent/usage-intent.js.map +1 -1
- package/dist/lib/agent/utils.js +2 -2
- package/dist/lib/agent/utils.js.map +1 -1
- package/dist/lib/ai-model/auto-glm/actions.js +1 -1
- package/dist/lib/ai-model/auto-glm/actions.js.map +1 -1
- package/dist/lib/ai-model/auto-glm/index.js +1 -1
- package/dist/lib/ai-model/auto-glm/index.js.map +1 -1
- package/dist/lib/ai-model/auto-glm/parser.js +1 -1
- package/dist/lib/ai-model/auto-glm/parser.js.map +1 -1
- package/dist/lib/ai-model/auto-glm/planning.js +1 -1
- package/dist/lib/ai-model/auto-glm/planning.js.map +1 -1
- package/dist/lib/ai-model/auto-glm/prompt.js +1 -1
- package/dist/lib/ai-model/auto-glm/prompt.js.map +1 -1
- package/dist/lib/ai-model/auto-glm/util.js +1 -1
- package/dist/lib/ai-model/auto-glm/util.js.map +1 -1
- package/dist/lib/ai-model/connectivity.js +1 -1
- package/dist/lib/ai-model/connectivity.js.map +1 -1
- package/dist/lib/ai-model/conversation-history.js +1 -1
- package/dist/lib/ai-model/conversation-history.js.map +1 -1
- package/dist/lib/ai-model/index.js +1 -1
- package/dist/lib/ai-model/index.js.map +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 +1 -1
- package/dist/lib/ai-model/llm-planning.js.map +1 -1
- package/dist/lib/ai-model/prompt/common.js +1 -1
- package/dist/lib/ai-model/prompt/common.js.map +1 -1
- package/dist/lib/ai-model/prompt/describe.js +1 -1
- package/dist/lib/ai-model/prompt/describe.js.map +1 -1
- package/dist/lib/ai-model/prompt/extraction.js +1 -1
- package/dist/lib/ai-model/prompt/extraction.js.map +1 -1
- package/dist/lib/ai-model/prompt/llm-locator.js +1 -1
- package/dist/lib/ai-model/prompt/llm-locator.js.map +1 -1
- package/dist/lib/ai-model/prompt/llm-planning.js +1 -1
- package/dist/lib/ai-model/prompt/llm-planning.js.map +1 -1
- package/dist/lib/ai-model/prompt/llm-section-locator.js +1 -1
- package/dist/lib/ai-model/prompt/llm-section-locator.js.map +1 -1
- package/dist/lib/ai-model/prompt/order-sensitive-judge.js +1 -1
- package/dist/lib/ai-model/prompt/order-sensitive-judge.js.map +1 -1
- package/dist/lib/ai-model/prompt/playwright-generator.js +1 -1
- package/dist/lib/ai-model/prompt/playwright-generator.js.map +1 -1
- package/dist/lib/ai-model/prompt/ui-tars-planning.js +1 -1
- package/dist/lib/ai-model/prompt/ui-tars-planning.js.map +1 -1
- package/dist/lib/ai-model/prompt/util.js +1 -1
- package/dist/lib/ai-model/prompt/util.js.map +1 -1
- package/dist/lib/ai-model/prompt/yaml-generator.js +1 -1
- package/dist/lib/ai-model/prompt/yaml-generator.js.map +1 -1
- package/dist/lib/ai-model/service-caller/codex-app-server.js +1 -1
- package/dist/lib/ai-model/service-caller/codex-app-server.js.map +1 -1
- package/dist/lib/ai-model/service-caller/image-detail.js +1 -1
- package/dist/lib/ai-model/service-caller/image-detail.js.map +1 -1
- package/dist/lib/ai-model/service-caller/index.js +1 -1
- package/dist/lib/ai-model/service-caller/index.js.map +1 -1
- package/dist/lib/ai-model/service-caller/request-timeout.js +1 -1
- package/dist/lib/ai-model/service-caller/request-timeout.js.map +1 -1
- package/dist/lib/ai-model/ui-tars-planning.js +1 -1
- package/dist/lib/ai-model/ui-tars-planning.js.map +1 -1
- package/dist/lib/common.js +1 -1
- package/dist/lib/common.js.map +1 -1
- package/dist/lib/device/device-options.js +1 -1
- package/dist/lib/device/device-options.js.map +1 -1
- package/dist/lib/device/index.js +1 -1
- package/dist/lib/device/index.js.map +1 -1
- package/dist/lib/dump/html-utils.js +1 -1
- package/dist/lib/dump/html-utils.js.map +1 -1
- package/dist/lib/dump/index.js +1 -1
- package/dist/lib/dump/index.js.map +1 -1
- package/dist/lib/dump/screenshot-restoration.js +1 -1
- package/dist/lib/dump/screenshot-restoration.js.map +1 -1
- package/dist/lib/dump/screenshot-store.js +1 -1
- package/dist/lib/dump/screenshot-store.js.map +1 -1
- package/dist/lib/index.js +8 -2
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/report-cli.js +1 -1
- package/dist/lib/report-cli.js.map +1 -1
- package/dist/lib/report-generator.js +1 -1
- package/dist/lib/report-generator.js.map +1 -1
- package/dist/lib/report-markdown.js +1 -1
- package/dist/lib/report-markdown.js.map +1 -1
- package/dist/lib/report.js +1 -1
- package/dist/lib/report.js.map +1 -1
- package/dist/lib/screenshot-item.js +1 -1
- package/dist/lib/screenshot-item.js.map +1 -1
- package/dist/lib/service/index.js +1 -1
- package/dist/lib/service/index.js.map +1 -1
- package/dist/lib/service/utils.js +1 -1
- package/dist/lib/service/utils.js.map +1 -1
- package/dist/lib/skill/index.js +1 -1
- package/dist/lib/skill/index.js.map +1 -1
- package/dist/lib/task-runner.js +1 -1
- package/dist/lib/task-runner.js.map +1 -1
- package/dist/lib/task-timing.js +1 -1
- package/dist/lib/task-timing.js.map +1 -1
- package/dist/lib/tree.js +1 -1
- package/dist/lib/tree.js.map +1 -1
- package/dist/lib/types.js +36 -9
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/utils.js +3 -3
- package/dist/lib/utils.js.map +1 -1
- package/dist/lib/yaml/builder.js +1 -1
- package/dist/lib/yaml/builder.js.map +1 -1
- package/dist/lib/yaml/index.js +1 -1
- package/dist/lib/yaml/index.js.map +1 -1
- package/dist/lib/yaml/player.js +1 -1
- package/dist/lib/yaml/player.js.map +1 -1
- package/dist/lib/yaml/utils.js +1 -1
- package/dist/lib/yaml/utils.js.map +1 -1
- package/dist/lib/yaml.js +1 -1
- package/dist/lib/yaml.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/types.d.ts +35 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/prompt/playwright-generator.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/prompt/playwright-generator.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 StreamingAIResponse,\n StreamingCodeGenerationOptions,\n} from '@/types';\nimport { PLAYWRIGHT_EXAMPLE_CODE } from '@aiscene/shared/constants';\nimport type { IModelConfig } from '@aiscene/shared/env';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport { callAI, callAIWithStringResponse } from '../index';\n// Import shared utilities and types from yaml-generator\nimport {\n type ChromeRecordedEvent,\n type EventCounts,\n type EventSummary,\n type InputDescription,\n type ProcessedEvent,\n createEventCounts,\n createMessageContent,\n extractInputDescriptions,\n filterEventsByType,\n getScreenshotsForLLM,\n prepareEventSummary,\n processEventsForLLM,\n validateEvents,\n} from './yaml-generator';\n\n// Playwright-specific interfaces\nexport interface PlaywrightGenerationOptions {\n testName?: string;\n includeScreenshots?: boolean;\n includeTimestamps?: boolean;\n maxScreenshots?: number;\n description?: string;\n viewportSize?: { width: number; height: number };\n waitForNetworkIdle?: boolean;\n waitForNetworkIdleTimeout?: number;\n}\n\n// Re-export shared types for backward compatibility\nexport type {\n ChromeRecordedEvent,\n EventCounts,\n InputDescription,\n ProcessedEvent,\n EventSummary,\n};\n\n// Re-export shared utilities for backward compatibility\nexport {\n getScreenshotsForLLM,\n filterEventsByType,\n createEventCounts,\n extractInputDescriptions,\n processEventsForLLM,\n prepareEventSummary,\n createMessageContent,\n validateEvents,\n};\n\n/**\n * Generates Playwright test code from recorded events\n */\nexport const generatePlaywrightTest = async (\n events: ChromeRecordedEvent[],\n options: PlaywrightGenerationOptions,\n modelConfig: IModelConfig,\n): Promise<string> => {\n // Validate input\n validateEvents(events);\n\n // Prepare event summary using shared utilities\n const summary = prepareEventSummary(events, {\n testName: options.testName,\n maxScreenshots: options.maxScreenshots || 3,\n });\n\n // Add Playwright-specific options to summary\n const playwrightSummary = {\n ...summary,\n waitForNetworkIdle: options.waitForNetworkIdle !== false,\n waitForNetworkIdleTimeout: options.waitForNetworkIdleTimeout || 2000,\n viewportSize: options.viewportSize || { width: 1280, height: 800 },\n };\n\n // Get screenshots for visual context\n const screenshots = getScreenshotsForLLM(events, options.maxScreenshots || 3);\n\n // Create prompt text\n const promptText = `Generate a Playwright test using @aiscene/web/playwright that reproduces this recorded browser session. The test should be based on the following events and follow the structure of the example provided. Make the test descriptive with appropriate assertions and validations.\n\nEvent Summary:\n${JSON.stringify(playwrightSummary, null, 2)}\n\nGenerated code should:\n1. Import required dependencies\n2. Set up the test with proper configuration\n3. Include a beforeEach hook to navigate to the starting URL\n4. Implement a test that uses Midscene AI methods (aiTap, aiInput, aiAssert, etc.)\n5. Include appropriate assertions and validations\n6. Follow best practices for Playwright tests\n7. Be ready to execute without further modification\n\nImportant: Return ONLY the raw Playwright test code. Do NOT wrap the response in markdown code blocks (no \\`\\`\\`typescript, \\`\\`\\`javascript or \\`\\`\\`). Start directly with the code content.`;\n\n // Create message content with screenshots\n const messageContent = createMessageContent(\n promptText,\n screenshots,\n options.includeScreenshots !== false,\n );\n\n // Create system prompt\n const systemPrompt = `You are an expert test automation engineer specializing in Playwright and Midscene. \nYour task is to generate a complete, executable Playwright test using @aiscene/web/playwright that reproduces a recorded browser session.\n\n${PLAYWRIGHT_EXAMPLE_CODE}`;\n\n // Use LLM to generate the Playwright test code\n const prompt: ChatCompletionMessageParam[] = [\n {\n role: 'system',\n content: systemPrompt,\n },\n {\n role: 'user',\n content: messageContent,\n },\n ];\n\n const response = await callAIWithStringResponse(prompt, modelConfig);\n\n if (response?.content && typeof response.content === 'string') {\n return response.content;\n }\n\n throw new Error('Failed to generate Playwright test code');\n};\n\n/**\n * Generates Playwright test code from recorded events with streaming support\n */\nexport const generatePlaywrightTestStream = async (\n events: ChromeRecordedEvent[],\n options: PlaywrightGenerationOptions & StreamingCodeGenerationOptions,\n modelConfig: IModelConfig,\n): Promise<StreamingAIResponse> => {\n // Validate input\n validateEvents(events);\n\n // Prepare event summary using shared utilities\n const summary = prepareEventSummary(events, {\n testName: options.testName,\n maxScreenshots: options.maxScreenshots || 3,\n });\n\n // Add Playwright-specific options to summary\n const playwrightSummary = {\n ...summary,\n waitForNetworkIdle: options.waitForNetworkIdle !== false,\n waitForNetworkIdleTimeout: options.waitForNetworkIdleTimeout || 2000,\n viewportSize: options.viewportSize || { width: 1280, height: 800 },\n };\n\n // Get screenshots for visual context\n const screenshots = getScreenshotsForLLM(events, options.maxScreenshots || 3);\n\n // Create prompt text\n const promptText = `Generate a Playwright test using @aiscene/web/playwright that reproduces this recorded browser session. The test should be based on the following events and follow the structure of the example provided. Make the test descriptive with appropriate assertions and validations.\n\nEvent Summary:\n${JSON.stringify(playwrightSummary, null, 2)}\n\nGenerated code should:\n1. Import required dependencies\n2. Set up the test with proper configuration\n3. Include a beforeEach hook to navigate to the starting URL\n4. Implement a test that uses Midscene AI methods (aiTap, aiInput, aiAssert, etc.)\n5. Include appropriate assertions and validations\n6. Follow best practices for Playwright tests\n7. Be ready to execute without further modification\n8. can't wrap this test code in markdown code block\n\nImportant: Return ONLY the raw Playwright test code. Do NOT wrap the response in markdown code blocks (no \\`\\`\\`typescript, \\`\\`\\`javascript or \\`\\`\\`). Start directly with the code content.`;\n\n // Create message content with screenshots\n const messageContent = createMessageContent(\n promptText,\n screenshots,\n options.includeScreenshots !== false,\n );\n\n // Create system prompt\n const systemPrompt = `You are an expert test automation engineer specializing in Playwright and Midscene. \nYour task is to generate a complete, executable Playwright test using @aiscene/web/playwright that reproduces a recorded browser session.\n\n${PLAYWRIGHT_EXAMPLE_CODE}`;\n\n // Use LLM to generate the Playwright test code with streaming\n const prompt: ChatCompletionMessageParam[] = [\n {\n role: 'system',\n content: systemPrompt,\n },\n {\n role: 'user',\n content: messageContent,\n },\n ];\n\n if (options.stream && options.onChunk) {\n // Use streaming\n return await callAI(prompt, modelConfig, {\n stream: true,\n onChunk: options.onChunk,\n });\n } else {\n // Fallback to non-streaming\n const response = await callAIWithStringResponse(prompt, modelConfig);\n\n if (response?.content && typeof response.content === 'string') {\n return {\n content: response.content,\n usage: response.usage,\n isStreamed: false,\n };\n }\n\n throw new Error('Failed to generate Playwright test code');\n }\n};\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","generatePlaywrightTest","events","options","modelConfig","validateEvents","summary","prepareEventSummary","playwrightSummary","screenshots","getScreenshotsForLLM","promptText","JSON","messageContent","createMessageContent","systemPrompt","PLAYWRIGHT_EXAMPLE_CODE","prompt","response","callAIWithStringResponse","Error","generatePlaywrightTestStream","callAI"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-model/prompt/playwright-generator.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/prompt/playwright-generator.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 StreamingAIResponse,\n StreamingCodeGenerationOptions,\n} from '@/types';\nimport { PLAYWRIGHT_EXAMPLE_CODE } from '@aiscene/shared/constants';\nimport type { IModelConfig } from '@aiscene/shared/env';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport { callAI, callAIWithStringResponse } from '../index';\n// Import shared utilities and types from yaml-generator\nimport {\n type ChromeRecordedEvent,\n type EventCounts,\n type EventSummary,\n type InputDescription,\n type ProcessedEvent,\n createEventCounts,\n createMessageContent,\n extractInputDescriptions,\n filterEventsByType,\n getScreenshotsForLLM,\n prepareEventSummary,\n processEventsForLLM,\n validateEvents,\n} from './yaml-generator';\n\n// Playwright-specific interfaces\nexport interface PlaywrightGenerationOptions {\n testName?: string;\n includeScreenshots?: boolean;\n includeTimestamps?: boolean;\n maxScreenshots?: number;\n description?: string;\n viewportSize?: { width: number; height: number };\n waitForNetworkIdle?: boolean;\n waitForNetworkIdleTimeout?: number;\n}\n\n// Re-export shared types for backward compatibility\nexport type {\n ChromeRecordedEvent,\n EventCounts,\n InputDescription,\n ProcessedEvent,\n EventSummary,\n};\n\n// Re-export shared utilities for backward compatibility\nexport {\n getScreenshotsForLLM,\n filterEventsByType,\n createEventCounts,\n extractInputDescriptions,\n processEventsForLLM,\n prepareEventSummary,\n createMessageContent,\n validateEvents,\n};\n\n/**\n * Generates Playwright test code from recorded events\n */\nexport const generatePlaywrightTest = async (\n events: ChromeRecordedEvent[],\n options: PlaywrightGenerationOptions,\n modelConfig: IModelConfig,\n): Promise<string> => {\n // Validate input\n validateEvents(events);\n\n // Prepare event summary using shared utilities\n const summary = prepareEventSummary(events, {\n testName: options.testName,\n maxScreenshots: options.maxScreenshots || 3,\n });\n\n // Add Playwright-specific options to summary\n const playwrightSummary = {\n ...summary,\n waitForNetworkIdle: options.waitForNetworkIdle !== false,\n waitForNetworkIdleTimeout: options.waitForNetworkIdleTimeout || 2000,\n viewportSize: options.viewportSize || { width: 1280, height: 800 },\n };\n\n // Get screenshots for visual context\n const screenshots = getScreenshotsForLLM(events, options.maxScreenshots || 3);\n\n // Create prompt text\n const promptText = `Generate a Playwright test using @aiscene/web/playwright that reproduces this recorded browser session. The test should be based on the following events and follow the structure of the example provided. Make the test descriptive with appropriate assertions and validations.\n\nEvent Summary:\n${JSON.stringify(playwrightSummary, null, 2)}\n\nGenerated code should:\n1. Import required dependencies\n2. Set up the test with proper configuration\n3. Include a beforeEach hook to navigate to the starting URL\n4. Implement a test that uses Midscene AI methods (aiTap, aiInput, aiAssert, etc.)\n5. Include appropriate assertions and validations\n6. Follow best practices for Playwright tests\n7. Be ready to execute without further modification\n\nImportant: Return ONLY the raw Playwright test code. Do NOT wrap the response in markdown code blocks (no \\`\\`\\`typescript, \\`\\`\\`javascript or \\`\\`\\`). Start directly with the code content.`;\n\n // Create message content with screenshots\n const messageContent = createMessageContent(\n promptText,\n screenshots,\n options.includeScreenshots !== false,\n );\n\n // Create system prompt\n const systemPrompt = `You are an expert test automation engineer specializing in Playwright and Midscene. \nYour task is to generate a complete, executable Playwright test using @aiscene/web/playwright that reproduces a recorded browser session.\n\n${PLAYWRIGHT_EXAMPLE_CODE}`;\n\n // Use LLM to generate the Playwright test code\n const prompt: ChatCompletionMessageParam[] = [\n {\n role: 'system',\n content: systemPrompt,\n },\n {\n role: 'user',\n content: messageContent,\n },\n ];\n\n const response = await callAIWithStringResponse(prompt, modelConfig);\n\n if (response?.content && typeof response.content === 'string') {\n return response.content;\n }\n\n throw new Error('Failed to generate Playwright test code');\n};\n\n/**\n * Generates Playwright test code from recorded events with streaming support\n */\nexport const generatePlaywrightTestStream = async (\n events: ChromeRecordedEvent[],\n options: PlaywrightGenerationOptions & StreamingCodeGenerationOptions,\n modelConfig: IModelConfig,\n): Promise<StreamingAIResponse> => {\n // Validate input\n validateEvents(events);\n\n // Prepare event summary using shared utilities\n const summary = prepareEventSummary(events, {\n testName: options.testName,\n maxScreenshots: options.maxScreenshots || 3,\n });\n\n // Add Playwright-specific options to summary\n const playwrightSummary = {\n ...summary,\n waitForNetworkIdle: options.waitForNetworkIdle !== false,\n waitForNetworkIdleTimeout: options.waitForNetworkIdleTimeout || 2000,\n viewportSize: options.viewportSize || { width: 1280, height: 800 },\n };\n\n // Get screenshots for visual context\n const screenshots = getScreenshotsForLLM(events, options.maxScreenshots || 3);\n\n // Create prompt text\n const promptText = `Generate a Playwright test using @aiscene/web/playwright that reproduces this recorded browser session. The test should be based on the following events and follow the structure of the example provided. Make the test descriptive with appropriate assertions and validations.\n\nEvent Summary:\n${JSON.stringify(playwrightSummary, null, 2)}\n\nGenerated code should:\n1. Import required dependencies\n2. Set up the test with proper configuration\n3. Include a beforeEach hook to navigate to the starting URL\n4. Implement a test that uses Midscene AI methods (aiTap, aiInput, aiAssert, etc.)\n5. Include appropriate assertions and validations\n6. Follow best practices for Playwright tests\n7. Be ready to execute without further modification\n8. can't wrap this test code in markdown code block\n\nImportant: Return ONLY the raw Playwright test code. Do NOT wrap the response in markdown code blocks (no \\`\\`\\`typescript, \\`\\`\\`javascript or \\`\\`\\`). Start directly with the code content.`;\n\n // Create message content with screenshots\n const messageContent = createMessageContent(\n promptText,\n screenshots,\n options.includeScreenshots !== false,\n );\n\n // Create system prompt\n const systemPrompt = `You are an expert test automation engineer specializing in Playwright and Midscene. \nYour task is to generate a complete, executable Playwright test using @aiscene/web/playwright that reproduces a recorded browser session.\n\n${PLAYWRIGHT_EXAMPLE_CODE}`;\n\n // Use LLM to generate the Playwright test code with streaming\n const prompt: ChatCompletionMessageParam[] = [\n {\n role: 'system',\n content: systemPrompt,\n },\n {\n role: 'user',\n content: messageContent,\n },\n ];\n\n if (options.stream && options.onChunk) {\n // Use streaming\n return await callAI(prompt, modelConfig, {\n stream: true,\n onChunk: options.onChunk,\n });\n } else {\n // Fallback to non-streaming\n const response = await callAIWithStringResponse(prompt, modelConfig);\n\n if (response?.content && typeof response.content === 'string') {\n return {\n content: response.content,\n usage: response.usage,\n isStreamed: false,\n };\n }\n\n throw new Error('Failed to generate Playwright test code');\n }\n};\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","generatePlaywrightTest","events","options","modelConfig","validateEvents","summary","prepareEventSummary","playwrightSummary","screenshots","getScreenshotsForLLM","promptText","JSON","messageContent","createMessageContent","systemPrompt","PLAYWRIGHT_EXAMPLE_CODE","prompt","response","callAIWithStringResponse","Error","generatePlaywrightTestStream","callAI"],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
|
|
|
13
13
|
})();
|
|
14
14
|
(()=>{
|
|
15
15
|
__webpack_require__.r = (exports1)=>{
|
|
16
|
-
if (
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
17
|
value: 'Module'
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports1, '__esModule', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/prompt/ui-tars-planning.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/prompt/ui-tars-planning.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 { getPreferredLanguage } from '@aiscene/shared/env';\n\nexport function getUiTarsPlanningPrompt(): string {\n const preferredLanguage = getPreferredLanguage();\n\n return `\nYou are a GUI agent. You are given a task and your action history, with screenshots. You need to perform the next action to complete the task. \n\n## Output Format\n\\`\\`\\`\nThought: ...\nAction: ...\n\\`\\`\\`\n\n## Action Space\n\nclick(start_box='[x1, y1, x2, y2]')\nleft_double(start_box='[x1, y1, x2, y2]')\nright_single(start_box='[x1, y1, x2, y2]')\ndrag(start_box='[x1, y1, x2, y2]', end_box='[x3, y3, x4, y4]')\nhotkey(key='')\ntype(content='xxx') # Use escape characters \\\\', \\\\\\\", and \\\\n in content part to ensure we can parse the content in normal python string format. If you want to submit your input, use \\\\n at the end of content. \nscroll(start_box='[x1, y1, x2, y2]', direction='down or up or right or left')\nwait() #Sleep for 5s and take a screenshot to check for any changes.\nfinished(content='xxx') # Use escape characters \\\\', \\\\\", and \\\\n in content part to ensure we can parse the content in normal python string format.\n\n\n## Note\n- Use ${preferredLanguage} in \\`Thought\\` part.\n- Write a small plan and finally summarize your next action (with its target element) in one sentence in \\`Thought\\` part.\n\n## User Instruction\n`;\n}\n\nexport const getSummary = (prediction: string) =>\n prediction\n .replace(/Reflection:[\\s\\S]*?(?=Action_Summary:|Action:|$)/g, '')\n .trim();\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","getUiTarsPlanningPrompt","preferredLanguage","getPreferredLanguage","getSummary","prediction"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,
|
|
1
|
+
{"version":3,"file":"ai-model/prompt/ui-tars-planning.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/prompt/ui-tars-planning.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 { getPreferredLanguage } from '@aiscene/shared/env';\n\nexport function getUiTarsPlanningPrompt(): string {\n const preferredLanguage = getPreferredLanguage();\n\n return `\nYou are a GUI agent. You are given a task and your action history, with screenshots. You need to perform the next action to complete the task. \n\n## Output Format\n\\`\\`\\`\nThought: ...\nAction: ...\n\\`\\`\\`\n\n## Action Space\n\nclick(start_box='[x1, y1, x2, y2]')\nleft_double(start_box='[x1, y1, x2, y2]')\nright_single(start_box='[x1, y1, x2, y2]')\ndrag(start_box='[x1, y1, x2, y2]', end_box='[x3, y3, x4, y4]')\nhotkey(key='')\ntype(content='xxx') # Use escape characters \\\\', \\\\\\\", and \\\\n in content part to ensure we can parse the content in normal python string format. If you want to submit your input, use \\\\n at the end of content. \nscroll(start_box='[x1, y1, x2, y2]', direction='down or up or right or left')\nwait() #Sleep for 5s and take a screenshot to check for any changes.\nfinished(content='xxx') # Use escape characters \\\\', \\\\\", and \\\\n in content part to ensure we can parse the content in normal python string format.\n\n\n## Note\n- Use ${preferredLanguage} in \\`Thought\\` part.\n- Write a small plan and finally summarize your next action (with its target element) in one sentence in \\`Thought\\` part.\n\n## User Instruction\n`;\n}\n\nexport const getSummary = (prediction: string) =>\n prediction\n .replace(/Reflection:[\\s\\S]*?(?=Action_Summary:|Action:|$)/g, '')\n .trim();\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","getUiTarsPlanningPrompt","preferredLanguage","getPreferredLanguage","getSummary","prediction"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;ACJO,SAASI;IACd,MAAMC,oBAAoBC,AAAAA,IAAAA,oBAAAA,oBAAAA,AAAAA;IAE1B,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;MAuBJ,EAAED,kBAAkB;;;;AAI1B,CAAC;AACD;AAEO,MAAME,aAAa,CAACC,aACzBA,WACG,OAAO,CAAC,qDAAqD,IAC7D,IAAI"}
|
|
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
|
|
|
13
13
|
})();
|
|
14
14
|
(()=>{
|
|
15
15
|
__webpack_require__.r = (exports1)=>{
|
|
16
|
-
if (
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
17
|
value: 'Module'
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports1, '__esModule', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/prompt/util.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/prompt/util.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 { SubGoal, SubGoalStatus } from '@/types';\n\n/**\n * Extract content from an XML tag in a string, searching from the end.\n * This approach handles cases where models prepend thinking content (like <think>...</think>)\n * before the actual response tags, or when there are incomplete/nested tags.\n *\n * Strategy: Find the LAST closing tag, then search backwards for the nearest opening tag.\n * This ensures we get the last complete tag pair, even if there are incomplete tags before it.\n *\n * @param xmlString - The XML string to parse\n * @param tagName - The name of the tag to extract (case-insensitive)\n * @returns The trimmed content of the tag, or undefined if not found\n */\nexport function extractXMLTag(\n xmlString: string,\n tagName: string,\n): string | undefined {\n const lowerXmlString = xmlString.toLowerCase();\n const lowerTagName = tagName.toLowerCase();\n const closeTag = `</${lowerTagName}>`;\n const openTag = `<${lowerTagName}>`;\n\n // Find the last closing tag\n const lastCloseIndex = lowerXmlString.lastIndexOf(closeTag);\n if (lastCloseIndex === -1) {\n // Fallback: handle half-open tags like `<action-type>Input` without\n // matching close tag. Extract until the next XML tag boundary.\n const lastOpenIndex = lowerXmlString.lastIndexOf(openTag);\n if (lastOpenIndex === -1) {\n return undefined;\n }\n\n const contentStart = lastOpenIndex + openTag.length;\n const remaining = xmlString.substring(contentStart);\n const nextTagIndex = remaining.indexOf('<');\n const content =\n nextTagIndex === -1 ? remaining : remaining.substring(0, nextTagIndex);\n\n return content.trim();\n }\n\n // Search backwards from the closing tag to find the nearest opening tag\n const searchArea = lowerXmlString.substring(0, lastCloseIndex);\n const lastOpenIndex = searchArea.lastIndexOf(openTag);\n if (lastOpenIndex === -1) {\n return undefined;\n }\n\n // Extract content between the tags (use original string to preserve case)\n const contentStart = lastOpenIndex + openTag.length;\n const contentEnd = lastCloseIndex;\n const content = xmlString.substring(contentStart, contentEnd);\n\n return content.trim();\n}\n\n/**\n * Parse sub-goals from XML content\n * Handles both formats:\n * - <sub-goal index=\"1\" status=\"pending\">description</sub-goal>\n * - <sub-goal index=\"1\" status=\"finished\" />\n */\nexport function parseSubGoalsFromXML(xmlContent: string): SubGoal[] {\n const subGoals: SubGoal[] = [];\n\n // Match both self-closing and regular sub-goal tags\n const regex =\n /<sub-goal\\s+index=\"(\\d+)\"\\s+status=\"(pending|finished)\"(?:\\s*\\/>|>([\\s\\S]*?)<\\/sub-goal>)/gi;\n\n let match: RegExpExecArray | null;\n match = regex.exec(xmlContent);\n while (match !== null) {\n const index = Number.parseInt(match[1], 10);\n const status = match[2] as SubGoalStatus;\n const description = match[3]?.trim() || '';\n\n subGoals.push({ index, status, description });\n match = regex.exec(xmlContent);\n }\n\n return subGoals;\n}\n\n/**\n * Extract indexes of sub-goals marked as finished from <mark-sub-goal-done> content\n */\nexport function parseMarkFinishedIndexes(xmlContent: string): number[] {\n const indexes: number[] = [];\n\n // Match self-closing sub-goal tags with status=\"finished\"\n const regex = /<sub-goal\\s+index=\"(\\d+)\"\\s+status=\"finished\"\\s*\\/>/gi;\n\n let match: RegExpExecArray | null;\n match = regex.exec(xmlContent);\n while (match !== null) {\n indexes.push(Number.parseInt(match[1], 10));\n match = regex.exec(xmlContent);\n }\n\n return indexes;\n}\n\nexport const distanceThreshold = 16;\n\nexport function distance(\n point1: { x: number; y: number },\n point2: { x: number; y: number },\n) {\n return Math.sqrt((point1.x - point2.x) ** 2 + (point1.y - point2.y) ** 2);\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","extractXMLTag","xmlString","tagName","lowerXmlString","lowerTagName","closeTag","openTag","lastCloseIndex","lastOpenIndex","contentStart","remaining","nextTagIndex","content","searchArea","contentEnd","parseSubGoalsFromXML","xmlContent","subGoals","regex","match","index","Number","status","description","parseMarkFinishedIndexes","indexes","distanceThreshold","distance","point1","point2","Math"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,
|
|
1
|
+
{"version":3,"file":"ai-model/prompt/util.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/prompt/util.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 { SubGoal, SubGoalStatus } from '@/types';\n\n/**\n * Extract content from an XML tag in a string, searching from the end.\n * This approach handles cases where models prepend thinking content (like <think>...</think>)\n * before the actual response tags, or when there are incomplete/nested tags.\n *\n * Strategy: Find the LAST closing tag, then search backwards for the nearest opening tag.\n * This ensures we get the last complete tag pair, even if there are incomplete tags before it.\n *\n * @param xmlString - The XML string to parse\n * @param tagName - The name of the tag to extract (case-insensitive)\n * @returns The trimmed content of the tag, or undefined if not found\n */\nexport function extractXMLTag(\n xmlString: string,\n tagName: string,\n): string | undefined {\n const lowerXmlString = xmlString.toLowerCase();\n const lowerTagName = tagName.toLowerCase();\n const closeTag = `</${lowerTagName}>`;\n const openTag = `<${lowerTagName}>`;\n\n // Find the last closing tag\n const lastCloseIndex = lowerXmlString.lastIndexOf(closeTag);\n if (lastCloseIndex === -1) {\n // Fallback: handle half-open tags like `<action-type>Input` without\n // matching close tag. Extract until the next XML tag boundary.\n const lastOpenIndex = lowerXmlString.lastIndexOf(openTag);\n if (lastOpenIndex === -1) {\n return undefined;\n }\n\n const contentStart = lastOpenIndex + openTag.length;\n const remaining = xmlString.substring(contentStart);\n const nextTagIndex = remaining.indexOf('<');\n const content =\n nextTagIndex === -1 ? remaining : remaining.substring(0, nextTagIndex);\n\n return content.trim();\n }\n\n // Search backwards from the closing tag to find the nearest opening tag\n const searchArea = lowerXmlString.substring(0, lastCloseIndex);\n const lastOpenIndex = searchArea.lastIndexOf(openTag);\n if (lastOpenIndex === -1) {\n return undefined;\n }\n\n // Extract content between the tags (use original string to preserve case)\n const contentStart = lastOpenIndex + openTag.length;\n const contentEnd = lastCloseIndex;\n const content = xmlString.substring(contentStart, contentEnd);\n\n return content.trim();\n}\n\n/**\n * Parse sub-goals from XML content\n * Handles both formats:\n * - <sub-goal index=\"1\" status=\"pending\">description</sub-goal>\n * - <sub-goal index=\"1\" status=\"finished\" />\n */\nexport function parseSubGoalsFromXML(xmlContent: string): SubGoal[] {\n const subGoals: SubGoal[] = [];\n\n // Match both self-closing and regular sub-goal tags\n const regex =\n /<sub-goal\\s+index=\"(\\d+)\"\\s+status=\"(pending|finished)\"(?:\\s*\\/>|>([\\s\\S]*?)<\\/sub-goal>)/gi;\n\n let match: RegExpExecArray | null;\n match = regex.exec(xmlContent);\n while (match !== null) {\n const index = Number.parseInt(match[1], 10);\n const status = match[2] as SubGoalStatus;\n const description = match[3]?.trim() || '';\n\n subGoals.push({ index, status, description });\n match = regex.exec(xmlContent);\n }\n\n return subGoals;\n}\n\n/**\n * Extract indexes of sub-goals marked as finished from <mark-sub-goal-done> content\n */\nexport function parseMarkFinishedIndexes(xmlContent: string): number[] {\n const indexes: number[] = [];\n\n // Match self-closing sub-goal tags with status=\"finished\"\n const regex = /<sub-goal\\s+index=\"(\\d+)\"\\s+status=\"finished\"\\s*\\/>/gi;\n\n let match: RegExpExecArray | null;\n match = regex.exec(xmlContent);\n while (match !== null) {\n indexes.push(Number.parseInt(match[1], 10));\n match = regex.exec(xmlContent);\n }\n\n return indexes;\n}\n\nexport const distanceThreshold = 16;\n\nexport function distance(\n point1: { x: number; y: number },\n point2: { x: number; y: number },\n) {\n return Math.sqrt((point1.x - point2.x) ** 2 + (point1.y - point2.y) ** 2);\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","extractXMLTag","xmlString","tagName","lowerXmlString","lowerTagName","closeTag","openTag","lastCloseIndex","lastOpenIndex","contentStart","remaining","nextTagIndex","content","searchArea","contentEnd","parseSubGoalsFromXML","xmlContent","subGoals","regex","match","index","Number","status","description","parseMarkFinishedIndexes","indexes","distanceThreshold","distance","point1","point2","Math"],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
|
|
|
13
13
|
})();
|
|
14
14
|
(()=>{
|
|
15
15
|
__webpack_require__.r = (exports1)=>{
|
|
16
|
-
if (
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
17
|
value: 'Module'
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports1, '__esModule', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/prompt/yaml-generator.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/prompt/yaml-generator.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 StreamingAIResponse,\n StreamingCodeGenerationOptions,\n} from '@/types';\nimport { YAML_EXAMPLE_CODE } from '@aiscene/shared/constants';\nimport type { IModelConfig } from '@aiscene/shared/env';\nimport {\n type ChatCompletionMessageParam,\n callAI,\n callAIWithStringResponse,\n} from '../index';\n\n// Common interfaces for test generation (shared between YAML and Playwright)\nexport interface EventCounts {\n navigation: number;\n click: number;\n input: number;\n scroll: number;\n total: number;\n}\n\nexport interface InputDescription {\n description: string;\n value: string;\n}\n\nexport interface ProcessedEvent {\n type: string;\n timestamp: number;\n url?: string;\n title?: string;\n elementDescription?: string;\n value?: string;\n pageInfo?: any;\n elementRect?: any;\n}\n\nexport interface EventSummary {\n testName: string;\n startUrl: string;\n eventCounts: EventCounts;\n urls: string[];\n clickDescriptions: string[];\n inputDescriptions: InputDescription[];\n events: ProcessedEvent[];\n}\n\n// Common ChromeRecordedEvent interface\nexport interface ChromeRecordedEvent {\n type: string;\n timestamp: number;\n url?: string;\n title?: string;\n elementDescription?: string;\n value?: string;\n pageInfo?: any;\n elementRect?: any;\n screenshotBefore?: string;\n screenshotAfter?: string;\n screenshotWithBox?: string;\n}\n\nexport interface YamlGenerationOptions {\n testName?: string;\n includeTimestamps?: boolean;\n maxScreenshots?: number;\n description?: string;\n /** Language for human-readable YAML content (e.g. 'English', 'Chinese'). Keys and API names are kept as-is. */\n language?: string;\n}\n\nexport interface FilteredEvents {\n navigationEvents: ChromeRecordedEvent[];\n clickEvents: ChromeRecordedEvent[];\n inputEvents: ChromeRecordedEvent[];\n scrollEvents: ChromeRecordedEvent[];\n}\n\n// Common utility functions (shared between YAML and Playwright generators)\n\n/**\n * Get screenshots from events for LLM context\n */\nexport const getScreenshotsForLLM = (\n events: ChromeRecordedEvent[],\n maxScreenshots = 1,\n): string[] => {\n // Find events with screenshots, prioritizing navigation and click events\n const eventsWithScreenshots = events.filter(\n (event) =>\n event.screenshotBefore ||\n event.screenshotAfter ||\n event.screenshotWithBox,\n );\n\n // Sort them by priority (navigation first, then clicks, then others)\n const sortedEvents = [...eventsWithScreenshots].sort((a, b) => {\n if (a.type === 'navigation' && b.type !== 'navigation') return -1;\n if (a.type !== 'navigation' && b.type === 'navigation') return 1;\n if (a.type === 'click' && b.type !== 'click') return -1;\n if (a.type !== 'click' && b.type === 'click') return 1;\n return 0;\n });\n\n // Extract up to maxScreenshots screenshots\n const screenshots: string[] = [];\n for (const event of sortedEvents) {\n // Prefer the most informative screenshot\n const screenshot =\n event.screenshotWithBox ||\n event.screenshotAfter ||\n event.screenshotBefore;\n if (screenshot && !screenshots.includes(screenshot)) {\n screenshots.push(screenshot);\n if (screenshots.length >= maxScreenshots) break;\n }\n }\n\n return screenshots;\n};\n\n/**\n * Filter events by type for easier processing\n */\nexport const filterEventsByType = (\n events: ChromeRecordedEvent[],\n): FilteredEvents => {\n return {\n navigationEvents: events.filter((event) => event.type === 'navigation'),\n clickEvents: events.filter((event) => event.type === 'click'),\n inputEvents: events.filter((event) => event.type === 'input'),\n scrollEvents: events.filter((event) => event.type === 'scroll'),\n };\n};\n\n/**\n * Create event counts summary\n */\nexport const createEventCounts = (\n filteredEvents: FilteredEvents,\n totalEvents: number,\n): EventCounts => {\n return {\n navigation: filteredEvents.navigationEvents.length,\n click: filteredEvents.clickEvents.length,\n input: filteredEvents.inputEvents.length,\n scroll: filteredEvents.scrollEvents.length,\n total: totalEvents,\n };\n};\n\n/**\n * Extract input descriptions from input events\n */\nexport const extractInputDescriptions = (\n inputEvents: ChromeRecordedEvent[],\n): InputDescription[] => {\n return inputEvents\n .map((event) => ({\n description: event.elementDescription || '',\n value: event.value || '',\n }))\n .filter((item) => item.description && item.value);\n};\n\n/**\n * Process events for LLM consumption\n */\nexport const processEventsForLLM = (\n events: ChromeRecordedEvent[],\n): ProcessedEvent[] => {\n return events.map((event) => ({\n type: event.type,\n timestamp: event.timestamp,\n url: event.url,\n title: event.title,\n elementDescription: event.elementDescription,\n value: event.value,\n pageInfo: event.pageInfo,\n elementRect: event.elementRect,\n }));\n};\n\n/**\n * Prepare comprehensive event summary for LLM\n */\nexport const prepareEventSummary = (\n events: ChromeRecordedEvent[],\n options: { testName?: string; maxScreenshots?: number } = {},\n): EventSummary => {\n const filteredEvents = filterEventsByType(events);\n const eventCounts = createEventCounts(filteredEvents, events.length);\n\n // Extract useful information from events\n const startUrl =\n filteredEvents.navigationEvents.length > 0\n ? filteredEvents.navigationEvents[0].url || ''\n : '';\n\n const clickDescriptions = filteredEvents.clickEvents\n .map((event) => event.elementDescription)\n .filter((desc): desc is string => Boolean(desc))\n .slice(0, 10);\n\n const inputDescriptions = extractInputDescriptions(\n filteredEvents.inputEvents,\n ).slice(0, 10);\n\n const urls = filteredEvents.navigationEvents\n .map((e) => e.url)\n .filter((url): url is string => Boolean(url))\n .slice(0, 5);\n\n const processedEvents = processEventsForLLM(events);\n\n return {\n testName: options.testName || 'Automated test from recorded events',\n startUrl,\n eventCounts,\n urls,\n clickDescriptions,\n inputDescriptions,\n events: processedEvents,\n };\n};\n\n/**\n * Create message content for LLM with optional screenshots\n */\nexport const createMessageContent = (\n promptText: string,\n screenshots: string[] = [],\n includeScreenshots = true,\n) => {\n const messageContent: any[] = [\n {\n type: 'text',\n text: promptText,\n },\n ];\n\n // Add screenshots if available and requested\n if (includeScreenshots && screenshots.length > 0) {\n messageContent.unshift({\n type: 'text',\n text: 'Here are screenshots from the recording session to help you understand the context:',\n });\n\n screenshots.forEach((screenshot) => {\n messageContent.push({\n type: 'image_url',\n image_url: {\n url: screenshot,\n },\n });\n });\n }\n\n return messageContent;\n};\n\nconst getYamlLanguageInstruction = (language?: string) => {\n const normalizedLanguage = language?.trim();\n if (!normalizedLanguage) {\n return '';\n }\n\n return `\nLanguage requirement:\n- Write all human-readable YAML content in ${normalizedLanguage}.\n- Keep YAML keys, field names, and Midscene API names unchanged.`;\n};\n\nconst createYamlPrompt = ({\n yamlSummary,\n screenshots,\n language,\n}: {\n yamlSummary: EventSummary & { includeTimestamps: boolean };\n screenshots: string[];\n language?: string;\n}): ChatCompletionMessageParam[] => {\n const prompt: ChatCompletionMessageParam[] = [\n {\n role: 'system',\n content: `You are an expert in Midscene.js YAML test generation. Generate clean, accurate YAML following these rules: ${YAML_EXAMPLE_CODE}`,\n },\n {\n role: 'user',\n content: `Generate YAML test for Midscene.js automation from recorded browser events.\n\nEvent Summary:\n${JSON.stringify(yamlSummary, null, 2)}\n\nConvert events:\n- navigation → target.url\n- click → aiTap with element description\n- input → aiInput with value and locate\n- scroll → aiScroll with appropriate direction\n- Add aiAssert for important state changes${getYamlLanguageInstruction(language)}\n\nImportant: Return ONLY the raw YAML content. Do NOT wrap the response in markdown code blocks (no \\`\\`\\`yaml or \\`\\`\\`). Start directly with the YAML content.`,\n },\n ];\n\n if (screenshots.length > 0) {\n prompt.push({\n role: 'user',\n content:\n 'Here are screenshots from the recording session to help you understand the context:',\n });\n\n prompt.push({\n role: 'user',\n content: screenshots.map((screenshot) => ({\n type: 'image_url',\n image_url: {\n url: screenshot,\n },\n })),\n });\n }\n\n return prompt;\n};\n\n/**\n * Validate events before processing\n */\nexport const validateEvents = (events: ChromeRecordedEvent[]): void => {\n if (!events.length) {\n throw new Error('No events provided for test generation');\n }\n};\n\n// YAML-specific generation functions\n\n/**\n * Generates YAML test configuration from recorded events using AI\n */\nexport const generateYamlTest = async (\n events: ChromeRecordedEvent[],\n options: YamlGenerationOptions,\n modelConfig: IModelConfig,\n): Promise<string> => {\n try {\n // Validate input\n validateEvents(events);\n\n // Prepare event summary using shared utilities\n const summary = prepareEventSummary(events, {\n testName: options.testName,\n maxScreenshots: options.maxScreenshots || 3,\n });\n\n // Add YAML-specific options to summary\n const yamlSummary = {\n ...summary,\n includeTimestamps: options.includeTimestamps || false,\n };\n\n // Get screenshots for visual context\n const screenshots = getScreenshotsForLLM(\n events,\n options.maxScreenshots || 3,\n );\n\n const prompt = createYamlPrompt({\n yamlSummary,\n screenshots,\n language: options.language,\n });\n\n const response = await callAIWithStringResponse(prompt, modelConfig);\n\n if (response?.content && typeof response.content === 'string') {\n return response.content;\n }\n\n throw new Error('Failed to generate YAML test configuration');\n } catch (error) {\n throw new Error(`Failed to generate YAML test: ${error}`);\n }\n};\n\n/**\n * Generates YAML test configuration from recorded events using AI with streaming support\n */\nexport const generateYamlTestStream = async (\n events: ChromeRecordedEvent[],\n options: YamlGenerationOptions & StreamingCodeGenerationOptions,\n modelConfig: IModelConfig,\n): Promise<StreamingAIResponse> => {\n try {\n // Validate input\n validateEvents(events);\n\n // Prepare event summary using shared utilities\n const summary = prepareEventSummary(events, {\n testName: options.testName,\n maxScreenshots: options.maxScreenshots || 3,\n });\n\n // Add YAML-specific options to summary\n const yamlSummary = {\n ...summary,\n includeTimestamps: options.includeTimestamps || false,\n };\n\n // Get screenshots for visual context\n const screenshots = getScreenshotsForLLM(\n events,\n options.maxScreenshots || 3,\n );\n\n const prompt = createYamlPrompt({\n yamlSummary,\n screenshots,\n language: options.language,\n });\n\n if (options.stream && options.onChunk) {\n // Use streaming\n return await callAI(prompt, modelConfig, {\n stream: true,\n onChunk: options.onChunk,\n });\n } else {\n // Fallback to non-streaming\n const response = await callAIWithStringResponse(prompt, modelConfig);\n\n if (response?.content && typeof response.content === 'string') {\n return {\n content: response.content,\n usage: response.usage,\n isStreamed: false,\n };\n }\n\n throw new Error('Failed to generate YAML test configuration');\n }\n } catch (error) {\n throw new Error(`Failed to generate YAML test: ${error}`);\n }\n};\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","getScreenshotsForLLM","events","maxScreenshots","eventsWithScreenshots","event","sortedEvents","a","b","screenshots","screenshot","filterEventsByType","createEventCounts","filteredEvents","totalEvents","extractInputDescriptions","inputEvents","item","processEventsForLLM","prepareEventSummary","options","eventCounts","startUrl","clickDescriptions","desc","Boolean","inputDescriptions","urls","e","url","processedEvents","createMessageContent","promptText","includeScreenshots","messageContent","getYamlLanguageInstruction","language","normalizedLanguage","createYamlPrompt","yamlSummary","prompt","YAML_EXAMPLE_CODE","JSON","validateEvents","Error","generateYamlTest","modelConfig","summary","response","callAIWithStringResponse","error","generateYamlTestStream","callAI"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-model/prompt/yaml-generator.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/prompt/yaml-generator.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 StreamingAIResponse,\n StreamingCodeGenerationOptions,\n} from '@/types';\nimport { YAML_EXAMPLE_CODE } from '@aiscene/shared/constants';\nimport type { IModelConfig } from '@aiscene/shared/env';\nimport {\n type ChatCompletionMessageParam,\n callAI,\n callAIWithStringResponse,\n} from '../index';\n\n// Common interfaces for test generation (shared between YAML and Playwright)\nexport interface EventCounts {\n navigation: number;\n click: number;\n input: number;\n scroll: number;\n total: number;\n}\n\nexport interface InputDescription {\n description: string;\n value: string;\n}\n\nexport interface ProcessedEvent {\n type: string;\n timestamp: number;\n url?: string;\n title?: string;\n elementDescription?: string;\n value?: string;\n pageInfo?: any;\n elementRect?: any;\n}\n\nexport interface EventSummary {\n testName: string;\n startUrl: string;\n eventCounts: EventCounts;\n urls: string[];\n clickDescriptions: string[];\n inputDescriptions: InputDescription[];\n events: ProcessedEvent[];\n}\n\n// Common ChromeRecordedEvent interface\nexport interface ChromeRecordedEvent {\n type: string;\n timestamp: number;\n url?: string;\n title?: string;\n elementDescription?: string;\n value?: string;\n pageInfo?: any;\n elementRect?: any;\n screenshotBefore?: string;\n screenshotAfter?: string;\n screenshotWithBox?: string;\n}\n\nexport interface YamlGenerationOptions {\n testName?: string;\n includeTimestamps?: boolean;\n maxScreenshots?: number;\n description?: string;\n /** Language for human-readable YAML content (e.g. 'English', 'Chinese'). Keys and API names are kept as-is. */\n language?: string;\n}\n\nexport interface FilteredEvents {\n navigationEvents: ChromeRecordedEvent[];\n clickEvents: ChromeRecordedEvent[];\n inputEvents: ChromeRecordedEvent[];\n scrollEvents: ChromeRecordedEvent[];\n}\n\n// Common utility functions (shared between YAML and Playwright generators)\n\n/**\n * Get screenshots from events for LLM context\n */\nexport const getScreenshotsForLLM = (\n events: ChromeRecordedEvent[],\n maxScreenshots = 1,\n): string[] => {\n // Find events with screenshots, prioritizing navigation and click events\n const eventsWithScreenshots = events.filter(\n (event) =>\n event.screenshotBefore ||\n event.screenshotAfter ||\n event.screenshotWithBox,\n );\n\n // Sort them by priority (navigation first, then clicks, then others)\n const sortedEvents = [...eventsWithScreenshots].sort((a, b) => {\n if (a.type === 'navigation' && b.type !== 'navigation') return -1;\n if (a.type !== 'navigation' && b.type === 'navigation') return 1;\n if (a.type === 'click' && b.type !== 'click') return -1;\n if (a.type !== 'click' && b.type === 'click') return 1;\n return 0;\n });\n\n // Extract up to maxScreenshots screenshots\n const screenshots: string[] = [];\n for (const event of sortedEvents) {\n // Prefer the most informative screenshot\n const screenshot =\n event.screenshotWithBox ||\n event.screenshotAfter ||\n event.screenshotBefore;\n if (screenshot && !screenshots.includes(screenshot)) {\n screenshots.push(screenshot);\n if (screenshots.length >= maxScreenshots) break;\n }\n }\n\n return screenshots;\n};\n\n/**\n * Filter events by type for easier processing\n */\nexport const filterEventsByType = (\n events: ChromeRecordedEvent[],\n): FilteredEvents => {\n return {\n navigationEvents: events.filter((event) => event.type === 'navigation'),\n clickEvents: events.filter((event) => event.type === 'click'),\n inputEvents: events.filter((event) => event.type === 'input'),\n scrollEvents: events.filter((event) => event.type === 'scroll'),\n };\n};\n\n/**\n * Create event counts summary\n */\nexport const createEventCounts = (\n filteredEvents: FilteredEvents,\n totalEvents: number,\n): EventCounts => {\n return {\n navigation: filteredEvents.navigationEvents.length,\n click: filteredEvents.clickEvents.length,\n input: filteredEvents.inputEvents.length,\n scroll: filteredEvents.scrollEvents.length,\n total: totalEvents,\n };\n};\n\n/**\n * Extract input descriptions from input events\n */\nexport const extractInputDescriptions = (\n inputEvents: ChromeRecordedEvent[],\n): InputDescription[] => {\n return inputEvents\n .map((event) => ({\n description: event.elementDescription || '',\n value: event.value || '',\n }))\n .filter((item) => item.description && item.value);\n};\n\n/**\n * Process events for LLM consumption\n */\nexport const processEventsForLLM = (\n events: ChromeRecordedEvent[],\n): ProcessedEvent[] => {\n return events.map((event) => ({\n type: event.type,\n timestamp: event.timestamp,\n url: event.url,\n title: event.title,\n elementDescription: event.elementDescription,\n value: event.value,\n pageInfo: event.pageInfo,\n elementRect: event.elementRect,\n }));\n};\n\n/**\n * Prepare comprehensive event summary for LLM\n */\nexport const prepareEventSummary = (\n events: ChromeRecordedEvent[],\n options: { testName?: string; maxScreenshots?: number } = {},\n): EventSummary => {\n const filteredEvents = filterEventsByType(events);\n const eventCounts = createEventCounts(filteredEvents, events.length);\n\n // Extract useful information from events\n const startUrl =\n filteredEvents.navigationEvents.length > 0\n ? filteredEvents.navigationEvents[0].url || ''\n : '';\n\n const clickDescriptions = filteredEvents.clickEvents\n .map((event) => event.elementDescription)\n .filter((desc): desc is string => Boolean(desc))\n .slice(0, 10);\n\n const inputDescriptions = extractInputDescriptions(\n filteredEvents.inputEvents,\n ).slice(0, 10);\n\n const urls = filteredEvents.navigationEvents\n .map((e) => e.url)\n .filter((url): url is string => Boolean(url))\n .slice(0, 5);\n\n const processedEvents = processEventsForLLM(events);\n\n return {\n testName: options.testName || 'Automated test from recorded events',\n startUrl,\n eventCounts,\n urls,\n clickDescriptions,\n inputDescriptions,\n events: processedEvents,\n };\n};\n\n/**\n * Create message content for LLM with optional screenshots\n */\nexport const createMessageContent = (\n promptText: string,\n screenshots: string[] = [],\n includeScreenshots = true,\n) => {\n const messageContent: any[] = [\n {\n type: 'text',\n text: promptText,\n },\n ];\n\n // Add screenshots if available and requested\n if (includeScreenshots && screenshots.length > 0) {\n messageContent.unshift({\n type: 'text',\n text: 'Here are screenshots from the recording session to help you understand the context:',\n });\n\n screenshots.forEach((screenshot) => {\n messageContent.push({\n type: 'image_url',\n image_url: {\n url: screenshot,\n },\n });\n });\n }\n\n return messageContent;\n};\n\nconst getYamlLanguageInstruction = (language?: string) => {\n const normalizedLanguage = language?.trim();\n if (!normalizedLanguage) {\n return '';\n }\n\n return `\nLanguage requirement:\n- Write all human-readable YAML content in ${normalizedLanguage}.\n- Keep YAML keys, field names, and Midscene API names unchanged.`;\n};\n\nconst createYamlPrompt = ({\n yamlSummary,\n screenshots,\n language,\n}: {\n yamlSummary: EventSummary & { includeTimestamps: boolean };\n screenshots: string[];\n language?: string;\n}): ChatCompletionMessageParam[] => {\n const prompt: ChatCompletionMessageParam[] = [\n {\n role: 'system',\n content: `You are an expert in Midscene.js YAML test generation. Generate clean, accurate YAML following these rules: ${YAML_EXAMPLE_CODE}`,\n },\n {\n role: 'user',\n content: `Generate YAML test for Midscene.js automation from recorded browser events.\n\nEvent Summary:\n${JSON.stringify(yamlSummary, null, 2)}\n\nConvert events:\n- navigation → target.url\n- click → aiTap with element description\n- input → aiInput with value and locate\n- scroll → aiScroll with appropriate direction\n- Add aiAssert for important state changes${getYamlLanguageInstruction(language)}\n\nImportant: Return ONLY the raw YAML content. Do NOT wrap the response in markdown code blocks (no \\`\\`\\`yaml or \\`\\`\\`). Start directly with the YAML content.`,\n },\n ];\n\n if (screenshots.length > 0) {\n prompt.push({\n role: 'user',\n content:\n 'Here are screenshots from the recording session to help you understand the context:',\n });\n\n prompt.push({\n role: 'user',\n content: screenshots.map((screenshot) => ({\n type: 'image_url',\n image_url: {\n url: screenshot,\n },\n })),\n });\n }\n\n return prompt;\n};\n\n/**\n * Validate events before processing\n */\nexport const validateEvents = (events: ChromeRecordedEvent[]): void => {\n if (!events.length) {\n throw new Error('No events provided for test generation');\n }\n};\n\n// YAML-specific generation functions\n\n/**\n * Generates YAML test configuration from recorded events using AI\n */\nexport const generateYamlTest = async (\n events: ChromeRecordedEvent[],\n options: YamlGenerationOptions,\n modelConfig: IModelConfig,\n): Promise<string> => {\n try {\n // Validate input\n validateEvents(events);\n\n // Prepare event summary using shared utilities\n const summary = prepareEventSummary(events, {\n testName: options.testName,\n maxScreenshots: options.maxScreenshots || 3,\n });\n\n // Add YAML-specific options to summary\n const yamlSummary = {\n ...summary,\n includeTimestamps: options.includeTimestamps || false,\n };\n\n // Get screenshots for visual context\n const screenshots = getScreenshotsForLLM(\n events,\n options.maxScreenshots || 3,\n );\n\n const prompt = createYamlPrompt({\n yamlSummary,\n screenshots,\n language: options.language,\n });\n\n const response = await callAIWithStringResponse(prompt, modelConfig);\n\n if (response?.content && typeof response.content === 'string') {\n return response.content;\n }\n\n throw new Error('Failed to generate YAML test configuration');\n } catch (error) {\n throw new Error(`Failed to generate YAML test: ${error}`);\n }\n};\n\n/**\n * Generates YAML test configuration from recorded events using AI with streaming support\n */\nexport const generateYamlTestStream = async (\n events: ChromeRecordedEvent[],\n options: YamlGenerationOptions & StreamingCodeGenerationOptions,\n modelConfig: IModelConfig,\n): Promise<StreamingAIResponse> => {\n try {\n // Validate input\n validateEvents(events);\n\n // Prepare event summary using shared utilities\n const summary = prepareEventSummary(events, {\n testName: options.testName,\n maxScreenshots: options.maxScreenshots || 3,\n });\n\n // Add YAML-specific options to summary\n const yamlSummary = {\n ...summary,\n includeTimestamps: options.includeTimestamps || false,\n };\n\n // Get screenshots for visual context\n const screenshots = getScreenshotsForLLM(\n events,\n options.maxScreenshots || 3,\n );\n\n const prompt = createYamlPrompt({\n yamlSummary,\n screenshots,\n language: options.language,\n });\n\n if (options.stream && options.onChunk) {\n // Use streaming\n return await callAI(prompt, modelConfig, {\n stream: true,\n onChunk: options.onChunk,\n });\n } else {\n // Fallback to non-streaming\n const response = await callAIWithStringResponse(prompt, modelConfig);\n\n if (response?.content && typeof response.content === 'string') {\n return {\n content: response.content,\n usage: response.usage,\n isStreamed: false,\n };\n }\n\n throw new Error('Failed to generate YAML test configuration');\n }\n } catch (error) {\n throw new Error(`Failed to generate YAML test: ${error}`);\n }\n};\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","getScreenshotsForLLM","events","maxScreenshots","eventsWithScreenshots","event","sortedEvents","a","b","screenshots","screenshot","filterEventsByType","createEventCounts","filteredEvents","totalEvents","extractInputDescriptions","inputEvents","item","processEventsForLLM","prepareEventSummary","options","eventCounts","startUrl","clickDescriptions","desc","Boolean","inputDescriptions","urls","e","url","processedEvents","createMessageContent","promptText","includeScreenshots","messageContent","getYamlLanguageInstruction","language","normalizedLanguage","createYamlPrompt","yamlSummary","prompt","YAML_EXAMPLE_CODE","JSON","validateEvents","Error","generateYamlTest","modelConfig","summary","response","callAIWithStringResponse","error","generateYamlTestStream","callAI"],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
|
|
|
13
13
|
})();
|
|
14
14
|
(()=>{
|
|
15
15
|
__webpack_require__.r = (exports1)=>{
|
|
16
|
-
if (
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
17
|
value: 'Module'
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports1, '__esModule', {
|
|
@@ -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 { IModelConfig } from '@aiscene/shared/env';\nimport { getDebug } from '@aiscene/shared/logger';\nimport { ifInBrowser } from '@aiscene/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?: boolean;\n modelConfig: IModelConfig;\n}): CodexReasoningEffort | undefined => {\n if (reasoningEnabled === true) return 'high';\n if (reasoningEnabled === false) 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 '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?: boolean;\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 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 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?: boolean;\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?: boolean;\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 { IModelConfig } from '@aiscene/shared/env';\nimport { getDebug } from '@aiscene/shared/logger';\nimport { ifInBrowser } from '@aiscene/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?: boolean;\n modelConfig: IModelConfig;\n}): CodexReasoningEffort | undefined => {\n if (reasoningEnabled === true) return 'high';\n if (reasoningEnabled === false) 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 '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?: boolean;\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 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 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?: boolean;\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?: boolean;\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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"}
|
|
@@ -13,7 +13,7 @@ var __webpack_require__ = {};
|
|
|
13
13
|
})();
|
|
14
14
|
(()=>{
|
|
15
15
|
__webpack_require__.r = (exports1)=>{
|
|
16
|
-
if (
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
17
|
value: 'Module'
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports1, '__esModule', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/service-caller/image-detail.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/service-caller/image-detail.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 { IModelConfig } from '@aiscene/shared/env';\n\nexport function shouldForceOriginalImageDetail(\n modelConfig: Pick<IModelConfig, 'intent' | 'modelFamily'>,\n): boolean {\n return (\n modelConfig.modelFamily === 'gpt-5' && modelConfig.intent === 'default'\n );\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","shouldForceOriginalImageDetail","modelConfig"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,
|
|
1
|
+
{"version":3,"file":"ai-model/service-caller/image-detail.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/service-caller/image-detail.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 { IModelConfig } from '@aiscene/shared/env';\n\nexport function shouldForceOriginalImageDetail(\n modelConfig: Pick<IModelConfig, 'intent' | 'modelFamily'>,\n): boolean {\n return (\n modelConfig.modelFamily === 'gpt-5' && modelConfig.intent === 'default'\n );\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","shouldForceOriginalImageDetail","modelConfig"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;ACJO,SAASI,+BACdC,WAAyD;IAEzD,OACEA,AAA4B,YAA5BA,YAAY,WAAW,IAAgBA,AAAuB,cAAvBA,YAAY,MAAM;AAE7D"}
|
|
@@ -22,7 +22,7 @@ var __webpack_require__ = {};
|
|
|
22
22
|
})();
|
|
23
23
|
(()=>{
|
|
24
24
|
__webpack_require__.r = (exports1)=>{
|
|
25
|
-
if (
|
|
25
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
26
26
|
value: 'Module'
|
|
27
27
|
});
|
|
28
28
|
Object.defineProperty(exports1, '__esModule', {
|