@aiscene/shared 8.0.3 → 8.0.4

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 (99) 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 +3 -1
  22. package/dist/es/img/info.mjs +45 -1
  23. package/dist/es/img/photon-loader.mjs +4 -0
  24. package/dist/es/recorder.mjs +249 -0
  25. package/dist/lib/agent-tools/agent-behavior-init-args.js +87 -0
  26. package/dist/lib/agent-tools/base-tools.js +197 -0
  27. package/dist/lib/agent-tools/chrome-path.js +87 -0
  28. package/dist/lib/agent-tools/cli-report-session.js +121 -0
  29. package/dist/lib/agent-tools/error-formatter.js +149 -0
  30. package/dist/lib/agent-tools/index.js +114 -0
  31. package/dist/lib/agent-tools/init-arg-utils.js +78 -0
  32. package/dist/lib/agent-tools/observation-artifact.js +42 -0
  33. package/dist/lib/agent-tools/observation-record.js +297 -0
  34. package/dist/lib/agent-tools/tool-defaults.js +97 -0
  35. package/dist/lib/agent-tools/tool-generator.js +569 -0
  36. package/dist/lib/agent-tools/types.js +40 -0
  37. package/dist/lib/agent-tools/user-prompt.js +103 -0
  38. package/dist/lib/cli/interrupt.js +156 -0
  39. package/dist/lib/cli/record-command.js +164 -0
  40. package/dist/lib/cli/screenshot-file.js +58 -0
  41. package/dist/lib/cli/verbose-ai-act.js +273 -0
  42. package/dist/lib/cli/verbose-screenshot.js +177 -0
  43. package/dist/lib/cli/verbose.js +465 -0
  44. package/dist/lib/env/parse-model-config.js +1 -1
  45. package/dist/lib/env/types.js +5 -0
  46. package/dist/lib/img/info.js +48 -1
  47. package/dist/lib/img/photon-loader.js +38 -0
  48. package/dist/lib/recorder.js +307 -0
  49. package/dist/types/agent-tools/agent-behavior-init-args.d.ts +17 -0
  50. package/dist/types/agent-tools/base-tools.d.ts +158 -0
  51. package/dist/types/agent-tools/chrome-path.d.ts +2 -0
  52. package/dist/types/agent-tools/cli-report-session.d.ts +12 -0
  53. package/dist/types/agent-tools/error-formatter.d.ts +30 -0
  54. package/dist/types/agent-tools/index.d.ts +9 -0
  55. package/dist/types/agent-tools/init-arg-utils.d.ts +13 -0
  56. package/dist/types/agent-tools/observation-artifact.d.ts +10 -0
  57. package/dist/types/agent-tools/observation-record.d.ts +38 -0
  58. package/dist/types/agent-tools/tool-defaults.d.ts +63 -0
  59. package/dist/types/agent-tools/tool-generator.d.ts +13 -0
  60. package/dist/types/agent-tools/types.d.ts +213 -0
  61. package/dist/types/agent-tools/user-prompt.d.ts +13 -0
  62. package/dist/types/cli/interrupt.d.ts +49 -0
  63. package/dist/types/cli/record-command.d.ts +3 -0
  64. package/dist/types/cli/screenshot-file.d.ts +10 -0
  65. package/dist/types/cli/verbose-ai-act.d.ts +44 -0
  66. package/dist/types/cli/verbose-screenshot.d.ts +10 -0
  67. package/dist/types/cli/verbose.d.ts +40 -0
  68. package/dist/types/env/types.d.ts +4 -3
  69. package/dist/types/img/info.d.ts +2 -0
  70. package/dist/types/img/photon-loader.d.ts +2 -0
  71. package/dist/types/mcp/types.d.ts +1 -0
  72. package/dist/types/recorder.d.ts +113 -0
  73. package/package.json +1 -1
  74. package/src/agent-tools/agent-behavior-init-args.ts +109 -0
  75. package/src/agent-tools/base-tools.ts +399 -0
  76. package/src/agent-tools/chrome-path.ts +74 -0
  77. package/src/agent-tools/cli-report-session.ts +130 -0
  78. package/src/agent-tools/error-formatter.ts +177 -0
  79. package/src/agent-tools/index.ts +9 -0
  80. package/src/agent-tools/init-arg-utils.ts +105 -0
  81. package/src/agent-tools/observation-artifact.ts +29 -0
  82. package/src/agent-tools/observation-record.ts +331 -0
  83. package/src/agent-tools/tool-defaults.ts +119 -0
  84. package/src/agent-tools/tool-generator.ts +866 -0
  85. package/src/agent-tools/types.ts +250 -0
  86. package/src/agent-tools/user-prompt.ts +102 -0
  87. package/src/cli/interrupt.ts +207 -0
  88. package/src/cli/record-command.ts +177 -0
  89. package/src/cli/screenshot-file.ts +61 -0
  90. package/src/cli/verbose-ai-act.ts +387 -0
  91. package/src/cli/verbose-screenshot.ts +269 -0
  92. package/src/cli/verbose.ts +753 -0
  93. package/src/env/types.ts +2 -0
  94. package/src/img/index.ts +12 -0
  95. package/src/img/info.ts +61 -0
  96. package/src/img/photon-loader.ts +5 -0
  97. package/src/img/transform.ts +261 -2
  98. package/src/mcp/types.ts +2 -0
  99. package/src/recorder.ts +625 -0
@@ -0,0 +1,44 @@
1
+ import { z } from "zod";
2
+ const agentBehaviorInitArgShape = {
3
+ aiActContext: z.string().optional().describe('Background knowledge passed to aiAct. Default: no extra context.'),
4
+ replanningCycleLimit: z.number().int().nonnegative().optional().describe('Maximum number of replanning cycles for aiAct. Default: model adapter default.'),
5
+ waitAfterAction: z.number().nonnegative().optional().describe('Wait time in milliseconds after each action execution. Default: 300ms.'),
6
+ screenshotShrinkFactor: z.number().min(1).optional().describe('Screenshot shrink factor before sending images to AI. Default: 1; high values may reduce recognition quality, especially on mobile.')
7
+ };
8
+ function extractAgentBehaviorInitArgs(extracted) {
9
+ if (!extracted) return;
10
+ const agentOptions = {
11
+ ...'string' == typeof extracted.aiActContext ? {
12
+ aiActContext: extracted.aiActContext
13
+ } : {},
14
+ ...'string' == typeof extracted.aiActionContext ? {
15
+ aiActionContext: extracted.aiActionContext
16
+ } : {},
17
+ ...'number' == typeof extracted.replanningCycleLimit ? {
18
+ replanningCycleLimit: extracted.replanningCycleLimit
19
+ } : {},
20
+ ...'number' == typeof extracted.waitAfterAction ? {
21
+ waitAfterAction: extracted.waitAfterAction
22
+ } : {},
23
+ ...'number' == typeof extracted.screenshotShrinkFactor ? {
24
+ screenshotShrinkFactor: extracted.screenshotShrinkFactor
25
+ } : {}
26
+ };
27
+ return Object.keys(agentOptions).length > 0 ? agentOptions : void 0;
28
+ }
29
+ function stableJsonValue(value) {
30
+ if (Array.isArray(value)) return value.map(stableJsonValue);
31
+ if (value && 'object' == typeof value) return Object.fromEntries(Object.entries(value).sort(([left], [right])=>left.localeCompare(right)).map(([key, nestedValue])=>[
32
+ key,
33
+ stableJsonValue(nestedValue)
34
+ ]));
35
+ return value;
36
+ }
37
+ function getAgentInitArgsSignature(initArgs) {
38
+ if (!initArgs || 0 === Object.keys(initArgs).length) return;
39
+ return JSON.stringify(stableJsonValue(initArgs));
40
+ }
41
+ function shouldRebuildAgentForInitArgs(currentSignature, nextSignature) {
42
+ return currentSignature !== nextSignature && (void 0 !== currentSignature || void 0 !== nextSignature);
43
+ }
44
+ export { agentBehaviorInitArgShape, extractAgentBehaviorInitArgs, getAgentInitArgsSignature, shouldRebuildAgentForInitArgs };
@@ -0,0 +1,163 @@
1
+ import { parseBase64 } from "@aiscene/shared/img";
2
+ import { getDebug } from "@aiscene/shared/logger";
3
+ import { createRecordCliCommand } from "../cli/record-command.mjs";
4
+ import { camelToKebab, getKeyAliases } from "../key-alias-utils.mjs";
5
+ import { generateCliReportSession, readCliReportSession, writeCliReportSession } from "./cli-report-session.mjs";
6
+ import { createNamespacedInitArgSchema, extractNamespacedArgs, sanitizeNamespacedArgs } from "./init-arg-utils.mjs";
7
+ import { mergeToolDefaults } from "./tool-defaults.mjs";
8
+ import { generateCommonTools, generateToolsFromActionSpace } from "./tool-generator.mjs";
9
+ function _define_property(obj, key, value) {
10
+ if (key in obj) Object.defineProperty(obj, key, {
11
+ value: value,
12
+ enumerable: true,
13
+ configurable: true,
14
+ writable: true
15
+ });
16
+ else obj[key] = value;
17
+ return obj;
18
+ }
19
+ const debug = getDebug('agent-tools:base-tools');
20
+ class BaseMidsceneTools {
21
+ getInitArgKeys() {
22
+ return this.initArgSpec ? Object.keys(this.initArgSpec.shape) : [];
23
+ }
24
+ extractAgentInitParam(args) {
25
+ if (!this.initArgSpec) return;
26
+ const extracted = extractNamespacedArgs(args, this.initArgSpec.namespace, this.getInitArgKeys());
27
+ if (this.initArgSpec.adapt) return this.initArgSpec.adapt(extracted);
28
+ return extracted;
29
+ }
30
+ sanitizeToolArgs(args) {
31
+ if (!this.initArgSpec) return args;
32
+ return sanitizeNamespacedArgs(args, this.initArgSpec.namespace, this.getInitArgKeys());
33
+ }
34
+ getAgentInitArgSchema() {
35
+ if (!this.initArgSpec) return {};
36
+ return createNamespacedInitArgSchema(this.initArgSpec.namespace, this.initArgSpec.shape);
37
+ }
38
+ getAgentInitArgCliMetadata() {
39
+ if (!this.initArgSpec?.cli) return;
40
+ const options = Object.fromEntries(this.getInitArgKeys().map((key)=>{
41
+ const canonicalKey = `${this.initArgSpec.namespace}.${key}`;
42
+ const preferredName = this.initArgSpec.cli?.preferredNames?.[key] ?? (this.initArgSpec.cli?.preferBareKeys ? camelToKebab(key) : canonicalKey);
43
+ const acceptedNames = new Set([
44
+ preferredName,
45
+ ...this.initArgSpec.cli?.preferBareKeys ? getKeyAliases(key) : getKeyAliases(canonicalKey)
46
+ ]);
47
+ acceptedNames.delete(preferredName);
48
+ return [
49
+ canonicalKey,
50
+ {
51
+ preferredName,
52
+ aliases: [
53
+ ...acceptedNames
54
+ ]
55
+ }
56
+ ];
57
+ }));
58
+ return {
59
+ options
60
+ };
61
+ }
62
+ preparePlatformTools() {
63
+ return [];
64
+ }
65
+ getCliReportSessionName() {}
66
+ createNewCliReportSession(targetIdentity) {
67
+ const sessionName = this.getCliReportSessionName();
68
+ if (!sessionName) return;
69
+ return generateCliReportSession(sessionName, targetIdentity);
70
+ }
71
+ commitCliReportSession(session) {
72
+ if (session) writeCliReportSession(session);
73
+ }
74
+ readCliReportFileName() {
75
+ const sessionName = this.getCliReportSessionName();
76
+ if (!sessionName) return;
77
+ return readCliReportSession(sessionName)?.reportFileName;
78
+ }
79
+ readCliReportAgentOptions() {
80
+ const reportFileName = this.readCliReportFileName();
81
+ if (!reportFileName) return;
82
+ return {
83
+ reportFileName,
84
+ reportAttributes: {
85
+ 'data-group-id': reportFileName
86
+ }
87
+ };
88
+ }
89
+ async initTools() {
90
+ this.toolDefinitions = [];
91
+ const platformTools = this.preparePlatformTools();
92
+ this.toolDefinitions.push(...platformTools);
93
+ let actionSpace;
94
+ if (this.agent) {
95
+ actionSpace = await this.agent.getActionSpace();
96
+ debug('Action space from agent:', actionSpace.map((a)=>a.name).join(', '));
97
+ } else {
98
+ const tempDevice = this.createTemporaryDevice();
99
+ actionSpace = tempDevice.actionSpace();
100
+ await tempDevice.destroy?.();
101
+ debug('Action space from temporary device:', actionSpace.map((a)=>a.name).join(', '));
102
+ }
103
+ const actionTools = generateToolsFromActionSpace(actionSpace, (args = {})=>this.ensureAgent(this.extractAgentInitParam(args)), (args = {})=>this.sanitizeToolArgs(args), this.getAgentInitArgSchema(), this.getAgentInitArgCliMetadata(), this.toolDefaults);
104
+ const commonTools = generateCommonTools((args = {})=>this.ensureAgent(this.extractAgentInitParam(args)), this.getAgentInitArgSchema(), this.getAgentInitArgCliMetadata(), this.toolDefaults);
105
+ this.toolDefinitions.push(...actionTools, ...commonTools);
106
+ debug('Total tools prepared:', this.toolDefinitions.length);
107
+ }
108
+ async destroy() {
109
+ await this.agent?.destroy?.();
110
+ }
111
+ getToolDefinitions() {
112
+ return this.toolDefinitions;
113
+ }
114
+ getCliToolDefinitions() {
115
+ return [
116
+ createRecordCliCommand((args = {})=>this.ensureAgent(this.extractAgentInitParam(args)), this.getAgentInitArgSchema(), this.getAgentInitArgCliMetadata())
117
+ ];
118
+ }
119
+ setAgent(agent) {
120
+ this.agent = agent;
121
+ }
122
+ setToolDefaults(toolDefaults) {
123
+ this.toolDefaults = mergeToolDefaults(this.toolDefaults, toolDefaults);
124
+ }
125
+ buildScreenshotContent(screenshot) {
126
+ const { mimeType, body } = parseBase64(screenshot);
127
+ return [
128
+ {
129
+ type: 'image',
130
+ data: body,
131
+ mimeType
132
+ }
133
+ ];
134
+ }
135
+ buildTextResult(text) {
136
+ return {
137
+ content: [
138
+ {
139
+ type: 'text',
140
+ text
141
+ }
142
+ ]
143
+ };
144
+ }
145
+ createDisconnectHandler(platformName) {
146
+ return async ()=>{
147
+ if (!this.agent) return this.buildTextResult('No active connection to disconnect');
148
+ try {
149
+ await this.agent.destroy?.();
150
+ } catch (error) {
151
+ debug('Failed to destroy agent during disconnect:', error);
152
+ }
153
+ this.agent = void 0;
154
+ return this.buildTextResult(`Disconnected from ${platformName}`);
155
+ };
156
+ }
157
+ constructor(){
158
+ _define_property(this, "agent", void 0);
159
+ _define_property(this, "toolDefinitions", []);
160
+ _define_property(this, "toolDefaults", {});
161
+ }
162
+ }
163
+ export { BaseMidsceneTools };
@@ -0,0 +1,50 @@
1
+ import { existsSync } from "node:fs";
2
+ import { MIDSCENE_CHROME_PATH, MIDSCENE_MCP_CHROME_PATH, globalConfigManager } from "../env/index.mjs";
3
+ import { getDebug } from "../logger.mjs";
4
+ const warnChromePath = getDebug('agent-tools:chrome-path', {
5
+ console: true
6
+ });
7
+ let hasWarnedLegacyChromePath = false;
8
+ let cachedSystemChromePath;
9
+ function getSystemChromePath() {
10
+ if (void 0 !== cachedSystemChromePath) return cachedSystemChromePath;
11
+ const platform = process.platform;
12
+ const chromePaths = {
13
+ darwin: [
14
+ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
15
+ '/Applications/Chromium.app/Contents/MacOS/Chromium'
16
+ ],
17
+ win32: [
18
+ 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
19
+ 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
20
+ `C:\\Users\\${process.env.USERNAME ?? process.env.USER}\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe`
21
+ ],
22
+ linux: [
23
+ '/opt/google/chrome/chrome',
24
+ '/opt/google/chrome/google-chrome',
25
+ '/usr/bin/google-chrome-stable',
26
+ '/usr/bin/google-chrome',
27
+ '/usr/bin/chromium-browser',
28
+ '/usr/bin/chromium',
29
+ '/snap/bin/chromium'
30
+ ]
31
+ };
32
+ const paths = chromePaths[platform] ?? [];
33
+ const foundPath = paths.find((p)=>existsSync(p));
34
+ if (foundPath) cachedSystemChromePath = foundPath;
35
+ return foundPath;
36
+ }
37
+ function resolveChromePath() {
38
+ const primaryEnvPath = globalConfigManager.getEnvConfigValue(MIDSCENE_CHROME_PATH);
39
+ const legacyEnvPath = globalConfigManager.getEnvConfigValue(MIDSCENE_MCP_CHROME_PATH);
40
+ const envPath = primaryEnvPath || legacyEnvPath;
41
+ if (!primaryEnvPath && legacyEnvPath && !hasWarnedLegacyChromePath) {
42
+ warnChromePath('MIDSCENE_MCP_CHROME_PATH is deprecated. Use MIDSCENE_CHROME_PATH instead.');
43
+ hasWarnedLegacyChromePath = true;
44
+ }
45
+ if (envPath && 'auto' !== envPath && existsSync(envPath)) return envPath;
46
+ const systemPath = getSystemChromePath();
47
+ if (systemPath) return systemPath;
48
+ throw new Error('Chrome not found. Install Google Chrome or set MIDSCENE_CHROME_PATH environment variable.');
49
+ }
50
+ export { getSystemChromePath, resolveChromePath };
@@ -0,0 +1,78 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { getMidsceneRunBaseDir, getMidsceneRunSubDir } from "../common.mjs";
4
+ const sessionDirName = 'cli-report-session';
5
+ function sanitizeSessionName(sessionName) {
6
+ return sessionName.replace(/[^a-zA-Z0-9._-]/g, '_') || 'default';
7
+ }
8
+ function sanitizeFileSegment(segment) {
9
+ const sanitized = segment.replace(/[^a-zA-Z0-9._-]/g, '_') || 'unknown';
10
+ return sanitized.slice(0, 80);
11
+ }
12
+ function ensureHtmlFileName(reportFileName) {
13
+ return reportFileName.endsWith('.html') ? reportFileName : `${reportFileName}.html`;
14
+ }
15
+ function formatDateForFileName(date) {
16
+ const pad = (value)=>String(value).padStart(2, '0');
17
+ const day = [
18
+ date.getFullYear(),
19
+ pad(date.getMonth() + 1),
20
+ pad(date.getDate())
21
+ ].join('-');
22
+ const time = [
23
+ pad(date.getHours()),
24
+ pad(date.getMinutes()),
25
+ pad(date.getSeconds())
26
+ ].join('-');
27
+ return `${day}_${time}`;
28
+ }
29
+ function randomId() {
30
+ return Math.random().toString(36).slice(2, 10);
31
+ }
32
+ function getCliReportSessionDir() {
33
+ const dir = join(getMidsceneRunBaseDir(), sessionDirName);
34
+ if (!existsSync(dir)) mkdirSync(dir, {
35
+ recursive: true
36
+ });
37
+ return dir;
38
+ }
39
+ function getCliReportSessionPath(sessionName) {
40
+ return join(getCliReportSessionDir(), `${sanitizeSessionName(sessionName)}.json`);
41
+ }
42
+ function generateCliReportSession(sessionName, targetIdentity) {
43
+ const identitySegment = targetIdentity ? `-${sanitizeFileSegment(targetIdentity)}` : '';
44
+ const reportFileName = `${sanitizeSessionName(sessionName)}${identitySegment}-${formatDateForFileName(new Date())}-${randomId()}`;
45
+ const reportPath = join(getMidsceneRunSubDir('report'), ensureHtmlFileName(reportFileName));
46
+ const session = {
47
+ version: 1,
48
+ sessionName,
49
+ ...targetIdentity ? {
50
+ targetIdentity
51
+ } : {},
52
+ reportFileName,
53
+ reportPath,
54
+ createdAt: Date.now()
55
+ };
56
+ return session;
57
+ }
58
+ function writeCliReportSession(session) {
59
+ writeFileSync(getCliReportSessionPath(session.sessionName), JSON.stringify(session, null, 2), 'utf-8');
60
+ }
61
+ function createCliReportSession(sessionName, targetIdentity) {
62
+ const session = generateCliReportSession(sessionName, targetIdentity);
63
+ writeCliReportSession(session);
64
+ return session;
65
+ }
66
+ function readCliReportSession(sessionName) {
67
+ const sessionPath = getCliReportSessionPath(sessionName);
68
+ if (!existsSync(sessionPath)) return;
69
+ try {
70
+ const raw = readFileSync(sessionPath, 'utf-8');
71
+ const parsed = JSON.parse(raw);
72
+ if (1 !== parsed.version || parsed.sessionName !== sessionName || 'string' != typeof parsed.reportFileName || !parsed.reportFileName.trim() || /[\\/]/.test(parsed.reportFileName)) return;
73
+ return parsed;
74
+ } catch {
75
+ return;
76
+ }
77
+ }
78
+ export { createCliReportSession, generateCliReportSession, readCliReportSession, writeCliReportSession };
@@ -0,0 +1,106 @@
1
+ const maxSerializedStringLength = 4096;
2
+ const truncatedStringSuffix = '… [truncated]';
3
+ function isObject(error) {
4
+ return 'object' == typeof error && null !== error || 'function' == typeof error;
5
+ }
6
+ function safelyReadProperty(error, key) {
7
+ try {
8
+ return Reflect.get(error, key);
9
+ } catch {
10
+ return;
11
+ }
12
+ }
13
+ function readBoundedDiagnostic(error, keys) {
14
+ for (const key of keys){
15
+ const value = safelyReadProperty(error, key);
16
+ if ('number' == typeof value) return value;
17
+ if ('string' == typeof value) return truncateSerializedErrorString(value);
18
+ }
19
+ }
20
+ function truncateSerializedErrorString(value) {
21
+ if (value.length <= maxSerializedStringLength) return value;
22
+ return `${value.slice(0, maxSerializedStringLength - truncatedStringSuffix.length)}${truncatedStringSuffix}`;
23
+ }
24
+ function readNonEmptyMessage(error) {
25
+ const message = safelyReadProperty(error, 'message');
26
+ return 'string' == typeof message && message ? message : void 0;
27
+ }
28
+ function extractStringMessage(error) {
29
+ const directMessage = readNonEmptyMessage(error);
30
+ if (directMessage) return directMessage;
31
+ for (const nestedKey of [
32
+ 'error',
33
+ 'cause'
34
+ ]){
35
+ const nestedError = safelyReadProperty(error, nestedKey);
36
+ if (!isObject(nestedError)) continue;
37
+ const nestedMessage = readNonEmptyMessage(nestedError);
38
+ if (nestedMessage) return nestedMessage;
39
+ }
40
+ }
41
+ function getErrorMessage(error) {
42
+ const result = serializeErrorValue(error);
43
+ const serialized = result.error;
44
+ if (!isObject(error) || result.hasMessage) return serialized.message;
45
+ const summary = {
46
+ name: serialized.name,
47
+ message: serialized.message
48
+ };
49
+ for (const key of [
50
+ 'code',
51
+ 'status',
52
+ 'requestId'
53
+ ]){
54
+ const value = serialized[key];
55
+ if (void 0 !== value) summary[key] = value;
56
+ }
57
+ return truncateSerializedErrorString(JSON.stringify(summary));
58
+ }
59
+ function getErrorStack(error) {
60
+ if (!isObject(error)) return;
61
+ const stack = safelyReadProperty(error, 'stack');
62
+ return 'string' == typeof stack ? stack : void 0;
63
+ }
64
+ function serializeErrorValue(error) {
65
+ if (!isObject(error)) {
66
+ const message = truncateSerializedErrorString(String(error));
67
+ return {
68
+ error: {
69
+ name: 'NonError',
70
+ message: message.trim() ? message : 'Empty string thrown'
71
+ },
72
+ hasMessage: Boolean(message.trim())
73
+ };
74
+ }
75
+ const name = safelyReadProperty(error, 'name');
76
+ const serializedName = truncateSerializedErrorString('string' == typeof name && name ? name : 'Error');
77
+ const message = extractStringMessage(error);
78
+ const serialized = {
79
+ name: serializedName,
80
+ message: truncateSerializedErrorString(message ?? `${serializedName} without a message`)
81
+ };
82
+ const stack = getErrorStack(error);
83
+ if (stack) serialized.stack = truncateSerializedErrorString(stack);
84
+ const code = readBoundedDiagnostic(error, [
85
+ 'code'
86
+ ]);
87
+ const status = readBoundedDiagnostic(error, [
88
+ 'status',
89
+ 'statusCode'
90
+ ]);
91
+ const requestId = readBoundedDiagnostic(error, [
92
+ 'requestId',
93
+ 'requestID'
94
+ ]);
95
+ if (void 0 !== code) serialized.code = code;
96
+ if (void 0 !== status) serialized.status = status;
97
+ if (void 0 !== requestId) serialized.requestId = requestId;
98
+ return {
99
+ error: serialized,
100
+ hasMessage: void 0 !== message
101
+ };
102
+ }
103
+ function serializeError(error) {
104
+ return serializeErrorValue(error).error;
105
+ }
106
+ export { getErrorMessage, getErrorStack, serializeError, truncateSerializedErrorString };
@@ -0,0 +1,9 @@
1
+ export * from "./base-tools.mjs";
2
+ export * from "./tool-defaults.mjs";
3
+ export * from "./agent-behavior-init-args.mjs";
4
+ export * from "./init-arg-utils.mjs";
5
+ export * from "./error-formatter.mjs";
6
+ export * from "./tool-generator.mjs";
7
+ export * from "./types.mjs";
8
+ export * from "./chrome-path.mjs";
9
+ export * from "./observation-record.mjs";
@@ -0,0 +1,38 @@
1
+ import { getKeyAliases, isRecord } from "../key-alias-utils.mjs";
2
+ function readAliasedValue(args, key) {
3
+ for (const alias of getKeyAliases(key))if (alias in args) return args[alias];
4
+ }
5
+ function readNamespacedArg(args, namespace, key) {
6
+ const namespacedArgs = readAliasedValue(args, namespace);
7
+ if (isRecord(namespacedArgs)) {
8
+ const nestedValue = readAliasedValue(namespacedArgs, key);
9
+ if (void 0 !== nestedValue) return nestedValue;
10
+ }
11
+ const dottedValue = readAliasedValue(args, `${namespace}.${key}`);
12
+ if (void 0 !== dottedValue) return dottedValue;
13
+ const directValue = readAliasedValue(args, key);
14
+ if (void 0 !== directValue) return directValue;
15
+ }
16
+ function extractNamespacedArgs(args, namespace, keys) {
17
+ const extracted = {};
18
+ for (const key of keys){
19
+ const value = readNamespacedArg(args, namespace, key);
20
+ if (void 0 !== value) extracted[key] = value;
21
+ }
22
+ return Object.keys(extracted).length > 0 ? extracted : void 0;
23
+ }
24
+ function sanitizeNamespacedArgs(args, namespace, keys) {
25
+ const excludedKeys = new Set(getKeyAliases(namespace));
26
+ for (const key of keys){
27
+ for (const alias of getKeyAliases(key))excludedKeys.add(alias);
28
+ for (const alias of getKeyAliases(`${namespace}.${key}`))excludedKeys.add(alias);
29
+ }
30
+ return Object.fromEntries(Object.entries(args).filter(([key])=>!excludedKeys.has(key)));
31
+ }
32
+ function createNamespacedInitArgSchema(namespace, shape) {
33
+ return Object.fromEntries(Object.entries(shape).map(([key, value])=>[
34
+ `${namespace}.${key}`,
35
+ value
36
+ ]));
37
+ }
38
+ export { createNamespacedInitArgSchema, extractNamespacedArgs, sanitizeNamespacedArgs };
@@ -0,0 +1,5 @@
1
+ const observationArtifactAdapterSymbol = Symbol('midscene.observationArtifactAdapter');
2
+ function resolveObservationArtifactAdapter(agent) {
3
+ return agent[observationArtifactAdapterSymbol];
4
+ }
5
+ export { observationArtifactAdapterSymbol, resolveObservationArtifactAdapter };