@midscene/core 1.17.5 → 1.17.6
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/utils.mjs +1 -1
- package/dist/es/ai-model/models/jev/locate.mjs +2 -12
- package/dist/es/ai-model/models/jev/locate.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/call-ai.mjs +4 -1
- package/dist/es/ai-model/service-caller/call-ai.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/openai/siwc/authorization.mjs +4 -3
- package/dist/es/ai-model/service-caller/openai/siwc/authorization.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/openai/siwc/network.mjs +36 -0
- package/dist/es/ai-model/service-caller/openai/siwc/network.mjs.map +1 -0
- package/dist/es/ai-model/service-caller/openai/siwc/refresh.mjs +5 -3
- package/dist/es/ai-model/service-caller/openai/siwc/refresh.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/openai/siwc/token-manager.mjs +7 -4
- package/dist/es/ai-model/service-caller/openai/siwc/token-manager.mjs.map +1 -1
- package/dist/es/ai-model/shared/json.mjs +6 -2
- package/dist/es/ai-model/shared/json.mjs.map +1 -1
- package/dist/es/report-html-template.mjs +1 -1
- package/dist/es/siwc.mjs +4 -0
- package/dist/es/task-runner.mjs +7 -2
- package/dist/es/task-runner.mjs.map +1 -1
- package/dist/es/utils.mjs +1 -1
- package/dist/lib/agent/utils.js +1 -1
- package/dist/lib/ai-model/models/jev/locate.js +2 -12
- package/dist/lib/ai-model/models/jev/locate.js.map +1 -1
- package/dist/lib/ai-model/service-caller/call-ai.js +4 -1
- package/dist/lib/ai-model/service-caller/call-ai.js.map +1 -1
- package/dist/lib/ai-model/service-caller/openai/siwc/authorization.js +3 -2
- package/dist/lib/ai-model/service-caller/openai/siwc/authorization.js.map +1 -1
- package/dist/lib/ai-model/service-caller/openai/siwc/network.js +73 -0
- package/dist/lib/ai-model/service-caller/openai/siwc/network.js.map +1 -0
- package/dist/lib/ai-model/service-caller/openai/siwc/refresh.js +4 -2
- package/dist/lib/ai-model/service-caller/openai/siwc/refresh.js.map +1 -1
- package/dist/lib/ai-model/service-caller/openai/siwc/token-manager.js +7 -4
- package/dist/lib/ai-model/service-caller/openai/siwc/token-manager.js.map +1 -1
- package/dist/lib/ai-model/shared/json.js +6 -2
- package/dist/lib/ai-model/shared/json.js.map +1 -1
- package/dist/lib/report-html-template.js +1 -1
- package/dist/lib/siwc.js +52 -0
- package/dist/lib/siwc.js.map +1 -0
- package/dist/lib/task-runner.js +7 -2
- package/dist/lib/task-runner.js.map +1 -1
- package/dist/lib/utils.js +1 -1
- package/dist/types/ai-model/models/jev/locate.d.ts.map +1 -1
- package/dist/types/ai-model/service-caller/openai/siwc/authorization.d.ts.map +1 -1
- package/dist/types/ai-model/service-caller/openai/siwc/network.d.ts +8 -0
- package/dist/types/ai-model/service-caller/openai/siwc/network.d.ts.map +1 -0
- package/dist/types/ai-model/service-caller/openai/siwc/refresh.d.ts +1 -1
- package/dist/types/ai-model/service-caller/openai/siwc/refresh.d.ts.map +1 -1
- package/dist/types/ai-model/service-caller/openai/siwc/token-manager.d.ts +2 -1
- package/dist/types/ai-model/service-caller/openai/siwc/token-manager.d.ts.map +1 -1
- package/dist/types/ai-model/shared/json.d.ts +4 -15
- package/dist/types/ai-model/shared/json.d.ts.map +1 -1
- package/dist/types/siwc.d.ts +5 -0
- package/dist/types/siwc.d.ts.map +1 -0
- package/dist/types/task-runner.d.ts.map +1 -1
- package/package.json +10 -2
package/dist/es/siwc.mjs
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { refreshSiwcCredentials } from "./ai-model/service-caller/openai/siwc/refresh.mjs";
|
|
2
|
+
import { createSiwcAuthorization, exchangeSiwcCode, parseSiwcCallback } from "./ai-model/service-caller/openai/siwc/authorization.mjs";
|
|
3
|
+
import { SiwcError } from "./ai-model/service-caller/openai/siwc/errors.mjs";
|
|
4
|
+
export { SiwcError, createSiwcAuthorization, exchangeSiwcCode, parseSiwcCallback, refreshSiwcCredentials };
|
package/dist/es/task-runner.mjs
CHANGED
|
@@ -15,6 +15,11 @@ function _define_property(obj, key, value) {
|
|
|
15
15
|
}
|
|
16
16
|
const debug = getDebug('task-runner');
|
|
17
17
|
const UI_CONTEXT_CACHE_TTL_MS = 300;
|
|
18
|
+
function serializeTaskError(error, signal) {
|
|
19
|
+
const serializedError = serializeError(error);
|
|
20
|
+
if (signal?.aborted && error === signal.reason) serializedError.message = truncateSerializedErrorString(`Operation interrupted by an external abort signal.\nReason: ${serializedError.message}`);
|
|
21
|
+
return serializedError;
|
|
22
|
+
}
|
|
18
23
|
function serializeErrorTask(task) {
|
|
19
24
|
if (!task) return;
|
|
20
25
|
return {
|
|
@@ -212,7 +217,7 @@ class TaskRunner {
|
|
|
212
217
|
taskIndex++;
|
|
213
218
|
} catch (error) {
|
|
214
219
|
successfullyCompleted = false;
|
|
215
|
-
const serializedError =
|
|
220
|
+
const serializedError = serializeTaskError(error, this.abortSignal);
|
|
216
221
|
task.error = serializedError;
|
|
217
222
|
task.errorMessage = serializedError.message;
|
|
218
223
|
task.errorStack = serializedError.stack;
|
|
@@ -242,7 +247,7 @@ class TaskRunner {
|
|
|
242
247
|
} else {
|
|
243
248
|
this.status = 'error';
|
|
244
249
|
const errorTask = this.latestErrorTask();
|
|
245
|
-
const error = errorTask?.error ?? (this.abortSignal?.aborted ?
|
|
250
|
+
const error = errorTask?.error ?? (this.abortSignal?.aborted ? serializeTaskError(this.abortSignal.reason, this.abortSignal) : {
|
|
246
251
|
name: 'Error',
|
|
247
252
|
message: 'Task execution failed'
|
|
248
253
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-runner.mjs","sources":["../../src/task-runner.ts"],"sourcesContent":["import type { ScreenshotItem } from '@/screenshot-item';\nimport { setTimingFieldOnce } from '@/task-timing';\nimport {\n ExecutionDump,\n type ExecutionRecorderItem,\n type ExecutionTask,\n type ExecutionTaskActionApply,\n type ExecutionTaskApply,\n type ExecutionTaskPlanningLocateOutput,\n type ExecutionTaskProgressOptions,\n type ExecutionTaskReturn,\n type ExecutorContext,\n type PlanningActionParamError,\n type UIContext,\n} from '@/types';\nimport {\n type SerializedError,\n serializeError,\n truncateSerializedErrorString,\n} from '@midscene/shared/agent-tools/error-formatter';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert, uuid } from '@midscene/shared/utils';\n\nconst debug = getDebug('task-runner');\nconst UI_CONTEXT_CACHE_TTL_MS = 300;\n\n/**\n * A native, per-task lifecycle notification. The runner is the single source\n * of truth for when a task actually transitions, so it reports each transition\n * exactly once with the task that changed. Consumers no longer have to re-scan\n * the task list and diff it against remembered keys to reconstruct this stream.\n */\nexport type TaskRunnerEventKind =\n | 'append'\n | 'start'\n | 'finish'\n | 'error'\n | 'cancel';\n\nexport interface TaskRunnerEvent {\n kind: TaskRunnerEventKind;\n task: ExecutionTask;\n runner: TaskRunner;\n}\n\nexport interface SerializedErrorTask {\n taskId: string;\n type: ExecutionTask['type'];\n subType?: string;\n status: ExecutionTask['status'];\n thought?: string;\n errorMessage?: string;\n}\n\nexport interface SerializedTaskExecutionError extends SerializedError {\n code: 'TASK_EXECUTION_FAILED';\n cause: SerializedError;\n task?: SerializedErrorTask;\n}\n\nfunction serializeErrorTask(\n task: ExecutionTask | null,\n): SerializedErrorTask | undefined {\n if (!task) {\n return undefined;\n }\n\n return {\n taskId: truncateSerializedErrorString(task.taskId),\n type: task.type,\n ...(task.subType === undefined\n ? {}\n : { subType: truncateSerializedErrorString(task.subType) }),\n status: task.status,\n ...(task.thought === undefined\n ? {}\n : { thought: truncateSerializedErrorString(task.thought) }),\n ...(task.errorMessage === undefined\n ? {}\n : {\n errorMessage: truncateSerializedErrorString(task.errorMessage),\n }),\n };\n}\n\nexport type TaskRunnerEventListener = (\n event: TaskRunnerEvent,\n) => Promise<void> | void;\n\n/** Minimal prompt-image shape retained as report asset metadata. */\nexport interface ExecutionReferenceImage {\n readonly url: string;\n}\n\ntype TaskRunnerInitOptions = ExecutionTaskProgressOptions & {\n tasks?: ExecutionTaskApply[];\n abortSignal?: AbortSignal;\n referenceImages?: readonly ExecutionReferenceImage[];\n /**\n * Coarse \"the execution snapshot changed\" signal. Fires on any state change\n * (append, status flips, completion) with the whole runner, so consumers can\n * re-dump/re-render the current snapshot. Deliberately batch-granular, unlike\n * the per-task {@link onTaskEvent} stream.\n */\n onSnapshotChange?: (\n runner: TaskRunner,\n error?: TaskExecutionError,\n ) => Promise<void> | void;\n onTaskEvent?: TaskRunnerEventListener;\n};\n\ntype TaskRunnerOperationOptions = {\n allowWhenError?: boolean;\n};\n\nexport class TaskRunner {\n readonly id: string;\n name: string;\n\n tasks: ExecutionTask[];\n\n // status of runner\n status: 'init' | 'pending' | 'running' | 'completed' | 'error';\n\n onTaskStart?: ExecutionTaskProgressOptions['onTaskStart'];\n\n private readonly uiContextBuilder: (\n signal?: AbortSignal,\n ) => Promise<UIContext>;\n private readonly abortSignal?: AbortSignal;\n\n private readonly onSnapshotChange?:\n | ((runner: TaskRunner, error?: TaskExecutionError) => Promise<void> | void)\n | undefined;\n\n private readonly onTaskEvent?: TaskRunnerEventListener | undefined;\n\n private readonly executionLogTime: number;\n\n private readonly referenceImageUrls = new Set<string>();\n\n constructor(\n name: string,\n uiContextBuilder: (signal?: AbortSignal) => Promise<UIContext>,\n options?: TaskRunnerInitOptions,\n ) {\n this.id = uuid();\n this.status =\n options?.tasks && options.tasks.length > 0 ? 'pending' : 'init';\n this.name = name;\n this.tasks = (options?.tasks || []).map((item) =>\n this.markTaskAsPending(item),\n );\n this.onTaskStart = options?.onTaskStart;\n this.uiContextBuilder = uiContextBuilder;\n this.abortSignal = options?.abortSignal;\n this.onSnapshotChange = options?.onSnapshotChange;\n this.onTaskEvent = options?.onTaskEvent;\n this.executionLogTime = Date.now();\n for (const image of options?.referenceImages ?? []) {\n this.referenceImageUrls.add(image.url);\n }\n }\n\n private async emitSnapshotChange(error?: TaskExecutionError): Promise<void> {\n if (!this.onSnapshotChange) {\n return;\n }\n await this.onSnapshotChange(this, error);\n }\n\n private async emitTaskEvent(\n kind: TaskRunnerEventKind,\n task: ExecutionTask,\n ): Promise<void> {\n if (!this.onTaskEvent) {\n return;\n }\n try {\n await this.onTaskEvent({ kind, task, runner: this });\n } catch (error) {\n console.error('Error in onTaskEvent listener', error);\n }\n }\n\n private lastUiContext?: {\n context: UIContext;\n capturedAt: number;\n };\n\n private async getUiContext(options?: { forceRefresh?: boolean }): Promise<\n UIContext | undefined\n > {\n this.abortSignal?.throwIfAborted();\n const now = Date.now();\n const shouldReuse =\n !options?.forceRefresh &&\n this.lastUiContext &&\n now - this.lastUiContext.capturedAt <= UI_CONTEXT_CACHE_TTL_MS;\n\n if (shouldReuse && this.lastUiContext?.context) {\n debug(\n `reuse cached uiContext captured ${now - this.lastUiContext.capturedAt}ms ago`,\n );\n return this.lastUiContext?.context;\n }\n\n try {\n const uiContext = await this.uiContextBuilder(this.abortSignal);\n this.abortSignal?.throwIfAborted();\n if (uiContext) {\n this.lastUiContext = {\n context: uiContext,\n capturedAt: Date.now(),\n };\n } else {\n this.lastUiContext = undefined;\n }\n return uiContext;\n } catch (error) {\n this.lastUiContext = undefined;\n throw error;\n }\n }\n\n private async captureScreenshot(): Promise<ScreenshotItem | undefined> {\n try {\n const uiContext = await this.getUiContext({ forceRefresh: true });\n return uiContext?.screenshot;\n } catch (error) {\n console.error('error while capturing screenshot', error);\n }\n return undefined;\n }\n\n private attachRecorderItem(\n task: ExecutionTask,\n screenshot: ScreenshotItem | undefined,\n phase: 'after-calling',\n ): void {\n if (!phase || !screenshot) {\n return;\n }\n\n const recorderItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: Date.now(),\n screenshot,\n timing: phase,\n };\n\n if (!task.recorder) {\n task.recorder = [recorderItem];\n return;\n }\n task.recorder.push(recorderItem);\n }\n\n private markTaskAsPending(task: ExecutionTaskApply): ExecutionTask {\n return {\n taskId: uuid(),\n status: 'pending',\n ...task,\n };\n }\n\n private normalizeStatusFromError(\n options?: TaskRunnerOperationOptions,\n errorMessage?: string,\n ): void {\n if (this.status !== 'error') {\n return;\n }\n assert(\n options?.allowWhenError,\n errorMessage ||\n `task runner is in error state, cannot proceed\\nerror=${this.latestErrorTask()?.errorMessage}\\n${this.latestErrorTask()?.errorStack}`,\n );\n // reset runner state so new tasks can run\n this.status = this.tasks.length > 0 ? 'pending' : 'init';\n }\n\n async append(\n task: ExecutionTaskApply[] | ExecutionTaskApply,\n options?: TaskRunnerOperationOptions,\n ): Promise<void> {\n this.abortSignal?.throwIfAborted();\n this.normalizeStatusFromError(\n options,\n `task runner is in error state, cannot append task\\nerror=${this.latestErrorTask()?.errorMessage}\\n${this.latestErrorTask()?.errorStack}`,\n );\n const appended: ExecutionTask[] = [];\n if (Array.isArray(task)) {\n appended.push(...task.map((item) => this.markTaskAsPending(item)));\n } else {\n appended.push(this.markTaskAsPending(task));\n }\n this.tasks.push(...appended);\n if (this.status !== 'running') {\n this.status = 'pending';\n }\n await this.emitSnapshotChange();\n for (const appendedTask of appended) {\n await this.emitTaskEvent('append', appendedTask);\n }\n }\n\n async appendAndFlush(\n task: ExecutionTaskApply[] | ExecutionTaskApply,\n options?: TaskRunnerOperationOptions,\n ): Promise<{ output: any; thought?: string } | undefined> {\n await this.append(task, options);\n return this.flush(options);\n }\n\n async flush(\n options?: TaskRunnerOperationOptions,\n ): Promise<{ output: any; thought?: string } | undefined> {\n if (this.status === 'init' && this.tasks.length > 0) {\n console.warn(\n 'illegal state for task runner, status is init but tasks are not empty',\n );\n }\n\n this.normalizeStatusFromError(options, 'task runner is in error state');\n assert(this.status !== 'running', 'task runner is already running');\n assert(this.status !== 'completed', 'task runner is already completed');\n\n const nextPendingIndex = this.tasks.findIndex(\n (task) => task.status === 'pending',\n );\n if (nextPendingIndex < 0) {\n // all tasks are completed\n return;\n }\n\n this.status = 'running';\n await this.emitSnapshotChange();\n let taskIndex = nextPendingIndex;\n let successfullyCompleted = true;\n\n let previousFindOutput: ExecutionTaskPlanningLocateOutput | undefined;\n\n while (taskIndex < this.tasks.length) {\n const task = this.tasks[taskIndex];\n assert(\n task.status === 'pending',\n `task status should be pending, but got: ${task.status}`,\n );\n let taskStarted = false;\n try {\n this.abortSignal?.throwIfAborted();\n taskStarted = true;\n task.timing = { start: Date.now() };\n task.status = 'running';\n await this.emitSnapshotChange();\n await this.emitTaskEvent('start', task);\n this.abortSignal?.throwIfAborted();\n try {\n if (this.onTaskStart) {\n await this.onTaskStart(task, this.abortSignal);\n }\n } catch (e) {\n console.error('error in onTaskStart', e);\n }\n this.abortSignal?.throwIfAborted();\n assert(\n ['Insight', 'Action Space', 'Planning'].indexOf(task.type) >= 0,\n `unsupported task type: ${task.type}`,\n );\n\n const { executor } = task;\n assert(executor, `executor is required for task type: ${task.type}`);\n\n let returnValue;\n // For Insight tasks (Query/Assert/WaitFor), always get fresh context\n // to ensure we have the latest UI state after any preceding actions\n const forceRefresh = task.type === 'Insight';\n setTimingFieldOnce(task.timing, 'getUiContextStart');\n const uiContext = await this.getUiContext({ forceRefresh });\n setTimingFieldOnce(task.timing, 'getUiContextEnd');\n this.abortSignal?.throwIfAborted();\n\n task.uiContext = uiContext;\n const executorContext: ExecutorContext = {\n task,\n element: previousFindOutput?.element,\n uiContext,\n signal: this.abortSignal,\n };\n\n if (task.type === 'Insight') {\n assert(\n task.subType === 'Query' ||\n task.subType === 'Assert' ||\n task.subType === 'WaitFor' ||\n task.subType === 'Boolean' ||\n task.subType === 'Number' ||\n task.subType === 'String',\n `unsupported service subType: ${task.subType}`,\n );\n returnValue = await task.executor(executorContext);\n } else if (task.type === 'Planning') {\n returnValue = await task.executor(executorContext);\n if (task.subType === 'Locate') {\n previousFindOutput = (\n returnValue as ExecutionTaskReturn<ExecutionTaskPlanningLocateOutput>\n )?.output;\n }\n } else if (task.type === 'Action Space') {\n try {\n returnValue = await task.executor(executorContext);\n } finally {\n // The short TTL still lets planning and the action itself share one\n // context. Once an action settles, time alone can no longer prove\n // that the cached context represents the current UI.\n this.lastUiContext = undefined;\n }\n } else {\n console.warn(\n `unsupported task type: ${task.type}, will try to execute it directly`,\n );\n returnValue = await task.executor(executorContext);\n }\n\n this.abortSignal?.throwIfAborted();\n const isLastTask = taskIndex === this.tasks.length - 1;\n\n if (isLastTask) {\n setTimingFieldOnce(task.timing, 'captureAfterCallingSnapshotStart');\n const screenshot = await this.captureScreenshot();\n this.abortSignal?.throwIfAborted();\n this.attachRecorderItem(task, screenshot, 'after-calling');\n setTimingFieldOnce(task.timing, 'captureAfterCallingSnapshotEnd');\n }\n // Cancellation may arrive during the report screenshot, after planning\n // has returned but before the next batch of actions is built.\n this.abortSignal?.throwIfAborted();\n\n Object.assign(task, returnValue);\n task.status = 'finished';\n task.timing.end = Date.now();\n task.timing.cost = task.timing.end - task.timing.start;\n await this.emitSnapshotChange();\n await this.emitTaskEvent('finish', task);\n taskIndex++;\n } catch (error) {\n successfullyCompleted = false;\n const serializedError = serializeError(error);\n task.error = serializedError;\n task.errorMessage = serializedError.message;\n task.errorStack = serializedError.stack;\n\n task.status = taskStarted ? 'failed' : 'cancelled';\n if (taskStarted && task.timing) {\n task.timing.end = Date.now();\n task.timing.cost = task.timing.end - task.timing.start;\n }\n await this.emitSnapshotChange();\n await this.emitTaskEvent(taskStarted ? 'error' : 'cancel', task);\n break;\n }\n }\n\n // set all remaining tasks as cancelled\n const cancelledTasks: ExecutionTask[] = [];\n for (let i = taskIndex + 1; i < this.tasks.length; i++) {\n this.tasks[i].status = 'cancelled';\n cancelledTasks.push(this.tasks[i]);\n }\n if (cancelledTasks.length > 0) {\n await this.emitSnapshotChange();\n for (const cancelledTask of cancelledTasks) {\n await this.emitTaskEvent('cancel', cancelledTask);\n }\n }\n\n let finalizeError: TaskExecutionError | undefined;\n if (!successfullyCompleted) {\n this.status = 'error';\n const errorTask = this.latestErrorTask();\n const error =\n errorTask?.error ??\n (this.abortSignal?.aborted\n ? serializeError(this.abortSignal.reason)\n : {\n name: 'Error',\n message: 'Task execution failed',\n });\n finalizeError = new TaskExecutionError(\n error,\n serializeErrorTask(errorTask),\n );\n await this.emitSnapshotChange(finalizeError);\n } else {\n this.status = 'completed';\n await this.emitSnapshotChange();\n }\n\n if (finalizeError) {\n throw finalizeError;\n }\n\n if (this.tasks.length) {\n // return the last output\n const outputIndex = Math.min(taskIndex, this.tasks.length - 1);\n const { thought, output } = this.tasks[outputIndex];\n return {\n thought,\n output,\n };\n }\n }\n\n isInErrorState(): boolean {\n return this.status === 'error';\n }\n\n latestErrorTask(): ExecutionTask | null {\n if (this.status !== 'error') {\n return null;\n }\n // Find the LAST failed task (not the first one)\n // This is important when using allowWhenError to continue after errors\n for (let i = this.tasks.length - 1; i >= 0; i--) {\n if (this.tasks[i].status === 'failed') {\n return this.tasks[i];\n }\n }\n return null;\n }\n\n dump(): ExecutionDump {\n return new ExecutionDump(\n {\n id: this.id,\n logTime: this.executionLogTime,\n name: this.name,\n tasks: this.tasks,\n },\n { referenceImageUrls: [...this.referenceImageUrls] },\n );\n }\n\n async appendErrorPlan(errorMsg: string): Promise<{\n output: undefined;\n runner: TaskRunner;\n }> {\n const errorTask: ExecutionTaskActionApply<PlanningActionParamError> = {\n type: 'Action Space',\n subType: 'Error',\n param: {\n thought: errorMsg,\n },\n thought: errorMsg,\n executor: async () => {\n throw new Error(errorMsg || 'error without thought');\n },\n };\n await this.appendAndFlush(errorTask);\n\n return {\n output: undefined,\n runner: this,\n };\n }\n}\n\nexport class TaskExecutionError extends Error {\n readonly code = 'TASK_EXECUTION_FAILED' as const;\n\n override readonly cause: SerializedError;\n\n readonly task?: SerializedErrorTask;\n\n constructor(error: SerializedError, task?: SerializedErrorTask) {\n super(error.message, { cause: error });\n this.name = 'TaskExecutionError';\n this.cause = error;\n this.task = task;\n if (this.stack) {\n this.stack = truncateSerializedErrorString(this.stack);\n }\n }\n\n /**\n * Return the same bounded fields already stored on the live error. The\n * wrapper stack identifies where TaskExecutionError was created; cause.stack\n * preserves the executor's original stack.\n */\n toJSON(): SerializedTaskExecutionError {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n ...(this.stack === undefined ? {} : { stack: this.stack }),\n cause: this.cause,\n ...(this.task === undefined ? {} : { task: this.task }),\n };\n }\n}\n"],"names":["debug","getDebug","UI_CONTEXT_CACHE_TTL_MS","serializeErrorTask","task","truncateSerializedErrorString","undefined","TaskRunner","error","kind","console","options","now","Date","shouldReuse","uiContext","screenshot","phase","recorderItem","uuid","errorMessage","assert","appended","Array","item","appendedTask","nextPendingIndex","taskIndex","successfullyCompleted","previousFindOutput","taskStarted","e","executor","returnValue","forceRefresh","setTimingFieldOnce","executorContext","isLastTask","Object","serializedError","serializeError","cancelledTasks","i","cancelledTask","finalizeError","errorTask","TaskExecutionError","outputIndex","Math","thought","output","ExecutionDump","errorMsg","Error","name","uiContextBuilder","Set","image"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"task-runner.mjs","sources":["../../src/task-runner.ts"],"sourcesContent":["import type { ScreenshotItem } from '@/screenshot-item';\nimport { setTimingFieldOnce } from '@/task-timing';\nimport {\n ExecutionDump,\n type ExecutionRecorderItem,\n type ExecutionTask,\n type ExecutionTaskActionApply,\n type ExecutionTaskApply,\n type ExecutionTaskPlanningLocateOutput,\n type ExecutionTaskProgressOptions,\n type ExecutionTaskReturn,\n type ExecutorContext,\n type PlanningActionParamError,\n type UIContext,\n} from '@/types';\nimport {\n type SerializedError,\n serializeError,\n truncateSerializedErrorString,\n} from '@midscene/shared/agent-tools/error-formatter';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert, uuid } from '@midscene/shared/utils';\n\nconst debug = getDebug('task-runner');\nconst UI_CONTEXT_CACHE_TTL_MS = 300;\n\nfunction serializeTaskError(\n error: unknown,\n signal?: AbortSignal,\n): SerializedError {\n const serializedError = serializeError(error);\n // Do not relabel an unrelated error that races with cancellation.\n // Preserve the original stack and diagnostics alongside the explanation.\n if (signal?.aborted && error === signal.reason) {\n serializedError.message = truncateSerializedErrorString(\n `Operation interrupted by an external abort signal.\\nReason: ${serializedError.message}`,\n );\n }\n return serializedError;\n}\n\n/**\n * A native, per-task lifecycle notification. The runner is the single source\n * of truth for when a task actually transitions, so it reports each transition\n * exactly once with the task that changed. Consumers no longer have to re-scan\n * the task list and diff it against remembered keys to reconstruct this stream.\n */\nexport type TaskRunnerEventKind =\n | 'append'\n | 'start'\n | 'finish'\n | 'error'\n | 'cancel';\n\nexport interface TaskRunnerEvent {\n kind: TaskRunnerEventKind;\n task: ExecutionTask;\n runner: TaskRunner;\n}\n\nexport interface SerializedErrorTask {\n taskId: string;\n type: ExecutionTask['type'];\n subType?: string;\n status: ExecutionTask['status'];\n thought?: string;\n errorMessage?: string;\n}\n\nexport interface SerializedTaskExecutionError extends SerializedError {\n code: 'TASK_EXECUTION_FAILED';\n cause: SerializedError;\n task?: SerializedErrorTask;\n}\n\nfunction serializeErrorTask(\n task: ExecutionTask | null,\n): SerializedErrorTask | undefined {\n if (!task) {\n return undefined;\n }\n\n return {\n taskId: truncateSerializedErrorString(task.taskId),\n type: task.type,\n ...(task.subType === undefined\n ? {}\n : { subType: truncateSerializedErrorString(task.subType) }),\n status: task.status,\n ...(task.thought === undefined\n ? {}\n : { thought: truncateSerializedErrorString(task.thought) }),\n ...(task.errorMessage === undefined\n ? {}\n : {\n errorMessage: truncateSerializedErrorString(task.errorMessage),\n }),\n };\n}\n\nexport type TaskRunnerEventListener = (\n event: TaskRunnerEvent,\n) => Promise<void> | void;\n\n/** Minimal prompt-image shape retained as report asset metadata. */\nexport interface ExecutionReferenceImage {\n readonly url: string;\n}\n\ntype TaskRunnerInitOptions = ExecutionTaskProgressOptions & {\n tasks?: ExecutionTaskApply[];\n abortSignal?: AbortSignal;\n referenceImages?: readonly ExecutionReferenceImage[];\n /**\n * Coarse \"the execution snapshot changed\" signal. Fires on any state change\n * (append, status flips, completion) with the whole runner, so consumers can\n * re-dump/re-render the current snapshot. Deliberately batch-granular, unlike\n * the per-task {@link onTaskEvent} stream.\n */\n onSnapshotChange?: (\n runner: TaskRunner,\n error?: TaskExecutionError,\n ) => Promise<void> | void;\n onTaskEvent?: TaskRunnerEventListener;\n};\n\ntype TaskRunnerOperationOptions = {\n allowWhenError?: boolean;\n};\n\nexport class TaskRunner {\n readonly id: string;\n name: string;\n\n tasks: ExecutionTask[];\n\n // status of runner\n status: 'init' | 'pending' | 'running' | 'completed' | 'error';\n\n onTaskStart?: ExecutionTaskProgressOptions['onTaskStart'];\n\n private readonly uiContextBuilder: (\n signal?: AbortSignal,\n ) => Promise<UIContext>;\n private readonly abortSignal?: AbortSignal;\n\n private readonly onSnapshotChange?:\n | ((runner: TaskRunner, error?: TaskExecutionError) => Promise<void> | void)\n | undefined;\n\n private readonly onTaskEvent?: TaskRunnerEventListener | undefined;\n\n private readonly executionLogTime: number;\n\n private readonly referenceImageUrls = new Set<string>();\n\n constructor(\n name: string,\n uiContextBuilder: (signal?: AbortSignal) => Promise<UIContext>,\n options?: TaskRunnerInitOptions,\n ) {\n this.id = uuid();\n this.status =\n options?.tasks && options.tasks.length > 0 ? 'pending' : 'init';\n this.name = name;\n this.tasks = (options?.tasks || []).map((item) =>\n this.markTaskAsPending(item),\n );\n this.onTaskStart = options?.onTaskStart;\n this.uiContextBuilder = uiContextBuilder;\n this.abortSignal = options?.abortSignal;\n this.onSnapshotChange = options?.onSnapshotChange;\n this.onTaskEvent = options?.onTaskEvent;\n this.executionLogTime = Date.now();\n for (const image of options?.referenceImages ?? []) {\n this.referenceImageUrls.add(image.url);\n }\n }\n\n private async emitSnapshotChange(error?: TaskExecutionError): Promise<void> {\n if (!this.onSnapshotChange) {\n return;\n }\n await this.onSnapshotChange(this, error);\n }\n\n private async emitTaskEvent(\n kind: TaskRunnerEventKind,\n task: ExecutionTask,\n ): Promise<void> {\n if (!this.onTaskEvent) {\n return;\n }\n try {\n await this.onTaskEvent({ kind, task, runner: this });\n } catch (error) {\n console.error('Error in onTaskEvent listener', error);\n }\n }\n\n private lastUiContext?: {\n context: UIContext;\n capturedAt: number;\n };\n\n private async getUiContext(options?: { forceRefresh?: boolean }): Promise<\n UIContext | undefined\n > {\n this.abortSignal?.throwIfAborted();\n const now = Date.now();\n const shouldReuse =\n !options?.forceRefresh &&\n this.lastUiContext &&\n now - this.lastUiContext.capturedAt <= UI_CONTEXT_CACHE_TTL_MS;\n\n if (shouldReuse && this.lastUiContext?.context) {\n debug(\n `reuse cached uiContext captured ${now - this.lastUiContext.capturedAt}ms ago`,\n );\n return this.lastUiContext?.context;\n }\n\n try {\n const uiContext = await this.uiContextBuilder(this.abortSignal);\n this.abortSignal?.throwIfAborted();\n if (uiContext) {\n this.lastUiContext = {\n context: uiContext,\n capturedAt: Date.now(),\n };\n } else {\n this.lastUiContext = undefined;\n }\n return uiContext;\n } catch (error) {\n this.lastUiContext = undefined;\n throw error;\n }\n }\n\n private async captureScreenshot(): Promise<ScreenshotItem | undefined> {\n try {\n const uiContext = await this.getUiContext({ forceRefresh: true });\n return uiContext?.screenshot;\n } catch (error) {\n console.error('error while capturing screenshot', error);\n }\n return undefined;\n }\n\n private attachRecorderItem(\n task: ExecutionTask,\n screenshot: ScreenshotItem | undefined,\n phase: 'after-calling',\n ): void {\n if (!phase || !screenshot) {\n return;\n }\n\n const recorderItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: Date.now(),\n screenshot,\n timing: phase,\n };\n\n if (!task.recorder) {\n task.recorder = [recorderItem];\n return;\n }\n task.recorder.push(recorderItem);\n }\n\n private markTaskAsPending(task: ExecutionTaskApply): ExecutionTask {\n return {\n taskId: uuid(),\n status: 'pending',\n ...task,\n };\n }\n\n private normalizeStatusFromError(\n options?: TaskRunnerOperationOptions,\n errorMessage?: string,\n ): void {\n if (this.status !== 'error') {\n return;\n }\n assert(\n options?.allowWhenError,\n errorMessage ||\n `task runner is in error state, cannot proceed\\nerror=${this.latestErrorTask()?.errorMessage}\\n${this.latestErrorTask()?.errorStack}`,\n );\n // reset runner state so new tasks can run\n this.status = this.tasks.length > 0 ? 'pending' : 'init';\n }\n\n async append(\n task: ExecutionTaskApply[] | ExecutionTaskApply,\n options?: TaskRunnerOperationOptions,\n ): Promise<void> {\n this.abortSignal?.throwIfAborted();\n this.normalizeStatusFromError(\n options,\n `task runner is in error state, cannot append task\\nerror=${this.latestErrorTask()?.errorMessage}\\n${this.latestErrorTask()?.errorStack}`,\n );\n const appended: ExecutionTask[] = [];\n if (Array.isArray(task)) {\n appended.push(...task.map((item) => this.markTaskAsPending(item)));\n } else {\n appended.push(this.markTaskAsPending(task));\n }\n this.tasks.push(...appended);\n if (this.status !== 'running') {\n this.status = 'pending';\n }\n await this.emitSnapshotChange();\n for (const appendedTask of appended) {\n await this.emitTaskEvent('append', appendedTask);\n }\n }\n\n async appendAndFlush(\n task: ExecutionTaskApply[] | ExecutionTaskApply,\n options?: TaskRunnerOperationOptions,\n ): Promise<{ output: any; thought?: string } | undefined> {\n await this.append(task, options);\n return this.flush(options);\n }\n\n async flush(\n options?: TaskRunnerOperationOptions,\n ): Promise<{ output: any; thought?: string } | undefined> {\n if (this.status === 'init' && this.tasks.length > 0) {\n console.warn(\n 'illegal state for task runner, status is init but tasks are not empty',\n );\n }\n\n this.normalizeStatusFromError(options, 'task runner is in error state');\n assert(this.status !== 'running', 'task runner is already running');\n assert(this.status !== 'completed', 'task runner is already completed');\n\n const nextPendingIndex = this.tasks.findIndex(\n (task) => task.status === 'pending',\n );\n if (nextPendingIndex < 0) {\n // all tasks are completed\n return;\n }\n\n this.status = 'running';\n await this.emitSnapshotChange();\n let taskIndex = nextPendingIndex;\n let successfullyCompleted = true;\n\n let previousFindOutput: ExecutionTaskPlanningLocateOutput | undefined;\n\n while (taskIndex < this.tasks.length) {\n const task = this.tasks[taskIndex];\n assert(\n task.status === 'pending',\n `task status should be pending, but got: ${task.status}`,\n );\n let taskStarted = false;\n try {\n this.abortSignal?.throwIfAborted();\n taskStarted = true;\n task.timing = { start: Date.now() };\n task.status = 'running';\n await this.emitSnapshotChange();\n await this.emitTaskEvent('start', task);\n this.abortSignal?.throwIfAborted();\n try {\n if (this.onTaskStart) {\n await this.onTaskStart(task, this.abortSignal);\n }\n } catch (e) {\n console.error('error in onTaskStart', e);\n }\n this.abortSignal?.throwIfAborted();\n assert(\n ['Insight', 'Action Space', 'Planning'].indexOf(task.type) >= 0,\n `unsupported task type: ${task.type}`,\n );\n\n const { executor } = task;\n assert(executor, `executor is required for task type: ${task.type}`);\n\n let returnValue;\n // For Insight tasks (Query/Assert/WaitFor), always get fresh context\n // to ensure we have the latest UI state after any preceding actions\n const forceRefresh = task.type === 'Insight';\n setTimingFieldOnce(task.timing, 'getUiContextStart');\n const uiContext = await this.getUiContext({ forceRefresh });\n setTimingFieldOnce(task.timing, 'getUiContextEnd');\n this.abortSignal?.throwIfAborted();\n\n task.uiContext = uiContext;\n const executorContext: ExecutorContext = {\n task,\n element: previousFindOutput?.element,\n uiContext,\n signal: this.abortSignal,\n };\n\n if (task.type === 'Insight') {\n assert(\n task.subType === 'Query' ||\n task.subType === 'Assert' ||\n task.subType === 'WaitFor' ||\n task.subType === 'Boolean' ||\n task.subType === 'Number' ||\n task.subType === 'String',\n `unsupported service subType: ${task.subType}`,\n );\n returnValue = await task.executor(executorContext);\n } else if (task.type === 'Planning') {\n returnValue = await task.executor(executorContext);\n if (task.subType === 'Locate') {\n previousFindOutput = (\n returnValue as ExecutionTaskReturn<ExecutionTaskPlanningLocateOutput>\n )?.output;\n }\n } else if (task.type === 'Action Space') {\n try {\n returnValue = await task.executor(executorContext);\n } finally {\n // The short TTL still lets planning and the action itself share one\n // context. Once an action settles, time alone can no longer prove\n // that the cached context represents the current UI.\n this.lastUiContext = undefined;\n }\n } else {\n console.warn(\n `unsupported task type: ${task.type}, will try to execute it directly`,\n );\n returnValue = await task.executor(executorContext);\n }\n\n this.abortSignal?.throwIfAborted();\n const isLastTask = taskIndex === this.tasks.length - 1;\n\n if (isLastTask) {\n setTimingFieldOnce(task.timing, 'captureAfterCallingSnapshotStart');\n const screenshot = await this.captureScreenshot();\n this.abortSignal?.throwIfAborted();\n this.attachRecorderItem(task, screenshot, 'after-calling');\n setTimingFieldOnce(task.timing, 'captureAfterCallingSnapshotEnd');\n }\n // Cancellation may arrive during the report screenshot, after planning\n // has returned but before the next batch of actions is built.\n this.abortSignal?.throwIfAborted();\n\n Object.assign(task, returnValue);\n task.status = 'finished';\n task.timing.end = Date.now();\n task.timing.cost = task.timing.end - task.timing.start;\n await this.emitSnapshotChange();\n await this.emitTaskEvent('finish', task);\n taskIndex++;\n } catch (error) {\n successfullyCompleted = false;\n const serializedError = serializeTaskError(error, this.abortSignal);\n task.error = serializedError;\n task.errorMessage = serializedError.message;\n task.errorStack = serializedError.stack;\n\n task.status = taskStarted ? 'failed' : 'cancelled';\n if (taskStarted && task.timing) {\n task.timing.end = Date.now();\n task.timing.cost = task.timing.end - task.timing.start;\n }\n await this.emitSnapshotChange();\n await this.emitTaskEvent(taskStarted ? 'error' : 'cancel', task);\n break;\n }\n }\n\n // set all remaining tasks as cancelled\n const cancelledTasks: ExecutionTask[] = [];\n for (let i = taskIndex + 1; i < this.tasks.length; i++) {\n this.tasks[i].status = 'cancelled';\n cancelledTasks.push(this.tasks[i]);\n }\n if (cancelledTasks.length > 0) {\n await this.emitSnapshotChange();\n for (const cancelledTask of cancelledTasks) {\n await this.emitTaskEvent('cancel', cancelledTask);\n }\n }\n\n let finalizeError: TaskExecutionError | undefined;\n if (!successfullyCompleted) {\n this.status = 'error';\n const errorTask = this.latestErrorTask();\n const error =\n errorTask?.error ??\n (this.abortSignal?.aborted\n ? serializeTaskError(this.abortSignal.reason, this.abortSignal)\n : {\n name: 'Error',\n message: 'Task execution failed',\n });\n finalizeError = new TaskExecutionError(\n error,\n serializeErrorTask(errorTask),\n );\n await this.emitSnapshotChange(finalizeError);\n } else {\n this.status = 'completed';\n await this.emitSnapshotChange();\n }\n\n if (finalizeError) {\n throw finalizeError;\n }\n\n if (this.tasks.length) {\n // return the last output\n const outputIndex = Math.min(taskIndex, this.tasks.length - 1);\n const { thought, output } = this.tasks[outputIndex];\n return {\n thought,\n output,\n };\n }\n }\n\n isInErrorState(): boolean {\n return this.status === 'error';\n }\n\n latestErrorTask(): ExecutionTask | null {\n if (this.status !== 'error') {\n return null;\n }\n // Find the LAST failed task (not the first one)\n // This is important when using allowWhenError to continue after errors\n for (let i = this.tasks.length - 1; i >= 0; i--) {\n if (this.tasks[i].status === 'failed') {\n return this.tasks[i];\n }\n }\n return null;\n }\n\n dump(): ExecutionDump {\n return new ExecutionDump(\n {\n id: this.id,\n logTime: this.executionLogTime,\n name: this.name,\n tasks: this.tasks,\n },\n { referenceImageUrls: [...this.referenceImageUrls] },\n );\n }\n\n async appendErrorPlan(errorMsg: string): Promise<{\n output: undefined;\n runner: TaskRunner;\n }> {\n const errorTask: ExecutionTaskActionApply<PlanningActionParamError> = {\n type: 'Action Space',\n subType: 'Error',\n param: {\n thought: errorMsg,\n },\n thought: errorMsg,\n executor: async () => {\n throw new Error(errorMsg || 'error without thought');\n },\n };\n await this.appendAndFlush(errorTask);\n\n return {\n output: undefined,\n runner: this,\n };\n }\n}\n\nexport class TaskExecutionError extends Error {\n readonly code = 'TASK_EXECUTION_FAILED' as const;\n\n override readonly cause: SerializedError;\n\n readonly task?: SerializedErrorTask;\n\n constructor(error: SerializedError, task?: SerializedErrorTask) {\n super(error.message, { cause: error });\n this.name = 'TaskExecutionError';\n this.cause = error;\n this.task = task;\n if (this.stack) {\n this.stack = truncateSerializedErrorString(this.stack);\n }\n }\n\n /**\n * Return the same bounded fields already stored on the live error. The\n * wrapper stack identifies where TaskExecutionError was created; cause.stack\n * preserves the executor's original stack.\n */\n toJSON(): SerializedTaskExecutionError {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n ...(this.stack === undefined ? {} : { stack: this.stack }),\n cause: this.cause,\n ...(this.task === undefined ? {} : { task: this.task }),\n };\n }\n}\n"],"names":["debug","getDebug","UI_CONTEXT_CACHE_TTL_MS","serializeTaskError","error","signal","serializedError","serializeError","truncateSerializedErrorString","serializeErrorTask","task","undefined","TaskRunner","kind","console","options","now","Date","shouldReuse","uiContext","screenshot","phase","recorderItem","uuid","errorMessage","assert","appended","Array","item","appendedTask","nextPendingIndex","taskIndex","successfullyCompleted","previousFindOutput","taskStarted","e","executor","returnValue","forceRefresh","setTimingFieldOnce","executorContext","isLastTask","Object","cancelledTasks","i","cancelledTask","finalizeError","errorTask","TaskExecutionError","outputIndex","Math","thought","output","ExecutionDump","errorMsg","Error","name","uiContextBuilder","Set","image"],"mappings":"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"}
|
package/dist/es/utils.mjs
CHANGED
|
@@ -184,7 +184,7 @@ function stringifyDumpData(data, indents) {
|
|
|
184
184
|
return JSON.stringify(data, replacerForPageObject, indents);
|
|
185
185
|
}
|
|
186
186
|
function getVersion() {
|
|
187
|
-
return "1.17.
|
|
187
|
+
return "1.17.6";
|
|
188
188
|
}
|
|
189
189
|
function debugLog(...message) {
|
|
190
190
|
const debugMode = process.env[MIDSCENE_DEBUG_MODE];
|
package/dist/lib/agent/utils.js
CHANGED
|
@@ -193,7 +193,7 @@ async function matchElementFromCache(context, cacheEntry, cachePrompt, cacheable
|
|
|
193
193
|
return;
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
|
-
const getMidsceneVersion = ()=>"1.17.
|
|
196
|
+
const getMidsceneVersion = ()=>"1.17.6";
|
|
197
197
|
const parsePrompt = (prompt)=>{
|
|
198
198
|
if ('string' == typeof prompt) return {
|
|
199
199
|
textPrompt: prompt,
|
|
@@ -45,10 +45,6 @@ const jevLocate = async ({ targetElementDescription, locateImage, options })=>{
|
|
|
45
45
|
...references.images
|
|
46
46
|
},
|
|
47
47
|
questions: {
|
|
48
|
-
present: {
|
|
49
|
-
type: 'noul',
|
|
50
|
-
instructions: 'Is the target described in `target` present in `screenshot`? Reference images, if any, describe the target; they are not the screenshot.'
|
|
51
|
-
},
|
|
52
48
|
target: {
|
|
53
49
|
type: 'box',
|
|
54
50
|
instructions: 'The single target described in `target`, in `screenshot`.'
|
|
@@ -58,17 +54,11 @@ const jevLocate = async ({ targetElementDescription, locateImage, options })=>{
|
|
|
58
54
|
abortSignal: options.abortSignal
|
|
59
55
|
});
|
|
60
56
|
const { answers } = schema_js_namespaceObject.systemOneResponseSchema.parse(JSON.parse(response.content));
|
|
61
|
-
(0, utils_namespaceObject.assert)(
|
|
57
|
+
(0, utils_namespaceObject.assert)(answers.target?.type === 'box', 'Invalid Jev locate answer');
|
|
62
58
|
return {
|
|
63
59
|
rawResponse: response.content,
|
|
64
60
|
usage: response.usage,
|
|
65
|
-
|
|
66
|
-
locatedPixelResult: (0, external_image_js_namespaceObject.mapJevBox)(answers.target.box, locateImage)
|
|
67
|
-
} : {
|
|
68
|
-
errors: [
|
|
69
|
-
'The target is not present in the screenshot'
|
|
70
|
-
]
|
|
71
|
-
}
|
|
61
|
+
locatedPixelResult: (0, external_image_js_namespaceObject.mapJevBox)(answers.target.box, locateImage)
|
|
72
62
|
};
|
|
73
63
|
};
|
|
74
64
|
exports.jevLocate = __webpack_exports__.jevLocate;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/models/jev/locate.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../src/ai-model/models/jev/locate.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 { userPromptToString } from '@/common';\nimport { assert } from '@midscene/shared/utils';\nimport { callSystemOneAI } from '../../service-caller';\nimport { systemOneResponseSchema } from '../../service-caller/system-one/schema';\nimport type { LocateFn } from '../../workflows/grounding/types';\nimport { mapJevBox, prepareJevImage, prepareReferences } from './image';\n\nexport const jevLocate: LocateFn = async ({\n targetElementDescription,\n locateImage,\n options,\n}) => {\n const image = await prepareJevImage(locateImage.imageBase64);\n const references = await prepareReferences(targetElementDescription);\n const target = userPromptToString(targetElementDescription);\n const response = await callSystemOneAI(\n {\n state: { target, references: references.references },\n images: { screenshot: image.imageBase64, ...references.images },\n questions: {\n
|
|
1
|
+
{"version":3,"file":"ai-model/models/jev/locate.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../src/ai-model/models/jev/locate.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 { userPromptToString } from '@/common';\nimport { assert } from '@midscene/shared/utils';\nimport { callSystemOneAI } from '../../service-caller';\nimport { systemOneResponseSchema } from '../../service-caller/system-one/schema';\nimport type { LocateFn } from '../../workflows/grounding/types';\nimport { mapJevBox, prepareJevImage, prepareReferences } from './image';\n\nexport const jevLocate: LocateFn = async ({\n targetElementDescription,\n locateImage,\n options,\n}) => {\n const image = await prepareJevImage(locateImage.imageBase64);\n const references = await prepareReferences(targetElementDescription);\n const target = userPromptToString(targetElementDescription);\n const response = await callSystemOneAI(\n {\n state: { target, references: references.references },\n images: { screenshot: image.imageBase64, ...references.images },\n questions: {\n target: {\n type: 'box',\n instructions:\n 'The single target described in `target`, in `screenshot`.',\n },\n },\n },\n options.modelRuntime,\n { abortSignal: options.abortSignal },\n );\n const { answers } = systemOneResponseSchema.parse(\n JSON.parse(response.content),\n );\n assert(answers.target?.type === 'box', 'Invalid Jev locate answer');\n return {\n rawResponse: response.content,\n usage: response.usage,\n locatedPixelResult: mapJevBox(answers.target.box, locateImage),\n };\n};\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","jevLocate","targetElementDescription","locateImage","options","image","prepareJevImage","references","prepareReferences","target","userPromptToString","response","callSystemOneAI","answers","systemOneResponseSchema","JSON","assert","mapJevBox"],"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;;;;;;;;;;;;ACCO,MAAMI,YAAsB,OAAO,EACxCC,wBAAwB,EACxBC,WAAW,EACXC,OAAO,EACR;IACC,MAAMC,QAAQ,MAAMC,AAAAA,IAAAA,kCAAAA,eAAAA,AAAAA,EAAgBH,YAAY,WAAW;IAC3D,MAAMI,aAAa,MAAMC,AAAAA,IAAAA,kCAAAA,iBAAAA,AAAAA,EAAkBN;IAC3C,MAAMO,SAASC,AAAAA,IAAAA,mCAAAA,kBAAAA,AAAAA,EAAmBR;IAClC,MAAMS,WAAW,MAAMC,AAAAA,IAAAA,yBAAAA,eAAAA,AAAAA,EACrB;QACE,OAAO;YAAEH;YAAQ,YAAYF,WAAW,UAAU;QAAC;QACnD,QAAQ;YAAE,YAAYF,MAAM,WAAW;YAAE,GAAGE,WAAW,MAAM;QAAC;QAC9D,WAAW;YACT,QAAQ;gBACN,MAAM;gBACN,cACE;YACJ;QACF;IACF,GACAH,QAAQ,YAAY,EACpB;QAAE,aAAaA,QAAQ,WAAW;IAAC;IAErC,MAAM,EAAES,OAAO,EAAE,GAAGC,0BAAAA,uBAAAA,CAAAA,KAA6B,CAC/CC,KAAK,KAAK,CAACJ,SAAS,OAAO;IAE7BK,IAAAA,sBAAAA,MAAAA,AAAAA,EAAOH,QAAQ,MAAM,EAAE,SAAS,OAAO;IACvC,OAAO;QACL,aAAaF,SAAS,OAAO;QAC7B,OAAOA,SAAS,KAAK;QACrB,oBAAoBM,AAAAA,IAAAA,kCAAAA,SAAAA,AAAAA,EAAUJ,QAAQ,MAAM,CAAC,GAAG,EAAEV;IACpD;AACF"}
|
|
@@ -157,7 +157,10 @@ async function callModelWithRetry(input) {
|
|
|
157
157
|
if (error instanceof index_js_namespaceObject.SiwcTokenExpiredError) {
|
|
158
158
|
const refresh = async ()=>{
|
|
159
159
|
(0, utils_namespaceObject.assert)(config.openaiApiKey, 'Missing rejected SIWC access token');
|
|
160
|
-
await index_js_namespaceObject.siwcTokenManager.refreshAccessToken(config.openaiApiKey
|
|
160
|
+
await index_js_namespaceObject.siwcTokenManager.refreshAccessToken(config.openaiApiKey, {
|
|
161
|
+
httpProxy: config.httpProxy,
|
|
162
|
+
socksProxy: config.socksProxy
|
|
163
|
+
});
|
|
161
164
|
return (0, index_js_namespaceObject.prepareSiwcCall)(input.modelRuntime, options);
|
|
162
165
|
};
|
|
163
166
|
const refreshed = options?.abortSignal ? await (0, external_request_timeout_js_namespaceObject.runWithAbortSignal)(options.abortSignal, refresh) : await refresh();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/service-caller/call-ai.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/service-caller/call-ai.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 { getDebug } from '@midscene/shared/logger';\nimport { assert, uuid } from '@midscene/shared/utils';\nimport type { ModelRuntime } from '../models';\nimport { callCodex, prepareCodexCall } from './codex/call-codex';\nimport { isCodexAppServerProvider } from './codex/codex-app-server';\nimport {\n isModelCallRecordingEnabled,\n recordModelCallEvent,\n} from './model-call-recorder';\nimport { type PreparedOpenAIInput, callOpenAI } from './openai/call-openai';\nimport { prepareChatCompletion } from './openai/chat-completion/chat-completion';\nimport { prepareResponses } from './openai/responses/responses';\nimport {\n SiwcTokenExpiredError,\n prepareSiwcCall,\n siwcTokenManager,\n} from './openai/siwc';\nimport {\n buildRequestAbortSignal,\n resolveEffectiveTimeoutMs,\n runWithAbortSignal,\n waitForRetry,\n} from './request-timeout';\nimport {\n prepareSystemOne,\n callSystemOne as sendSystemOneRequest,\n} from './system-one';\nimport type { SystemOneRequest } from './system-one/schema';\nimport type { ModelCallMessages } from './types';\nimport type {\n AICallResult,\n CallAIOptions,\n ModelCallContext,\n ModelCallResult,\n} from './types';\nimport {\n appendAIRequestFailureSummary,\n buildUsageInfo,\n nextInternalCallId,\n normalizeRetryCount,\n toError,\n} from './utils';\n\nconst DEFAULT_MODEL_PROTOCOL = 'openai-chat';\n\nexport async function callGenerativeAI(\n messages: ModelCallMessages,\n originalModelRuntime: ModelRuntime,\n originalOptions?: CallAIOptions,\n): Promise<AICallResult> {\n originalOptions?.abortSignal?.throwIfAborted();\n const isStreaming = originalOptions?.stream === true;\n if (isStreaming) {\n // Explicit streaming is currently used only by recorder code generation.\n // Streaming can also be aggregated without onChunk, but then the caller\n // cannot consume incremental output, which is the purpose of this option.\n // Environment-enabled streaming supports that aggregation-only use case.\n // Once onChunk delivers a chunk, later errors are not retried to avoid\n // delivering duplicate content. Errors before the first chunk can retry.\n assert(\n typeof originalOptions?.onChunk === 'function',\n 'onChunk is required when stream: true is explicitly specified',\n );\n }\n\n // Resolve authentication constraints before protocol selection and validation.\n const { modelRuntime, options } = await prepareSiwcCall(\n originalModelRuntime,\n originalOptions,\n );\n\n const { config: modelConfig } = modelRuntime;\n return executeModelCall(modelRuntime, options, async () => {\n const input = { messages, modelRuntime, options };\n if (isCodexAppServerProvider(modelConfig.openaiBaseURL)) {\n return { kind: 'codex', input: prepareCodexCall(input) };\n }\n const protocol = modelConfig.protocol ?? DEFAULT_MODEL_PROTOCOL;\n\n assert(\n modelRuntime.adapter.supportedProtocols.includes(protocol),\n `Model adapter \"${modelConfig.modelFamily ?? 'default'}\" does not support protocol \"${protocol}\"`,\n );\n if (protocol === 'openai-responses') {\n return { kind: 'responses', input: await prepareResponses(input) };\n }\n return {\n kind: 'chat-completion',\n input: await prepareChatCompletion(input),\n };\n });\n}\n\nexport async function callSystemOneAI(\n request: SystemOneRequest,\n modelRuntime: ModelRuntime,\n options?: CallAIOptions,\n): Promise<AICallResult> {\n options?.abortSignal?.throwIfAborted();\n assert(!options?.stream, 'Jev does not support streaming output');\n assert(\n modelRuntime.config.modelFamily === 'jev',\n 'System One currently only supports the Jev model family in Midscene',\n );\n return executeModelCall(modelRuntime, options, async () => ({\n kind: 'system-one',\n input: await prepareSystemOne(modelRuntime.config, request),\n }));\n}\n\nasync function executeModelCall(\n modelRuntime: ModelRuntime,\n options: CallAIOptions | undefined,\n prepare: () => Promise<PreparedModelInput>,\n): Promise<AICallResult> {\n // Keep identifiers stable across all request attempts.\n const executionId = modelRuntime.executionId ?? `unscoped-${uuid()}`;\n const internalCallId = nextInternalCallId();\n const { config: modelConfig } = modelRuntime;\n\n const prepared = options?.abortSignal\n ? await runWithAbortSignal(options.abortSignal, prepare)\n : await prepare();\n\n const result = await callModelWithRetry({\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n });\n\n const {\n rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n ...response\n } = result;\n\n const rawUsageInfo = buildUsageInfo({\n requestKind: prepared.kind,\n stream: response.isStreamed,\n usageData: rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n modelName: modelConfig.modelName,\n modelDescription: modelConfig.modelDescription,\n slot: modelConfig.slot,\n internalCallId,\n });\n\n const usage = rawUsageInfo\n ? { ...rawUsageInfo, modelFallback: modelRuntime.modelFallback }\n : undefined;\n\n const debugProfileStats = getDebug('ai:profile:stats');\n const debugProfileDetail = getDebug('ai:profile:detail');\n debugProfileStats(\n `model, ${modelConfig.modelName}, mode, ${modelConfig.modelFamily || 'default'}, streaming, ${response.isStreamed}, prompt-tokens, ${usage?.prompt_tokens ?? ''}, completion-tokens, ${usage?.completion_tokens ?? ''}, total-tokens, ${usage?.total_tokens ?? ''}, cached-input, ${usage?.cached_input ?? ''}, cost-ms, ${timeCost ?? ''}, requestId, ${requestId ?? ''}, slot, ${modelConfig.slot}, configured-temperature, ${modelConfig.temperature ?? ''}`,\n );\n debugProfileDetail(`model usage detail: ${JSON.stringify(usage)}`);\n\n if (usage && modelRuntime.onUsage) {\n modelRuntime.onUsage(usage);\n }\n return { ...response, usage };\n}\n\ntype PreparedModelInput =\n | {\n kind: 'system-one';\n input: Awaited<ReturnType<typeof prepareSystemOne>>;\n }\n | { kind: 'codex'; input: ReturnType<typeof prepareCodexCall> }\n | PreparedOpenAIInput;\n\ntype ModelCallInput = {\n modelRuntime: ModelRuntime;\n options?: CallAIOptions;\n executionId: string;\n internalCallId: string;\n prepared: PreparedModelInput;\n};\n\n/** Carries the original failure across the retry boundary without replaying output. */\nclass NonRetryableModelCallError extends Error {\n readonly cause: Error;\n\n constructor(cause: Error) {\n super(cause.message, { cause });\n this.cause = cause;\n }\n}\n\nasync function callModelWithRetry(\n input: ModelCallInput,\n): Promise<ModelCallResult & { totalTimeCost: number; retryCount: number }> {\n const startTime = Date.now();\n const {\n modelRuntime: { config },\n options,\n } = input;\n const maxAttempts = normalizeRetryCount(config.retryCount) + 1;\n const retryInterval = config.retryInterval ?? 2000;\n const attemptErrors: Array<{ attempt: number; error: unknown }> = [];\n\n for (let attempt = 1; ; attempt++) {\n options?.abortSignal?.throwIfAborted();\n try {\n const result = await callModelOnce(input, attempt);\n return {\n ...result,\n totalTimeCost: Date.now() - startTime,\n retryCount: attempt - 1,\n };\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n if (error instanceof NonRetryableModelCallError) {\n throw error.cause;\n }\n // A rejected SIWC token gets one authentication retry, independently of\n // normal retryCount. Delivered chunks are rejected above before refreshing.\n if (error instanceof SiwcTokenExpiredError) {\n const refresh = async () => {\n assert(config.openaiApiKey, 'Missing rejected SIWC access token');\n await siwcTokenManager.refreshAccessToken(config.openaiApiKey);\n return prepareSiwcCall(input.modelRuntime, options);\n };\n // Cancel only this caller's wait; other callers may share the refresh.\n const refreshed = options?.abortSignal\n ? await runWithAbortSignal(options.abortSignal, refresh)\n : await refresh();\n options?.abortSignal?.throwIfAborted();\n try {\n const result = await callModelOnce(\n { ...input, ...refreshed },\n attempt + 1,\n );\n return {\n ...result,\n totalTimeCost: Date.now() - startTime,\n retryCount: attempt,\n };\n } catch (retryError) {\n // Do not re-enter either retry path after the refreshed request fails.\n throw retryError instanceof NonRetryableModelCallError\n ? retryError.cause\n : retryError;\n }\n }\n const lastError = toError(error);\n attemptErrors.push({ attempt, error: lastError });\n if (attempt === maxAttempts) {\n throw appendAIRequestFailureSummary(\n lastError,\n attemptErrors,\n maxAttempts,\n );\n }\n getDebug('ai:call', {\n console: true,\n warning: {\n kind: 'model-request-retry',\n modelName: config.modelName,\n error: lastError,\n callId: input.internalCallId,\n attempt,\n maxAttempts,\n delayMs: retryInterval,\n },\n })(\n `AI call failed (attempt ${attempt}/${maxAttempts}), retrying in ${retryInterval}ms... Error: ${lastError.message}`,\n );\n }\n await waitForRetry(retryInterval, options?.abortSignal);\n }\n}\n\nasync function callModelOnce(\n {\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n }: ModelCallInput,\n attempt: number,\n): Promise<ModelCallResult> {\n const { config: modelConfig } = modelRuntime;\n const recordingEnabled = isModelCallRecordingEnabled();\n const recordEvent =\n recordingEnabled || modelRuntime.onRequest\n ? (event: Record<string, unknown>) => {\n if (event.type === 'request') {\n const request = event.request as { url?: string } | undefined;\n modelRuntime.onRequest?.(request?.url);\n }\n if (!recordingEnabled) return;\n void recordModelCallEvent({\n executionId,\n callId: internalCallId,\n semanticRetryAttempt: options?.semanticRetryAttempt,\n slot: modelConfig.slot,\n intent: modelConfig.intent,\n modelFamily: modelConfig.modelFamily,\n modelFallback: modelRuntime.modelFallback,\n ...event,\n attempt,\n });\n }\n : undefined;\n const effectiveTimeoutMs = resolveEffectiveTimeoutMs(modelConfig.timeout);\n const { signal: requestSignal, cleanup } = buildRequestAbortSignal(\n effectiveTimeoutMs,\n options?.abortSignal,\n );\n let deliveredChunk = false;\n const onChunk = options?.onChunk;\n const context: ModelCallContext = {\n modelRuntime,\n executionId,\n recordEvent,\n requestSignal,\n effectiveTimeoutMs,\n options: onChunk\n ? {\n ...options,\n onChunk: (chunk) => {\n requestSignal.throwIfAborted();\n deliveredChunk = true;\n onChunk(chunk);\n },\n }\n : options,\n };\n try {\n return await runWithAbortSignal(requestSignal, () =>\n prepared.kind === 'system-one'\n ? sendSystemOneRequest(context, prepared.input)\n : prepared.kind === 'codex'\n ? callCodex(context, prepared.input)\n : callOpenAI(context, prepared),\n );\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n const lastError = toError(error);\n if (deliveredChunk) {\n throw new NonRetryableModelCallError(lastError);\n }\n throw lastError;\n } finally {\n cleanup();\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","DEFAULT_MODEL_PROTOCOL","callGenerativeAI","messages","originalModelRuntime","originalOptions","isStreaming","assert","modelRuntime","options","prepareSiwcCall","modelConfig","executeModelCall","input","isCodexAppServerProvider","prepareCodexCall","protocol","prepareResponses","prepareChatCompletion","callSystemOneAI","request","prepareSystemOne","prepare","executionId","uuid","internalCallId","nextInternalCallId","prepared","runWithAbortSignal","result","callModelWithRetry","rawUsage","timeCost","totalTimeCost","retryCount","requestId","responseModelName","response","rawUsageInfo","buildUsageInfo","usage","undefined","debugProfileStats","getDebug","debugProfileDetail","JSON","NonRetryableModelCallError","Error","cause","startTime","Date","config","maxAttempts","normalizeRetryCount","retryInterval","attemptErrors","attempt","callModelOnce","error","SiwcTokenExpiredError","refresh","siwcTokenManager","refreshed","retryError","lastError","toError","appendAIRequestFailureSummary","waitForRetry","recordingEnabled","isModelCallRecordingEnabled","recordEvent","event","recordModelCallEvent","effectiveTimeoutMs","resolveEffectiveTimeoutMs","requestSignal","cleanup","buildRequestAbortSignal","deliveredChunk","onChunk","context","chunk","sendSystemOneRequest","callCodex","callOpenAI"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-model/service-caller/call-ai.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/service-caller/call-ai.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 { getDebug } from '@midscene/shared/logger';\nimport { assert, uuid } from '@midscene/shared/utils';\nimport type { ModelRuntime } from '../models';\nimport { callCodex, prepareCodexCall } from './codex/call-codex';\nimport { isCodexAppServerProvider } from './codex/codex-app-server';\nimport {\n isModelCallRecordingEnabled,\n recordModelCallEvent,\n} from './model-call-recorder';\nimport { type PreparedOpenAIInput, callOpenAI } from './openai/call-openai';\nimport { prepareChatCompletion } from './openai/chat-completion/chat-completion';\nimport { prepareResponses } from './openai/responses/responses';\nimport {\n SiwcTokenExpiredError,\n prepareSiwcCall,\n siwcTokenManager,\n} from './openai/siwc';\nimport {\n buildRequestAbortSignal,\n resolveEffectiveTimeoutMs,\n runWithAbortSignal,\n waitForRetry,\n} from './request-timeout';\nimport {\n prepareSystemOne,\n callSystemOne as sendSystemOneRequest,\n} from './system-one';\nimport type { SystemOneRequest } from './system-one/schema';\nimport type { ModelCallMessages } from './types';\nimport type {\n AICallResult,\n CallAIOptions,\n ModelCallContext,\n ModelCallResult,\n} from './types';\nimport {\n appendAIRequestFailureSummary,\n buildUsageInfo,\n nextInternalCallId,\n normalizeRetryCount,\n toError,\n} from './utils';\n\nconst DEFAULT_MODEL_PROTOCOL = 'openai-chat';\n\nexport async function callGenerativeAI(\n messages: ModelCallMessages,\n originalModelRuntime: ModelRuntime,\n originalOptions?: CallAIOptions,\n): Promise<AICallResult> {\n originalOptions?.abortSignal?.throwIfAborted();\n const isStreaming = originalOptions?.stream === true;\n if (isStreaming) {\n // Explicit streaming is currently used only by recorder code generation.\n // Streaming can also be aggregated without onChunk, but then the caller\n // cannot consume incremental output, which is the purpose of this option.\n // Environment-enabled streaming supports that aggregation-only use case.\n // Once onChunk delivers a chunk, later errors are not retried to avoid\n // delivering duplicate content. Errors before the first chunk can retry.\n assert(\n typeof originalOptions?.onChunk === 'function',\n 'onChunk is required when stream: true is explicitly specified',\n );\n }\n\n // Resolve authentication constraints before protocol selection and validation.\n const { modelRuntime, options } = await prepareSiwcCall(\n originalModelRuntime,\n originalOptions,\n );\n\n const { config: modelConfig } = modelRuntime;\n return executeModelCall(modelRuntime, options, async () => {\n const input = { messages, modelRuntime, options };\n if (isCodexAppServerProvider(modelConfig.openaiBaseURL)) {\n return { kind: 'codex', input: prepareCodexCall(input) };\n }\n const protocol = modelConfig.protocol ?? DEFAULT_MODEL_PROTOCOL;\n\n assert(\n modelRuntime.adapter.supportedProtocols.includes(protocol),\n `Model adapter \"${modelConfig.modelFamily ?? 'default'}\" does not support protocol \"${protocol}\"`,\n );\n if (protocol === 'openai-responses') {\n return { kind: 'responses', input: await prepareResponses(input) };\n }\n return {\n kind: 'chat-completion',\n input: await prepareChatCompletion(input),\n };\n });\n}\n\nexport async function callSystemOneAI(\n request: SystemOneRequest,\n modelRuntime: ModelRuntime,\n options?: CallAIOptions,\n): Promise<AICallResult> {\n options?.abortSignal?.throwIfAborted();\n assert(!options?.stream, 'Jev does not support streaming output');\n assert(\n modelRuntime.config.modelFamily === 'jev',\n 'System One currently only supports the Jev model family in Midscene',\n );\n return executeModelCall(modelRuntime, options, async () => ({\n kind: 'system-one',\n input: await prepareSystemOne(modelRuntime.config, request),\n }));\n}\n\nasync function executeModelCall(\n modelRuntime: ModelRuntime,\n options: CallAIOptions | undefined,\n prepare: () => Promise<PreparedModelInput>,\n): Promise<AICallResult> {\n // Keep identifiers stable across all request attempts.\n const executionId = modelRuntime.executionId ?? `unscoped-${uuid()}`;\n const internalCallId = nextInternalCallId();\n const { config: modelConfig } = modelRuntime;\n\n const prepared = options?.abortSignal\n ? await runWithAbortSignal(options.abortSignal, prepare)\n : await prepare();\n\n const result = await callModelWithRetry({\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n });\n\n const {\n rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n ...response\n } = result;\n\n const rawUsageInfo = buildUsageInfo({\n requestKind: prepared.kind,\n stream: response.isStreamed,\n usageData: rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n modelName: modelConfig.modelName,\n modelDescription: modelConfig.modelDescription,\n slot: modelConfig.slot,\n internalCallId,\n });\n\n const usage = rawUsageInfo\n ? { ...rawUsageInfo, modelFallback: modelRuntime.modelFallback }\n : undefined;\n\n const debugProfileStats = getDebug('ai:profile:stats');\n const debugProfileDetail = getDebug('ai:profile:detail');\n debugProfileStats(\n `model, ${modelConfig.modelName}, mode, ${modelConfig.modelFamily || 'default'}, streaming, ${response.isStreamed}, prompt-tokens, ${usage?.prompt_tokens ?? ''}, completion-tokens, ${usage?.completion_tokens ?? ''}, total-tokens, ${usage?.total_tokens ?? ''}, cached-input, ${usage?.cached_input ?? ''}, cost-ms, ${timeCost ?? ''}, requestId, ${requestId ?? ''}, slot, ${modelConfig.slot}, configured-temperature, ${modelConfig.temperature ?? ''}`,\n );\n debugProfileDetail(`model usage detail: ${JSON.stringify(usage)}`);\n\n if (usage && modelRuntime.onUsage) {\n modelRuntime.onUsage(usage);\n }\n return { ...response, usage };\n}\n\ntype PreparedModelInput =\n | {\n kind: 'system-one';\n input: Awaited<ReturnType<typeof prepareSystemOne>>;\n }\n | { kind: 'codex'; input: ReturnType<typeof prepareCodexCall> }\n | PreparedOpenAIInput;\n\ntype ModelCallInput = {\n modelRuntime: ModelRuntime;\n options?: CallAIOptions;\n executionId: string;\n internalCallId: string;\n prepared: PreparedModelInput;\n};\n\n/** Carries the original failure across the retry boundary without replaying output. */\nclass NonRetryableModelCallError extends Error {\n readonly cause: Error;\n\n constructor(cause: Error) {\n super(cause.message, { cause });\n this.cause = cause;\n }\n}\n\nasync function callModelWithRetry(\n input: ModelCallInput,\n): Promise<ModelCallResult & { totalTimeCost: number; retryCount: number }> {\n const startTime = Date.now();\n const {\n modelRuntime: { config },\n options,\n } = input;\n const maxAttempts = normalizeRetryCount(config.retryCount) + 1;\n const retryInterval = config.retryInterval ?? 2000;\n const attemptErrors: Array<{ attempt: number; error: unknown }> = [];\n\n for (let attempt = 1; ; attempt++) {\n options?.abortSignal?.throwIfAborted();\n try {\n const result = await callModelOnce(input, attempt);\n return {\n ...result,\n totalTimeCost: Date.now() - startTime,\n retryCount: attempt - 1,\n };\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n if (error instanceof NonRetryableModelCallError) {\n throw error.cause;\n }\n // A rejected SIWC token gets one authentication retry, independently of\n // normal retryCount. Delivered chunks are rejected above before refreshing.\n if (error instanceof SiwcTokenExpiredError) {\n const refresh = async () => {\n assert(config.openaiApiKey, 'Missing rejected SIWC access token');\n await siwcTokenManager.refreshAccessToken(config.openaiApiKey, {\n httpProxy: config.httpProxy,\n socksProxy: config.socksProxy,\n });\n return prepareSiwcCall(input.modelRuntime, options);\n };\n // Cancel only this caller's wait; other callers may share the refresh.\n const refreshed = options?.abortSignal\n ? await runWithAbortSignal(options.abortSignal, refresh)\n : await refresh();\n options?.abortSignal?.throwIfAborted();\n try {\n const result = await callModelOnce(\n { ...input, ...refreshed },\n attempt + 1,\n );\n return {\n ...result,\n totalTimeCost: Date.now() - startTime,\n retryCount: attempt,\n };\n } catch (retryError) {\n // Do not re-enter either retry path after the refreshed request fails.\n throw retryError instanceof NonRetryableModelCallError\n ? retryError.cause\n : retryError;\n }\n }\n const lastError = toError(error);\n attemptErrors.push({ attempt, error: lastError });\n if (attempt === maxAttempts) {\n throw appendAIRequestFailureSummary(\n lastError,\n attemptErrors,\n maxAttempts,\n );\n }\n getDebug('ai:call', {\n console: true,\n warning: {\n kind: 'model-request-retry',\n modelName: config.modelName,\n error: lastError,\n callId: input.internalCallId,\n attempt,\n maxAttempts,\n delayMs: retryInterval,\n },\n })(\n `AI call failed (attempt ${attempt}/${maxAttempts}), retrying in ${retryInterval}ms... Error: ${lastError.message}`,\n );\n }\n await waitForRetry(retryInterval, options?.abortSignal);\n }\n}\n\nasync function callModelOnce(\n {\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n }: ModelCallInput,\n attempt: number,\n): Promise<ModelCallResult> {\n const { config: modelConfig } = modelRuntime;\n const recordingEnabled = isModelCallRecordingEnabled();\n const recordEvent =\n recordingEnabled || modelRuntime.onRequest\n ? (event: Record<string, unknown>) => {\n if (event.type === 'request') {\n const request = event.request as { url?: string } | undefined;\n modelRuntime.onRequest?.(request?.url);\n }\n if (!recordingEnabled) return;\n void recordModelCallEvent({\n executionId,\n callId: internalCallId,\n semanticRetryAttempt: options?.semanticRetryAttempt,\n slot: modelConfig.slot,\n intent: modelConfig.intent,\n modelFamily: modelConfig.modelFamily,\n modelFallback: modelRuntime.modelFallback,\n ...event,\n attempt,\n });\n }\n : undefined;\n const effectiveTimeoutMs = resolveEffectiveTimeoutMs(modelConfig.timeout);\n const { signal: requestSignal, cleanup } = buildRequestAbortSignal(\n effectiveTimeoutMs,\n options?.abortSignal,\n );\n let deliveredChunk = false;\n const onChunk = options?.onChunk;\n const context: ModelCallContext = {\n modelRuntime,\n executionId,\n recordEvent,\n requestSignal,\n effectiveTimeoutMs,\n options: onChunk\n ? {\n ...options,\n onChunk: (chunk) => {\n requestSignal.throwIfAborted();\n deliveredChunk = true;\n onChunk(chunk);\n },\n }\n : options,\n };\n try {\n return await runWithAbortSignal(requestSignal, () =>\n prepared.kind === 'system-one'\n ? sendSystemOneRequest(context, prepared.input)\n : prepared.kind === 'codex'\n ? callCodex(context, prepared.input)\n : callOpenAI(context, prepared),\n );\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n const lastError = toError(error);\n if (deliveredChunk) {\n throw new NonRetryableModelCallError(lastError);\n }\n throw lastError;\n } finally {\n cleanup();\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","DEFAULT_MODEL_PROTOCOL","callGenerativeAI","messages","originalModelRuntime","originalOptions","isStreaming","assert","modelRuntime","options","prepareSiwcCall","modelConfig","executeModelCall","input","isCodexAppServerProvider","prepareCodexCall","protocol","prepareResponses","prepareChatCompletion","callSystemOneAI","request","prepareSystemOne","prepare","executionId","uuid","internalCallId","nextInternalCallId","prepared","runWithAbortSignal","result","callModelWithRetry","rawUsage","timeCost","totalTimeCost","retryCount","requestId","responseModelName","response","rawUsageInfo","buildUsageInfo","usage","undefined","debugProfileStats","getDebug","debugProfileDetail","JSON","NonRetryableModelCallError","Error","cause","startTime","Date","config","maxAttempts","normalizeRetryCount","retryInterval","attemptErrors","attempt","callModelOnce","error","SiwcTokenExpiredError","refresh","siwcTokenManager","refreshed","retryError","lastError","toError","appendAIRequestFailureSummary","waitForRetry","recordingEnabled","isModelCallRecordingEnabled","recordEvent","event","recordModelCallEvent","effectiveTimeoutMs","resolveEffectiveTimeoutMs","requestSignal","cleanup","buildRequestAbortSignal","deliveredChunk","onChunk","context","chunk","sendSystemOneRequest","callCodex","callOpenAI"],"mappings":"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"}
|
|
@@ -30,6 +30,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
30
30
|
});
|
|
31
31
|
const external_jose_namespaceObject = require("jose");
|
|
32
32
|
const external_errors_js_namespaceObject = require("./errors.js");
|
|
33
|
+
const external_network_js_namespaceObject = require("./network.js");
|
|
33
34
|
const ISSUER = 'https://auth.openai.com';
|
|
34
35
|
const RESOURCE = 'https://api.openai.com/v1';
|
|
35
36
|
function base64url(bytes) {
|
|
@@ -88,7 +89,7 @@ function parseSiwcCallback(url, attempt) {
|
|
|
88
89
|
async function exchangeSiwcCode(attempt, callback, signal, dependencies) {
|
|
89
90
|
signal.throwIfAborted();
|
|
90
91
|
const response = await (0, external_errors_js_namespaceObject.withSiwcStage)('Token exchange', async ()=>{
|
|
91
|
-
const response = await (dependencies?.fetch ??
|
|
92
|
+
const response = await (dependencies?.fetch ?? external_network_js_namespaceObject.fetchSiwc)(`${ISSUER}/api/accounts/oauth/token`, {
|
|
92
93
|
method: 'POST',
|
|
93
94
|
headers: {
|
|
94
95
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
@@ -111,7 +112,7 @@ async function exchangeSiwcCode(attempt, callback, signal, dependencies) {
|
|
|
111
112
|
if (!tokens || 'string' != typeof tokens.access_token || !tokens.access_token || 'string' != typeof tokens.refresh_token || !tokens.refresh_token || 'string' != typeof tokens.id_token || 'string' != typeof tokens.scope || 'number' != typeof tokens.expires_in || !Number.isFinite(tokens.expires_in) || tokens.expires_in <= 0 || 'string' != typeof tokens.token_type || 'bearer' !== tokens.token_type.toLowerCase()) throw new Error('OpenAI returned an invalid token response.');
|
|
112
113
|
const scopes = tokens.scope.split(/\s+/);
|
|
113
114
|
if (!scopes.includes('chatgpt.tokens.use.direct')) throw new Error('ChatGPT plan usage was not authorized.');
|
|
114
|
-
const { payload } = await (0, external_errors_js_namespaceObject.withSiwcStage)('ID token verification', ()=>(0, external_jose_namespaceObject.jwtVerify)(tokens.id_token, dependencies?.keys ?? (0,
|
|
115
|
+
const { payload } = await (0, external_errors_js_namespaceObject.withSiwcStage)('ID token verification', ()=>(0, external_jose_namespaceObject.jwtVerify)(tokens.id_token, dependencies?.keys ?? (0, external_network_js_namespaceObject.createSiwcJWKSet)(ISSUER, signal), {
|
|
115
116
|
issuer: ISSUER,
|
|
116
117
|
audience: callback.clientId,
|
|
117
118
|
algorithms: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/service-caller/openai/siwc/authorization.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../../src/ai-model/service-caller/openai/siwc/authorization.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 JWTVerifyGetKey, createRemoteJWKSet, jwtVerify } from 'jose';\nimport { tokenResponseError, withSiwcStage } from './errors';\n\nconst ISSUER = 'https://auth.openai.com';\nconst RESOURCE = 'https://api.openai.com/v1';\nexport interface SiwcLoginAttempt {\n hostId: string;\n redirectUri: string;\n clientId?: string;\n state: string;\n nonce: string;\n verifier: string;\n expiresAt: number;\n}\n\nfunction base64url(bytes: Uint8Array): string {\n return btoa(String.fromCharCode(...bytes))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n}\n\nexport async function createSiwcAuthorization(options: {\n hostId: string;\n clientId?: string;\n redirectUri: string;\n agentName: string;\n}) {\n const { hostId, clientId, redirectUri, agentName } = options;\n const random = () => base64url(crypto.getRandomValues(new Uint8Array(32)));\n const attempt: SiwcLoginAttempt = {\n hostId,\n redirectUri,\n clientId,\n state: random(),\n nonce: random(),\n verifier: random(),\n expiresAt: Date.now() + 5 * 60_000,\n };\n const challenge = await crypto.subtle.digest(\n 'SHA-256',\n new TextEncoder().encode(attempt.verifier),\n );\n const url = new URL(`${ISSUER}/api/accounts/authorize`);\n url.search = new URLSearchParams({\n client_id: clientId ?? 'dynamic_agent_client',\n ...(clientId ? {} : { agent_name_hint: agentName }),\n ext_agent_host_id: hostId,\n response_type: 'code',\n redirect_uri: attempt.redirectUri,\n scope:\n 'openid profile email offline_access resource.invoke chatgpt.tokens.use.direct',\n resource: RESOURCE,\n state: attempt.state,\n nonce: attempt.nonce,\n code_challenge_method: 'S256',\n code_challenge: base64url(new Uint8Array(challenge)),\n }).toString();\n return { attempt, url: url.toString() };\n}\n\nexport function parseSiwcCallback(url: string, attempt: SiwcLoginAttempt) {\n const callback = new URL(url);\n const expected = new URL(attempt.redirectUri);\n if (\n callback.origin !== expected.origin ||\n callback.pathname !== expected.pathname\n ) {\n return undefined;\n }\n const params = callback.searchParams;\n if (\n params.getAll('state').length !== 1 ||\n params.get('state') !== attempt.state\n ) {\n return undefined;\n }\n if (Date.now() >= attempt.expiresAt) {\n throw new Error('Authorization timed out. Start authorization again.');\n }\n if (params.has('error')) {\n throw new Error(\n `OpenAI authorization failed: ${params.get('error_description') || params.get('error')}`,\n );\n }\n const code = params.get('code');\n const clientId = params.get('client_id') || attempt.clientId;\n if (\n !code ||\n !clientId ||\n clientId === 'dynamic_agent_client' ||\n params.getAll('code').length !== 1 ||\n params.getAll('client_id').length > 1 ||\n (attempt.clientId && clientId !== attempt.clientId)\n ) {\n throw new Error('Invalid OpenAI authorization callback.');\n }\n return { code, clientId };\n}\n\nexport async function exchangeSiwcCode(\n attempt: SiwcLoginAttempt,\n callback: { code: string; clientId: string },\n signal: AbortSignal,\n dependencies?: { fetch: typeof fetch; keys: JWTVerifyGetKey },\n) {\n signal.throwIfAborted();\n const response = await withSiwcStage('Token exchange', async () => {\n const response = await (dependencies?.fetch ?? fetch)(\n `${ISSUER}/api/accounts/oauth/token`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n client_id: callback.clientId,\n code: callback.code,\n code_verifier: attempt.verifier,\n redirect_uri: attempt.redirectUri,\n resource: RESOURCE,\n }),\n signal,\n redirect: 'error',\n },\n );\n if (!response.ok) {\n throw await tokenResponseError(response);\n }\n return response;\n });\n const tokens = await withSiwcStage('Token response parsing', () =>\n response.json(),\n );\n if (\n !tokens ||\n typeof tokens.access_token !== 'string' ||\n !tokens.access_token ||\n typeof tokens.refresh_token !== 'string' ||\n !tokens.refresh_token ||\n typeof tokens.id_token !== 'string' ||\n typeof tokens.scope !== 'string' ||\n typeof tokens.expires_in !== 'number' ||\n !Number.isFinite(tokens.expires_in) ||\n tokens.expires_in <= 0 ||\n typeof tokens.token_type !== 'string' ||\n tokens.token_type.toLowerCase() !== 'bearer'\n ) {\n throw new Error('OpenAI returned an invalid token response.');\n }\n const scopes = tokens.scope.split(/\\s+/);\n if (!scopes.includes('chatgpt.tokens.use.direct')) {\n throw new Error('ChatGPT plan usage was not authorized.');\n }\n const { payload } = await withSiwcStage('ID token verification', () =>\n jwtVerify(\n tokens.id_token,\n dependencies?.keys ??\n createRemoteJWKSet(new URL(`${ISSUER}/.well-known/jwks.json`)),\n {\n issuer: ISSUER,\n audience: callback.clientId,\n algorithms: ['RS256'],\n // Some CI machines have incorrect system clocks. Do not compare ID token\n // exp/nbf claims against local time when accepting newly returned tokens.\n // Keep signature, issuer, audience and required-claim validation.\n clockTolerance: Number.POSITIVE_INFINITY,\n requiredClaims: ['sub', 'exp', 'iat', 'nonce'],\n },\n ),\n );\n if (payload.nonce !== attempt.nonce || !payload.sub) {\n throw new Error('OpenAI login identity or nonce did not match.');\n }\n signal.throwIfAborted();\n return {\n ...(typeof payload.email === 'string' ? { email: payload.email } : {}),\n ext_agent_host_id: attempt.hostId,\n client_id: callback.clientId,\n subject: payload.sub,\n issuer: ISSUER,\n access_token: tokens.access_token as string,\n refresh_token: tokens.refresh_token as string,\n id_token: tokens.id_token as string,\n scopes,\n expires_at: Date.now() + tokens.expires_in * 1000,\n };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","ISSUER","RESOURCE","base64url","bytes","btoa","String","createSiwcAuthorization","options","hostId","clientId","redirectUri","agentName","random","crypto","Uint8Array","attempt","Date","challenge","TextEncoder","url","URL","URLSearchParams","parseSiwcCallback","callback","expected","params","Error","code","exchangeSiwcCode","signal","dependencies","response","withSiwcStage","fetch","tokenResponseError","tokens","Number","scopes","payload","jwtVerify","createRemoteJWKSet"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-model/service-caller/openai/siwc/authorization.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../../src/ai-model/service-caller/openai/siwc/authorization.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 JWTVerifyGetKey, jwtVerify } from 'jose';\nimport { tokenResponseError, withSiwcStage } from './errors';\nimport { createSiwcJWKSet, fetchSiwc } from './network';\n\nconst ISSUER = 'https://auth.openai.com';\nconst RESOURCE = 'https://api.openai.com/v1';\nexport interface SiwcLoginAttempt {\n hostId: string;\n redirectUri: string;\n clientId?: string;\n state: string;\n nonce: string;\n verifier: string;\n expiresAt: number;\n}\n\nfunction base64url(bytes: Uint8Array): string {\n return btoa(String.fromCharCode(...bytes))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n}\n\nexport async function createSiwcAuthorization(options: {\n hostId: string;\n clientId?: string;\n redirectUri: string;\n agentName: string;\n}) {\n const { hostId, clientId, redirectUri, agentName } = options;\n const random = () => base64url(crypto.getRandomValues(new Uint8Array(32)));\n const attempt: SiwcLoginAttempt = {\n hostId,\n redirectUri,\n clientId,\n state: random(),\n nonce: random(),\n verifier: random(),\n expiresAt: Date.now() + 5 * 60_000,\n };\n const challenge = await crypto.subtle.digest(\n 'SHA-256',\n new TextEncoder().encode(attempt.verifier),\n );\n const url = new URL(`${ISSUER}/api/accounts/authorize`);\n url.search = new URLSearchParams({\n client_id: clientId ?? 'dynamic_agent_client',\n ...(clientId ? {} : { agent_name_hint: agentName }),\n ext_agent_host_id: hostId,\n response_type: 'code',\n redirect_uri: attempt.redirectUri,\n scope:\n 'openid profile email offline_access resource.invoke chatgpt.tokens.use.direct',\n resource: RESOURCE,\n state: attempt.state,\n nonce: attempt.nonce,\n code_challenge_method: 'S256',\n code_challenge: base64url(new Uint8Array(challenge)),\n }).toString();\n return { attempt, url: url.toString() };\n}\n\nexport function parseSiwcCallback(url: string, attempt: SiwcLoginAttempt) {\n const callback = new URL(url);\n const expected = new URL(attempt.redirectUri);\n if (\n callback.origin !== expected.origin ||\n callback.pathname !== expected.pathname\n ) {\n return undefined;\n }\n const params = callback.searchParams;\n if (\n params.getAll('state').length !== 1 ||\n params.get('state') !== attempt.state\n ) {\n return undefined;\n }\n if (Date.now() >= attempt.expiresAt) {\n throw new Error('Authorization timed out. Start authorization again.');\n }\n if (params.has('error')) {\n throw new Error(\n `OpenAI authorization failed: ${params.get('error_description') || params.get('error')}`,\n );\n }\n const code = params.get('code');\n const clientId = params.get('client_id') || attempt.clientId;\n if (\n !code ||\n !clientId ||\n clientId === 'dynamic_agent_client' ||\n params.getAll('code').length !== 1 ||\n params.getAll('client_id').length > 1 ||\n (attempt.clientId && clientId !== attempt.clientId)\n ) {\n throw new Error('Invalid OpenAI authorization callback.');\n }\n return { code, clientId };\n}\n\nexport async function exchangeSiwcCode(\n attempt: SiwcLoginAttempt,\n callback: { code: string; clientId: string },\n signal: AbortSignal,\n dependencies?: { fetch: typeof fetch; keys: JWTVerifyGetKey },\n) {\n signal.throwIfAborted();\n const response = await withSiwcStage('Token exchange', async () => {\n const response = await (dependencies?.fetch ?? fetchSiwc)(\n `${ISSUER}/api/accounts/oauth/token`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n client_id: callback.clientId,\n code: callback.code,\n code_verifier: attempt.verifier,\n redirect_uri: attempt.redirectUri,\n resource: RESOURCE,\n }),\n signal,\n redirect: 'error',\n },\n );\n if (!response.ok) {\n throw await tokenResponseError(response);\n }\n return response;\n });\n const tokens = await withSiwcStage('Token response parsing', () =>\n response.json(),\n );\n if (\n !tokens ||\n typeof tokens.access_token !== 'string' ||\n !tokens.access_token ||\n typeof tokens.refresh_token !== 'string' ||\n !tokens.refresh_token ||\n typeof tokens.id_token !== 'string' ||\n typeof tokens.scope !== 'string' ||\n typeof tokens.expires_in !== 'number' ||\n !Number.isFinite(tokens.expires_in) ||\n tokens.expires_in <= 0 ||\n typeof tokens.token_type !== 'string' ||\n tokens.token_type.toLowerCase() !== 'bearer'\n ) {\n throw new Error('OpenAI returned an invalid token response.');\n }\n const scopes = tokens.scope.split(/\\s+/);\n if (!scopes.includes('chatgpt.tokens.use.direct')) {\n throw new Error('ChatGPT plan usage was not authorized.');\n }\n const { payload } = await withSiwcStage('ID token verification', () =>\n jwtVerify(\n tokens.id_token,\n dependencies?.keys ?? createSiwcJWKSet(ISSUER, signal),\n {\n issuer: ISSUER,\n audience: callback.clientId,\n algorithms: ['RS256'],\n // Some CI machines have incorrect system clocks. Do not compare ID token\n // exp/nbf claims against local time when accepting newly returned tokens.\n // Keep signature, issuer, audience and required-claim validation.\n clockTolerance: Number.POSITIVE_INFINITY,\n requiredClaims: ['sub', 'exp', 'iat', 'nonce'],\n },\n ),\n );\n if (payload.nonce !== attempt.nonce || !payload.sub) {\n throw new Error('OpenAI login identity or nonce did not match.');\n }\n signal.throwIfAborted();\n return {\n ...(typeof payload.email === 'string' ? { email: payload.email } : {}),\n ext_agent_host_id: attempt.hostId,\n client_id: callback.clientId,\n subject: payload.sub,\n issuer: ISSUER,\n access_token: tokens.access_token as string,\n refresh_token: tokens.refresh_token as string,\n id_token: tokens.id_token as string,\n scopes,\n expires_at: Date.now() + tokens.expires_in * 1000,\n };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","ISSUER","RESOURCE","base64url","bytes","btoa","String","createSiwcAuthorization","options","hostId","clientId","redirectUri","agentName","random","crypto","Uint8Array","attempt","Date","challenge","TextEncoder","url","URL","URLSearchParams","parseSiwcCallback","callback","expected","params","Error","code","exchangeSiwcCode","signal","dependencies","response","withSiwcStage","fetchSiwc","tokenResponseError","tokens","Number","scopes","payload","jwtVerify","createSiwcJWKSet"],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
createSiwcJWKSet: ()=>createSiwcJWKSet,
|
|
28
|
+
fetchSiwc: ()=>fetchSiwc
|
|
29
|
+
});
|
|
30
|
+
const utils_namespaceObject = require("@midscene/shared/utils");
|
|
31
|
+
const external_jose_namespaceObject = require("jose");
|
|
32
|
+
const index_js_namespaceObject = require("../../proxy/index.js");
|
|
33
|
+
async function fetchSiwc(input, init, proxy) {
|
|
34
|
+
if (utils_namespaceObject.ifInBrowser) return fetch(input, init);
|
|
35
|
+
const { httpProxy, socksProxy } = proxy ?? {
|
|
36
|
+
httpProxy: process.env.MIDSCENE_MODEL_HTTP_PROXY?.trim() || void 0,
|
|
37
|
+
socksProxy: process.env.MIDSCENE_MODEL_SOCKS_PROXY?.trim() || void 0
|
|
38
|
+
};
|
|
39
|
+
const dispatcher = await (0, index_js_namespaceObject.createProxyAgentIfNeeded)({
|
|
40
|
+
httpProxy,
|
|
41
|
+
socksProxy
|
|
42
|
+
});
|
|
43
|
+
if (!dispatcher) return fetch(input, init);
|
|
44
|
+
try {
|
|
45
|
+
return await fetch(input, {
|
|
46
|
+
...init,
|
|
47
|
+
dispatcher
|
|
48
|
+
});
|
|
49
|
+
} finally{
|
|
50
|
+
dispatcher.close();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function createSiwcJWKSet(issuer, signal, request = fetchSiwc) {
|
|
54
|
+
return async (header, token)=>{
|
|
55
|
+
const response = await request(`${issuer}/.well-known/jwks.json`, {
|
|
56
|
+
signal,
|
|
57
|
+
redirect: 'error'
|
|
58
|
+
});
|
|
59
|
+
if (!response.ok) throw new Error(`Failed to fetch OpenAI JWKS: HTTP ${response.status}`);
|
|
60
|
+
return (0, external_jose_namespaceObject.createLocalJWKSet)(await response.json())(header, token);
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
exports.createSiwcJWKSet = __webpack_exports__.createSiwcJWKSet;
|
|
64
|
+
exports.fetchSiwc = __webpack_exports__.fetchSiwc;
|
|
65
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
66
|
+
"createSiwcJWKSet",
|
|
67
|
+
"fetchSiwc"
|
|
68
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
69
|
+
Object.defineProperty(exports, '__esModule', {
|
|
70
|
+
value: true
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
//# sourceMappingURL=network.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-model/service-caller/openai/siwc/network.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../../src/ai-model/service-caller/openai/siwc/network.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 { ifInBrowser } from '@midscene/shared/utils';\nimport { type JWTVerifyGetKey, createLocalJWKSet } from 'jose';\nimport type { Dispatcher } from 'undici';\nimport { createProxyAgentIfNeeded } from '../../proxy';\n\nexport interface SiwcProxyConfig {\n httpProxy?: string;\n socksProxy?: string;\n}\n\nexport async function fetchSiwc(\n input: Parameters<typeof fetch>[0],\n init?: RequestInit,\n proxy?: SiwcProxyConfig,\n) {\n if (ifInBrowser) {\n return fetch(input, init);\n }\n const { httpProxy, socksProxy } = proxy ?? {\n httpProxy: process.env.MIDSCENE_MODEL_HTTP_PROXY?.trim() || undefined,\n socksProxy: process.env.MIDSCENE_MODEL_SOCKS_PROXY?.trim() || undefined,\n };\n const dispatcher = (await createProxyAgentIfNeeded({\n httpProxy,\n socksProxy,\n })) as Dispatcher | undefined;\n if (!dispatcher) {\n return fetch(input, init);\n }\n try {\n return await fetch(input, { ...init, dispatcher } as RequestInit);\n } finally {\n // Graceful close waits for the response body to be consumed by the caller.\n void dispatcher.close();\n }\n}\n\nexport function createSiwcJWKSet(\n issuer: string,\n signal: AbortSignal,\n request: typeof fetch = fetchSiwc,\n): JWTVerifyGetKey {\n return async (header, token) => {\n const response = await request(`${issuer}/.well-known/jwks.json`, {\n signal,\n redirect: 'error',\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch OpenAI JWKS: HTTP ${response.status}`);\n }\n return createLocalJWKSet(await response.json())(header, token);\n };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","fetchSiwc","input","init","proxy","ifInBrowser","fetch","httpProxy","socksProxy","process","undefined","dispatcher","createProxyAgentIfNeeded","createSiwcJWKSet","issuer","signal","request","header","token","response","Error","createLocalJWKSet"],"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;;;;;;;;;;;ACIO,eAAeI,UACpBC,KAAkC,EAClCC,IAAkB,EAClBC,KAAuB;IAEvB,IAAIC,sBAAAA,WAAWA,EACb,OAAOC,MAAMJ,OAAOC;IAEtB,MAAM,EAAEI,SAAS,EAAEC,UAAU,EAAE,GAAGJ,SAAS;QACzC,WAAWK,QAAQ,GAAG,CAAC,yBAAyB,EAAE,UAAUC;QAC5D,YAAYD,QAAQ,GAAG,CAAC,0BAA0B,EAAE,UAAUC;IAChE;IACA,MAAMC,aAAc,MAAMC,AAAAA,IAAAA,yBAAAA,wBAAAA,AAAAA,EAAyB;QACjDL;QACAC;IACF;IACA,IAAI,CAACG,YACH,OAAOL,MAAMJ,OAAOC;IAEtB,IAAI;QACF,OAAO,MAAMG,MAAMJ,OAAO;YAAE,GAAGC,IAAI;YAAEQ;QAAW;IAClD,SAAU;QAEHA,WAAW,KAAK;IACvB;AACF;AAEO,SAASE,iBACdC,MAAc,EACdC,MAAmB,EACnBC,UAAwBf,SAAS;IAEjC,OAAO,OAAOgB,QAAQC;QACpB,MAAMC,WAAW,MAAMH,QAAQ,GAAGF,OAAO,sBAAsB,CAAC,EAAE;YAChEC;YACA,UAAU;QACZ;QACA,IAAI,CAACI,SAAS,EAAE,EACd,MAAM,IAAIC,MAAM,CAAC,kCAAkC,EAAED,SAAS,MAAM,EAAE;QAExE,OAAOE,AAAAA,IAAAA,8BAAAA,iBAAAA,AAAAA,EAAkB,MAAMF,SAAS,IAAI,IAAIF,QAAQC;IAC1D;AACF"}
|
|
@@ -28,13 +28,15 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
28
28
|
});
|
|
29
29
|
const external_jose_namespaceObject = require("jose");
|
|
30
30
|
const external_errors_js_namespaceObject = require("./errors.js");
|
|
31
|
+
const external_network_js_namespaceObject = require("./network.js");
|
|
31
32
|
async function refreshSiwcCredentials(saved, signal, dependencies) {
|
|
32
33
|
const { client_id: clientId, refresh_token: refreshToken } = saved;
|
|
33
34
|
if (!clientId || !refreshToken) throw new Error('Missing client ID or refresh token.');
|
|
35
|
+
const request = dependencies?.fetch ?? external_network_js_namespaceObject.fetchSiwc;
|
|
34
36
|
const issuer = 'https://auth.openai.com';
|
|
35
37
|
signal.throwIfAborted();
|
|
36
38
|
const response = await (0, external_errors_js_namespaceObject.withSiwcStage)('Token refresh', async ()=>{
|
|
37
|
-
const response = await (
|
|
39
|
+
const response = await request(`${issuer}/api/accounts/oauth/token`, {
|
|
38
40
|
method: 'POST',
|
|
39
41
|
headers: {
|
|
40
42
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
@@ -57,7 +59,7 @@ async function refreshSiwcCredentials(saved, signal, dependencies) {
|
|
|
57
59
|
if (!scopes.includes('chatgpt.tokens.use.direct')) throw new Error('ChatGPT plan usage is no longer authorized.');
|
|
58
60
|
if (void 0 !== tokens.id_token) {
|
|
59
61
|
if ('string' != typeof tokens.id_token || !tokens.id_token) throw new Error('Invalid refreshed ID token.');
|
|
60
|
-
const keys = dependencies?.keys ?? (0,
|
|
62
|
+
const keys = dependencies?.keys ?? (0, external_network_js_namespaceObject.createSiwcJWKSet)(issuer, signal, request);
|
|
61
63
|
const { payload } = await (0, external_errors_js_namespaceObject.withSiwcStage)('ID token verification', ()=>(0, external_jose_namespaceObject.jwtVerify)(tokens.id_token, keys, {
|
|
62
64
|
issuer,
|
|
63
65
|
audience: saved.client_id,
|