@aiscene/shared 8.0.3 → 8.0.5

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.
Files changed (105) hide show
  1. package/dist/es/agent-tools/agent-behavior-init-args.mjs +44 -0
  2. package/dist/es/agent-tools/base-tools.mjs +163 -0
  3. package/dist/es/agent-tools/chrome-path.mjs +50 -0
  4. package/dist/es/agent-tools/cli-report-session.mjs +78 -0
  5. package/dist/es/agent-tools/error-formatter.mjs +106 -0
  6. package/dist/es/agent-tools/index.mjs +9 -0
  7. package/dist/es/agent-tools/init-arg-utils.mjs +38 -0
  8. package/dist/es/agent-tools/observation-artifact.mjs +5 -0
  9. package/dist/es/agent-tools/observation-record.mjs +248 -0
  10. package/dist/es/agent-tools/tool-defaults.mjs +54 -0
  11. package/dist/es/agent-tools/tool-generator.mjs +529 -0
  12. package/dist/es/agent-tools/types.mjs +3 -0
  13. package/dist/es/agent-tools/user-prompt.mjs +66 -0
  14. package/dist/es/cli/interrupt.mjs +116 -0
  15. package/dist/es/cli/record-command.mjs +130 -0
  16. package/dist/es/cli/screenshot-file.mjs +24 -0
  17. package/dist/es/cli/verbose-ai-act.mjs +230 -0
  18. package/dist/es/cli/verbose-screenshot.mjs +134 -0
  19. package/dist/es/cli/verbose.mjs +404 -0
  20. package/dist/es/env/parse-model-config.mjs +1 -1
  21. package/dist/es/env/types.mjs +18 -3
  22. package/dist/es/img/index.mjs +3 -3
  23. package/dist/es/img/info.mjs +45 -1
  24. package/dist/es/img/photon-loader.mjs +4 -0
  25. package/dist/es/img/transform.mjs +113 -3
  26. package/dist/es/recorder.mjs +249 -0
  27. package/dist/lib/agent-tools/agent-behavior-init-args.js +87 -0
  28. package/dist/lib/agent-tools/base-tools.js +197 -0
  29. package/dist/lib/agent-tools/chrome-path.js +87 -0
  30. package/dist/lib/agent-tools/cli-report-session.js +121 -0
  31. package/dist/lib/agent-tools/error-formatter.js +149 -0
  32. package/dist/lib/agent-tools/index.js +114 -0
  33. package/dist/lib/agent-tools/init-arg-utils.js +78 -0
  34. package/dist/lib/agent-tools/observation-artifact.js +42 -0
  35. package/dist/lib/agent-tools/observation-record.js +297 -0
  36. package/dist/lib/agent-tools/tool-defaults.js +97 -0
  37. package/dist/lib/agent-tools/tool-generator.js +569 -0
  38. package/dist/lib/agent-tools/types.js +40 -0
  39. package/dist/lib/agent-tools/user-prompt.js +103 -0
  40. package/dist/lib/cli/interrupt.js +156 -0
  41. package/dist/lib/cli/record-command.js +164 -0
  42. package/dist/lib/cli/screenshot-file.js +58 -0
  43. package/dist/lib/cli/verbose-ai-act.js +273 -0
  44. package/dist/lib/cli/verbose-screenshot.js +177 -0
  45. package/dist/lib/cli/verbose.js +465 -0
  46. package/dist/lib/env/parse-model-config.js +1 -1
  47. package/dist/lib/env/types.js +32 -2
  48. package/dist/lib/img/index.js +29 -5
  49. package/dist/lib/img/info.js +48 -1
  50. package/dist/lib/img/photon-loader.js +38 -0
  51. package/dist/lib/img/transform.js +135 -4
  52. package/dist/lib/recorder.js +307 -0
  53. package/dist/types/agent-tools/agent-behavior-init-args.d.ts +17 -0
  54. package/dist/types/agent-tools/base-tools.d.ts +158 -0
  55. package/dist/types/agent-tools/chrome-path.d.ts +2 -0
  56. package/dist/types/agent-tools/cli-report-session.d.ts +12 -0
  57. package/dist/types/agent-tools/error-formatter.d.ts +30 -0
  58. package/dist/types/agent-tools/index.d.ts +9 -0
  59. package/dist/types/agent-tools/init-arg-utils.d.ts +13 -0
  60. package/dist/types/agent-tools/observation-artifact.d.ts +10 -0
  61. package/dist/types/agent-tools/observation-record.d.ts +38 -0
  62. package/dist/types/agent-tools/tool-defaults.d.ts +63 -0
  63. package/dist/types/agent-tools/tool-generator.d.ts +13 -0
  64. package/dist/types/agent-tools/types.d.ts +213 -0
  65. package/dist/types/agent-tools/user-prompt.d.ts +13 -0
  66. package/dist/types/cli/interrupt.d.ts +49 -0
  67. package/dist/types/cli/record-command.d.ts +3 -0
  68. package/dist/types/cli/screenshot-file.d.ts +10 -0
  69. package/dist/types/cli/verbose-ai-act.d.ts +44 -0
  70. package/dist/types/cli/verbose-screenshot.d.ts +10 -0
  71. package/dist/types/cli/verbose.d.ts +40 -0
  72. package/dist/types/env/types.d.ts +16 -7
  73. package/dist/types/img/index.d.ts +2 -2
  74. package/dist/types/img/info.d.ts +2 -0
  75. package/dist/types/img/photon-loader.d.ts +2 -0
  76. package/dist/types/img/transform.d.ts +22 -2
  77. package/dist/types/mcp/types.d.ts +1 -0
  78. package/dist/types/recorder.d.ts +113 -0
  79. package/package.json +1 -1
  80. package/src/agent-tools/agent-behavior-init-args.ts +109 -0
  81. package/src/agent-tools/base-tools.ts +399 -0
  82. package/src/agent-tools/chrome-path.ts +74 -0
  83. package/src/agent-tools/cli-report-session.ts +130 -0
  84. package/src/agent-tools/error-formatter.ts +177 -0
  85. package/src/agent-tools/index.ts +9 -0
  86. package/src/agent-tools/init-arg-utils.ts +105 -0
  87. package/src/agent-tools/observation-artifact.ts +29 -0
  88. package/src/agent-tools/observation-record.ts +331 -0
  89. package/src/agent-tools/tool-defaults.ts +119 -0
  90. package/src/agent-tools/tool-generator.ts +866 -0
  91. package/src/agent-tools/types.ts +250 -0
  92. package/src/agent-tools/user-prompt.ts +102 -0
  93. package/src/cli/interrupt.ts +207 -0
  94. package/src/cli/record-command.ts +177 -0
  95. package/src/cli/screenshot-file.ts +61 -0
  96. package/src/cli/verbose-ai-act.ts +387 -0
  97. package/src/cli/verbose-screenshot.ts +269 -0
  98. package/src/cli/verbose.ts +753 -0
  99. package/src/env/types.ts +30 -2
  100. package/src/img/index.ts +12 -0
  101. package/src/img/info.ts +61 -0
  102. package/src/img/photon-loader.ts +5 -0
  103. package/src/img/transform.ts +262 -3
  104. package/src/mcp/types.ts +2 -0
  105. package/src/recorder.ts +625 -0
@@ -0,0 +1,404 @@
1
+ import { aiActCliProgressRenderer, cliAiActProgressScope } from "./verbose-ai-act.mjs";
2
+ import { collectScreenshotRefs, renderScreenshotList } from "./verbose-screenshot.mjs";
3
+ const cliVerboseFlag = 'verbose';
4
+ const progressRenderers = {
5
+ [cliAiActProgressScope]: aiActCliProgressRenderer
6
+ };
7
+ function progressRendererForEvent(event) {
8
+ if ('object' != typeof event || null === event) return;
9
+ const scope = event.scope;
10
+ if ('string' != typeof scope) return;
11
+ const renderer = progressRenderers[scope];
12
+ return renderer ? {
13
+ scope,
14
+ renderer
15
+ } : void 0;
16
+ }
17
+ const progressEventName = 'midscene_progress';
18
+ const cliVerboseContextKey = '__midscene_cli_verbose_context__';
19
+ const getGlobalContext = ()=>{
20
+ const globalWithContext = globalThis;
21
+ if (!globalWithContext[cliVerboseContextKey]) globalWithContext[cliVerboseContextKey] = {
22
+ current: {
23
+ enabled: false
24
+ }
25
+ };
26
+ return globalWithContext[cliVerboseContextKey];
27
+ };
28
+ function parseVerboseFormat(rawFormat) {
29
+ if ('text' === rawFormat || 'jsonl' === rawFormat) return rawFormat;
30
+ throw new Error(`Unsupported --${cliVerboseFlag} format "${rawFormat}". Use "--${cliVerboseFlag}" or "--${cliVerboseFlag}=jsonl".`);
31
+ }
32
+ function stripVerboseFlag(argv) {
33
+ const rawArgs = [];
34
+ let verbose = false;
35
+ let format = 'text';
36
+ for (const arg of argv){
37
+ if (arg === `--${cliVerboseFlag}`) {
38
+ verbose = true;
39
+ continue;
40
+ }
41
+ if (arg.startsWith(`--${cliVerboseFlag}=`)) {
42
+ verbose = true;
43
+ format = parseVerboseFormat(arg.slice(`--${cliVerboseFlag}=`.length));
44
+ continue;
45
+ }
46
+ rawArgs.push(arg);
47
+ }
48
+ return {
49
+ rawArgs,
50
+ verbose,
51
+ format
52
+ };
53
+ }
54
+ async function withCliVerboseContext(context, fn) {
55
+ const globalContext = getGlobalContext();
56
+ const previous = globalContext.current;
57
+ globalContext.current = {
58
+ ...context,
59
+ renderedLineKeys: context.renderedLineKeys ?? new Set()
60
+ };
61
+ try {
62
+ return await fn();
63
+ } finally{
64
+ globalContext.current = previous;
65
+ }
66
+ }
67
+ function getCliVerboseContext() {
68
+ return getGlobalContext().current;
69
+ }
70
+ function isCliVerboseEnabled() {
71
+ return getCliVerboseContext().enabled;
72
+ }
73
+ function emitCliVerboseEvent(event) {
74
+ const context = getCliVerboseContext();
75
+ if (!context.enabled) return;
76
+ const payload = {
77
+ type: progressEventName,
78
+ timestamp: new Date().toISOString(),
79
+ scriptName: context.scriptName,
80
+ command: context.commandName,
81
+ ...event
82
+ };
83
+ if ('jsonl' === context.format) return void console.log(JSON.stringify(payload));
84
+ const text = renderCliVerboseEventText(payload, context);
85
+ if (text) console.log(text);
86
+ }
87
+ function errorMessageOf(error) {
88
+ return error instanceof Error ? error.message : String(error);
89
+ }
90
+ function isRecord(value) {
91
+ return 'object' == typeof value && null !== value && !Array.isArray(value);
92
+ }
93
+ function compactText(value) {
94
+ if (null == value || '' === value) return '';
95
+ if ('string' == typeof value) return value.length > 180 ? `${value.slice(0, 177)}...` : value;
96
+ if ('number' == typeof value || 'boolean' == typeof value) return String(value);
97
+ try {
98
+ const json = JSON.stringify(value);
99
+ return json.length > 180 ? `${json.slice(0, 177)}...` : json;
100
+ } catch {
101
+ return String(value);
102
+ }
103
+ }
104
+ function compactPrimitiveCliVerboseValue(value) {
105
+ if (null == value) return {
106
+ handled: true,
107
+ value
108
+ };
109
+ if ('string' == typeof value) return {
110
+ handled: true,
111
+ value: value.length > 180 ? `${value.slice(0, 177)}...` : value
112
+ };
113
+ if ('number' == typeof value || 'boolean' == typeof value) return {
114
+ handled: true,
115
+ value
116
+ };
117
+ if ('object' != typeof value) return {
118
+ handled: true,
119
+ value: String(value)
120
+ };
121
+ return {
122
+ handled: false
123
+ };
124
+ }
125
+ function compactStructuredCliVerboseValue(value) {
126
+ const primitive = compactPrimitiveCliVerboseValue(value);
127
+ if (primitive.handled) return primitive.value;
128
+ if (Array.isArray(value)) return value.slice(0, 5).map(compactStructuredCliVerboseValue);
129
+ if (!isRecord(value)) return String(value);
130
+ const entries = Object.entries(value).slice(0, 6);
131
+ return Object.fromEntries(entries.map(([key, entryValue])=>[
132
+ key,
133
+ compactStructuredCliVerboseValue(entryValue)
134
+ ]));
135
+ }
136
+ function compactCliVerboseValue(value) {
137
+ const primitive = compactPrimitiveCliVerboseValue(value);
138
+ if (primitive.handled) return primitive.value;
139
+ if (Array.isArray(value)) return value.slice(0, 5).map(compactCliVerboseValue);
140
+ if (isRecord(value) && 'string' == typeof value.prompt) return compactCliVerboseValue(value.prompt);
141
+ if (!isRecord(value)) return String(value);
142
+ const entries = Object.entries(value).slice(0, 6);
143
+ return Object.fromEntries(entries.map(([key, entryValue])=>[
144
+ key,
145
+ compactCliVerboseValue(entryValue)
146
+ ]));
147
+ }
148
+ function compactCliVerboseArgs(args) {
149
+ return Object.fromEntries(Object.entries(args).slice(0, 8).map(([key, value])=>[
150
+ key,
151
+ compactStructuredCliVerboseValue(value)
152
+ ]));
153
+ }
154
+ function summarizeParam(param) {
155
+ if (!param || 'object' != typeof param) return compactCliVerboseValue(param);
156
+ const record = param;
157
+ if ('string' == typeof record.prompt) return compactCliVerboseValue(record.prompt);
158
+ if (record.locate && 'object' == typeof record.locate && null !== record.locate) {
159
+ const locate = record.locate;
160
+ return {
161
+ locate: compactCliVerboseValue(locate.prompt),
162
+ ...Object.fromEntries(Object.entries(record).filter(([key])=>'locate' !== key).slice(0, 4).map(([key, value])=>[
163
+ key,
164
+ compactCliVerboseValue(value)
165
+ ]))
166
+ };
167
+ }
168
+ return compactCliVerboseValue(record);
169
+ }
170
+ function summarizeUserInstruction(value) {
171
+ if ('string' == typeof value) return compactText(value);
172
+ if (isRecord(value) && 'string' == typeof value.prompt) return compactText(value.prompt);
173
+ return compactText(value);
174
+ }
175
+ function summarizeTaskParamText(task) {
176
+ if (!isRecord(task.param)) return compactText(summarizeParam(task.param));
177
+ if ('Planning' === task.type && 'Locate' !== task.subType) {
178
+ if (task.param.userInstructionDisplay) return summarizeUserInstruction(task.param.userInstructionDisplay);
179
+ if (task.param.userInstruction) return summarizeUserInstruction(task.param.userInstruction);
180
+ }
181
+ if (task.param.dataDemand) return compactText(summarizeParam(task.param.dataDemand));
182
+ if (task.param.assertion) return compactText(summarizeParam(task.param.assertion));
183
+ return compactText(summarizeParam(task.param));
184
+ }
185
+ function summarizeSubGoals(value) {
186
+ if (!Array.isArray(value) || 0 === value.length) return '';
187
+ const goals = value.slice(0, 6).map((goal)=>{
188
+ if (!isRecord(goal)) return '';
189
+ const index = 'number' == typeof goal.index ? `${goal.index}. ` : '';
190
+ const status = 'string' == typeof goal.status ? `[${goal.status}] ` : '';
191
+ const description = 'string' == typeof goal.description ? goal.description : '';
192
+ return `${index}${status}${description}`.trim();
193
+ }).filter(Boolean);
194
+ return goals.length > 0 ? `sub-goals: ${goals.join('; ')}` : '';
195
+ }
196
+ function summarizeActions(value) {
197
+ if (!Array.isArray(value) || 0 === value.length) return '';
198
+ const actions = value.slice(0, 5).map((action)=>{
199
+ if (!isRecord(action)) return '';
200
+ const type = 'string' == typeof action.type ? action.type : 'Action';
201
+ const param = compactText(summarizeParam(action.param));
202
+ return param ? `${type}: ${param}` : type;
203
+ }).filter(Boolean);
204
+ return actions.length > 0 ? `actions: ${actions.join('; ')}` : '';
205
+ }
206
+ function summarizeTaskOutputText(task) {
207
+ if (!isRecord(task.output)) return compactText(task.output);
208
+ return summarizeSubGoals(task.output.updateSubGoals) || compactText(task.output.log) || compactText(task.output.output) || summarizeActions(task.output.actions);
209
+ }
210
+ function summarizeTaskText(task) {
211
+ const parts = [
212
+ task.type,
213
+ task.subType
214
+ ].filter((part)=>'string' == typeof part && part.length > 0);
215
+ const label = parts.length > 0 ? parts.join('/') : 'Task';
216
+ const status = 'string' == typeof task.status && task.status.length > 0 ? task.status : 'unknown';
217
+ const param = summarizeTaskParamText(task);
218
+ const output = summarizeTaskOutputText(task);
219
+ const thought = compactText(task.thought);
220
+ const detail = output || thought || param;
221
+ return detail ? `${label} ${status}: ${detail}` : `${label} ${status}`;
222
+ }
223
+ function isCliVerboseExecutionDumpLike(value) {
224
+ return isRecord(value) && Array.isArray(value.tasks);
225
+ }
226
+ function summarizeDumpUpdate(executionDump, screenshotOptions = {}) {
227
+ if (!isCliVerboseExecutionDumpLike(executionDump)) return;
228
+ const tasks = executionDump.tasks;
229
+ const latestTask = tasks[tasks.length - 1];
230
+ const steps = tasks.map((task, index)=>({
231
+ id: task.taskId,
232
+ index: index + 1,
233
+ total: tasks.length,
234
+ type: task.type,
235
+ subType: task.subType,
236
+ status: task.status,
237
+ param: summarizeParam(task.param),
238
+ message: summarizeTaskText(task),
239
+ error: task.errorMessage,
240
+ durationMs: task.timing?.cost,
241
+ screenshots: collectScreenshotRefs(task, screenshotOptions).slice(-3)
242
+ }));
243
+ return {
244
+ execution: {
245
+ id: executionDump.id,
246
+ name: executionDump.name,
247
+ description: compactCliVerboseValue(executionDump.description),
248
+ taskCount: tasks.length
249
+ },
250
+ steps,
251
+ task: latestTask ? {
252
+ id: latestTask.taskId,
253
+ index: tasks.length,
254
+ total: tasks.length,
255
+ type: latestTask.type,
256
+ subType: latestTask.subType,
257
+ status: latestTask.status,
258
+ param: summarizeParam(latestTask.param),
259
+ message: summarizeTaskText(latestTask),
260
+ error: latestTask.errorMessage,
261
+ durationMs: latestTask.timing?.cost
262
+ } : void 0,
263
+ screenshots: collectScreenshotRefs(tasks, screenshotOptions).slice(-5)
264
+ };
265
+ }
266
+ function stringifyArgs(args) {
267
+ if (!isRecord(args) || 0 === Object.keys(args).length) return '';
268
+ return Object.entries(args).map(([key, value])=>`${key}=${compactText(value)}`).join(', ');
269
+ }
270
+ function isActVerboseEvent(command, tool) {
271
+ return 'act' === command || 'act' === tool;
272
+ }
273
+ function renderLinesOnce(context, lines) {
274
+ if (0 === lines.length) return;
275
+ if (!context.renderedLineKeys) context.renderedLineKeys = new Set();
276
+ const renderedLineKeys = context.renderedLineKeys;
277
+ const pendingLines = lines.filter((line)=>{
278
+ if (renderedLineKeys.has(line.key)) return false;
279
+ renderedLineKeys.add(line.key);
280
+ return true;
281
+ });
282
+ return pendingLines.length > 0 ? pendingLines.map((line)=>line.text).join('\n') : void 0;
283
+ }
284
+ function renderCliVerboseEventText(event, context) {
285
+ const command = 'string' == typeof event.command ? event.command : 'command';
286
+ const tool = 'string' == typeof event.tool ? event.tool : void 0;
287
+ switch(event.event){
288
+ case 'agent_progress':
289
+ {
290
+ const scope = 'string' == typeof event.scope ? event.scope : void 0;
291
+ const renderer = scope ? progressRenderers[scope] : void 0;
292
+ const progressEvent = isRecord(event.progress) ? event.progress : void 0;
293
+ if (!renderer || !progressEvent) return;
294
+ return renderLinesOnce(context, renderer.buildLines(progressEvent));
295
+ }
296
+ case 'command_start':
297
+ {
298
+ if (isActVerboseEvent(command, tool)) return;
299
+ const args = stringifyArgs(event.args);
300
+ return args ? `[Midscene] ${command} started (${args})` : `[Midscene] ${command} started`;
301
+ }
302
+ case 'agent_ready':
303
+ if (isActVerboseEvent(command, tool)) return;
304
+ return `[Midscene] ${tool ?? command} ready`;
305
+ case 'recording_ready':
306
+ return '[Midscene] Recording. Press Ctrl+C to stop and save.';
307
+ case 'recording_stopping':
308
+ if ('watchdog' === event.reason) return '[Midscene] Recording watchdog reached; finalizing and saving.';
309
+ if ('sigterm' === event.reason) return '[Midscene] SIGTERM received; finalizing and saving.';
310
+ return 'sighup' === event.reason ? '[Midscene] SIGHUP received; finalizing and saving.' : '[Midscene] Ctrl+C received; finalizing and saving. Press Ctrl+C again to force exit.';
311
+ case 'dump_update':
312
+ {
313
+ if (isActVerboseEvent(command, tool)) return;
314
+ const task = isRecord(event.task) ? event.task : void 0;
315
+ const steps = Array.isArray(event.steps) ? event.steps.filter(isRecord) : [];
316
+ const execution = isRecord(event.execution) ? event.execution : void 0;
317
+ const executionName = 'string' == typeof execution?.name ? execution.name : 'execution';
318
+ const lines = steps.length > 0 ? [
319
+ `[Midscene] Progress: ${executionName} (${steps.length} steps)`,
320
+ ...steps.map((step)=>{
321
+ const index = 'number' == typeof step.index && 'number' == typeof step.total ? `Step ${step.index}/${step.total}` : 'Step';
322
+ const message = 'string' == typeof step.message ? step.message : 'string' == typeof step.status ? step.status : 'updated';
323
+ return `[Midscene] ${index}: ${message}`;
324
+ })
325
+ ] : [
326
+ `[Midscene] Step: ${'string' == typeof task?.message ? task.message : 'string' == typeof task?.status ? task.status : 'updated'}`
327
+ ];
328
+ const screenshots = renderScreenshotList(event.screenshots);
329
+ if (screenshots) lines.push(`[Midscene] Screenshot: ${screenshots}`);
330
+ if ('string' == typeof event.report && event.report.length > 0) lines.push(`[Midscene] Report: ${event.report}`);
331
+ return lines.join('\n');
332
+ }
333
+ case 'artifact':
334
+ {
335
+ if (isActVerboseEvent(command, tool)) return;
336
+ const kind = 'string' == typeof event.kind ? event.kind : 'artifact';
337
+ const path = 'string' == typeof event.path ? event.path : void 0;
338
+ return path ? `[Midscene] ${kind} saved: ${path}` : `[Midscene] ${kind} ready`;
339
+ }
340
+ case 'command_done':
341
+ {
342
+ if (isActVerboseEvent(command, tool)) {
343
+ if ('error' === event.status) {
344
+ const error = 'string' == typeof event.error && event.error.length > 0 ? `: ${event.error}` : '';
345
+ return renderLinesOnce(context, [
346
+ {
347
+ key: `aiAct:command_failed:${event.error ?? 'unknown'}`,
348
+ text: `[Midscene][aiAct] Failed${error}`
349
+ }
350
+ ]);
351
+ }
352
+ return;
353
+ }
354
+ const status = 'error' === event.status ? 'failed' : 'finished';
355
+ const duration = 'number' == typeof event.durationMs ? ` in ${event.durationMs}ms` : '';
356
+ const error = 'error' === event.status && 'string' == typeof event.error ? `: ${event.error}` : '';
357
+ return `[Midscene] ${command} ${status}${duration}${error}`;
358
+ }
359
+ default:
360
+ return;
361
+ }
362
+ }
363
+ function attachCliVerboseDumpListener(agent, options) {
364
+ if (!isCliVerboseEnabled()) return ()=>{};
365
+ const isActTool = options?.toolName === 'act';
366
+ const screenshotExportCache = new Map();
367
+ if (isActTool && 'function' == typeof agent.addProgressListener) return agent.addProgressListener((event)=>{
368
+ const match = progressRendererForEvent(event);
369
+ if (!match) return;
370
+ const context = getCliVerboseContext();
371
+ const isTextMode = 'jsonl' !== context.format;
372
+ const progress = match.renderer.normalize(event, {
373
+ reportFile: agent.reportFile,
374
+ exportMode: isTextMode ? 'report' : 'none',
375
+ cache: screenshotExportCache
376
+ });
377
+ if (!progress) return;
378
+ emitCliVerboseEvent({
379
+ event: 'agent_progress',
380
+ tool: options?.toolName,
381
+ scope: match.scope,
382
+ progress
383
+ });
384
+ });
385
+ if (isActTool) return ()=>{};
386
+ if ('function' != typeof agent.addDumpUpdateListener) return ()=>{};
387
+ return agent.addDumpUpdateListener((_dump, executionDump)=>{
388
+ const context = getCliVerboseContext();
389
+ const isTextMode = 'jsonl' !== context.format;
390
+ const summaryExportMode = isTextMode && !isActTool ? 'tmp' : 'none';
391
+ const summary = summarizeDumpUpdate(executionDump, {
392
+ exportMode: summaryExportMode,
393
+ cache: screenshotExportCache
394
+ });
395
+ if (!summary) return;
396
+ emitCliVerboseEvent({
397
+ event: 'dump_update',
398
+ tool: options?.toolName,
399
+ report: agent.reportFile || void 0,
400
+ ...summary
401
+ });
402
+ });
403
+ }
404
+ export { attachCliVerboseDumpListener, errorMessageOf as cliVerboseErrorMessage, cliVerboseFlag, compactCliVerboseArgs, compactCliVerboseValue, emitCliVerboseEvent, getCliVerboseContext, isCliVerboseEnabled, stripVerboseFlag, withCliVerboseContext };
@@ -5,7 +5,7 @@ import { assert } from "../utils.mjs";
5
5
  import { maskConfig, parseJson } from "./helper.mjs";
6
6
  import { initDebugConfig } from "./init-debug.mjs";
7
7
  const MODEL_CONFIG_DOC_URL = 'https://midscenejs.com/model-common-config.html';
8
- const getCurrentVersion = ()=>"8.0.3";
8
+ const getCurrentVersion = ()=>"8.0.5";
9
9
  const getInvalidModelFamilyMessage = (modelFamily)=>`Invalid MIDSCENE_MODEL_FAMILY value: ${modelFamily}. Current version v${getCurrentVersion()} accepts the following model families: ${MODEL_FAMILY_VALUES.join(', ')}. You can also visit ${MODEL_CONFIG_DOC_URL} for the latest configuration information.`;
10
10
  const KEYS_MAP = {
11
11
  insight: INSIGHT_MODEL_CONFIG_KEYS,
@@ -6,6 +6,7 @@ const MIDSCENE_DEBUG_MODEL_RESPONSE = 'MIDSCENE_DEBUG_MODEL_RESPONSE';
6
6
  const MIDSCENE_DANGEROUSLY_PRINT_ALL_CONFIG = 'MIDSCENE_DANGEROUSLY_PRINT_ALL_CONFIG';
7
7
  const MIDSCENE_DEBUG_MODE = 'MIDSCENE_DEBUG_MODE';
8
8
  const MIDSCENE_MCP_USE_PUPPETEER_MODE = 'MIDSCENE_MCP_USE_PUPPETEER_MODE';
9
+ const MIDSCENE_CHROME_PATH = 'MIDSCENE_CHROME_PATH';
9
10
  const MIDSCENE_MCP_CHROME_PATH = 'MIDSCENE_MCP_CHROME_PATH';
10
11
  const MIDSCENE_MCP_ANDROID_MODE = 'MIDSCENE_MCP_ANDROID_MODE';
11
12
  const DOCKER_CONTAINER = 'DOCKER_CONTAINER';
@@ -23,6 +24,7 @@ const MIDSCENE_MODEL_RETRY_INTERVAL = 'MIDSCENE_MODEL_RETRY_INTERVAL';
23
24
  const MIDSCENE_MODEL_REASONING_EFFORT = 'MIDSCENE_MODEL_REASONING_EFFORT';
24
25
  const MIDSCENE_MODEL_REASONING_ENABLED = 'MIDSCENE_MODEL_REASONING_ENABLED';
25
26
  const MIDSCENE_MODEL_REASONING_BUDGET = 'MIDSCENE_MODEL_REASONING_BUDGET';
27
+ const MIDSCENE_MODEL_RESPONSE_FORMAT = 'MIDSCENE_MODEL_RESPONSE_FORMAT';
26
28
  const OPENAI_API_KEY = 'OPENAI_API_KEY';
27
29
  const OPENAI_BASE_URL = 'OPENAI_BASE_URL';
28
30
  const MIDSCENE_OPENAI_INIT_CONFIG_JSON = 'MIDSCENE_OPENAI_INIT_CONFIG_JSON';
@@ -50,6 +52,7 @@ const MIDSCENE_PREFERRED_LANGUAGE = 'MIDSCENE_PREFERRED_LANGUAGE';
50
52
  const MIDSCENE_CACHE_MAX_FILENAME_LENGTH = 'MIDSCENE_CACHE_MAX_FILENAME_LENGTH';
51
53
  const MIDSCENE_REPLANNING_CYCLE_LIMIT = 'MIDSCENE_REPLANNING_CYCLE_LIMIT';
52
54
  const MIDSCENE_RUN_DIR = 'MIDSCENE_RUN_DIR';
55
+ const MIDSCENE_RECORD_MODEL_CALL = 'MIDSCENE_RECORD_MODEL_CALL';
53
56
  const MIDSCENE_INSIGHT_MODEL_NAME = 'MIDSCENE_INSIGHT_MODEL_NAME';
54
57
  const MIDSCENE_INSIGHT_MODEL_SOCKS_PROXY = 'MIDSCENE_INSIGHT_MODEL_SOCKS_PROXY';
55
58
  const MIDSCENE_INSIGHT_MODEL_HTTP_PROXY = 'MIDSCENE_INSIGHT_MODEL_HTTP_PROXY';
@@ -65,6 +68,7 @@ const MIDSCENE_INSIGHT_MODEL_FAMILY = 'MIDSCENE_INSIGHT_MODEL_FAMILY';
65
68
  const MIDSCENE_INSIGHT_MODEL_REASONING_EFFORT = 'MIDSCENE_INSIGHT_MODEL_REASONING_EFFORT';
66
69
  const MIDSCENE_INSIGHT_MODEL_REASONING_ENABLED = 'MIDSCENE_INSIGHT_MODEL_REASONING_ENABLED';
67
70
  const MIDSCENE_INSIGHT_MODEL_REASONING_BUDGET = 'MIDSCENE_INSIGHT_MODEL_REASONING_BUDGET';
71
+ const MIDSCENE_INSIGHT_MODEL_RESPONSE_FORMAT = 'MIDSCENE_INSIGHT_MODEL_RESPONSE_FORMAT';
68
72
  const MIDSCENE_PLANNING_MODEL_NAME = 'MIDSCENE_PLANNING_MODEL_NAME';
69
73
  const MIDSCENE_PLANNING_MODEL_SOCKS_PROXY = 'MIDSCENE_PLANNING_MODEL_SOCKS_PROXY';
70
74
  const MIDSCENE_PLANNING_MODEL_HTTP_PROXY = 'MIDSCENE_PLANNING_MODEL_HTTP_PROXY';
@@ -80,6 +84,7 @@ const MIDSCENE_PLANNING_MODEL_FAMILY = 'MIDSCENE_PLANNING_MODEL_FAMILY';
80
84
  const MIDSCENE_PLANNING_MODEL_REASONING_EFFORT = 'MIDSCENE_PLANNING_MODEL_REASONING_EFFORT';
81
85
  const MIDSCENE_PLANNING_MODEL_REASONING_ENABLED = 'MIDSCENE_PLANNING_MODEL_REASONING_ENABLED';
82
86
  const MIDSCENE_PLANNING_MODEL_REASONING_BUDGET = 'MIDSCENE_PLANNING_MODEL_REASONING_BUDGET';
87
+ const MIDSCENE_PLANNING_MODEL_RESPONSE_FORMAT = 'MIDSCENE_PLANNING_MODEL_RESPONSE_FORMAT';
83
88
  const MIDSCENE_MODEL_FAMILY = 'MIDSCENE_MODEL_FAMILY';
84
89
  const UNUSED_ENV_KEYS = [
85
90
  MIDSCENE_DANGEROUSLY_PRINT_ALL_CONFIG
@@ -88,7 +93,8 @@ const BASIC_ENV_KEYS = [
88
93
  MIDSCENE_DEBUG_MODE,
89
94
  MIDSCENE_DEBUG_MODEL_PROFILE,
90
95
  MIDSCENE_DEBUG_MODEL_RESPONSE,
91
- MIDSCENE_RUN_DIR
96
+ MIDSCENE_RUN_DIR,
97
+ MIDSCENE_RECORD_MODEL_CALL
92
98
  ];
93
99
  const BOOLEAN_ENV_KEYS = [
94
100
  MIDSCENE_CACHE,
@@ -115,6 +121,7 @@ const STRING_ENV_KEYS = [
115
121
  MIDSCENE_REPORT_TAG_NAME,
116
122
  MIDSCENE_PREFERRED_LANGUAGE,
117
123
  MATCH_BY_POSITION,
124
+ MIDSCENE_CHROME_PATH,
118
125
  MIDSCENE_MCP_CHROME_PATH,
119
126
  DOCKER_CONTAINER
120
127
  ];
@@ -138,6 +145,7 @@ const MODEL_ENV_KEYS = [
138
145
  MIDSCENE_MODEL_REASONING_EFFORT,
139
146
  MIDSCENE_MODEL_REASONING_ENABLED,
140
147
  MIDSCENE_MODEL_REASONING_BUDGET,
148
+ MIDSCENE_MODEL_RESPONSE_FORMAT,
141
149
  MIDSCENE_USE_VLM_UI_TARS,
142
150
  MIDSCENE_USE_QWEN_VL,
143
151
  MIDSCENE_USE_QWEN3_VL,
@@ -164,6 +172,7 @@ const MODEL_ENV_KEYS = [
164
172
  MIDSCENE_INSIGHT_MODEL_REASONING_EFFORT,
165
173
  MIDSCENE_INSIGHT_MODEL_REASONING_ENABLED,
166
174
  MIDSCENE_INSIGHT_MODEL_REASONING_BUDGET,
175
+ MIDSCENE_INSIGHT_MODEL_RESPONSE_FORMAT,
167
176
  MIDSCENE_PLANNING_MODEL_NAME,
168
177
  MIDSCENE_PLANNING_MODEL_SOCKS_PROXY,
169
178
  MIDSCENE_PLANNING_MODEL_HTTP_PROXY,
@@ -179,6 +188,7 @@ const MODEL_ENV_KEYS = [
179
188
  MIDSCENE_PLANNING_MODEL_REASONING_EFFORT,
180
189
  MIDSCENE_PLANNING_MODEL_REASONING_ENABLED,
181
190
  MIDSCENE_PLANNING_MODEL_REASONING_BUDGET,
191
+ MIDSCENE_PLANNING_MODEL_RESPONSE_FORMAT,
182
192
  MIDSCENE_MODEL_FAMILY
183
193
  ];
184
194
  const ALL_ENV_KEYS = [
@@ -193,6 +203,7 @@ const MODEL_FAMILY_VALUES = [
193
203
  'gemini',
194
204
  'qwen2.5-vl',
195
205
  'qwen3-vl',
206
+ 'qwen3',
196
207
  'qwen3.5',
197
208
  'qwen3.6',
198
209
  'vlm-ui-tars',
@@ -201,7 +212,11 @@ const MODEL_FAMILY_VALUES = [
201
212
  'glm-v',
202
213
  'auto-glm',
203
214
  'auto-glm-multilingual',
204
- 'gpt-5'
215
+ 'gpt-5',
216
+ 'deepseek',
217
+ 'kimi',
218
+ 'kimi3',
219
+ 'xiaomi-mimo'
205
220
  ];
206
221
  var types_UITarsModelVersion = /*#__PURE__*/ function(UITarsModelVersion) {
207
222
  UITarsModelVersion["V1_0"] = "1.0";
@@ -210,4 +225,4 @@ var types_UITarsModelVersion = /*#__PURE__*/ function(UITarsModelVersion) {
210
225
  UITarsModelVersion["DOUBAO_1_5_20B"] = "doubao-1.5-20B";
211
226
  return UITarsModelVersion;
212
227
  }({});
213
- export { ALL_ENV_KEYS, BASIC_ENV_KEYS, BOOLEAN_ENV_KEYS, DOCKER_CONTAINER, GLOBAL_ENV_KEYS, MATCH_BY_POSITION, MIDSCENE_ADB_PATH, MIDSCENE_ADB_REMOTE_HOST, MIDSCENE_ADB_REMOTE_PORT, MIDSCENE_ANDROID_IME_STRATEGY, MIDSCENE_CACHE, MIDSCENE_CACHE_MAX_FILENAME_LENGTH, MIDSCENE_DANGEROUSLY_PRINT_ALL_CONFIG, MIDSCENE_DEBUG_MODE, MIDSCENE_DEBUG_MODEL_PROFILE, MIDSCENE_DEBUG_MODEL_RESPONSE, MIDSCENE_INSIGHT_MODEL_API_KEY, MIDSCENE_INSIGHT_MODEL_BASE_URL, MIDSCENE_INSIGHT_MODEL_EXTRA_BODY_JSON, MIDSCENE_INSIGHT_MODEL_FAMILY, MIDSCENE_INSIGHT_MODEL_HTTP_PROXY, MIDSCENE_INSIGHT_MODEL_INIT_CONFIG_JSON, MIDSCENE_INSIGHT_MODEL_NAME, MIDSCENE_INSIGHT_MODEL_REASONING_BUDGET, MIDSCENE_INSIGHT_MODEL_REASONING_EFFORT, MIDSCENE_INSIGHT_MODEL_REASONING_ENABLED, MIDSCENE_INSIGHT_MODEL_RETRY_COUNT, MIDSCENE_INSIGHT_MODEL_RETRY_INTERVAL, MIDSCENE_INSIGHT_MODEL_SOCKS_PROXY, MIDSCENE_INSIGHT_MODEL_TEMPERATURE, MIDSCENE_INSIGHT_MODEL_TIMEOUT, MIDSCENE_IOS_DEVICE_CLASS_OVERRIDE, MIDSCENE_IOS_DEVICE_UDID, MIDSCENE_IOS_SIMULATOR_UDID, MIDSCENE_LANGFUSE_DEBUG, MIDSCENE_LANGSMITH_DEBUG, MIDSCENE_MCP_ANDROID_MODE, MIDSCENE_MCP_CHROME_PATH, MIDSCENE_MCP_USE_PUPPETEER_MODE, MIDSCENE_MODEL_API_KEY, MIDSCENE_MODEL_BASE_URL, MIDSCENE_MODEL_EXTRA_BODY_JSON, MIDSCENE_MODEL_FAMILY, MIDSCENE_MODEL_HTTP_PROXY, MIDSCENE_MODEL_INIT_CONFIG_JSON, MIDSCENE_MODEL_MAX_TOKENS, MIDSCENE_MODEL_NAME, MIDSCENE_MODEL_REASONING_BUDGET, MIDSCENE_MODEL_REASONING_EFFORT, MIDSCENE_MODEL_REASONING_ENABLED, MIDSCENE_MODEL_RETRY_COUNT, MIDSCENE_MODEL_RETRY_INTERVAL, MIDSCENE_MODEL_SOCKS_PROXY, MIDSCENE_MODEL_TEMPERATURE, MIDSCENE_MODEL_TIMEOUT, MIDSCENE_OPENAI_HTTP_PROXY, MIDSCENE_OPENAI_INIT_CONFIG_JSON, MIDSCENE_OPENAI_SOCKS_PROXY, MIDSCENE_PLANNING_MODEL_API_KEY, MIDSCENE_PLANNING_MODEL_BASE_URL, MIDSCENE_PLANNING_MODEL_EXTRA_BODY_JSON, MIDSCENE_PLANNING_MODEL_FAMILY, MIDSCENE_PLANNING_MODEL_HTTP_PROXY, MIDSCENE_PLANNING_MODEL_INIT_CONFIG_JSON, MIDSCENE_PLANNING_MODEL_NAME, MIDSCENE_PLANNING_MODEL_REASONING_BUDGET, MIDSCENE_PLANNING_MODEL_REASONING_EFFORT, MIDSCENE_PLANNING_MODEL_REASONING_ENABLED, MIDSCENE_PLANNING_MODEL_RETRY_COUNT, MIDSCENE_PLANNING_MODEL_RETRY_INTERVAL, MIDSCENE_PLANNING_MODEL_SOCKS_PROXY, MIDSCENE_PLANNING_MODEL_TEMPERATURE, MIDSCENE_PLANNING_MODEL_TIMEOUT, MIDSCENE_PREFERRED_LANGUAGE, MIDSCENE_REPLANNING_CYCLE_LIMIT, MIDSCENE_REPORT_QUIET, MIDSCENE_REPORT_TAG_NAME, MIDSCENE_RUN_DIR, MIDSCENE_USE_DOUBAO_VISION, MIDSCENE_USE_GEMINI, MIDSCENE_USE_QWEN3_VL, MIDSCENE_USE_QWEN_VL, MIDSCENE_USE_VLM_UI_TARS, MIDSCENE_USE_VL_MODEL, MODEL_ENV_KEYS, MODEL_FAMILY_VALUES, NUMBER_ENV_KEYS, OPENAI_API_KEY, OPENAI_BASE_URL, OPENAI_MAX_TOKENS, STRING_ENV_KEYS, types_UITarsModelVersion as UITarsModelVersion, UNUSED_ENV_KEYS };
228
+ export { ALL_ENV_KEYS, BASIC_ENV_KEYS, BOOLEAN_ENV_KEYS, DOCKER_CONTAINER, GLOBAL_ENV_KEYS, MATCH_BY_POSITION, MIDSCENE_ADB_PATH, MIDSCENE_ADB_REMOTE_HOST, MIDSCENE_ADB_REMOTE_PORT, MIDSCENE_ANDROID_IME_STRATEGY, MIDSCENE_CACHE, MIDSCENE_CACHE_MAX_FILENAME_LENGTH, MIDSCENE_CHROME_PATH, MIDSCENE_DANGEROUSLY_PRINT_ALL_CONFIG, MIDSCENE_DEBUG_MODE, MIDSCENE_DEBUG_MODEL_PROFILE, MIDSCENE_DEBUG_MODEL_RESPONSE, MIDSCENE_INSIGHT_MODEL_API_KEY, MIDSCENE_INSIGHT_MODEL_BASE_URL, MIDSCENE_INSIGHT_MODEL_EXTRA_BODY_JSON, MIDSCENE_INSIGHT_MODEL_FAMILY, MIDSCENE_INSIGHT_MODEL_HTTP_PROXY, MIDSCENE_INSIGHT_MODEL_INIT_CONFIG_JSON, MIDSCENE_INSIGHT_MODEL_NAME, MIDSCENE_INSIGHT_MODEL_REASONING_BUDGET, MIDSCENE_INSIGHT_MODEL_REASONING_EFFORT, MIDSCENE_INSIGHT_MODEL_REASONING_ENABLED, MIDSCENE_INSIGHT_MODEL_RESPONSE_FORMAT, MIDSCENE_INSIGHT_MODEL_RETRY_COUNT, MIDSCENE_INSIGHT_MODEL_RETRY_INTERVAL, MIDSCENE_INSIGHT_MODEL_SOCKS_PROXY, MIDSCENE_INSIGHT_MODEL_TEMPERATURE, MIDSCENE_INSIGHT_MODEL_TIMEOUT, MIDSCENE_IOS_DEVICE_CLASS_OVERRIDE, MIDSCENE_IOS_DEVICE_UDID, MIDSCENE_IOS_SIMULATOR_UDID, MIDSCENE_LANGFUSE_DEBUG, MIDSCENE_LANGSMITH_DEBUG, MIDSCENE_MCP_ANDROID_MODE, MIDSCENE_MCP_CHROME_PATH, MIDSCENE_MCP_USE_PUPPETEER_MODE, MIDSCENE_MODEL_API_KEY, MIDSCENE_MODEL_BASE_URL, MIDSCENE_MODEL_EXTRA_BODY_JSON, MIDSCENE_MODEL_FAMILY, MIDSCENE_MODEL_HTTP_PROXY, MIDSCENE_MODEL_INIT_CONFIG_JSON, MIDSCENE_MODEL_MAX_TOKENS, MIDSCENE_MODEL_NAME, MIDSCENE_MODEL_REASONING_BUDGET, MIDSCENE_MODEL_REASONING_EFFORT, MIDSCENE_MODEL_REASONING_ENABLED, MIDSCENE_MODEL_RESPONSE_FORMAT, MIDSCENE_MODEL_RETRY_COUNT, MIDSCENE_MODEL_RETRY_INTERVAL, MIDSCENE_MODEL_SOCKS_PROXY, MIDSCENE_MODEL_TEMPERATURE, MIDSCENE_MODEL_TIMEOUT, MIDSCENE_OPENAI_HTTP_PROXY, MIDSCENE_OPENAI_INIT_CONFIG_JSON, MIDSCENE_OPENAI_SOCKS_PROXY, MIDSCENE_PLANNING_MODEL_API_KEY, MIDSCENE_PLANNING_MODEL_BASE_URL, MIDSCENE_PLANNING_MODEL_EXTRA_BODY_JSON, MIDSCENE_PLANNING_MODEL_FAMILY, MIDSCENE_PLANNING_MODEL_HTTP_PROXY, MIDSCENE_PLANNING_MODEL_INIT_CONFIG_JSON, MIDSCENE_PLANNING_MODEL_NAME, MIDSCENE_PLANNING_MODEL_REASONING_BUDGET, MIDSCENE_PLANNING_MODEL_REASONING_EFFORT, MIDSCENE_PLANNING_MODEL_REASONING_ENABLED, MIDSCENE_PLANNING_MODEL_RESPONSE_FORMAT, MIDSCENE_PLANNING_MODEL_RETRY_COUNT, MIDSCENE_PLANNING_MODEL_RETRY_INTERVAL, MIDSCENE_PLANNING_MODEL_SOCKS_PROXY, MIDSCENE_PLANNING_MODEL_TEMPERATURE, MIDSCENE_PLANNING_MODEL_TIMEOUT, MIDSCENE_PREFERRED_LANGUAGE, MIDSCENE_RECORD_MODEL_CALL, MIDSCENE_REPLANNING_CYCLE_LIMIT, MIDSCENE_REPORT_QUIET, MIDSCENE_REPORT_TAG_NAME, MIDSCENE_RUN_DIR, MIDSCENE_USE_DOUBAO_VISION, MIDSCENE_USE_GEMINI, MIDSCENE_USE_QWEN3_VL, MIDSCENE_USE_QWEN_VL, MIDSCENE_USE_VLM_UI_TARS, MIDSCENE_USE_VL_MODEL, MODEL_ENV_KEYS, MODEL_FAMILY_VALUES, NUMBER_ENV_KEYS, OPENAI_API_KEY, OPENAI_BASE_URL, OPENAI_MAX_TOKENS, STRING_ENV_KEYS, types_UITarsModelVersion as UITarsModelVersion, UNUSED_ENV_KEYS };
@@ -1,4 +1,4 @@
1
- import { imageInfoOfBase64, isValidImageBuffer, isValidJPEGImageBuffer, isValidPNGImageBuffer, validateScreenshotBuffer } from "./info.mjs";
2
- import { createImgBase64ByFormat, cropByRect, httpImg2Base64, localImg2Base64, paddingToMatchBlockByBase64, parseBase64, preProcessImageUrl, resizeAndConvertImgBuffer, resizeImgBase64, saveBase64Image, scaleImage, zoomForGPT4o } from "./transform.mjs";
1
+ import { encodedImageInfoOfBuffer, imageInfoOfBase64, isValidImageBuffer, isValidJPEGImageBuffer, isValidPNGImageBuffer, validateScreenshotBuffer } from "./info.mjs";
2
+ import { constrainBase64ImageToMaxSize, convertBase64ImageToJpeg, convertImgBufferToJpeg, createImgBase64ByFormat, cropByRect, httpImg2Base64, inferBase64ImageFormat, localImg2Base64, normalizeBase64Image, normalizeScreenshotBase64, paddingToMatchBlockByBase64, parseBase64, preProcessImageUrl, resizeAndConvertImgBuffer, resizeBase64ImageToJpeg, resizeImgBase64, saveBase64Image, scaleImage, zoomForGPT4o } from "./transform.mjs";
3
3
  import { annotateRects, compositeElementInfoImg, processImageElementInfo } from "./box-select.mjs";
4
- export { annotateRects, compositeElementInfoImg, createImgBase64ByFormat, cropByRect, httpImg2Base64, imageInfoOfBase64, isValidImageBuffer, isValidJPEGImageBuffer, isValidPNGImageBuffer, localImg2Base64, paddingToMatchBlockByBase64, parseBase64, preProcessImageUrl, processImageElementInfo, resizeAndConvertImgBuffer, resizeImgBase64, saveBase64Image, scaleImage, validateScreenshotBuffer, zoomForGPT4o };
4
+ export { annotateRects, compositeElementInfoImg, constrainBase64ImageToMaxSize, convertBase64ImageToJpeg, convertImgBufferToJpeg, createImgBase64ByFormat, cropByRect, encodedImageInfoOfBuffer, httpImg2Base64, imageInfoOfBase64, inferBase64ImageFormat, isValidImageBuffer, isValidJPEGImageBuffer, isValidPNGImageBuffer, localImg2Base64, normalizeBase64Image, normalizeScreenshotBase64, paddingToMatchBlockByBase64, parseBase64, preProcessImageUrl, processImageElementInfo, resizeAndConvertImgBuffer, resizeBase64ImageToJpeg, resizeImgBase64, saveBase64Image, scaleImage, validateScreenshotBuffer, zoomForGPT4o };
@@ -1,5 +1,49 @@
1
1
  import node_assert from "node:assert";
2
2
  import get_photon from "./get-photon.mjs";
3
+ const isJpegStartOfFrameMarker = (marker)=>marker >= 0xc0 && marker <= 0xcf && 0xc4 !== marker && 0xc8 !== marker && 0xcc !== marker;
4
+ function jpegInfoFromBuffer(imageBuffer) {
5
+ let offset = 2;
6
+ while(offset < imageBuffer.length){
7
+ if (0xff !== imageBuffer[offset]) {
8
+ offset += 1;
9
+ continue;
10
+ }
11
+ while(offset < imageBuffer.length && 0xff === imageBuffer[offset])offset += 1;
12
+ if (offset >= imageBuffer.length) break;
13
+ const marker = imageBuffer[offset];
14
+ offset += 1;
15
+ if (0xd9 === marker || 0xda === marker) break;
16
+ if (0x01 === marker || 0xd8 === marker || marker >= 0xd0 && marker <= 0xd7) continue;
17
+ if (offset + 2 > imageBuffer.length) break;
18
+ const segmentLength = imageBuffer.readUInt16BE(offset);
19
+ if (segmentLength < 2 || offset + segmentLength > imageBuffer.length) break;
20
+ if (isJpegStartOfFrameMarker(marker)) {
21
+ if (segmentLength < 7) break;
22
+ const height = imageBuffer.readUInt16BE(offset + 3);
23
+ const width = imageBuffer.readUInt16BE(offset + 5);
24
+ node_assert(width && height, 'Invalid image: cannot get width or height');
25
+ return {
26
+ width,
27
+ height
28
+ };
29
+ }
30
+ offset += segmentLength;
31
+ }
32
+ throw new Error('Invalid image: cannot get JPEG width or height');
33
+ }
34
+ function encodedImageInfoOfBuffer(imageBuffer) {
35
+ if (isValidPNGImageBuffer(imageBuffer)) {
36
+ const width = imageBuffer.readUInt32BE(16);
37
+ const height = imageBuffer.readUInt32BE(20);
38
+ node_assert(width && height, 'Invalid image: cannot get width or height');
39
+ return {
40
+ width,
41
+ height
42
+ };
43
+ }
44
+ if (isValidJPEGImageBuffer(imageBuffer)) return jpegInfoFromBuffer(imageBuffer);
45
+ throw new Error('Invalid image: unsupported format');
46
+ }
3
47
  async function imageInfoOfBase64(imageBase64) {
4
48
  const { PhotonImage } = await get_photon();
5
49
  const base64Data = imageBase64.replace(/^data:image\/\w+;base64,/, '');
@@ -32,4 +76,4 @@ function validateScreenshotBuffer(screenshotBuffer, { label, minBufferSize = 0 }
32
76
  if (!isValidImageBuffer(screenshotBuffer)) throw new Error(`${label} buffer has invalid image format`);
33
77
  if (minBufferSize > 0 && bufferSize < minBufferSize) throw new Error(`${label} validation failed: buffer size ${bufferSize} bytes (minimum: ${minBufferSize})`);
34
78
  }
35
- export { imageInfoOfBase64, isValidImageBuffer, isValidJPEGImageBuffer, isValidPNGImageBuffer, validateScreenshotBuffer };
79
+ export { encodedImageInfoOfBuffer, imageInfoOfBase64, isValidImageBuffer, isValidJPEGImageBuffer, isValidPNGImageBuffer, validateScreenshotBuffer };
@@ -0,0 +1,4 @@
1
+ async function loadPhotonModule() {
2
+ return import("@silvia-odwyer/photon");
3
+ }
4
+ export { loadPhotonModule };