@midscene/test 1.12.3 → 1.12.4-beta-20260902093735.0

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.
@@ -127,7 +127,7 @@ const aiActOptionsInputSchema = z.strictObject({
127
127
  z.boolean()
128
128
  ]).optional().describe('Whether to enable deep thinking for this action.'),
129
129
  deepLocate: z.boolean().optional().describe('Whether to use deep element location.'),
130
- context: z.string().optional().describe('Additional context supplied to the UI Agent.')
130
+ context: z.string().optional().describe('Additional facts, rules, constraints, or output requirements for this AI call. It overrides Agent API and default contexts; an empty string disables inherited user context.')
131
131
  });
132
132
  const aiActInputSchema = z.strictObject({
133
133
  prompt: nonBlankPrompt('The natural-language UI task to perform.'),
@@ -141,7 +141,7 @@ const aiAssertOptionsInputSchema = z.strictObject({
141
141
  z.literal('visible-only')
142
142
  ]).optional().describe('How DOM information is included in the assertion.'),
143
143
  screenshotIncluded: z.boolean().optional().describe('Whether the assertion includes a screenshot.'),
144
- context: z.string().optional().describe('Additional context supplied to the UI Agent.')
144
+ context: z.string().optional().describe('Additional facts, decision rules, constraints, or output requirements for this assertion. It overrides Agent API and default contexts; an empty string disables inherited user context.')
145
145
  });
146
146
  const aiAssertInputSchema = z.strictObject({
147
147
  prompt: nonBlankPrompt('The natural-language condition that must be true.'),
@@ -245,10 +245,6 @@ const renderNodeHistory = (history)=>{
245
245
  ...renderedEntries
246
246
  ].join('\n');
247
247
  };
248
- const mergeContext = (explicit, history)=>[
249
- explicit,
250
- renderNodeHistory(history)
251
- ].filter(Boolean).join('\n\n') || void 0;
252
248
  const toAgentPrompt = (input)=>{
253
249
  if (void 0 === input.images && void 0 === input.convertHttpImage2Base64) return input.prompt;
254
250
  return {
@@ -310,11 +306,15 @@ function createMidsceneNodes(options) {
310
306
  async execute (ctx) {
311
307
  const agent = await getAgent(ctx);
312
308
  const aiAct = requireAgentMethod(agent, 'aiAct', 'aiAct');
313
- const output = await aiAct.call(agent, toAgentPrompt(ctx.input), {
309
+ const additionalContext = renderNodeHistory(ctx.history);
310
+ const aiActOptions = {
314
311
  ...ctx.input.options,
315
- context: mergeContext(ctx.input.options?.context, ctx.history),
316
- abortSignal: ctx.signal
317
- });
312
+ abortSignal: ctx.signal,
313
+ ...void 0 === additionalContext ? {} : {
314
+ _internalAdditionalContext: additionalContext
315
+ }
316
+ };
317
+ const output = await aiAct.call(agent, toAgentPrompt(ctx.input), aiActOptions);
318
318
  return void 0 === output ? void 0 : {
319
319
  summary: output
320
320
  };
@@ -327,11 +327,15 @@ function createMidsceneNodes(options) {
327
327
  async execute (ctx) {
328
328
  const agent = await getAgent(ctx);
329
329
  const aiAssert = requireAgentMethod(agent, 'aiAssert', 'aiAssert');
330
- await aiAssert.call(agent, toAgentPrompt(ctx.input), ctx.input.message, {
330
+ const additionalContext = renderNodeHistory(ctx.history);
331
+ const aiAssertOptions = {
331
332
  ...ctx.input.options,
332
- context: mergeContext(ctx.input.options?.context, ctx.history),
333
- abortSignal: ctx.signal
334
- });
333
+ abortSignal: ctx.signal,
334
+ ...void 0 === additionalContext ? {} : {
335
+ _internalAdditionalContext: additionalContext
336
+ }
337
+ };
338
+ await aiAssert.call(agent, toAgentPrompt(ctx.input), ctx.input.message, aiAssertOptions);
335
339
  return {
336
340
  summary: `Assertion passed: ${ctx.input.prompt}`
337
341
  };
@@ -1 +1 @@
1
- {"version":3,"file":"midscene/index.mjs","sources":["../../../src/errors.ts","../../../src/node/define-node.ts","../../../src/device/lifecycle.ts","../../../src/midscene/index.ts"],"sourcesContent":["import type { z } from 'zod/v4';\n\nexport interface WorkflowErrorOptions {\n code?: string;\n details?: unknown;\n cause?: unknown;\n}\n\nexport class WorkflowError extends Error {\n readonly code: string;\n readonly details?: unknown;\n\n constructor(message: string, options: WorkflowErrorOptions = {}) {\n super(message, { cause: options.cause });\n this.name = new.target.name;\n this.code = options.code ?? 'WORKFLOW_ERROR';\n this.details = options.details;\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n ...(this.details === undefined ? {} : { details: this.details }),\n };\n }\n}\n\nexport class WorkflowParseError extends WorkflowError {\n constructor(message: string, details?: unknown, cause?: unknown) {\n super(message, { code: 'WORKFLOW_PARSE_ERROR', details, cause });\n }\n}\n\nexport class NodeDefinitionError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_DEFINITION_ERROR', details });\n }\n}\n\nexport class DuplicateNodeError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is already registered.`, {\n code: 'DUPLICATE_NODE',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeNotFoundError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is not registered.`, {\n code: 'NODE_NOT_FOUND',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeInputValidationError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_INPUT_VALIDATION_ERROR', details });\n }\n\n static fromZod(node: string, error: z.ZodError): NodeInputValidationError {\n const issues = error.issues.map((issue) => ({\n code: issue.code,\n path: issue.path.map(String).join('.'),\n message: issue.message,\n }));\n const firstIssue = issues[0];\n const path = firstIssue?.path || '<root>';\n const message = firstIssue?.message ?? 'invalid input';\n return new NodeInputValidationError(\n `Node \"${node}\" input validation failed at \"${path}\": ${message}`,\n { node, issues },\n );\n }\n}\n\nexport class StepTimeoutError extends WorkflowError {\n readonly timeoutMs: number;\n readonly node?: string;\n\n constructor(timeoutMs: number, node?: string) {\n super(\n node\n ? `Node \"${node}\" timed out after ${timeoutMs}ms.`\n : `Step timed out after ${timeoutMs}ms.`,\n {\n code: 'STEP_TIMEOUT',\n details: { timeoutMs, ...(node === undefined ? {} : { node }) },\n },\n );\n this.timeoutMs = timeoutMs;\n this.node = node;\n }\n}\n\nexport class NodeExecutionError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string, cause: unknown) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Node \"${node}\" failed: ${causeMessage}`, {\n code: 'NODE_EXECUTION_ERROR',\n details: { node },\n cause,\n });\n this.node = node;\n }\n}\n\nexport class WorkflowLifecycleError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'WORKFLOW_LIFECYCLE_ERROR', details });\n }\n}\n\nexport class ProjectSetupError extends WorkflowError {\n constructor(cause: unknown, details: { projectName: string }) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" setup failed: ${causeMessage}`, {\n code: 'PROJECT_SETUP_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class ProjectTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: { projectName: string; registrationIndex: number },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" teardown failed: ${causeMessage}`, {\n code: 'PROJECT_TEARDOWN_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class NodeScopeTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: {\n scope: 'case' | 'document';\n scopeId: string;\n node: string;\n registrationIndex: number;\n },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(\n `${details.scope === 'case' ? 'Case attempt' : 'Workflow document'} node teardown failed for \"${details.node}\": ${causeMessage}`,\n { code: 'NODE_SCOPE_TEARDOWN_ERROR', details, cause },\n );\n }\n}\n\nexport class FatalDeviceError extends WorkflowError {\n constructor(message: string, cause?: unknown) {\n super(message, { code: 'FATAL_DEVICE_ERROR', cause });\n }\n}\n\nexport const isFatalDeviceError = (error: unknown): boolean => {\n if (error instanceof FatalDeviceError) return true;\n if (error instanceof WorkflowError && error.code === 'FATAL_DEVICE_ERROR') {\n return true;\n }\n if (\n error instanceof Error &&\n /device offline|device not found|(?:adb|bdc|device) connection (?:was )?closed/i.test(\n error.message,\n )\n ) {\n return true;\n }\n return error instanceof Error && error.cause !== undefined\n ? isFatalDeviceError(error.cause)\n : false;\n};\n\nexport class CaseExecutionError extends WorkflowError {\n readonly result: import('./engine/types').CaseRunResult;\n\n constructor(result: import('./engine/types').CaseRunResult) {\n super(`Case \"${result.name}\" failed.`, {\n code: 'CASE_EXECUTION_FAILED',\n details: { caseId: result.caseId, runId: result.runId },\n });\n this.result = result;\n }\n}\n\nexport class WorkflowDocumentExecutionError extends WorkflowError {\n readonly result: import('./engine/types').WorkflowDocumentRunResult;\n\n constructor(result: import('./engine/types').WorkflowDocumentRunResult) {\n super(`Workflow document \"${result.sourcePath}\" failed.`, {\n code: 'WORKFLOW_DOCUMENT_EXECUTION_FAILED',\n details: {\n documentId: result.documentId,\n documentRunId: result.documentRunId,\n },\n });\n this.result = result;\n }\n}\n\nexport function normalizeNodeExecutionError(\n error: unknown,\n node: string,\n): WorkflowError {\n return error instanceof WorkflowError\n ? error\n : new NodeExecutionError(node, error);\n}\n","import { z } from 'zod/v4';\nimport { NodeDefinitionError } from '../errors';\nimport type {\n DefineNodeOptions,\n DefineNodeWithSchemaOptions,\n NodeDefinition,\n NodeDefinitionWithSchema,\n NodeInputSchema,\n} from './types';\n\nconst validateOptionalText = (\n value: unknown,\n field: 'title' | 'description',\n node: string,\n): void => {\n if (\n value !== undefined &&\n (typeof value !== 'string' || value.trim().length === 0)\n ) {\n throw new NodeDefinitionError(\n `Node \"${node}\" ${field} must be a non-empty string.`,\n { node, field },\n );\n }\n};\n\nconst validateInputSchema = (schema: unknown, node: string): void => {\n if (schema === undefined) return;\n if (!(schema instanceof z.ZodObject)) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must be a Zod object schema.`,\n { node, field: 'inputSchema' },\n );\n }\n if ('$' in schema.shape) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must not declare \"$\" as an input property.`,\n { node, field: 'inputSchema.$' },\n );\n }\n};\n\nconst validateDefinition = (options: {\n name: string;\n title?: unknown;\n description?: unknown;\n inputSchema?: unknown;\n execute: unknown;\n}): void => {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError('Node definition must be an object.');\n }\n\n if (typeof options.name !== 'string' || options.name.trim().length === 0) {\n throw new NodeDefinitionError('Node name must be a non-empty string.');\n }\n\n validateOptionalText(options.title, 'title', options.name);\n validateOptionalText(options.description, 'description', options.name);\n validateInputSchema(options.inputSchema, options.name);\n\n if (typeof options.execute !== 'function') {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" must provide an execute function.`,\n { node: options.name },\n );\n }\n};\n\nexport function defineNode<\n TSchema extends NodeInputSchema,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeWithSchemaOptions<TSchema, TData, TContext>,\n): NodeDefinitionWithSchema<TSchema, TData, TContext>;\n\nexport function defineNode<\n TInput = unknown,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeOptions<TInput, TData, TContext>,\n): NodeDefinition<TInput, TData, TContext>;\n\nexport function defineNode(\n options: DefineNodeOptions<any, any, any>,\n): NodeDefinition<any, any, any> {\n validateDefinition(options);\n return options;\n}\n","import { z } from 'zod/v4';\nimport type { Awaitable } from '../engine/types';\nimport { NodeExecutionError } from '../errors';\nimport { defineNode } from '../node/define-node';\nimport type { NodeDefinition, NodeExecutionContext } from '../node/types';\n\ntype NodeContext<TContext> = NodeExecutionContext<unknown, TContext>;\ntype AgentGetter<TContext> = (ctx: NodeContext<TContext>) => Awaitable<unknown>;\ntype LifecycleMethod = 'launch' | 'terminate';\n\n/** Device capabilities required by Android and iOS lifecycle Nodes. */\nexport interface DeviceLifecycleAgent {\n launch(uri: string): Promise<void>;\n terminate(uri: string): Promise<void>;\n}\n\nconst lifecycleInputSchema = (\n operation: LifecycleMethod,\n description: string,\n) =>\n z\n .strictObject({\n prompt: z\n .string()\n .regex(/\\S/, 'prompt must contain a non-whitespace character')\n .optional()\n .describe(`String shorthand for the app to ${operation}.`),\n uri: z\n .string()\n .regex(/\\S/, 'uri must contain a non-whitespace character')\n .optional()\n .describe(description),\n })\n .superRefine((input, ctx) => {\n if ((input.prompt === undefined) === (input.uri === undefined)) {\n ctx.addIssue({\n code: 'custom',\n message: 'exactly one of prompt and uri is required',\n });\n }\n });\n\n/** Input schema for the device launch Node. */\nexport const launchInputSchema = lifecycleInputSchema(\n 'launch',\n 'The app, URL, URI, package name, or bundle identifier to launch.',\n);\n\n/** Input schema for the device terminate Node. */\nexport const terminateInputSchema = lifecycleInputSchema(\n 'terminate',\n 'The package name, bundle identifier, or app name to terminate.',\n);\n\nexport type LaunchNodeInput = z.infer<typeof launchInputSchema>;\nexport type TerminateNodeInput = z.infer<typeof terminateInputSchema>;\n\nconst requireLifecycleMethod = (\n agent: unknown,\n method: LifecycleMethod,\n agentName: string,\n): DeviceLifecycleAgent[LifecycleMethod] => {\n if (\n typeof agent !== 'object' ||\n agent === null ||\n typeof (agent as Record<LifecycleMethod, unknown>)[method] !== 'function'\n ) {\n throw new NodeExecutionError(\n method,\n new TypeError(`getAgent() must return ${agentName} with ${method}().`),\n );\n }\n return (agent as DeviceLifecycleAgent)[method];\n};\n\nexport const createLaunchNode = <TContext>(\n getAgent: AgentGetter<TContext>,\n agentName = 'an Agent',\n): NodeDefinition<any, any, TContext> =>\n defineNode<typeof launchInputSchema, unknown, TContext>({\n name: 'launch',\n description:\n 'Launch an app, URL, or URI through the current Midscene Agent. This Node does not install or manage applications.',\n inputSchema: launchInputSchema,\n async execute(ctx) {\n const uri = ctx.input.uri ?? ctx.input.prompt!;\n const agent = await getAgent(ctx);\n const launch = requireLifecycleMethod(agent, 'launch', agentName);\n await launch.call(agent, uri);\n return { summary: `Launched ${uri}` };\n },\n });\n\nconst createTerminateNode = <TContext>(\n getAgent: AgentGetter<TContext>,\n agentName: string,\n): NodeDefinition<any, any, TContext> =>\n defineNode<typeof terminateInputSchema, unknown, TContext>({\n name: 'terminate',\n description:\n 'Terminate an application through the current Midscene Agent. This Node does not uninstall the application or clear its data.',\n inputSchema: terminateInputSchema,\n async execute(ctx) {\n const uri = ctx.input.uri ?? ctx.input.prompt!;\n const agent = await getAgent(ctx);\n const terminate = requireLifecycleMethod(agent, 'terminate', agentName);\n await terminate.call(agent, uri);\n return { summary: `Terminated ${uri}` };\n },\n });\n\nexport const createDeviceLifecycleNodes = <TContext>(\n getAgent: (ctx: NodeContext<TContext>) => Awaitable<DeviceLifecycleAgent>,\n agentName: string,\n): readonly NodeDefinition<any, any, TContext>[] => [\n createLaunchNode(getAgent, agentName),\n createTerminateNode(getAgent, agentName),\n];\n","import { z } from 'zod/v4';\nimport { createLaunchNode } from '../device/lifecycle';\nexport type { LaunchNodeInput } from '../device/lifecycle';\nexport { launchInputSchema } from '../device/lifecycle';\nimport type { Awaitable, NodeHistoryEntry } from '../engine/types';\nimport { NodeDefinitionError, NodeExecutionError } from '../errors';\nimport { defineNode } from '../node/define-node';\nimport type {\n NodeDefinition,\n NodeExecutionContext,\n NodeResult,\n} from '../node/types';\n\nexport interface MidsceneAiActOptions {\n cacheable?: boolean;\n fileChooserAccept?: string | string[];\n deepThink?: 'unset' | boolean;\n deepLocate?: boolean;\n context?: string;\n abortSignal?: AbortSignal;\n}\n\nexport interface MidsceneAiAssertOptions {\n domIncluded?: boolean | 'visible-only';\n screenshotIncluded?: boolean;\n context?: string;\n abortSignal?: AbortSignal;\n keepRawResponse?: boolean;\n}\n\nexport interface MidscenePromptImage {\n name: string;\n url: string;\n}\n\nexport type MidsceneUserPrompt =\n | string\n | {\n prompt: string;\n images?: MidscenePromptImage[];\n convertHttpImage2Base64?: boolean;\n };\n\nexport interface MidsceneReportScreenshot {\n base64: string;\n description?: string;\n}\n\nexport interface MidsceneRecordToReportOptions {\n content?: string;\n screenshotBase64?: string;\n screenshots?: MidsceneReportScreenshot[];\n}\n\nexport interface MidsceneUIAgent {\n aiAct(\n prompt: MidsceneUserPrompt,\n options?: MidsceneAiActOptions,\n ): Promise<string | undefined>;\n aiAssert(\n prompt: MidsceneUserPrompt,\n message?: string,\n options?: MidsceneAiAssertOptions,\n ): Promise<unknown>;\n recordToReport(\n title?: string,\n options?: MidsceneRecordToReportOptions,\n ): Promise<unknown>;\n /** Available on device Agents that support launching an app, URL, or URI. */\n launch?(uri: string): Promise<void>;\n}\n\nexport interface AgentProvider<TContext> {\n getAgent(\n runId: string,\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n // biome-ignore lint/suspicious/noConfusingVoidType: providers without a report intentionally return void.\n releaseAgent?(runId: string): Awaitable<AgentReleaseResult | void>;\n dispose?(): Awaitable<void>;\n}\n\nexport interface AgentReleaseResult {\n /** Absolute path to the finalized report for this Agent scope. */\n reportPath?: string;\n}\n\nexport interface AgentExecutorInput<TContext> {\n prompt: string;\n history: readonly NodeHistoryEntry[];\n context: TContext;\n signal: AbortSignal;\n execution:\n | { scope: 'case'; runId: string }\n | { scope: 'document'; runId: string };\n}\n\nexport interface AgentExecutor<TContext> {\n // biome-ignore lint/suspicious/noConfusingVoidType: executors may perform side effects without returning a summary.\n execute(input: AgentExecutorInput<TContext>): Awaitable<NodeResult | void>;\n}\n\nconst nonBlankPrompt = (description: string) =>\n z\n .string()\n .regex(/\\S/, 'prompt must contain a non-whitespace character')\n .describe(description);\n\nconst promptImagesInputSchema = z\n .array(\n z.strictObject({\n name: nonBlankPrompt('The name used to identify this reference image.'),\n url: nonBlankPrompt(\n 'The URL, data URL, or file path of this reference image.',\n ),\n }),\n )\n .min(1)\n .optional();\n\nconst promptImageConversionInputSchema = z\n .boolean()\n .optional()\n .describe('Whether HTTP reference images are converted to base64 first.');\n\nconst aiActOptionsInputSchema = z.strictObject({\n cacheable: z\n .boolean()\n .optional()\n .describe('Whether this action may use the Midscene cache.'),\n fileChooserAccept: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('Accepted file types for a file chooser.'),\n deepThink: z\n .union([z.literal('unset'), z.boolean()])\n .optional()\n .describe('Whether to enable deep thinking for this action.'),\n deepLocate: z\n .boolean()\n .optional()\n .describe('Whether to use deep element location.'),\n context: z\n .string()\n .optional()\n .describe('Additional context supplied to the UI Agent.'),\n});\n\nexport const aiActInputSchema = z.strictObject({\n prompt: nonBlankPrompt('The natural-language UI task to perform.'),\n images: promptImagesInputSchema,\n convertHttpImage2Base64: promptImageConversionInputSchema,\n options: aiActOptionsInputSchema.optional(),\n});\n\nconst aiAssertOptionsInputSchema = z.strictObject({\n domIncluded: z\n .union([z.boolean(), z.literal('visible-only')])\n .optional()\n .describe('How DOM information is included in the assertion.'),\n screenshotIncluded: z\n .boolean()\n .optional()\n .describe('Whether the assertion includes a screenshot.'),\n context: z\n .string()\n .optional()\n .describe('Additional context supplied to the UI Agent.'),\n});\n\nexport const aiAssertInputSchema = z.strictObject({\n prompt: nonBlankPrompt('The natural-language condition that must be true.'),\n images: promptImagesInputSchema,\n convertHttpImage2Base64: promptImageConversionInputSchema,\n message: z.string().optional().describe('The assertion failure message.'),\n options: aiAssertOptionsInputSchema.optional(),\n});\n\nconst reportScreenshotInputSchema = z.strictObject({\n base64: z.string().min(1).describe('A base64-encoded screenshot.'),\n description: z.string().optional().describe('What the screenshot shows.'),\n});\n\nexport const recordToReportInputSchema = z\n .strictObject({\n prompt: z.string().optional().describe('String shorthand for the title.'),\n title: z.string().optional().describe('The report section title.'),\n content: z.string().optional().describe('The report text content.'),\n screenshotBase64: z\n .string()\n .optional()\n .describe('One base64-encoded screenshot.'),\n screenshots: z\n .array(reportScreenshotInputSchema)\n .min(1)\n .optional()\n .describe('Screenshots attached to the report section.'),\n })\n .superRefine((input, ctx) => {\n if (input.prompt !== undefined && input.title !== undefined) {\n ctx.addIssue({\n code: 'custom',\n message: 'prompt and title are mutually exclusive',\n });\n }\n if (\n input.screenshotBase64 !== undefined &&\n input.screenshots !== undefined\n ) {\n ctx.addIssue({\n code: 'custom',\n message: 'screenshotBase64 and screenshots are mutually exclusive',\n });\n }\n });\n\nexport const waitInputSchema = z.strictObject({\n duration: z.number().positive().describe('How long to wait.'),\n unit: z\n .enum(['ms', 's', 'min'])\n .default('ms')\n .describe('Duration unit: milliseconds, seconds, or minutes.'),\n});\n\nexport const agentInputSchema = z.strictObject({\n prompt: nonBlankPrompt(\n 'A self-contained task, including allowed tools and success conditions.',\n ),\n});\n\nexport type AiActNodeInput = z.infer<typeof aiActInputSchema>;\nexport type AiAssertNodeInput = z.infer<typeof aiAssertInputSchema>;\nexport type RecordToReportNodeInput = z.infer<typeof recordToReportInputSchema>;\nexport type WaitNodeInput = z.infer<typeof waitInputSchema>;\nexport type AgentNodeInput = z.infer<typeof agentInputSchema>;\n\nexport interface CreateMidsceneNodesOptions<TContext> {\n getAgent?(\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n agentProvider?: AgentProvider<TContext>;\n /** Disable when a project registers its own platform-specific launch Node. */\n includeLaunch?: boolean;\n agentExecutor?: AgentExecutor<TContext>;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst requireAgentMethod = <TMethod extends keyof MidsceneUIAgent>(\n agent: MidsceneUIAgent,\n method: TMethod,\n node: string,\n): NonNullable<MidsceneUIAgent[TMethod]> => {\n if (!isRecord(agent) || typeof agent[method] !== 'function') {\n throw new NodeExecutionError(\n node,\n new TypeError(`getAgent() must return an Agent with ${method}().`),\n );\n }\n return agent[method] as NonNullable<MidsceneUIAgent[TMethod]>;\n};\n\nconst maxHistoryContextCharacters = 64_000;\nconst maxHistoryValuePreviewCharacters = 8_000;\nconst maxHistoryEntryCharacters = 24_000;\nconst historyOmissionNoticeReserve = 256;\n\nconst compactHistoryContextValue = (value: unknown): unknown => {\n const serialized = JSON.stringify(value);\n if (\n serialized === undefined ||\n serialized.length <= maxHistoryValuePreviewCharacters\n ) {\n return value;\n }\n return {\n omittedFromContext: true,\n originalCharacters: serialized.length,\n preview:\n typeof value === 'string'\n ? value.slice(0, maxHistoryValuePreviewCharacters)\n : serialized.slice(0, maxHistoryValuePreviewCharacters),\n };\n};\n\nconst serializeHistoryEntryForContext = (\n entry: NodeHistoryEntry,\n index: number,\n): string => {\n const compacted = Object.fromEntries(\n Object.entries({ index, ...entry }).map(([key, value]) => [\n key,\n compactHistoryContextValue(value),\n ]),\n );\n const serialized = JSON.stringify(compacted);\n if (serialized.length <= maxHistoryEntryCharacters) return serialized;\n\n return JSON.stringify({\n index,\n scope: entry.scope,\n phase: entry.phase,\n stepIndex: entry.stepIndex,\n node: entry.node,\n status: entry.status,\n ...(entry.summary === undefined\n ? {}\n : { summary: compactHistoryContextValue(entry.summary) }),\n omittedFromContext: true,\n compactedCharacters: serialized.length,\n });\n};\n\nexport const renderNodeHistory = (\n history: readonly NodeHistoryEntry[],\n): string | undefined => {\n if (history.length === 0) return undefined;\n\n const heading = 'Previous workflow results (read-only):';\n const availableCharacters =\n maxHistoryContextCharacters - heading.length - historyOmissionNoticeReserve;\n const renderedEntries: string[] = [];\n let renderedCharacters = 0;\n\n for (let index = history.length - 1; index >= 0; index -= 1) {\n const rendered = serializeHistoryEntryForContext(history[index], index + 1);\n const separatorCharacters = renderedEntries.length === 0 ? 0 : 1;\n if (\n renderedCharacters + separatorCharacters + rendered.length >\n availableCharacters\n ) {\n break;\n }\n renderedEntries.unshift(rendered);\n renderedCharacters += separatorCharacters + rendered.length;\n }\n\n const omittedEntries = history.length - renderedEntries.length;\n return [\n heading,\n ...(omittedEntries === 0\n ? []\n : [\n `${omittedEntries} earlier history entr${omittedEntries === 1 ? 'y was' : 'ies were'} omitted from Agent context to stay within the size limit. Complete results remain available in the Test Runner output.`,\n ]),\n ...renderedEntries,\n ].join('\\n');\n};\n\nconst mergeContext = (\n explicit: string | undefined,\n history: readonly NodeHistoryEntry[],\n): string | undefined =>\n [explicit, renderNodeHistory(history)].filter(Boolean).join('\\n\\n') ||\n undefined;\n\nconst toAgentPrompt = (input: {\n prompt: string;\n images?: MidscenePromptImage[];\n convertHttpImage2Base64?: boolean;\n}): MidsceneUserPrompt => {\n if (\n input.images === undefined &&\n input.convertHttpImage2Base64 === undefined\n ) {\n return input.prompt;\n }\n return {\n prompt: input.prompt,\n ...(input.images === undefined ? {} : { images: input.images }),\n ...(input.convertHttpImage2Base64 === undefined\n ? {}\n : { convertHttpImage2Base64: input.convertHttpImage2Base64 }),\n };\n};\n\nconst waitFor = async (durationMs: number, signal: AbortSignal) => {\n if (signal.aborted) {\n throw signal.reason ?? new Error('Wait aborted.');\n }\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n signal.removeEventListener('abort', abort);\n resolve();\n }, durationMs);\n const abort = () => {\n clearTimeout(timeout);\n reject(signal.reason ?? new Error('Wait aborted.'));\n };\n signal.addEventListener('abort', abort, { once: true });\n });\n};\n\nexport function createMidsceneNodes<TContext>(\n options: CreateMidsceneNodesOptions<TContext>,\n): readonly NodeDefinition<any, any, TContext>[] {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() options must be an object.',\n );\n }\n if (\n typeof options.agentProvider?.getAgent !== 'function' &&\n typeof options.getAgent !== 'function'\n ) {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() requires getAgent or agentProvider.getAgent.',\n );\n }\n\n const registeredAgentScopes = new Set<string>();\n const getExecutionId = (ctx: NodeExecutionContext<unknown, TContext>) =>\n ctx.scope === 'case' ? ctx.case.runId : ctx.document.documentRunId;\n const getAgent = async (\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Promise<MidsceneUIAgent> => {\n if (!options.agentProvider) return options.getAgent!(ctx);\n const runId = getExecutionId(ctx);\n if (\n options.agentProvider.releaseAgent &&\n !registeredAgentScopes.has(runId)\n ) {\n registeredAgentScopes.add(runId);\n ctx.onTeardown(async () => {\n try {\n const released = await options.agentProvider!.releaseAgent!(runId);\n return released?.reportPath\n ? { reportPaths: [released.reportPath] }\n : undefined;\n } finally {\n registeredAgentScopes.delete(runId);\n }\n });\n }\n return options.agentProvider.getAgent(runId, ctx);\n };\n\n return [\n defineNode<typeof aiActInputSchema, unknown, TContext>({\n name: 'aiAct',\n description: 'Perform a natural-language task with a Midscene UI Agent.',\n inputSchema: aiActInputSchema,\n async execute(ctx) {\n const agent = await getAgent(ctx);\n const aiAct = requireAgentMethod(agent, 'aiAct', 'aiAct');\n const output = await aiAct.call(agent, toAgentPrompt(ctx.input), {\n ...ctx.input.options,\n context: mergeContext(ctx.input.options?.context, ctx.history),\n abortSignal: ctx.signal,\n });\n return output === undefined ? undefined : { summary: output };\n },\n }),\n defineNode<typeof aiAssertInputSchema, unknown, TContext>({\n name: 'aiAssert',\n description:\n 'Assert a natural-language condition with a Midscene UI Agent.',\n inputSchema: aiAssertInputSchema,\n async execute(ctx) {\n const agent = await getAgent(ctx);\n const aiAssert = requireAgentMethod(agent, 'aiAssert', 'aiAssert');\n await aiAssert.call(\n agent,\n toAgentPrompt(ctx.input),\n ctx.input.message,\n {\n ...ctx.input.options,\n context: mergeContext(ctx.input.options?.context, ctx.history),\n abortSignal: ctx.signal,\n },\n );\n return { summary: `Assertion passed: ${ctx.input.prompt}` };\n },\n }),\n defineNode<typeof recordToReportInputSchema, unknown, TContext>({\n name: 'recordToReport',\n description: 'Add text or screenshots to the current Midscene report.',\n inputSchema: recordToReportInputSchema,\n async execute(ctx) {\n const title = ctx.input.title ?? ctx.input.prompt;\n const reportOptions: MidsceneRecordToReportOptions = {\n ...(ctx.input.content === undefined\n ? {}\n : { content: ctx.input.content }),\n ...(ctx.input.screenshotBase64 === undefined\n ? {}\n : { screenshotBase64: ctx.input.screenshotBase64 }),\n ...(ctx.input.screenshots === undefined\n ? {}\n : { screenshots: ctx.input.screenshots }),\n };\n const agent = await getAgent(ctx);\n const recordToReport = requireAgentMethod(\n agent,\n 'recordToReport',\n 'recordToReport',\n );\n await recordToReport.call(agent, title, reportOptions);\n return { summary: `Recorded to report: ${title ?? 'untitled'}` };\n },\n }),\n ...(options.includeLaunch === false ? [] : [createLaunchNode(getAgent)]),\n defineNode<typeof waitInputSchema, unknown, TContext>({\n name: 'wait',\n description: 'Wait for a fixed duration while honoring cancellation.',\n inputSchema: waitInputSchema,\n async execute(ctx) {\n const multiplier =\n ctx.input.unit === 'min'\n ? 60_000\n : ctx.input.unit === 's'\n ? 1_000\n : 1;\n const durationMs = ctx.input.duration * multiplier;\n await waitFor(durationMs, ctx.signal);\n return { summary: `Waited ${durationMs}ms` };\n },\n }),\n defineNode<typeof agentInputSchema, unknown, TContext>({\n name: 'agent',\n description:\n 'Execute one self-contained natural-language task with an injected Agent executor.',\n inputSchema: agentInputSchema,\n async execute(ctx) {\n if (!options.agentExecutor) {\n throw new NodeExecutionError(\n 'agent',\n new TypeError('createMidsceneNodes() requires an agentExecutor.'),\n );\n }\n const execution =\n ctx.scope === 'case'\n ? { scope: 'case' as const, runId: ctx.case.runId }\n : {\n scope: 'document' as const,\n runId: ctx.document.documentRunId,\n };\n const result = await options.agentExecutor.execute({\n prompt: ctx.input.prompt,\n history: ctx.history,\n context: ctx.context,\n signal: ctx.signal,\n execution,\n });\n return result ?? { summary: 'Agent task completed.' };\n },\n }),\n ];\n}\n"],"names":["WorkflowError","Error","undefined","message","options","NodeDefinitionError","details","NodeExecutionError","node","cause","causeMessage","String","validateOptionalText","value","field","validateInputSchema","schema","z","validateDefinition","defineNode","lifecycleInputSchema","operation","description","input","ctx","launchInputSchema","requireLifecycleMethod","agent","method","agentName","TypeError","createLaunchNode","getAgent","uri","launch","nonBlankPrompt","promptImagesInputSchema","promptImageConversionInputSchema","aiActOptionsInputSchema","aiActInputSchema","aiAssertOptionsInputSchema","aiAssertInputSchema","reportScreenshotInputSchema","recordToReportInputSchema","waitInputSchema","agentInputSchema","isRecord","Array","requireAgentMethod","maxHistoryContextCharacters","maxHistoryValuePreviewCharacters","maxHistoryEntryCharacters","historyOmissionNoticeReserve","compactHistoryContextValue","serialized","JSON","serializeHistoryEntryForContext","entry","index","compacted","Object","key","renderNodeHistory","history","heading","availableCharacters","renderedEntries","renderedCharacters","rendered","separatorCharacters","omittedEntries","mergeContext","explicit","Boolean","toAgentPrompt","waitFor","durationMs","signal","Promise","resolve","reject","timeout","setTimeout","abort","clearTimeout","createMidsceneNodes","registeredAgentScopes","Set","getExecutionId","runId","released","aiAct","output","aiAssert","title","reportOptions","recordToReport","multiplier","execution","result"],"mappings":"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"}
1
+ {"version":3,"file":"midscene/index.mjs","sources":["../../../src/errors.ts","../../../src/node/define-node.ts","../../../src/device/lifecycle.ts","../../../src/midscene/index.ts"],"sourcesContent":["import type { z } from 'zod/v4';\n\nexport interface WorkflowErrorOptions {\n code?: string;\n details?: unknown;\n cause?: unknown;\n}\n\nexport class WorkflowError extends Error {\n readonly code: string;\n readonly details?: unknown;\n\n constructor(message: string, options: WorkflowErrorOptions = {}) {\n super(message, { cause: options.cause });\n this.name = new.target.name;\n this.code = options.code ?? 'WORKFLOW_ERROR';\n this.details = options.details;\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n ...(this.details === undefined ? {} : { details: this.details }),\n };\n }\n}\n\nexport class WorkflowParseError extends WorkflowError {\n constructor(message: string, details?: unknown, cause?: unknown) {\n super(message, { code: 'WORKFLOW_PARSE_ERROR', details, cause });\n }\n}\n\nexport class NodeDefinitionError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_DEFINITION_ERROR', details });\n }\n}\n\nexport class DuplicateNodeError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is already registered.`, {\n code: 'DUPLICATE_NODE',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeNotFoundError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is not registered.`, {\n code: 'NODE_NOT_FOUND',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeInputValidationError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_INPUT_VALIDATION_ERROR', details });\n }\n\n static fromZod(node: string, error: z.ZodError): NodeInputValidationError {\n const issues = error.issues.map((issue) => ({\n code: issue.code,\n path: issue.path.map(String).join('.'),\n message: issue.message,\n }));\n const firstIssue = issues[0];\n const path = firstIssue?.path || '<root>';\n const message = firstIssue?.message ?? 'invalid input';\n return new NodeInputValidationError(\n `Node \"${node}\" input validation failed at \"${path}\": ${message}`,\n { node, issues },\n );\n }\n}\n\nexport class StepTimeoutError extends WorkflowError {\n readonly timeoutMs: number;\n readonly node?: string;\n\n constructor(timeoutMs: number, node?: string) {\n super(\n node\n ? `Node \"${node}\" timed out after ${timeoutMs}ms.`\n : `Step timed out after ${timeoutMs}ms.`,\n {\n code: 'STEP_TIMEOUT',\n details: { timeoutMs, ...(node === undefined ? {} : { node }) },\n },\n );\n this.timeoutMs = timeoutMs;\n this.node = node;\n }\n}\n\nexport class NodeExecutionError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string, cause: unknown) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Node \"${node}\" failed: ${causeMessage}`, {\n code: 'NODE_EXECUTION_ERROR',\n details: { node },\n cause,\n });\n this.node = node;\n }\n}\n\nexport class WorkflowLifecycleError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'WORKFLOW_LIFECYCLE_ERROR', details });\n }\n}\n\nexport class ProjectSetupError extends WorkflowError {\n constructor(cause: unknown, details: { projectName: string }) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" setup failed: ${causeMessage}`, {\n code: 'PROJECT_SETUP_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class ProjectTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: { projectName: string; registrationIndex: number },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" teardown failed: ${causeMessage}`, {\n code: 'PROJECT_TEARDOWN_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class NodeScopeTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: {\n scope: 'case' | 'document';\n scopeId: string;\n node: string;\n registrationIndex: number;\n },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(\n `${details.scope === 'case' ? 'Case attempt' : 'Workflow document'} node teardown failed for \"${details.node}\": ${causeMessage}`,\n { code: 'NODE_SCOPE_TEARDOWN_ERROR', details, cause },\n );\n }\n}\n\nexport class FatalDeviceError extends WorkflowError {\n constructor(message: string, cause?: unknown) {\n super(message, { code: 'FATAL_DEVICE_ERROR', cause });\n }\n}\n\nexport const isFatalDeviceError = (error: unknown): boolean => {\n if (error instanceof FatalDeviceError) return true;\n if (error instanceof WorkflowError && error.code === 'FATAL_DEVICE_ERROR') {\n return true;\n }\n if (\n error instanceof Error &&\n /device offline|device not found|(?:adb|bdc|device) connection (?:was )?closed/i.test(\n error.message,\n )\n ) {\n return true;\n }\n return error instanceof Error && error.cause !== undefined\n ? isFatalDeviceError(error.cause)\n : false;\n};\n\nexport class CaseExecutionError extends WorkflowError {\n readonly result: import('./engine/types').CaseRunResult;\n\n constructor(result: import('./engine/types').CaseRunResult) {\n super(`Case \"${result.name}\" failed.`, {\n code: 'CASE_EXECUTION_FAILED',\n details: { caseId: result.caseId, runId: result.runId },\n });\n this.result = result;\n }\n}\n\nexport class WorkflowDocumentExecutionError extends WorkflowError {\n readonly result: import('./engine/types').WorkflowDocumentRunResult;\n\n constructor(result: import('./engine/types').WorkflowDocumentRunResult) {\n super(`Workflow document \"${result.sourcePath}\" failed.`, {\n code: 'WORKFLOW_DOCUMENT_EXECUTION_FAILED',\n details: {\n documentId: result.documentId,\n documentRunId: result.documentRunId,\n },\n });\n this.result = result;\n }\n}\n\nexport function normalizeNodeExecutionError(\n error: unknown,\n node: string,\n): WorkflowError {\n return error instanceof WorkflowError\n ? error\n : new NodeExecutionError(node, error);\n}\n","import { z } from 'zod/v4';\nimport { NodeDefinitionError } from '../errors';\nimport type {\n DefineNodeOptions,\n DefineNodeWithSchemaOptions,\n NodeDefinition,\n NodeDefinitionWithSchema,\n NodeInputSchema,\n} from './types';\n\nconst validateOptionalText = (\n value: unknown,\n field: 'title' | 'description',\n node: string,\n): void => {\n if (\n value !== undefined &&\n (typeof value !== 'string' || value.trim().length === 0)\n ) {\n throw new NodeDefinitionError(\n `Node \"${node}\" ${field} must be a non-empty string.`,\n { node, field },\n );\n }\n};\n\nconst validateInputSchema = (schema: unknown, node: string): void => {\n if (schema === undefined) return;\n if (!(schema instanceof z.ZodObject)) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must be a Zod object schema.`,\n { node, field: 'inputSchema' },\n );\n }\n if ('$' in schema.shape) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must not declare \"$\" as an input property.`,\n { node, field: 'inputSchema.$' },\n );\n }\n};\n\nconst validateDefinition = (options: {\n name: string;\n title?: unknown;\n description?: unknown;\n inputSchema?: unknown;\n execute: unknown;\n}): void => {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError('Node definition must be an object.');\n }\n\n if (typeof options.name !== 'string' || options.name.trim().length === 0) {\n throw new NodeDefinitionError('Node name must be a non-empty string.');\n }\n\n validateOptionalText(options.title, 'title', options.name);\n validateOptionalText(options.description, 'description', options.name);\n validateInputSchema(options.inputSchema, options.name);\n\n if (typeof options.execute !== 'function') {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" must provide an execute function.`,\n { node: options.name },\n );\n }\n};\n\nexport function defineNode<\n TSchema extends NodeInputSchema,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeWithSchemaOptions<TSchema, TData, TContext>,\n): NodeDefinitionWithSchema<TSchema, TData, TContext>;\n\nexport function defineNode<\n TInput = unknown,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeOptions<TInput, TData, TContext>,\n): NodeDefinition<TInput, TData, TContext>;\n\nexport function defineNode(\n options: DefineNodeOptions<any, any, any>,\n): NodeDefinition<any, any, any> {\n validateDefinition(options);\n return options;\n}\n","import { z } from 'zod/v4';\nimport type { Awaitable } from '../engine/types';\nimport { NodeExecutionError } from '../errors';\nimport { defineNode } from '../node/define-node';\nimport type { NodeDefinition, NodeExecutionContext } from '../node/types';\n\ntype NodeContext<TContext> = NodeExecutionContext<unknown, TContext>;\ntype AgentGetter<TContext> = (ctx: NodeContext<TContext>) => Awaitable<unknown>;\ntype LifecycleMethod = 'launch' | 'terminate';\n\n/** Device capabilities required by Android and iOS lifecycle Nodes. */\nexport interface DeviceLifecycleAgent {\n launch(uri: string): Promise<void>;\n terminate(uri: string): Promise<void>;\n}\n\nconst lifecycleInputSchema = (\n operation: LifecycleMethod,\n description: string,\n) =>\n z\n .strictObject({\n prompt: z\n .string()\n .regex(/\\S/, 'prompt must contain a non-whitespace character')\n .optional()\n .describe(`String shorthand for the app to ${operation}.`),\n uri: z\n .string()\n .regex(/\\S/, 'uri must contain a non-whitespace character')\n .optional()\n .describe(description),\n })\n .superRefine((input, ctx) => {\n if ((input.prompt === undefined) === (input.uri === undefined)) {\n ctx.addIssue({\n code: 'custom',\n message: 'exactly one of prompt and uri is required',\n });\n }\n });\n\n/** Input schema for the device launch Node. */\nexport const launchInputSchema = lifecycleInputSchema(\n 'launch',\n 'The app, URL, URI, package name, or bundle identifier to launch.',\n);\n\n/** Input schema for the device terminate Node. */\nexport const terminateInputSchema = lifecycleInputSchema(\n 'terminate',\n 'The package name, bundle identifier, or app name to terminate.',\n);\n\nexport type LaunchNodeInput = z.infer<typeof launchInputSchema>;\nexport type TerminateNodeInput = z.infer<typeof terminateInputSchema>;\n\nconst requireLifecycleMethod = (\n agent: unknown,\n method: LifecycleMethod,\n agentName: string,\n): DeviceLifecycleAgent[LifecycleMethod] => {\n if (\n typeof agent !== 'object' ||\n agent === null ||\n typeof (agent as Record<LifecycleMethod, unknown>)[method] !== 'function'\n ) {\n throw new NodeExecutionError(\n method,\n new TypeError(`getAgent() must return ${agentName} with ${method}().`),\n );\n }\n return (agent as DeviceLifecycleAgent)[method];\n};\n\nexport const createLaunchNode = <TContext>(\n getAgent: AgentGetter<TContext>,\n agentName = 'an Agent',\n): NodeDefinition<any, any, TContext> =>\n defineNode<typeof launchInputSchema, unknown, TContext>({\n name: 'launch',\n description:\n 'Launch an app, URL, or URI through the current Midscene Agent. This Node does not install or manage applications.',\n inputSchema: launchInputSchema,\n async execute(ctx) {\n const uri = ctx.input.uri ?? ctx.input.prompt!;\n const agent = await getAgent(ctx);\n const launch = requireLifecycleMethod(agent, 'launch', agentName);\n await launch.call(agent, uri);\n return { summary: `Launched ${uri}` };\n },\n });\n\nconst createTerminateNode = <TContext>(\n getAgent: AgentGetter<TContext>,\n agentName: string,\n): NodeDefinition<any, any, TContext> =>\n defineNode<typeof terminateInputSchema, unknown, TContext>({\n name: 'terminate',\n description:\n 'Terminate an application through the current Midscene Agent. This Node does not uninstall the application or clear its data.',\n inputSchema: terminateInputSchema,\n async execute(ctx) {\n const uri = ctx.input.uri ?? ctx.input.prompt!;\n const agent = await getAgent(ctx);\n const terminate = requireLifecycleMethod(agent, 'terminate', agentName);\n await terminate.call(agent, uri);\n return { summary: `Terminated ${uri}` };\n },\n });\n\nexport const createDeviceLifecycleNodes = <TContext>(\n getAgent: (ctx: NodeContext<TContext>) => Awaitable<DeviceLifecycleAgent>,\n agentName: string,\n): readonly NodeDefinition<any, any, TContext>[] => [\n createLaunchNode(getAgent, agentName),\n createTerminateNode(getAgent, agentName),\n];\n","import { z } from 'zod/v4';\nimport { createLaunchNode } from '../device/lifecycle';\nexport type { LaunchNodeInput } from '../device/lifecycle';\nexport { launchInputSchema } from '../device/lifecycle';\nimport type { Awaitable, NodeHistoryEntry } from '../engine/types';\nimport { NodeDefinitionError, NodeExecutionError } from '../errors';\nimport { defineNode } from '../node/define-node';\nimport type {\n NodeDefinition,\n NodeExecutionContext,\n NodeResult,\n} from '../node/types';\n\nexport interface MidsceneAiActOptions {\n cacheable?: boolean;\n fileChooserAccept?: string | string[];\n deepThink?: 'unset' | boolean;\n deepLocate?: boolean;\n /**\n * Additional facts, rules, constraints, or output requirements for this AI\n * call. It overrides Agent API and default contexts; `''` disables inherited\n * user context for this call.\n */\n context?: string;\n abortSignal?: AbortSignal;\n}\n\ntype MidsceneAiActInternalOptions = MidsceneAiActOptions & {\n /** Workflow history rendered by Core as a separate read-only prompt block. */\n _internalAdditionalContext?: string;\n};\n\nexport interface MidsceneAiAssertOptions {\n domIncluded?: boolean | 'visible-only';\n screenshotIncluded?: boolean;\n /**\n * Additional facts, decision rules, constraints, or output requirements for\n * this assertion. It overrides Agent API and default contexts; `''` disables\n * inherited user context for this call.\n */\n context?: string;\n abortSignal?: AbortSignal;\n keepRawResponse?: boolean;\n}\n\ntype MidsceneAiAssertInternalOptions = MidsceneAiAssertOptions & {\n /** Workflow history rendered by Core as a separate read-only prompt block. */\n _internalAdditionalContext?: string;\n};\n\nexport interface MidscenePromptImage {\n name: string;\n url: string;\n}\n\nexport type MidsceneUserPrompt =\n | string\n | {\n prompt: string;\n images?: MidscenePromptImage[];\n convertHttpImage2Base64?: boolean;\n };\n\nexport interface MidsceneReportScreenshot {\n base64: string;\n description?: string;\n}\n\nexport interface MidsceneRecordToReportOptions {\n content?: string;\n screenshotBase64?: string;\n screenshots?: MidsceneReportScreenshot[];\n}\n\nexport interface MidsceneUIAgent {\n aiAct(\n prompt: MidsceneUserPrompt,\n options?: MidsceneAiActOptions,\n ): Promise<string | undefined>;\n aiAssert(\n prompt: MidsceneUserPrompt,\n message?: string,\n options?: MidsceneAiAssertOptions,\n ): Promise<unknown>;\n recordToReport(\n title?: string,\n options?: MidsceneRecordToReportOptions,\n ): Promise<unknown>;\n /** Available on device Agents that support launching an app, URL, or URI. */\n launch?(uri: string): Promise<void>;\n}\n\nexport interface AgentProvider<TContext> {\n getAgent(\n runId: string,\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n // biome-ignore lint/suspicious/noConfusingVoidType: providers without a report intentionally return void.\n releaseAgent?(runId: string): Awaitable<AgentReleaseResult | void>;\n dispose?(): Awaitable<void>;\n}\n\nexport interface AgentReleaseResult {\n /** Absolute path to the finalized report for this Agent scope. */\n reportPath?: string;\n}\n\nexport interface AgentExecutorInput<TContext> {\n prompt: string;\n history: readonly NodeHistoryEntry[];\n context: TContext;\n signal: AbortSignal;\n execution:\n | { scope: 'case'; runId: string }\n | { scope: 'document'; runId: string };\n}\n\nexport interface AgentExecutor<TContext> {\n // biome-ignore lint/suspicious/noConfusingVoidType: executors may perform side effects without returning a summary.\n execute(input: AgentExecutorInput<TContext>): Awaitable<NodeResult | void>;\n}\n\nconst nonBlankPrompt = (description: string) =>\n z\n .string()\n .regex(/\\S/, 'prompt must contain a non-whitespace character')\n .describe(description);\n\nconst promptImagesInputSchema = z\n .array(\n z.strictObject({\n name: nonBlankPrompt('The name used to identify this reference image.'),\n url: nonBlankPrompt(\n 'The URL, data URL, or file path of this reference image.',\n ),\n }),\n )\n .min(1)\n .optional();\n\nconst promptImageConversionInputSchema = z\n .boolean()\n .optional()\n .describe('Whether HTTP reference images are converted to base64 first.');\n\nconst aiActOptionsInputSchema = z.strictObject({\n cacheable: z\n .boolean()\n .optional()\n .describe('Whether this action may use the Midscene cache.'),\n fileChooserAccept: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('Accepted file types for a file chooser.'),\n deepThink: z\n .union([z.literal('unset'), z.boolean()])\n .optional()\n .describe('Whether to enable deep thinking for this action.'),\n deepLocate: z\n .boolean()\n .optional()\n .describe('Whether to use deep element location.'),\n context: z\n .string()\n .optional()\n .describe(\n 'Additional facts, rules, constraints, or output requirements for this AI call. It overrides Agent API and default contexts; an empty string disables inherited user context.',\n ),\n});\n\nexport const aiActInputSchema = z.strictObject({\n prompt: nonBlankPrompt('The natural-language UI task to perform.'),\n images: promptImagesInputSchema,\n convertHttpImage2Base64: promptImageConversionInputSchema,\n options: aiActOptionsInputSchema.optional(),\n});\n\nconst aiAssertOptionsInputSchema = z.strictObject({\n domIncluded: z\n .union([z.boolean(), z.literal('visible-only')])\n .optional()\n .describe('How DOM information is included in the assertion.'),\n screenshotIncluded: z\n .boolean()\n .optional()\n .describe('Whether the assertion includes a screenshot.'),\n context: z\n .string()\n .optional()\n .describe(\n 'Additional facts, decision rules, constraints, or output requirements for this assertion. It overrides Agent API and default contexts; an empty string disables inherited user context.',\n ),\n});\n\nexport const aiAssertInputSchema = z.strictObject({\n prompt: nonBlankPrompt('The natural-language condition that must be true.'),\n images: promptImagesInputSchema,\n convertHttpImage2Base64: promptImageConversionInputSchema,\n message: z.string().optional().describe('The assertion failure message.'),\n options: aiAssertOptionsInputSchema.optional(),\n});\n\nconst reportScreenshotInputSchema = z.strictObject({\n base64: z.string().min(1).describe('A base64-encoded screenshot.'),\n description: z.string().optional().describe('What the screenshot shows.'),\n});\n\nexport const recordToReportInputSchema = z\n .strictObject({\n prompt: z.string().optional().describe('String shorthand for the title.'),\n title: z.string().optional().describe('The report section title.'),\n content: z.string().optional().describe('The report text content.'),\n screenshotBase64: z\n .string()\n .optional()\n .describe('One base64-encoded screenshot.'),\n screenshots: z\n .array(reportScreenshotInputSchema)\n .min(1)\n .optional()\n .describe('Screenshots attached to the report section.'),\n })\n .superRefine((input, ctx) => {\n if (input.prompt !== undefined && input.title !== undefined) {\n ctx.addIssue({\n code: 'custom',\n message: 'prompt and title are mutually exclusive',\n });\n }\n if (\n input.screenshotBase64 !== undefined &&\n input.screenshots !== undefined\n ) {\n ctx.addIssue({\n code: 'custom',\n message: 'screenshotBase64 and screenshots are mutually exclusive',\n });\n }\n });\n\nexport const waitInputSchema = z.strictObject({\n duration: z.number().positive().describe('How long to wait.'),\n unit: z\n .enum(['ms', 's', 'min'])\n .default('ms')\n .describe('Duration unit: milliseconds, seconds, or minutes.'),\n});\n\nexport const agentInputSchema = z.strictObject({\n prompt: nonBlankPrompt(\n 'A self-contained task, including allowed tools and success conditions.',\n ),\n});\n\nexport type AiActNodeInput = z.infer<typeof aiActInputSchema>;\nexport type AiAssertNodeInput = z.infer<typeof aiAssertInputSchema>;\nexport type RecordToReportNodeInput = z.infer<typeof recordToReportInputSchema>;\nexport type WaitNodeInput = z.infer<typeof waitInputSchema>;\nexport type AgentNodeInput = z.infer<typeof agentInputSchema>;\n\nexport interface CreateMidsceneNodesOptions<TContext> {\n getAgent?(\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n agentProvider?: AgentProvider<TContext>;\n /** Disable when a project registers its own platform-specific launch Node. */\n includeLaunch?: boolean;\n agentExecutor?: AgentExecutor<TContext>;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst requireAgentMethod = <TMethod extends keyof MidsceneUIAgent>(\n agent: MidsceneUIAgent,\n method: TMethod,\n node: string,\n): NonNullable<MidsceneUIAgent[TMethod]> => {\n if (!isRecord(agent) || typeof agent[method] !== 'function') {\n throw new NodeExecutionError(\n node,\n new TypeError(`getAgent() must return an Agent with ${method}().`),\n );\n }\n return agent[method] as NonNullable<MidsceneUIAgent[TMethod]>;\n};\n\nconst maxHistoryContextCharacters = 64_000;\nconst maxHistoryValuePreviewCharacters = 8_000;\nconst maxHistoryEntryCharacters = 24_000;\nconst historyOmissionNoticeReserve = 256;\n\nconst compactHistoryContextValue = (value: unknown): unknown => {\n const serialized = JSON.stringify(value);\n if (\n serialized === undefined ||\n serialized.length <= maxHistoryValuePreviewCharacters\n ) {\n return value;\n }\n return {\n omittedFromContext: true,\n originalCharacters: serialized.length,\n preview:\n typeof value === 'string'\n ? value.slice(0, maxHistoryValuePreviewCharacters)\n : serialized.slice(0, maxHistoryValuePreviewCharacters),\n };\n};\n\nconst serializeHistoryEntryForContext = (\n entry: NodeHistoryEntry,\n index: number,\n): string => {\n const compacted = Object.fromEntries(\n Object.entries({ index, ...entry }).map(([key, value]) => [\n key,\n compactHistoryContextValue(value),\n ]),\n );\n const serialized = JSON.stringify(compacted);\n if (serialized.length <= maxHistoryEntryCharacters) return serialized;\n\n return JSON.stringify({\n index,\n scope: entry.scope,\n phase: entry.phase,\n stepIndex: entry.stepIndex,\n node: entry.node,\n status: entry.status,\n ...(entry.summary === undefined\n ? {}\n : { summary: compactHistoryContextValue(entry.summary) }),\n omittedFromContext: true,\n compactedCharacters: serialized.length,\n });\n};\n\nexport const renderNodeHistory = (\n history: readonly NodeHistoryEntry[],\n): string | undefined => {\n if (history.length === 0) return undefined;\n\n const heading = 'Previous workflow results (read-only):';\n const availableCharacters =\n maxHistoryContextCharacters - heading.length - historyOmissionNoticeReserve;\n const renderedEntries: string[] = [];\n let renderedCharacters = 0;\n\n for (let index = history.length - 1; index >= 0; index -= 1) {\n const rendered = serializeHistoryEntryForContext(history[index], index + 1);\n const separatorCharacters = renderedEntries.length === 0 ? 0 : 1;\n if (\n renderedCharacters + separatorCharacters + rendered.length >\n availableCharacters\n ) {\n break;\n }\n renderedEntries.unshift(rendered);\n renderedCharacters += separatorCharacters + rendered.length;\n }\n\n const omittedEntries = history.length - renderedEntries.length;\n return [\n heading,\n ...(omittedEntries === 0\n ? []\n : [\n `${omittedEntries} earlier history entr${omittedEntries === 1 ? 'y was' : 'ies were'} omitted from Agent context to stay within the size limit. Complete results remain available in the Test Runner output.`,\n ]),\n ...renderedEntries,\n ].join('\\n');\n};\n\nconst toAgentPrompt = (input: {\n prompt: string;\n images?: MidscenePromptImage[];\n convertHttpImage2Base64?: boolean;\n}): MidsceneUserPrompt => {\n if (\n input.images === undefined &&\n input.convertHttpImage2Base64 === undefined\n ) {\n return input.prompt;\n }\n return {\n prompt: input.prompt,\n ...(input.images === undefined ? {} : { images: input.images }),\n ...(input.convertHttpImage2Base64 === undefined\n ? {}\n : { convertHttpImage2Base64: input.convertHttpImage2Base64 }),\n };\n};\n\nconst waitFor = async (durationMs: number, signal: AbortSignal) => {\n if (signal.aborted) {\n throw signal.reason ?? new Error('Wait aborted.');\n }\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n signal.removeEventListener('abort', abort);\n resolve();\n }, durationMs);\n const abort = () => {\n clearTimeout(timeout);\n reject(signal.reason ?? new Error('Wait aborted.'));\n };\n signal.addEventListener('abort', abort, { once: true });\n });\n};\n\nexport function createMidsceneNodes<TContext>(\n options: CreateMidsceneNodesOptions<TContext>,\n): readonly NodeDefinition<any, any, TContext>[] {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() options must be an object.',\n );\n }\n if (\n typeof options.agentProvider?.getAgent !== 'function' &&\n typeof options.getAgent !== 'function'\n ) {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() requires getAgent or agentProvider.getAgent.',\n );\n }\n\n const registeredAgentScopes = new Set<string>();\n const getExecutionId = (ctx: NodeExecutionContext<unknown, TContext>) =>\n ctx.scope === 'case' ? ctx.case.runId : ctx.document.documentRunId;\n const getAgent = async (\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Promise<MidsceneUIAgent> => {\n if (!options.agentProvider) return options.getAgent!(ctx);\n const runId = getExecutionId(ctx);\n if (\n options.agentProvider.releaseAgent &&\n !registeredAgentScopes.has(runId)\n ) {\n registeredAgentScopes.add(runId);\n ctx.onTeardown(async () => {\n try {\n const released = await options.agentProvider!.releaseAgent!(runId);\n return released?.reportPath\n ? { reportPaths: [released.reportPath] }\n : undefined;\n } finally {\n registeredAgentScopes.delete(runId);\n }\n });\n }\n return options.agentProvider.getAgent(runId, ctx);\n };\n\n return [\n defineNode<typeof aiActInputSchema, unknown, TContext>({\n name: 'aiAct',\n description: 'Perform a natural-language task with a Midscene UI Agent.',\n inputSchema: aiActInputSchema,\n async execute(ctx) {\n const agent = await getAgent(ctx);\n const aiAct = requireAgentMethod(agent, 'aiAct', 'aiAct');\n const additionalContext = renderNodeHistory(ctx.history);\n const aiActOptions: MidsceneAiActInternalOptions = {\n ...ctx.input.options,\n abortSignal: ctx.signal,\n ...(additionalContext === undefined\n ? {}\n : { _internalAdditionalContext: additionalContext }),\n };\n const output = await aiAct.call(\n agent,\n toAgentPrompt(ctx.input),\n aiActOptions,\n );\n return output === undefined ? undefined : { summary: output };\n },\n }),\n defineNode<typeof aiAssertInputSchema, unknown, TContext>({\n name: 'aiAssert',\n description:\n 'Assert a natural-language condition with a Midscene UI Agent.',\n inputSchema: aiAssertInputSchema,\n async execute(ctx) {\n const agent = await getAgent(ctx);\n const aiAssert = requireAgentMethod(agent, 'aiAssert', 'aiAssert');\n const additionalContext = renderNodeHistory(ctx.history);\n const aiAssertOptions: MidsceneAiAssertInternalOptions = {\n ...ctx.input.options,\n abortSignal: ctx.signal,\n ...(additionalContext === undefined\n ? {}\n : { _internalAdditionalContext: additionalContext }),\n };\n await aiAssert.call(\n agent,\n toAgentPrompt(ctx.input),\n ctx.input.message,\n aiAssertOptions,\n );\n return { summary: `Assertion passed: ${ctx.input.prompt}` };\n },\n }),\n defineNode<typeof recordToReportInputSchema, unknown, TContext>({\n name: 'recordToReport',\n description: 'Add text or screenshots to the current Midscene report.',\n inputSchema: recordToReportInputSchema,\n async execute(ctx) {\n const title = ctx.input.title ?? ctx.input.prompt;\n const reportOptions: MidsceneRecordToReportOptions = {\n ...(ctx.input.content === undefined\n ? {}\n : { content: ctx.input.content }),\n ...(ctx.input.screenshotBase64 === undefined\n ? {}\n : { screenshotBase64: ctx.input.screenshotBase64 }),\n ...(ctx.input.screenshots === undefined\n ? {}\n : { screenshots: ctx.input.screenshots }),\n };\n const agent = await getAgent(ctx);\n const recordToReport = requireAgentMethod(\n agent,\n 'recordToReport',\n 'recordToReport',\n );\n await recordToReport.call(agent, title, reportOptions);\n return { summary: `Recorded to report: ${title ?? 'untitled'}` };\n },\n }),\n ...(options.includeLaunch === false ? [] : [createLaunchNode(getAgent)]),\n defineNode<typeof waitInputSchema, unknown, TContext>({\n name: 'wait',\n description: 'Wait for a fixed duration while honoring cancellation.',\n inputSchema: waitInputSchema,\n async execute(ctx) {\n const multiplier =\n ctx.input.unit === 'min'\n ? 60_000\n : ctx.input.unit === 's'\n ? 1_000\n : 1;\n const durationMs = ctx.input.duration * multiplier;\n await waitFor(durationMs, ctx.signal);\n return { summary: `Waited ${durationMs}ms` };\n },\n }),\n defineNode<typeof agentInputSchema, unknown, TContext>({\n name: 'agent',\n description:\n 'Execute one self-contained natural-language task with an injected Agent executor.',\n inputSchema: agentInputSchema,\n async execute(ctx) {\n if (!options.agentExecutor) {\n throw new NodeExecutionError(\n 'agent',\n new TypeError('createMidsceneNodes() requires an agentExecutor.'),\n );\n }\n const execution =\n ctx.scope === 'case'\n ? { scope: 'case' as const, runId: ctx.case.runId }\n : {\n scope: 'document' as const,\n runId: ctx.document.documentRunId,\n };\n const result = await options.agentExecutor.execute({\n prompt: ctx.input.prompt,\n history: ctx.history,\n context: ctx.context,\n signal: ctx.signal,\n execution,\n });\n return result ?? { summary: 'Agent task completed.' };\n },\n }),\n ];\n}\n"],"names":["WorkflowError","Error","undefined","message","options","NodeDefinitionError","details","NodeExecutionError","node","cause","causeMessage","String","validateOptionalText","value","field","validateInputSchema","schema","z","validateDefinition","defineNode","lifecycleInputSchema","operation","description","input","ctx","launchInputSchema","requireLifecycleMethod","agent","method","agentName","TypeError","createLaunchNode","getAgent","uri","launch","nonBlankPrompt","promptImagesInputSchema","promptImageConversionInputSchema","aiActOptionsInputSchema","aiActInputSchema","aiAssertOptionsInputSchema","aiAssertInputSchema","reportScreenshotInputSchema","recordToReportInputSchema","waitInputSchema","agentInputSchema","isRecord","Array","requireAgentMethod","maxHistoryContextCharacters","maxHistoryValuePreviewCharacters","maxHistoryEntryCharacters","historyOmissionNoticeReserve","compactHistoryContextValue","serialized","JSON","serializeHistoryEntryForContext","entry","index","compacted","Object","key","renderNodeHistory","history","heading","availableCharacters","renderedEntries","renderedCharacters","rendered","separatorCharacters","omittedEntries","toAgentPrompt","waitFor","durationMs","signal","Promise","resolve","reject","timeout","setTimeout","abort","clearTimeout","createMidsceneNodes","registeredAgentScopes","Set","getExecutionId","runId","released","aiAct","additionalContext","aiActOptions","output","aiAssert","aiAssertOptions","title","reportOptions","recordToReport","multiplier","execution","result"],"mappings":"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"}
@@ -162,7 +162,7 @@ const aiActOptionsInputSchema = v4_namespaceObject.z.strictObject({
162
162
  v4_namespaceObject.z.boolean()
163
163
  ]).optional().describe('Whether to enable deep thinking for this action.'),
164
164
  deepLocate: v4_namespaceObject.z.boolean().optional().describe('Whether to use deep element location.'),
165
- context: v4_namespaceObject.z.string().optional().describe('Additional context supplied to the UI Agent.')
165
+ context: v4_namespaceObject.z.string().optional().describe('Additional facts, rules, constraints, or output requirements for this AI call. It overrides Agent API and default contexts; an empty string disables inherited user context.')
166
166
  });
167
167
  const aiActInputSchema = v4_namespaceObject.z.strictObject({
168
168
  prompt: nonBlankPrompt('The natural-language UI task to perform.'),
@@ -176,7 +176,7 @@ const aiAssertOptionsInputSchema = v4_namespaceObject.z.strictObject({
176
176
  v4_namespaceObject.z.literal('visible-only')
177
177
  ]).optional().describe('How DOM information is included in the assertion.'),
178
178
  screenshotIncluded: v4_namespaceObject.z.boolean().optional().describe('Whether the assertion includes a screenshot.'),
179
- context: v4_namespaceObject.z.string().optional().describe('Additional context supplied to the UI Agent.')
179
+ context: v4_namespaceObject.z.string().optional().describe('Additional facts, decision rules, constraints, or output requirements for this assertion. It overrides Agent API and default contexts; an empty string disables inherited user context.')
180
180
  });
181
181
  const aiAssertInputSchema = v4_namespaceObject.z.strictObject({
182
182
  prompt: nonBlankPrompt('The natural-language condition that must be true.'),
@@ -280,10 +280,6 @@ const renderNodeHistory = (history)=>{
280
280
  ...renderedEntries
281
281
  ].join('\n');
282
282
  };
283
- const mergeContext = (explicit, history)=>[
284
- explicit,
285
- renderNodeHistory(history)
286
- ].filter(Boolean).join('\n\n') || void 0;
287
283
  const toAgentPrompt = (input)=>{
288
284
  if (void 0 === input.images && void 0 === input.convertHttpImage2Base64) return input.prompt;
289
285
  return {
@@ -345,11 +341,15 @@ function createMidsceneNodes(options) {
345
341
  async execute (ctx) {
346
342
  const agent = await getAgent(ctx);
347
343
  const aiAct = requireAgentMethod(agent, 'aiAct', 'aiAct');
348
- const output = await aiAct.call(agent, toAgentPrompt(ctx.input), {
344
+ const additionalContext = renderNodeHistory(ctx.history);
345
+ const aiActOptions = {
349
346
  ...ctx.input.options,
350
- context: mergeContext(ctx.input.options?.context, ctx.history),
351
- abortSignal: ctx.signal
352
- });
347
+ abortSignal: ctx.signal,
348
+ ...void 0 === additionalContext ? {} : {
349
+ _internalAdditionalContext: additionalContext
350
+ }
351
+ };
352
+ const output = await aiAct.call(agent, toAgentPrompt(ctx.input), aiActOptions);
353
353
  return void 0 === output ? void 0 : {
354
354
  summary: output
355
355
  };
@@ -362,11 +362,15 @@ function createMidsceneNodes(options) {
362
362
  async execute (ctx) {
363
363
  const agent = await getAgent(ctx);
364
364
  const aiAssert = requireAgentMethod(agent, 'aiAssert', 'aiAssert');
365
- await aiAssert.call(agent, toAgentPrompt(ctx.input), ctx.input.message, {
365
+ const additionalContext = renderNodeHistory(ctx.history);
366
+ const aiAssertOptions = {
366
367
  ...ctx.input.options,
367
- context: mergeContext(ctx.input.options?.context, ctx.history),
368
- abortSignal: ctx.signal
369
- });
368
+ abortSignal: ctx.signal,
369
+ ...void 0 === additionalContext ? {} : {
370
+ _internalAdditionalContext: additionalContext
371
+ }
372
+ };
373
+ await aiAssert.call(agent, toAgentPrompt(ctx.input), ctx.input.message, aiAssertOptions);
370
374
  return {
371
375
  summary: `Assertion passed: ${ctx.input.prompt}`
372
376
  };
@@ -1 +1 @@
1
- {"version":3,"file":"midscene/index.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/errors.ts","../../../src/node/define-node.ts","../../../src/device/lifecycle.ts","../../../src/midscene/index.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 { z } from 'zod/v4';\n\nexport interface WorkflowErrorOptions {\n code?: string;\n details?: unknown;\n cause?: unknown;\n}\n\nexport class WorkflowError extends Error {\n readonly code: string;\n readonly details?: unknown;\n\n constructor(message: string, options: WorkflowErrorOptions = {}) {\n super(message, { cause: options.cause });\n this.name = new.target.name;\n this.code = options.code ?? 'WORKFLOW_ERROR';\n this.details = options.details;\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n ...(this.details === undefined ? {} : { details: this.details }),\n };\n }\n}\n\nexport class WorkflowParseError extends WorkflowError {\n constructor(message: string, details?: unknown, cause?: unknown) {\n super(message, { code: 'WORKFLOW_PARSE_ERROR', details, cause });\n }\n}\n\nexport class NodeDefinitionError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_DEFINITION_ERROR', details });\n }\n}\n\nexport class DuplicateNodeError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is already registered.`, {\n code: 'DUPLICATE_NODE',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeNotFoundError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is not registered.`, {\n code: 'NODE_NOT_FOUND',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeInputValidationError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_INPUT_VALIDATION_ERROR', details });\n }\n\n static fromZod(node: string, error: z.ZodError): NodeInputValidationError {\n const issues = error.issues.map((issue) => ({\n code: issue.code,\n path: issue.path.map(String).join('.'),\n message: issue.message,\n }));\n const firstIssue = issues[0];\n const path = firstIssue?.path || '<root>';\n const message = firstIssue?.message ?? 'invalid input';\n return new NodeInputValidationError(\n `Node \"${node}\" input validation failed at \"${path}\": ${message}`,\n { node, issues },\n );\n }\n}\n\nexport class StepTimeoutError extends WorkflowError {\n readonly timeoutMs: number;\n readonly node?: string;\n\n constructor(timeoutMs: number, node?: string) {\n super(\n node\n ? `Node \"${node}\" timed out after ${timeoutMs}ms.`\n : `Step timed out after ${timeoutMs}ms.`,\n {\n code: 'STEP_TIMEOUT',\n details: { timeoutMs, ...(node === undefined ? {} : { node }) },\n },\n );\n this.timeoutMs = timeoutMs;\n this.node = node;\n }\n}\n\nexport class NodeExecutionError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string, cause: unknown) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Node \"${node}\" failed: ${causeMessage}`, {\n code: 'NODE_EXECUTION_ERROR',\n details: { node },\n cause,\n });\n this.node = node;\n }\n}\n\nexport class WorkflowLifecycleError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'WORKFLOW_LIFECYCLE_ERROR', details });\n }\n}\n\nexport class ProjectSetupError extends WorkflowError {\n constructor(cause: unknown, details: { projectName: string }) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" setup failed: ${causeMessage}`, {\n code: 'PROJECT_SETUP_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class ProjectTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: { projectName: string; registrationIndex: number },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" teardown failed: ${causeMessage}`, {\n code: 'PROJECT_TEARDOWN_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class NodeScopeTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: {\n scope: 'case' | 'document';\n scopeId: string;\n node: string;\n registrationIndex: number;\n },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(\n `${details.scope === 'case' ? 'Case attempt' : 'Workflow document'} node teardown failed for \"${details.node}\": ${causeMessage}`,\n { code: 'NODE_SCOPE_TEARDOWN_ERROR', details, cause },\n );\n }\n}\n\nexport class FatalDeviceError extends WorkflowError {\n constructor(message: string, cause?: unknown) {\n super(message, { code: 'FATAL_DEVICE_ERROR', cause });\n }\n}\n\nexport const isFatalDeviceError = (error: unknown): boolean => {\n if (error instanceof FatalDeviceError) return true;\n if (error instanceof WorkflowError && error.code === 'FATAL_DEVICE_ERROR') {\n return true;\n }\n if (\n error instanceof Error &&\n /device offline|device not found|(?:adb|bdc|device) connection (?:was )?closed/i.test(\n error.message,\n )\n ) {\n return true;\n }\n return error instanceof Error && error.cause !== undefined\n ? isFatalDeviceError(error.cause)\n : false;\n};\n\nexport class CaseExecutionError extends WorkflowError {\n readonly result: import('./engine/types').CaseRunResult;\n\n constructor(result: import('./engine/types').CaseRunResult) {\n super(`Case \"${result.name}\" failed.`, {\n code: 'CASE_EXECUTION_FAILED',\n details: { caseId: result.caseId, runId: result.runId },\n });\n this.result = result;\n }\n}\n\nexport class WorkflowDocumentExecutionError extends WorkflowError {\n readonly result: import('./engine/types').WorkflowDocumentRunResult;\n\n constructor(result: import('./engine/types').WorkflowDocumentRunResult) {\n super(`Workflow document \"${result.sourcePath}\" failed.`, {\n code: 'WORKFLOW_DOCUMENT_EXECUTION_FAILED',\n details: {\n documentId: result.documentId,\n documentRunId: result.documentRunId,\n },\n });\n this.result = result;\n }\n}\n\nexport function normalizeNodeExecutionError(\n error: unknown,\n node: string,\n): WorkflowError {\n return error instanceof WorkflowError\n ? error\n : new NodeExecutionError(node, error);\n}\n","import { z } from 'zod/v4';\nimport { NodeDefinitionError } from '../errors';\nimport type {\n DefineNodeOptions,\n DefineNodeWithSchemaOptions,\n NodeDefinition,\n NodeDefinitionWithSchema,\n NodeInputSchema,\n} from './types';\n\nconst validateOptionalText = (\n value: unknown,\n field: 'title' | 'description',\n node: string,\n): void => {\n if (\n value !== undefined &&\n (typeof value !== 'string' || value.trim().length === 0)\n ) {\n throw new NodeDefinitionError(\n `Node \"${node}\" ${field} must be a non-empty string.`,\n { node, field },\n );\n }\n};\n\nconst validateInputSchema = (schema: unknown, node: string): void => {\n if (schema === undefined) return;\n if (!(schema instanceof z.ZodObject)) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must be a Zod object schema.`,\n { node, field: 'inputSchema' },\n );\n }\n if ('$' in schema.shape) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must not declare \"$\" as an input property.`,\n { node, field: 'inputSchema.$' },\n );\n }\n};\n\nconst validateDefinition = (options: {\n name: string;\n title?: unknown;\n description?: unknown;\n inputSchema?: unknown;\n execute: unknown;\n}): void => {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError('Node definition must be an object.');\n }\n\n if (typeof options.name !== 'string' || options.name.trim().length === 0) {\n throw new NodeDefinitionError('Node name must be a non-empty string.');\n }\n\n validateOptionalText(options.title, 'title', options.name);\n validateOptionalText(options.description, 'description', options.name);\n validateInputSchema(options.inputSchema, options.name);\n\n if (typeof options.execute !== 'function') {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" must provide an execute function.`,\n { node: options.name },\n );\n }\n};\n\nexport function defineNode<\n TSchema extends NodeInputSchema,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeWithSchemaOptions<TSchema, TData, TContext>,\n): NodeDefinitionWithSchema<TSchema, TData, TContext>;\n\nexport function defineNode<\n TInput = unknown,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeOptions<TInput, TData, TContext>,\n): NodeDefinition<TInput, TData, TContext>;\n\nexport function defineNode(\n options: DefineNodeOptions<any, any, any>,\n): NodeDefinition<any, any, any> {\n validateDefinition(options);\n return options;\n}\n","import { z } from 'zod/v4';\nimport type { Awaitable } from '../engine/types';\nimport { NodeExecutionError } from '../errors';\nimport { defineNode } from '../node/define-node';\nimport type { NodeDefinition, NodeExecutionContext } from '../node/types';\n\ntype NodeContext<TContext> = NodeExecutionContext<unknown, TContext>;\ntype AgentGetter<TContext> = (ctx: NodeContext<TContext>) => Awaitable<unknown>;\ntype LifecycleMethod = 'launch' | 'terminate';\n\n/** Device capabilities required by Android and iOS lifecycle Nodes. */\nexport interface DeviceLifecycleAgent {\n launch(uri: string): Promise<void>;\n terminate(uri: string): Promise<void>;\n}\n\nconst lifecycleInputSchema = (\n operation: LifecycleMethod,\n description: string,\n) =>\n z\n .strictObject({\n prompt: z\n .string()\n .regex(/\\S/, 'prompt must contain a non-whitespace character')\n .optional()\n .describe(`String shorthand for the app to ${operation}.`),\n uri: z\n .string()\n .regex(/\\S/, 'uri must contain a non-whitespace character')\n .optional()\n .describe(description),\n })\n .superRefine((input, ctx) => {\n if ((input.prompt === undefined) === (input.uri === undefined)) {\n ctx.addIssue({\n code: 'custom',\n message: 'exactly one of prompt and uri is required',\n });\n }\n });\n\n/** Input schema for the device launch Node. */\nexport const launchInputSchema = lifecycleInputSchema(\n 'launch',\n 'The app, URL, URI, package name, or bundle identifier to launch.',\n);\n\n/** Input schema for the device terminate Node. */\nexport const terminateInputSchema = lifecycleInputSchema(\n 'terminate',\n 'The package name, bundle identifier, or app name to terminate.',\n);\n\nexport type LaunchNodeInput = z.infer<typeof launchInputSchema>;\nexport type TerminateNodeInput = z.infer<typeof terminateInputSchema>;\n\nconst requireLifecycleMethod = (\n agent: unknown,\n method: LifecycleMethod,\n agentName: string,\n): DeviceLifecycleAgent[LifecycleMethod] => {\n if (\n typeof agent !== 'object' ||\n agent === null ||\n typeof (agent as Record<LifecycleMethod, unknown>)[method] !== 'function'\n ) {\n throw new NodeExecutionError(\n method,\n new TypeError(`getAgent() must return ${agentName} with ${method}().`),\n );\n }\n return (agent as DeviceLifecycleAgent)[method];\n};\n\nexport const createLaunchNode = <TContext>(\n getAgent: AgentGetter<TContext>,\n agentName = 'an Agent',\n): NodeDefinition<any, any, TContext> =>\n defineNode<typeof launchInputSchema, unknown, TContext>({\n name: 'launch',\n description:\n 'Launch an app, URL, or URI through the current Midscene Agent. This Node does not install or manage applications.',\n inputSchema: launchInputSchema,\n async execute(ctx) {\n const uri = ctx.input.uri ?? ctx.input.prompt!;\n const agent = await getAgent(ctx);\n const launch = requireLifecycleMethod(agent, 'launch', agentName);\n await launch.call(agent, uri);\n return { summary: `Launched ${uri}` };\n },\n });\n\nconst createTerminateNode = <TContext>(\n getAgent: AgentGetter<TContext>,\n agentName: string,\n): NodeDefinition<any, any, TContext> =>\n defineNode<typeof terminateInputSchema, unknown, TContext>({\n name: 'terminate',\n description:\n 'Terminate an application through the current Midscene Agent. This Node does not uninstall the application or clear its data.',\n inputSchema: terminateInputSchema,\n async execute(ctx) {\n const uri = ctx.input.uri ?? ctx.input.prompt!;\n const agent = await getAgent(ctx);\n const terminate = requireLifecycleMethod(agent, 'terminate', agentName);\n await terminate.call(agent, uri);\n return { summary: `Terminated ${uri}` };\n },\n });\n\nexport const createDeviceLifecycleNodes = <TContext>(\n getAgent: (ctx: NodeContext<TContext>) => Awaitable<DeviceLifecycleAgent>,\n agentName: string,\n): readonly NodeDefinition<any, any, TContext>[] => [\n createLaunchNode(getAgent, agentName),\n createTerminateNode(getAgent, agentName),\n];\n","import { z } from 'zod/v4';\nimport { createLaunchNode } from '../device/lifecycle';\nexport type { LaunchNodeInput } from '../device/lifecycle';\nexport { launchInputSchema } from '../device/lifecycle';\nimport type { Awaitable, NodeHistoryEntry } from '../engine/types';\nimport { NodeDefinitionError, NodeExecutionError } from '../errors';\nimport { defineNode } from '../node/define-node';\nimport type {\n NodeDefinition,\n NodeExecutionContext,\n NodeResult,\n} from '../node/types';\n\nexport interface MidsceneAiActOptions {\n cacheable?: boolean;\n fileChooserAccept?: string | string[];\n deepThink?: 'unset' | boolean;\n deepLocate?: boolean;\n context?: string;\n abortSignal?: AbortSignal;\n}\n\nexport interface MidsceneAiAssertOptions {\n domIncluded?: boolean | 'visible-only';\n screenshotIncluded?: boolean;\n context?: string;\n abortSignal?: AbortSignal;\n keepRawResponse?: boolean;\n}\n\nexport interface MidscenePromptImage {\n name: string;\n url: string;\n}\n\nexport type MidsceneUserPrompt =\n | string\n | {\n prompt: string;\n images?: MidscenePromptImage[];\n convertHttpImage2Base64?: boolean;\n };\n\nexport interface MidsceneReportScreenshot {\n base64: string;\n description?: string;\n}\n\nexport interface MidsceneRecordToReportOptions {\n content?: string;\n screenshotBase64?: string;\n screenshots?: MidsceneReportScreenshot[];\n}\n\nexport interface MidsceneUIAgent {\n aiAct(\n prompt: MidsceneUserPrompt,\n options?: MidsceneAiActOptions,\n ): Promise<string | undefined>;\n aiAssert(\n prompt: MidsceneUserPrompt,\n message?: string,\n options?: MidsceneAiAssertOptions,\n ): Promise<unknown>;\n recordToReport(\n title?: string,\n options?: MidsceneRecordToReportOptions,\n ): Promise<unknown>;\n /** Available on device Agents that support launching an app, URL, or URI. */\n launch?(uri: string): Promise<void>;\n}\n\nexport interface AgentProvider<TContext> {\n getAgent(\n runId: string,\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n // biome-ignore lint/suspicious/noConfusingVoidType: providers without a report intentionally return void.\n releaseAgent?(runId: string): Awaitable<AgentReleaseResult | void>;\n dispose?(): Awaitable<void>;\n}\n\nexport interface AgentReleaseResult {\n /** Absolute path to the finalized report for this Agent scope. */\n reportPath?: string;\n}\n\nexport interface AgentExecutorInput<TContext> {\n prompt: string;\n history: readonly NodeHistoryEntry[];\n context: TContext;\n signal: AbortSignal;\n execution:\n | { scope: 'case'; runId: string }\n | { scope: 'document'; runId: string };\n}\n\nexport interface AgentExecutor<TContext> {\n // biome-ignore lint/suspicious/noConfusingVoidType: executors may perform side effects without returning a summary.\n execute(input: AgentExecutorInput<TContext>): Awaitable<NodeResult | void>;\n}\n\nconst nonBlankPrompt = (description: string) =>\n z\n .string()\n .regex(/\\S/, 'prompt must contain a non-whitespace character')\n .describe(description);\n\nconst promptImagesInputSchema = z\n .array(\n z.strictObject({\n name: nonBlankPrompt('The name used to identify this reference image.'),\n url: nonBlankPrompt(\n 'The URL, data URL, or file path of this reference image.',\n ),\n }),\n )\n .min(1)\n .optional();\n\nconst promptImageConversionInputSchema = z\n .boolean()\n .optional()\n .describe('Whether HTTP reference images are converted to base64 first.');\n\nconst aiActOptionsInputSchema = z.strictObject({\n cacheable: z\n .boolean()\n .optional()\n .describe('Whether this action may use the Midscene cache.'),\n fileChooserAccept: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('Accepted file types for a file chooser.'),\n deepThink: z\n .union([z.literal('unset'), z.boolean()])\n .optional()\n .describe('Whether to enable deep thinking for this action.'),\n deepLocate: z\n .boolean()\n .optional()\n .describe('Whether to use deep element location.'),\n context: z\n .string()\n .optional()\n .describe('Additional context supplied to the UI Agent.'),\n});\n\nexport const aiActInputSchema = z.strictObject({\n prompt: nonBlankPrompt('The natural-language UI task to perform.'),\n images: promptImagesInputSchema,\n convertHttpImage2Base64: promptImageConversionInputSchema,\n options: aiActOptionsInputSchema.optional(),\n});\n\nconst aiAssertOptionsInputSchema = z.strictObject({\n domIncluded: z\n .union([z.boolean(), z.literal('visible-only')])\n .optional()\n .describe('How DOM information is included in the assertion.'),\n screenshotIncluded: z\n .boolean()\n .optional()\n .describe('Whether the assertion includes a screenshot.'),\n context: z\n .string()\n .optional()\n .describe('Additional context supplied to the UI Agent.'),\n});\n\nexport const aiAssertInputSchema = z.strictObject({\n prompt: nonBlankPrompt('The natural-language condition that must be true.'),\n images: promptImagesInputSchema,\n convertHttpImage2Base64: promptImageConversionInputSchema,\n message: z.string().optional().describe('The assertion failure message.'),\n options: aiAssertOptionsInputSchema.optional(),\n});\n\nconst reportScreenshotInputSchema = z.strictObject({\n base64: z.string().min(1).describe('A base64-encoded screenshot.'),\n description: z.string().optional().describe('What the screenshot shows.'),\n});\n\nexport const recordToReportInputSchema = z\n .strictObject({\n prompt: z.string().optional().describe('String shorthand for the title.'),\n title: z.string().optional().describe('The report section title.'),\n content: z.string().optional().describe('The report text content.'),\n screenshotBase64: z\n .string()\n .optional()\n .describe('One base64-encoded screenshot.'),\n screenshots: z\n .array(reportScreenshotInputSchema)\n .min(1)\n .optional()\n .describe('Screenshots attached to the report section.'),\n })\n .superRefine((input, ctx) => {\n if (input.prompt !== undefined && input.title !== undefined) {\n ctx.addIssue({\n code: 'custom',\n message: 'prompt and title are mutually exclusive',\n });\n }\n if (\n input.screenshotBase64 !== undefined &&\n input.screenshots !== undefined\n ) {\n ctx.addIssue({\n code: 'custom',\n message: 'screenshotBase64 and screenshots are mutually exclusive',\n });\n }\n });\n\nexport const waitInputSchema = z.strictObject({\n duration: z.number().positive().describe('How long to wait.'),\n unit: z\n .enum(['ms', 's', 'min'])\n .default('ms')\n .describe('Duration unit: milliseconds, seconds, or minutes.'),\n});\n\nexport const agentInputSchema = z.strictObject({\n prompt: nonBlankPrompt(\n 'A self-contained task, including allowed tools and success conditions.',\n ),\n});\n\nexport type AiActNodeInput = z.infer<typeof aiActInputSchema>;\nexport type AiAssertNodeInput = z.infer<typeof aiAssertInputSchema>;\nexport type RecordToReportNodeInput = z.infer<typeof recordToReportInputSchema>;\nexport type WaitNodeInput = z.infer<typeof waitInputSchema>;\nexport type AgentNodeInput = z.infer<typeof agentInputSchema>;\n\nexport interface CreateMidsceneNodesOptions<TContext> {\n getAgent?(\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n agentProvider?: AgentProvider<TContext>;\n /** Disable when a project registers its own platform-specific launch Node. */\n includeLaunch?: boolean;\n agentExecutor?: AgentExecutor<TContext>;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst requireAgentMethod = <TMethod extends keyof MidsceneUIAgent>(\n agent: MidsceneUIAgent,\n method: TMethod,\n node: string,\n): NonNullable<MidsceneUIAgent[TMethod]> => {\n if (!isRecord(agent) || typeof agent[method] !== 'function') {\n throw new NodeExecutionError(\n node,\n new TypeError(`getAgent() must return an Agent with ${method}().`),\n );\n }\n return agent[method] as NonNullable<MidsceneUIAgent[TMethod]>;\n};\n\nconst maxHistoryContextCharacters = 64_000;\nconst maxHistoryValuePreviewCharacters = 8_000;\nconst maxHistoryEntryCharacters = 24_000;\nconst historyOmissionNoticeReserve = 256;\n\nconst compactHistoryContextValue = (value: unknown): unknown => {\n const serialized = JSON.stringify(value);\n if (\n serialized === undefined ||\n serialized.length <= maxHistoryValuePreviewCharacters\n ) {\n return value;\n }\n return {\n omittedFromContext: true,\n originalCharacters: serialized.length,\n preview:\n typeof value === 'string'\n ? value.slice(0, maxHistoryValuePreviewCharacters)\n : serialized.slice(0, maxHistoryValuePreviewCharacters),\n };\n};\n\nconst serializeHistoryEntryForContext = (\n entry: NodeHistoryEntry,\n index: number,\n): string => {\n const compacted = Object.fromEntries(\n Object.entries({ index, ...entry }).map(([key, value]) => [\n key,\n compactHistoryContextValue(value),\n ]),\n );\n const serialized = JSON.stringify(compacted);\n if (serialized.length <= maxHistoryEntryCharacters) return serialized;\n\n return JSON.stringify({\n index,\n scope: entry.scope,\n phase: entry.phase,\n stepIndex: entry.stepIndex,\n node: entry.node,\n status: entry.status,\n ...(entry.summary === undefined\n ? {}\n : { summary: compactHistoryContextValue(entry.summary) }),\n omittedFromContext: true,\n compactedCharacters: serialized.length,\n });\n};\n\nexport const renderNodeHistory = (\n history: readonly NodeHistoryEntry[],\n): string | undefined => {\n if (history.length === 0) return undefined;\n\n const heading = 'Previous workflow results (read-only):';\n const availableCharacters =\n maxHistoryContextCharacters - heading.length - historyOmissionNoticeReserve;\n const renderedEntries: string[] = [];\n let renderedCharacters = 0;\n\n for (let index = history.length - 1; index >= 0; index -= 1) {\n const rendered = serializeHistoryEntryForContext(history[index], index + 1);\n const separatorCharacters = renderedEntries.length === 0 ? 0 : 1;\n if (\n renderedCharacters + separatorCharacters + rendered.length >\n availableCharacters\n ) {\n break;\n }\n renderedEntries.unshift(rendered);\n renderedCharacters += separatorCharacters + rendered.length;\n }\n\n const omittedEntries = history.length - renderedEntries.length;\n return [\n heading,\n ...(omittedEntries === 0\n ? []\n : [\n `${omittedEntries} earlier history entr${omittedEntries === 1 ? 'y was' : 'ies were'} omitted from Agent context to stay within the size limit. Complete results remain available in the Test Runner output.`,\n ]),\n ...renderedEntries,\n ].join('\\n');\n};\n\nconst mergeContext = (\n explicit: string | undefined,\n history: readonly NodeHistoryEntry[],\n): string | undefined =>\n [explicit, renderNodeHistory(history)].filter(Boolean).join('\\n\\n') ||\n undefined;\n\nconst toAgentPrompt = (input: {\n prompt: string;\n images?: MidscenePromptImage[];\n convertHttpImage2Base64?: boolean;\n}): MidsceneUserPrompt => {\n if (\n input.images === undefined &&\n input.convertHttpImage2Base64 === undefined\n ) {\n return input.prompt;\n }\n return {\n prompt: input.prompt,\n ...(input.images === undefined ? {} : { images: input.images }),\n ...(input.convertHttpImage2Base64 === undefined\n ? {}\n : { convertHttpImage2Base64: input.convertHttpImage2Base64 }),\n };\n};\n\nconst waitFor = async (durationMs: number, signal: AbortSignal) => {\n if (signal.aborted) {\n throw signal.reason ?? new Error('Wait aborted.');\n }\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n signal.removeEventListener('abort', abort);\n resolve();\n }, durationMs);\n const abort = () => {\n clearTimeout(timeout);\n reject(signal.reason ?? new Error('Wait aborted.'));\n };\n signal.addEventListener('abort', abort, { once: true });\n });\n};\n\nexport function createMidsceneNodes<TContext>(\n options: CreateMidsceneNodesOptions<TContext>,\n): readonly NodeDefinition<any, any, TContext>[] {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() options must be an object.',\n );\n }\n if (\n typeof options.agentProvider?.getAgent !== 'function' &&\n typeof options.getAgent !== 'function'\n ) {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() requires getAgent or agentProvider.getAgent.',\n );\n }\n\n const registeredAgentScopes = new Set<string>();\n const getExecutionId = (ctx: NodeExecutionContext<unknown, TContext>) =>\n ctx.scope === 'case' ? ctx.case.runId : ctx.document.documentRunId;\n const getAgent = async (\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Promise<MidsceneUIAgent> => {\n if (!options.agentProvider) return options.getAgent!(ctx);\n const runId = getExecutionId(ctx);\n if (\n options.agentProvider.releaseAgent &&\n !registeredAgentScopes.has(runId)\n ) {\n registeredAgentScopes.add(runId);\n ctx.onTeardown(async () => {\n try {\n const released = await options.agentProvider!.releaseAgent!(runId);\n return released?.reportPath\n ? { reportPaths: [released.reportPath] }\n : undefined;\n } finally {\n registeredAgentScopes.delete(runId);\n }\n });\n }\n return options.agentProvider.getAgent(runId, ctx);\n };\n\n return [\n defineNode<typeof aiActInputSchema, unknown, TContext>({\n name: 'aiAct',\n description: 'Perform a natural-language task with a Midscene UI Agent.',\n inputSchema: aiActInputSchema,\n async execute(ctx) {\n const agent = await getAgent(ctx);\n const aiAct = requireAgentMethod(agent, 'aiAct', 'aiAct');\n const output = await aiAct.call(agent, toAgentPrompt(ctx.input), {\n ...ctx.input.options,\n context: mergeContext(ctx.input.options?.context, ctx.history),\n abortSignal: ctx.signal,\n });\n return output === undefined ? undefined : { summary: output };\n },\n }),\n defineNode<typeof aiAssertInputSchema, unknown, TContext>({\n name: 'aiAssert',\n description:\n 'Assert a natural-language condition with a Midscene UI Agent.',\n inputSchema: aiAssertInputSchema,\n async execute(ctx) {\n const agent = await getAgent(ctx);\n const aiAssert = requireAgentMethod(agent, 'aiAssert', 'aiAssert');\n await aiAssert.call(\n agent,\n toAgentPrompt(ctx.input),\n ctx.input.message,\n {\n ...ctx.input.options,\n context: mergeContext(ctx.input.options?.context, ctx.history),\n abortSignal: ctx.signal,\n },\n );\n return { summary: `Assertion passed: ${ctx.input.prompt}` };\n },\n }),\n defineNode<typeof recordToReportInputSchema, unknown, TContext>({\n name: 'recordToReport',\n description: 'Add text or screenshots to the current Midscene report.',\n inputSchema: recordToReportInputSchema,\n async execute(ctx) {\n const title = ctx.input.title ?? ctx.input.prompt;\n const reportOptions: MidsceneRecordToReportOptions = {\n ...(ctx.input.content === undefined\n ? {}\n : { content: ctx.input.content }),\n ...(ctx.input.screenshotBase64 === undefined\n ? {}\n : { screenshotBase64: ctx.input.screenshotBase64 }),\n ...(ctx.input.screenshots === undefined\n ? {}\n : { screenshots: ctx.input.screenshots }),\n };\n const agent = await getAgent(ctx);\n const recordToReport = requireAgentMethod(\n agent,\n 'recordToReport',\n 'recordToReport',\n );\n await recordToReport.call(agent, title, reportOptions);\n return { summary: `Recorded to report: ${title ?? 'untitled'}` };\n },\n }),\n ...(options.includeLaunch === false ? [] : [createLaunchNode(getAgent)]),\n defineNode<typeof waitInputSchema, unknown, TContext>({\n name: 'wait',\n description: 'Wait for a fixed duration while honoring cancellation.',\n inputSchema: waitInputSchema,\n async execute(ctx) {\n const multiplier =\n ctx.input.unit === 'min'\n ? 60_000\n : ctx.input.unit === 's'\n ? 1_000\n : 1;\n const durationMs = ctx.input.duration * multiplier;\n await waitFor(durationMs, ctx.signal);\n return { summary: `Waited ${durationMs}ms` };\n },\n }),\n defineNode<typeof agentInputSchema, unknown, TContext>({\n name: 'agent',\n description:\n 'Execute one self-contained natural-language task with an injected Agent executor.',\n inputSchema: agentInputSchema,\n async execute(ctx) {\n if (!options.agentExecutor) {\n throw new NodeExecutionError(\n 'agent',\n new TypeError('createMidsceneNodes() requires an agentExecutor.'),\n );\n }\n const execution =\n ctx.scope === 'case'\n ? { scope: 'case' as const, runId: ctx.case.runId }\n : {\n scope: 'document' as const,\n runId: ctx.document.documentRunId,\n };\n const result = await options.agentExecutor.execute({\n prompt: ctx.input.prompt,\n history: ctx.history,\n context: ctx.context,\n signal: ctx.signal,\n execution,\n });\n return result ?? { summary: 'Agent task completed.' };\n },\n }),\n ];\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","WorkflowError","Error","undefined","message","options","NodeDefinitionError","details","NodeExecutionError","node","cause","causeMessage","String","validateOptionalText","value","field","validateInputSchema","schema","z","validateDefinition","defineNode","lifecycleInputSchema","operation","description","input","ctx","launchInputSchema","requireLifecycleMethod","agent","method","agentName","TypeError","createLaunchNode","getAgent","uri","launch","nonBlankPrompt","promptImagesInputSchema","promptImageConversionInputSchema","aiActOptionsInputSchema","aiActInputSchema","aiAssertOptionsInputSchema","aiAssertInputSchema","reportScreenshotInputSchema","recordToReportInputSchema","waitInputSchema","agentInputSchema","isRecord","Array","requireAgentMethod","maxHistoryContextCharacters","maxHistoryValuePreviewCharacters","maxHistoryEntryCharacters","historyOmissionNoticeReserve","compactHistoryContextValue","serialized","JSON","serializeHistoryEntryForContext","entry","index","compacted","renderNodeHistory","history","heading","availableCharacters","renderedEntries","renderedCharacters","rendered","separatorCharacters","omittedEntries","mergeContext","explicit","Boolean","toAgentPrompt","waitFor","durationMs","signal","Promise","resolve","reject","timeout","setTimeout","abort","clearTimeout","createMidsceneNodes","registeredAgentScopes","Set","getExecutionId","runId","released","aiAct","output","aiAssert","title","reportOptions","recordToReport","multiplier","execution","result"],"mappings":"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"}
1
+ {"version":3,"file":"midscene/index.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/errors.ts","../../../src/node/define-node.ts","../../../src/device/lifecycle.ts","../../../src/midscene/index.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 { z } from 'zod/v4';\n\nexport interface WorkflowErrorOptions {\n code?: string;\n details?: unknown;\n cause?: unknown;\n}\n\nexport class WorkflowError extends Error {\n readonly code: string;\n readonly details?: unknown;\n\n constructor(message: string, options: WorkflowErrorOptions = {}) {\n super(message, { cause: options.cause });\n this.name = new.target.name;\n this.code = options.code ?? 'WORKFLOW_ERROR';\n this.details = options.details;\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n ...(this.details === undefined ? {} : { details: this.details }),\n };\n }\n}\n\nexport class WorkflowParseError extends WorkflowError {\n constructor(message: string, details?: unknown, cause?: unknown) {\n super(message, { code: 'WORKFLOW_PARSE_ERROR', details, cause });\n }\n}\n\nexport class NodeDefinitionError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_DEFINITION_ERROR', details });\n }\n}\n\nexport class DuplicateNodeError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is already registered.`, {\n code: 'DUPLICATE_NODE',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeNotFoundError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is not registered.`, {\n code: 'NODE_NOT_FOUND',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeInputValidationError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_INPUT_VALIDATION_ERROR', details });\n }\n\n static fromZod(node: string, error: z.ZodError): NodeInputValidationError {\n const issues = error.issues.map((issue) => ({\n code: issue.code,\n path: issue.path.map(String).join('.'),\n message: issue.message,\n }));\n const firstIssue = issues[0];\n const path = firstIssue?.path || '<root>';\n const message = firstIssue?.message ?? 'invalid input';\n return new NodeInputValidationError(\n `Node \"${node}\" input validation failed at \"${path}\": ${message}`,\n { node, issues },\n );\n }\n}\n\nexport class StepTimeoutError extends WorkflowError {\n readonly timeoutMs: number;\n readonly node?: string;\n\n constructor(timeoutMs: number, node?: string) {\n super(\n node\n ? `Node \"${node}\" timed out after ${timeoutMs}ms.`\n : `Step timed out after ${timeoutMs}ms.`,\n {\n code: 'STEP_TIMEOUT',\n details: { timeoutMs, ...(node === undefined ? {} : { node }) },\n },\n );\n this.timeoutMs = timeoutMs;\n this.node = node;\n }\n}\n\nexport class NodeExecutionError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string, cause: unknown) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Node \"${node}\" failed: ${causeMessage}`, {\n code: 'NODE_EXECUTION_ERROR',\n details: { node },\n cause,\n });\n this.node = node;\n }\n}\n\nexport class WorkflowLifecycleError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'WORKFLOW_LIFECYCLE_ERROR', details });\n }\n}\n\nexport class ProjectSetupError extends WorkflowError {\n constructor(cause: unknown, details: { projectName: string }) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" setup failed: ${causeMessage}`, {\n code: 'PROJECT_SETUP_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class ProjectTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: { projectName: string; registrationIndex: number },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" teardown failed: ${causeMessage}`, {\n code: 'PROJECT_TEARDOWN_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class NodeScopeTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: {\n scope: 'case' | 'document';\n scopeId: string;\n node: string;\n registrationIndex: number;\n },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(\n `${details.scope === 'case' ? 'Case attempt' : 'Workflow document'} node teardown failed for \"${details.node}\": ${causeMessage}`,\n { code: 'NODE_SCOPE_TEARDOWN_ERROR', details, cause },\n );\n }\n}\n\nexport class FatalDeviceError extends WorkflowError {\n constructor(message: string, cause?: unknown) {\n super(message, { code: 'FATAL_DEVICE_ERROR', cause });\n }\n}\n\nexport const isFatalDeviceError = (error: unknown): boolean => {\n if (error instanceof FatalDeviceError) return true;\n if (error instanceof WorkflowError && error.code === 'FATAL_DEVICE_ERROR') {\n return true;\n }\n if (\n error instanceof Error &&\n /device offline|device not found|(?:adb|bdc|device) connection (?:was )?closed/i.test(\n error.message,\n )\n ) {\n return true;\n }\n return error instanceof Error && error.cause !== undefined\n ? isFatalDeviceError(error.cause)\n : false;\n};\n\nexport class CaseExecutionError extends WorkflowError {\n readonly result: import('./engine/types').CaseRunResult;\n\n constructor(result: import('./engine/types').CaseRunResult) {\n super(`Case \"${result.name}\" failed.`, {\n code: 'CASE_EXECUTION_FAILED',\n details: { caseId: result.caseId, runId: result.runId },\n });\n this.result = result;\n }\n}\n\nexport class WorkflowDocumentExecutionError extends WorkflowError {\n readonly result: import('./engine/types').WorkflowDocumentRunResult;\n\n constructor(result: import('./engine/types').WorkflowDocumentRunResult) {\n super(`Workflow document \"${result.sourcePath}\" failed.`, {\n code: 'WORKFLOW_DOCUMENT_EXECUTION_FAILED',\n details: {\n documentId: result.documentId,\n documentRunId: result.documentRunId,\n },\n });\n this.result = result;\n }\n}\n\nexport function normalizeNodeExecutionError(\n error: unknown,\n node: string,\n): WorkflowError {\n return error instanceof WorkflowError\n ? error\n : new NodeExecutionError(node, error);\n}\n","import { z } from 'zod/v4';\nimport { NodeDefinitionError } from '../errors';\nimport type {\n DefineNodeOptions,\n DefineNodeWithSchemaOptions,\n NodeDefinition,\n NodeDefinitionWithSchema,\n NodeInputSchema,\n} from './types';\n\nconst validateOptionalText = (\n value: unknown,\n field: 'title' | 'description',\n node: string,\n): void => {\n if (\n value !== undefined &&\n (typeof value !== 'string' || value.trim().length === 0)\n ) {\n throw new NodeDefinitionError(\n `Node \"${node}\" ${field} must be a non-empty string.`,\n { node, field },\n );\n }\n};\n\nconst validateInputSchema = (schema: unknown, node: string): void => {\n if (schema === undefined) return;\n if (!(schema instanceof z.ZodObject)) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must be a Zod object schema.`,\n { node, field: 'inputSchema' },\n );\n }\n if ('$' in schema.shape) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must not declare \"$\" as an input property.`,\n { node, field: 'inputSchema.$' },\n );\n }\n};\n\nconst validateDefinition = (options: {\n name: string;\n title?: unknown;\n description?: unknown;\n inputSchema?: unknown;\n execute: unknown;\n}): void => {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError('Node definition must be an object.');\n }\n\n if (typeof options.name !== 'string' || options.name.trim().length === 0) {\n throw new NodeDefinitionError('Node name must be a non-empty string.');\n }\n\n validateOptionalText(options.title, 'title', options.name);\n validateOptionalText(options.description, 'description', options.name);\n validateInputSchema(options.inputSchema, options.name);\n\n if (typeof options.execute !== 'function') {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" must provide an execute function.`,\n { node: options.name },\n );\n }\n};\n\nexport function defineNode<\n TSchema extends NodeInputSchema,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeWithSchemaOptions<TSchema, TData, TContext>,\n): NodeDefinitionWithSchema<TSchema, TData, TContext>;\n\nexport function defineNode<\n TInput = unknown,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeOptions<TInput, TData, TContext>,\n): NodeDefinition<TInput, TData, TContext>;\n\nexport function defineNode(\n options: DefineNodeOptions<any, any, any>,\n): NodeDefinition<any, any, any> {\n validateDefinition(options);\n return options;\n}\n","import { z } from 'zod/v4';\nimport type { Awaitable } from '../engine/types';\nimport { NodeExecutionError } from '../errors';\nimport { defineNode } from '../node/define-node';\nimport type { NodeDefinition, NodeExecutionContext } from '../node/types';\n\ntype NodeContext<TContext> = NodeExecutionContext<unknown, TContext>;\ntype AgentGetter<TContext> = (ctx: NodeContext<TContext>) => Awaitable<unknown>;\ntype LifecycleMethod = 'launch' | 'terminate';\n\n/** Device capabilities required by Android and iOS lifecycle Nodes. */\nexport interface DeviceLifecycleAgent {\n launch(uri: string): Promise<void>;\n terminate(uri: string): Promise<void>;\n}\n\nconst lifecycleInputSchema = (\n operation: LifecycleMethod,\n description: string,\n) =>\n z\n .strictObject({\n prompt: z\n .string()\n .regex(/\\S/, 'prompt must contain a non-whitespace character')\n .optional()\n .describe(`String shorthand for the app to ${operation}.`),\n uri: z\n .string()\n .regex(/\\S/, 'uri must contain a non-whitespace character')\n .optional()\n .describe(description),\n })\n .superRefine((input, ctx) => {\n if ((input.prompt === undefined) === (input.uri === undefined)) {\n ctx.addIssue({\n code: 'custom',\n message: 'exactly one of prompt and uri is required',\n });\n }\n });\n\n/** Input schema for the device launch Node. */\nexport const launchInputSchema = lifecycleInputSchema(\n 'launch',\n 'The app, URL, URI, package name, or bundle identifier to launch.',\n);\n\n/** Input schema for the device terminate Node. */\nexport const terminateInputSchema = lifecycleInputSchema(\n 'terminate',\n 'The package name, bundle identifier, or app name to terminate.',\n);\n\nexport type LaunchNodeInput = z.infer<typeof launchInputSchema>;\nexport type TerminateNodeInput = z.infer<typeof terminateInputSchema>;\n\nconst requireLifecycleMethod = (\n agent: unknown,\n method: LifecycleMethod,\n agentName: string,\n): DeviceLifecycleAgent[LifecycleMethod] => {\n if (\n typeof agent !== 'object' ||\n agent === null ||\n typeof (agent as Record<LifecycleMethod, unknown>)[method] !== 'function'\n ) {\n throw new NodeExecutionError(\n method,\n new TypeError(`getAgent() must return ${agentName} with ${method}().`),\n );\n }\n return (agent as DeviceLifecycleAgent)[method];\n};\n\nexport const createLaunchNode = <TContext>(\n getAgent: AgentGetter<TContext>,\n agentName = 'an Agent',\n): NodeDefinition<any, any, TContext> =>\n defineNode<typeof launchInputSchema, unknown, TContext>({\n name: 'launch',\n description:\n 'Launch an app, URL, or URI through the current Midscene Agent. This Node does not install or manage applications.',\n inputSchema: launchInputSchema,\n async execute(ctx) {\n const uri = ctx.input.uri ?? ctx.input.prompt!;\n const agent = await getAgent(ctx);\n const launch = requireLifecycleMethod(agent, 'launch', agentName);\n await launch.call(agent, uri);\n return { summary: `Launched ${uri}` };\n },\n });\n\nconst createTerminateNode = <TContext>(\n getAgent: AgentGetter<TContext>,\n agentName: string,\n): NodeDefinition<any, any, TContext> =>\n defineNode<typeof terminateInputSchema, unknown, TContext>({\n name: 'terminate',\n description:\n 'Terminate an application through the current Midscene Agent. This Node does not uninstall the application or clear its data.',\n inputSchema: terminateInputSchema,\n async execute(ctx) {\n const uri = ctx.input.uri ?? ctx.input.prompt!;\n const agent = await getAgent(ctx);\n const terminate = requireLifecycleMethod(agent, 'terminate', agentName);\n await terminate.call(agent, uri);\n return { summary: `Terminated ${uri}` };\n },\n });\n\nexport const createDeviceLifecycleNodes = <TContext>(\n getAgent: (ctx: NodeContext<TContext>) => Awaitable<DeviceLifecycleAgent>,\n agentName: string,\n): readonly NodeDefinition<any, any, TContext>[] => [\n createLaunchNode(getAgent, agentName),\n createTerminateNode(getAgent, agentName),\n];\n","import { z } from 'zod/v4';\nimport { createLaunchNode } from '../device/lifecycle';\nexport type { LaunchNodeInput } from '../device/lifecycle';\nexport { launchInputSchema } from '../device/lifecycle';\nimport type { Awaitable, NodeHistoryEntry } from '../engine/types';\nimport { NodeDefinitionError, NodeExecutionError } from '../errors';\nimport { defineNode } from '../node/define-node';\nimport type {\n NodeDefinition,\n NodeExecutionContext,\n NodeResult,\n} from '../node/types';\n\nexport interface MidsceneAiActOptions {\n cacheable?: boolean;\n fileChooserAccept?: string | string[];\n deepThink?: 'unset' | boolean;\n deepLocate?: boolean;\n /**\n * Additional facts, rules, constraints, or output requirements for this AI\n * call. It overrides Agent API and default contexts; `''` disables inherited\n * user context for this call.\n */\n context?: string;\n abortSignal?: AbortSignal;\n}\n\ntype MidsceneAiActInternalOptions = MidsceneAiActOptions & {\n /** Workflow history rendered by Core as a separate read-only prompt block. */\n _internalAdditionalContext?: string;\n};\n\nexport interface MidsceneAiAssertOptions {\n domIncluded?: boolean | 'visible-only';\n screenshotIncluded?: boolean;\n /**\n * Additional facts, decision rules, constraints, or output requirements for\n * this assertion. It overrides Agent API and default contexts; `''` disables\n * inherited user context for this call.\n */\n context?: string;\n abortSignal?: AbortSignal;\n keepRawResponse?: boolean;\n}\n\ntype MidsceneAiAssertInternalOptions = MidsceneAiAssertOptions & {\n /** Workflow history rendered by Core as a separate read-only prompt block. */\n _internalAdditionalContext?: string;\n};\n\nexport interface MidscenePromptImage {\n name: string;\n url: string;\n}\n\nexport type MidsceneUserPrompt =\n | string\n | {\n prompt: string;\n images?: MidscenePromptImage[];\n convertHttpImage2Base64?: boolean;\n };\n\nexport interface MidsceneReportScreenshot {\n base64: string;\n description?: string;\n}\n\nexport interface MidsceneRecordToReportOptions {\n content?: string;\n screenshotBase64?: string;\n screenshots?: MidsceneReportScreenshot[];\n}\n\nexport interface MidsceneUIAgent {\n aiAct(\n prompt: MidsceneUserPrompt,\n options?: MidsceneAiActOptions,\n ): Promise<string | undefined>;\n aiAssert(\n prompt: MidsceneUserPrompt,\n message?: string,\n options?: MidsceneAiAssertOptions,\n ): Promise<unknown>;\n recordToReport(\n title?: string,\n options?: MidsceneRecordToReportOptions,\n ): Promise<unknown>;\n /** Available on device Agents that support launching an app, URL, or URI. */\n launch?(uri: string): Promise<void>;\n}\n\nexport interface AgentProvider<TContext> {\n getAgent(\n runId: string,\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n // biome-ignore lint/suspicious/noConfusingVoidType: providers without a report intentionally return void.\n releaseAgent?(runId: string): Awaitable<AgentReleaseResult | void>;\n dispose?(): Awaitable<void>;\n}\n\nexport interface AgentReleaseResult {\n /** Absolute path to the finalized report for this Agent scope. */\n reportPath?: string;\n}\n\nexport interface AgentExecutorInput<TContext> {\n prompt: string;\n history: readonly NodeHistoryEntry[];\n context: TContext;\n signal: AbortSignal;\n execution:\n | { scope: 'case'; runId: string }\n | { scope: 'document'; runId: string };\n}\n\nexport interface AgentExecutor<TContext> {\n // biome-ignore lint/suspicious/noConfusingVoidType: executors may perform side effects without returning a summary.\n execute(input: AgentExecutorInput<TContext>): Awaitable<NodeResult | void>;\n}\n\nconst nonBlankPrompt = (description: string) =>\n z\n .string()\n .regex(/\\S/, 'prompt must contain a non-whitespace character')\n .describe(description);\n\nconst promptImagesInputSchema = z\n .array(\n z.strictObject({\n name: nonBlankPrompt('The name used to identify this reference image.'),\n url: nonBlankPrompt(\n 'The URL, data URL, or file path of this reference image.',\n ),\n }),\n )\n .min(1)\n .optional();\n\nconst promptImageConversionInputSchema = z\n .boolean()\n .optional()\n .describe('Whether HTTP reference images are converted to base64 first.');\n\nconst aiActOptionsInputSchema = z.strictObject({\n cacheable: z\n .boolean()\n .optional()\n .describe('Whether this action may use the Midscene cache.'),\n fileChooserAccept: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('Accepted file types for a file chooser.'),\n deepThink: z\n .union([z.literal('unset'), z.boolean()])\n .optional()\n .describe('Whether to enable deep thinking for this action.'),\n deepLocate: z\n .boolean()\n .optional()\n .describe('Whether to use deep element location.'),\n context: z\n .string()\n .optional()\n .describe(\n 'Additional facts, rules, constraints, or output requirements for this AI call. It overrides Agent API and default contexts; an empty string disables inherited user context.',\n ),\n});\n\nexport const aiActInputSchema = z.strictObject({\n prompt: nonBlankPrompt('The natural-language UI task to perform.'),\n images: promptImagesInputSchema,\n convertHttpImage2Base64: promptImageConversionInputSchema,\n options: aiActOptionsInputSchema.optional(),\n});\n\nconst aiAssertOptionsInputSchema = z.strictObject({\n domIncluded: z\n .union([z.boolean(), z.literal('visible-only')])\n .optional()\n .describe('How DOM information is included in the assertion.'),\n screenshotIncluded: z\n .boolean()\n .optional()\n .describe('Whether the assertion includes a screenshot.'),\n context: z\n .string()\n .optional()\n .describe(\n 'Additional facts, decision rules, constraints, or output requirements for this assertion. It overrides Agent API and default contexts; an empty string disables inherited user context.',\n ),\n});\n\nexport const aiAssertInputSchema = z.strictObject({\n prompt: nonBlankPrompt('The natural-language condition that must be true.'),\n images: promptImagesInputSchema,\n convertHttpImage2Base64: promptImageConversionInputSchema,\n message: z.string().optional().describe('The assertion failure message.'),\n options: aiAssertOptionsInputSchema.optional(),\n});\n\nconst reportScreenshotInputSchema = z.strictObject({\n base64: z.string().min(1).describe('A base64-encoded screenshot.'),\n description: z.string().optional().describe('What the screenshot shows.'),\n});\n\nexport const recordToReportInputSchema = z\n .strictObject({\n prompt: z.string().optional().describe('String shorthand for the title.'),\n title: z.string().optional().describe('The report section title.'),\n content: z.string().optional().describe('The report text content.'),\n screenshotBase64: z\n .string()\n .optional()\n .describe('One base64-encoded screenshot.'),\n screenshots: z\n .array(reportScreenshotInputSchema)\n .min(1)\n .optional()\n .describe('Screenshots attached to the report section.'),\n })\n .superRefine((input, ctx) => {\n if (input.prompt !== undefined && input.title !== undefined) {\n ctx.addIssue({\n code: 'custom',\n message: 'prompt and title are mutually exclusive',\n });\n }\n if (\n input.screenshotBase64 !== undefined &&\n input.screenshots !== undefined\n ) {\n ctx.addIssue({\n code: 'custom',\n message: 'screenshotBase64 and screenshots are mutually exclusive',\n });\n }\n });\n\nexport const waitInputSchema = z.strictObject({\n duration: z.number().positive().describe('How long to wait.'),\n unit: z\n .enum(['ms', 's', 'min'])\n .default('ms')\n .describe('Duration unit: milliseconds, seconds, or minutes.'),\n});\n\nexport const agentInputSchema = z.strictObject({\n prompt: nonBlankPrompt(\n 'A self-contained task, including allowed tools and success conditions.',\n ),\n});\n\nexport type AiActNodeInput = z.infer<typeof aiActInputSchema>;\nexport type AiAssertNodeInput = z.infer<typeof aiAssertInputSchema>;\nexport type RecordToReportNodeInput = z.infer<typeof recordToReportInputSchema>;\nexport type WaitNodeInput = z.infer<typeof waitInputSchema>;\nexport type AgentNodeInput = z.infer<typeof agentInputSchema>;\n\nexport interface CreateMidsceneNodesOptions<TContext> {\n getAgent?(\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n agentProvider?: AgentProvider<TContext>;\n /** Disable when a project registers its own platform-specific launch Node. */\n includeLaunch?: boolean;\n agentExecutor?: AgentExecutor<TContext>;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst requireAgentMethod = <TMethod extends keyof MidsceneUIAgent>(\n agent: MidsceneUIAgent,\n method: TMethod,\n node: string,\n): NonNullable<MidsceneUIAgent[TMethod]> => {\n if (!isRecord(agent) || typeof agent[method] !== 'function') {\n throw new NodeExecutionError(\n node,\n new TypeError(`getAgent() must return an Agent with ${method}().`),\n );\n }\n return agent[method] as NonNullable<MidsceneUIAgent[TMethod]>;\n};\n\nconst maxHistoryContextCharacters = 64_000;\nconst maxHistoryValuePreviewCharacters = 8_000;\nconst maxHistoryEntryCharacters = 24_000;\nconst historyOmissionNoticeReserve = 256;\n\nconst compactHistoryContextValue = (value: unknown): unknown => {\n const serialized = JSON.stringify(value);\n if (\n serialized === undefined ||\n serialized.length <= maxHistoryValuePreviewCharacters\n ) {\n return value;\n }\n return {\n omittedFromContext: true,\n originalCharacters: serialized.length,\n preview:\n typeof value === 'string'\n ? value.slice(0, maxHistoryValuePreviewCharacters)\n : serialized.slice(0, maxHistoryValuePreviewCharacters),\n };\n};\n\nconst serializeHistoryEntryForContext = (\n entry: NodeHistoryEntry,\n index: number,\n): string => {\n const compacted = Object.fromEntries(\n Object.entries({ index, ...entry }).map(([key, value]) => [\n key,\n compactHistoryContextValue(value),\n ]),\n );\n const serialized = JSON.stringify(compacted);\n if (serialized.length <= maxHistoryEntryCharacters) return serialized;\n\n return JSON.stringify({\n index,\n scope: entry.scope,\n phase: entry.phase,\n stepIndex: entry.stepIndex,\n node: entry.node,\n status: entry.status,\n ...(entry.summary === undefined\n ? {}\n : { summary: compactHistoryContextValue(entry.summary) }),\n omittedFromContext: true,\n compactedCharacters: serialized.length,\n });\n};\n\nexport const renderNodeHistory = (\n history: readonly NodeHistoryEntry[],\n): string | undefined => {\n if (history.length === 0) return undefined;\n\n const heading = 'Previous workflow results (read-only):';\n const availableCharacters =\n maxHistoryContextCharacters - heading.length - historyOmissionNoticeReserve;\n const renderedEntries: string[] = [];\n let renderedCharacters = 0;\n\n for (let index = history.length - 1; index >= 0; index -= 1) {\n const rendered = serializeHistoryEntryForContext(history[index], index + 1);\n const separatorCharacters = renderedEntries.length === 0 ? 0 : 1;\n if (\n renderedCharacters + separatorCharacters + rendered.length >\n availableCharacters\n ) {\n break;\n }\n renderedEntries.unshift(rendered);\n renderedCharacters += separatorCharacters + rendered.length;\n }\n\n const omittedEntries = history.length - renderedEntries.length;\n return [\n heading,\n ...(omittedEntries === 0\n ? []\n : [\n `${omittedEntries} earlier history entr${omittedEntries === 1 ? 'y was' : 'ies were'} omitted from Agent context to stay within the size limit. Complete results remain available in the Test Runner output.`,\n ]),\n ...renderedEntries,\n ].join('\\n');\n};\n\nconst toAgentPrompt = (input: {\n prompt: string;\n images?: MidscenePromptImage[];\n convertHttpImage2Base64?: boolean;\n}): MidsceneUserPrompt => {\n if (\n input.images === undefined &&\n input.convertHttpImage2Base64 === undefined\n ) {\n return input.prompt;\n }\n return {\n prompt: input.prompt,\n ...(input.images === undefined ? {} : { images: input.images }),\n ...(input.convertHttpImage2Base64 === undefined\n ? {}\n : { convertHttpImage2Base64: input.convertHttpImage2Base64 }),\n };\n};\n\nconst waitFor = async (durationMs: number, signal: AbortSignal) => {\n if (signal.aborted) {\n throw signal.reason ?? new Error('Wait aborted.');\n }\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n signal.removeEventListener('abort', abort);\n resolve();\n }, durationMs);\n const abort = () => {\n clearTimeout(timeout);\n reject(signal.reason ?? new Error('Wait aborted.'));\n };\n signal.addEventListener('abort', abort, { once: true });\n });\n};\n\nexport function createMidsceneNodes<TContext>(\n options: CreateMidsceneNodesOptions<TContext>,\n): readonly NodeDefinition<any, any, TContext>[] {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() options must be an object.',\n );\n }\n if (\n typeof options.agentProvider?.getAgent !== 'function' &&\n typeof options.getAgent !== 'function'\n ) {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() requires getAgent or agentProvider.getAgent.',\n );\n }\n\n const registeredAgentScopes = new Set<string>();\n const getExecutionId = (ctx: NodeExecutionContext<unknown, TContext>) =>\n ctx.scope === 'case' ? ctx.case.runId : ctx.document.documentRunId;\n const getAgent = async (\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Promise<MidsceneUIAgent> => {\n if (!options.agentProvider) return options.getAgent!(ctx);\n const runId = getExecutionId(ctx);\n if (\n options.agentProvider.releaseAgent &&\n !registeredAgentScopes.has(runId)\n ) {\n registeredAgentScopes.add(runId);\n ctx.onTeardown(async () => {\n try {\n const released = await options.agentProvider!.releaseAgent!(runId);\n return released?.reportPath\n ? { reportPaths: [released.reportPath] }\n : undefined;\n } finally {\n registeredAgentScopes.delete(runId);\n }\n });\n }\n return options.agentProvider.getAgent(runId, ctx);\n };\n\n return [\n defineNode<typeof aiActInputSchema, unknown, TContext>({\n name: 'aiAct',\n description: 'Perform a natural-language task with a Midscene UI Agent.',\n inputSchema: aiActInputSchema,\n async execute(ctx) {\n const agent = await getAgent(ctx);\n const aiAct = requireAgentMethod(agent, 'aiAct', 'aiAct');\n const additionalContext = renderNodeHistory(ctx.history);\n const aiActOptions: MidsceneAiActInternalOptions = {\n ...ctx.input.options,\n abortSignal: ctx.signal,\n ...(additionalContext === undefined\n ? {}\n : { _internalAdditionalContext: additionalContext }),\n };\n const output = await aiAct.call(\n agent,\n toAgentPrompt(ctx.input),\n aiActOptions,\n );\n return output === undefined ? undefined : { summary: output };\n },\n }),\n defineNode<typeof aiAssertInputSchema, unknown, TContext>({\n name: 'aiAssert',\n description:\n 'Assert a natural-language condition with a Midscene UI Agent.',\n inputSchema: aiAssertInputSchema,\n async execute(ctx) {\n const agent = await getAgent(ctx);\n const aiAssert = requireAgentMethod(agent, 'aiAssert', 'aiAssert');\n const additionalContext = renderNodeHistory(ctx.history);\n const aiAssertOptions: MidsceneAiAssertInternalOptions = {\n ...ctx.input.options,\n abortSignal: ctx.signal,\n ...(additionalContext === undefined\n ? {}\n : { _internalAdditionalContext: additionalContext }),\n };\n await aiAssert.call(\n agent,\n toAgentPrompt(ctx.input),\n ctx.input.message,\n aiAssertOptions,\n );\n return { summary: `Assertion passed: ${ctx.input.prompt}` };\n },\n }),\n defineNode<typeof recordToReportInputSchema, unknown, TContext>({\n name: 'recordToReport',\n description: 'Add text or screenshots to the current Midscene report.',\n inputSchema: recordToReportInputSchema,\n async execute(ctx) {\n const title = ctx.input.title ?? ctx.input.prompt;\n const reportOptions: MidsceneRecordToReportOptions = {\n ...(ctx.input.content === undefined\n ? {}\n : { content: ctx.input.content }),\n ...(ctx.input.screenshotBase64 === undefined\n ? {}\n : { screenshotBase64: ctx.input.screenshotBase64 }),\n ...(ctx.input.screenshots === undefined\n ? {}\n : { screenshots: ctx.input.screenshots }),\n };\n const agent = await getAgent(ctx);\n const recordToReport = requireAgentMethod(\n agent,\n 'recordToReport',\n 'recordToReport',\n );\n await recordToReport.call(agent, title, reportOptions);\n return { summary: `Recorded to report: ${title ?? 'untitled'}` };\n },\n }),\n ...(options.includeLaunch === false ? [] : [createLaunchNode(getAgent)]),\n defineNode<typeof waitInputSchema, unknown, TContext>({\n name: 'wait',\n description: 'Wait for a fixed duration while honoring cancellation.',\n inputSchema: waitInputSchema,\n async execute(ctx) {\n const multiplier =\n ctx.input.unit === 'min'\n ? 60_000\n : ctx.input.unit === 's'\n ? 1_000\n : 1;\n const durationMs = ctx.input.duration * multiplier;\n await waitFor(durationMs, ctx.signal);\n return { summary: `Waited ${durationMs}ms` };\n },\n }),\n defineNode<typeof agentInputSchema, unknown, TContext>({\n name: 'agent',\n description:\n 'Execute one self-contained natural-language task with an injected Agent executor.',\n inputSchema: agentInputSchema,\n async execute(ctx) {\n if (!options.agentExecutor) {\n throw new NodeExecutionError(\n 'agent',\n new TypeError('createMidsceneNodes() requires an agentExecutor.'),\n );\n }\n const execution =\n ctx.scope === 'case'\n ? { scope: 'case' as const, runId: ctx.case.runId }\n : {\n scope: 'document' as const,\n runId: ctx.document.documentRunId,\n };\n const result = await options.agentExecutor.execute({\n prompt: ctx.input.prompt,\n history: ctx.history,\n context: ctx.context,\n signal: ctx.signal,\n execution,\n });\n return result ?? { summary: 'Agent task completed.' };\n },\n }),\n ];\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","WorkflowError","Error","undefined","message","options","NodeDefinitionError","details","NodeExecutionError","node","cause","causeMessage","String","validateOptionalText","value","field","validateInputSchema","schema","z","validateDefinition","defineNode","lifecycleInputSchema","operation","description","input","ctx","launchInputSchema","requireLifecycleMethod","agent","method","agentName","TypeError","createLaunchNode","getAgent","uri","launch","nonBlankPrompt","promptImagesInputSchema","promptImageConversionInputSchema","aiActOptionsInputSchema","aiActInputSchema","aiAssertOptionsInputSchema","aiAssertInputSchema","reportScreenshotInputSchema","recordToReportInputSchema","waitInputSchema","agentInputSchema","isRecord","Array","requireAgentMethod","maxHistoryContextCharacters","maxHistoryValuePreviewCharacters","maxHistoryEntryCharacters","historyOmissionNoticeReserve","compactHistoryContextValue","serialized","JSON","serializeHistoryEntryForContext","entry","index","compacted","renderNodeHistory","history","heading","availableCharacters","renderedEntries","renderedCharacters","rendered","separatorCharacters","omittedEntries","toAgentPrompt","waitFor","durationMs","signal","Promise","resolve","reject","timeout","setTimeout","abort","clearTimeout","createMidsceneNodes","registeredAgentScopes","Set","getExecutionId","runId","released","aiAct","additionalContext","aiActOptions","output","aiAssert","aiAssertOptions","title","reportOptions","recordToReport","multiplier","execution","result"],"mappings":"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"}
@@ -122,6 +122,11 @@ export declare interface MidsceneAiActOptions {
122
122
  fileChooserAccept?: string | string[];
123
123
  deepThink?: 'unset' | boolean;
124
124
  deepLocate?: boolean;
125
+ /**
126
+ * Additional facts, rules, constraints, or output requirements for this AI
127
+ * call. It overrides Agent API and default contexts; `''` disables inherited
128
+ * user context for this call.
129
+ */
125
130
  context?: string;
126
131
  abortSignal?: AbortSignal;
127
132
  }
@@ -129,6 +134,11 @@ export declare interface MidsceneAiActOptions {
129
134
  export declare interface MidsceneAiAssertOptions {
130
135
  domIncluded?: boolean | 'visible-only';
131
136
  screenshotIncluded?: boolean;
137
+ /**
138
+ * Additional facts, decision rules, constraints, or output requirements for
139
+ * this assertion. It overrides Agent API and default contexts; `''` disables
140
+ * inherited user context for this call.
141
+ */
132
142
  context?: string;
133
143
  abortSignal?: AbortSignal;
134
144
  keepRawResponse?: boolean;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@midscene/test",
3
3
  "description": "Extensible YAML test runner and node SDK for Midscene.",
4
- "version": "1.12.3",
4
+ "version": "1.12.4-beta-20260902093735.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/web-infra-dev/midscene.git",
@@ -63,9 +63,9 @@
63
63
  "playwright": "^1.45.0",
64
64
  "typescript": "^5.8.3",
65
65
  "vitest": "3.0.5",
66
- "@midscene/ios": "1.12.3",
67
- "@midscene/android": "1.12.3",
68
- "@midscene/web": "1.12.3"
66
+ "@midscene/android": "1.12.4-beta-20260902093735.0",
67
+ "@midscene/web": "1.12.4-beta-20260902093735.0",
68
+ "@midscene/ios": "1.12.4-beta-20260902093735.0"
69
69
  },
70
70
  "peerDependencies": {
71
71
  "playwright": "^1.45.0"