@browserbasehq/orca 3.2.1-preview.0 → 3.2.1-preview.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/lib/inference.js +29 -22
- package/dist/cjs/lib/inference.js.map +1 -1
- package/dist/cjs/lib/prompt.js +5 -5
- package/dist/cjs/lib/prompt.js.map +1 -1
- package/dist/cjs/tests/integration/flowLogger.spec.js +12 -8
- package/dist/cjs/tests/integration/flowLogger.spec.js.map +1 -1
- package/dist/cjs/tests/integration/testUtils.js +1 -1
- package/dist/cjs/tests/integration/testUtils.js.map +1 -1
- package/dist/cjs/tests/integration/timeouts.spec.js +6 -4
- package/dist/cjs/tests/integration/timeouts.spec.js.map +1 -1
- package/dist/esm/lib/inference.js +29 -22
- package/dist/esm/lib/inference.js.map +1 -1
- package/dist/esm/lib/prompt.js +5 -5
- package/dist/esm/lib/prompt.js.map +1 -1
- package/dist/esm/tests/integration/flowLogger.spec.js +12 -8
- package/dist/esm/tests/integration/flowLogger.spec.js.map +1 -1
- package/dist/esm/tests/integration/testUtils.js +1 -1
- package/dist/esm/tests/integration/testUtils.js.map +1 -1
- package/dist/esm/tests/integration/timeouts.spec.js +6 -4
- package/dist/esm/tests/integration/timeouts.spec.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inference.js","sourceRoot":"","sources":["../../../lib/inference.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport { LogLine } from \"./v3/types/public/logs.js\";\nimport { ChatMessage, LLMClient } from \"./v3/llm/LLMClient.js\";\nimport { getEnvTimeoutMs, withTimeout } from \"./v3/timeoutConfig.js\";\nimport {\n buildActSystemPrompt,\n buildExtractSystemPrompt,\n buildExtractUserPrompt,\n buildMetadataPrompt,\n buildMetadataSystemPrompt,\n buildObserveSystemPrompt,\n buildObserveUserMessage,\n} from \"./prompt.js\";\nimport { appendSummary, writeTimestampedTxtFile } from \"./inferenceLogUtils.js\";\nimport type {\n InferStagehandSchema,\n StagehandZodObject,\n} from \"./v3/zodCompat.js\";\nimport { SupportedUnderstudyAction } from \"./v3/types/private/handlers.js\";\nimport type { Variables } from \"./v3/types/public/agent.js\";\n\n// Re-export for backward compatibility\nexport type { LLMParsedResponse, LLMUsage } from \"./v3/llm/LLMClient.js\";\n\nfunction withLlmTimeout<T>(promise: Promise<T>, operation: string): Promise<T> {\n return withTimeout(\n promise,\n getEnvTimeoutMs(\"LLM_MAX_MS\"),\n `LLM ${operation}`,\n );\n}\n\nexport async function extract<T extends StagehandZodObject>({\n instruction,\n domElements,\n schema,\n llmClient,\n logger,\n userProvidedInstructions,\n logInferenceToFile = false,\n}: {\n instruction: string;\n domElements: string;\n schema: T;\n llmClient: LLMClient;\n userProvidedInstructions?: string;\n logger: (message: LogLine) => void;\n logInferenceToFile?: boolean;\n}) {\n const metadataSchema = z.object({\n progress: z\n .string()\n .describe(\n \"progress of what has been extracted so far, as concise as possible\",\n ),\n completed: z\n .boolean()\n .describe(\n \"true if the goal is now accomplished. Use this conservatively, only when sure that the goal has been completed.\",\n ),\n });\n\n type ExtractionResponse = InferStagehandSchema<T>;\n type MetadataResponse = z.infer<typeof metadataSchema>;\n\n const isUsingAnthropic = llmClient.type === \"anthropic\";\n const isGPT5 = llmClient.modelName.includes(\"gpt-5\"); // TODO: remove this as we update support for gpt-5 configuration options\n\n const extractCallMessages: ChatMessage[] = [\n buildExtractSystemPrompt(isUsingAnthropic, userProvidedInstructions),\n buildExtractUserPrompt(instruction, domElements, isUsingAnthropic),\n ];\n\n let extractCallFile = \"\";\n let extractCallTimestamp = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"extract_call\",\n {\n modelCall: \"extract\",\n messages: extractCallMessages,\n },\n );\n extractCallFile = fileName;\n extractCallTimestamp = timestamp;\n }\n\n const extractStartTime = Date.now();\n const extractionResponse = await withLlmTimeout(\n llmClient.createChatCompletion<ExtractionResponse>({\n options: {\n messages: extractCallMessages,\n response_model: {\n schema,\n name: \"Extraction\",\n },\n temperature: isGPT5 ? 1 : 0.1,\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n }),\n \"extract\",\n );\n const extractEndTime = Date.now();\n\n const { data: extractedData, usage: extractUsage } = extractionResponse;\n\n let extractResponseFile: string;\n if (logInferenceToFile) {\n const { fileName } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"extract_response\",\n {\n modelResponse: \"extract\",\n rawResponse: extractedData,\n },\n );\n extractResponseFile = fileName;\n\n appendSummary(\"extract\", {\n extract_inference_type: \"extract\",\n timestamp: extractCallTimestamp,\n LLM_input_file: extractCallFile,\n LLM_output_file: extractResponseFile,\n prompt_tokens: extractUsage?.prompt_tokens ?? 0,\n completion_tokens: extractUsage?.completion_tokens ?? 0,\n reasoning_tokens: extractUsage?.reasoning_tokens ?? 0,\n cached_input_tokens: extractUsage?.cached_input_tokens ?? 0,\n inference_time_ms: extractEndTime - extractStartTime,\n });\n }\n\n const metadataCallMessages: ChatMessage[] = [\n buildMetadataSystemPrompt(),\n buildMetadataPrompt(instruction, extractedData),\n ];\n\n let metadataCallFile = \"\";\n let metadataCallTimestamp = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"metadata_call\",\n {\n modelCall: \"metadata\",\n messages: metadataCallMessages,\n },\n );\n metadataCallFile = fileName;\n metadataCallTimestamp = timestamp;\n }\n\n const metadataStartTime = Date.now();\n const metadataResponse = await withLlmTimeout(\n llmClient.createChatCompletion<MetadataResponse>({\n options: {\n messages: metadataCallMessages,\n response_model: {\n name: \"Metadata\",\n schema: metadataSchema,\n },\n temperature: isGPT5 ? 1 : 0.1,\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n }),\n \"extract metadata\",\n );\n const metadataEndTime = Date.now();\n\n const {\n data: {\n completed: metadataResponseCompleted,\n progress: metadataResponseProgress,\n },\n usage: metadataResponseUsage,\n } = metadataResponse;\n\n let metadataResponseFile: string;\n if (logInferenceToFile) {\n const { fileName } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"metadata_response\",\n {\n modelResponse: \"metadata\",\n completed: metadataResponseCompleted,\n progress: metadataResponseProgress,\n },\n );\n metadataResponseFile = fileName;\n\n appendSummary(\"extract\", {\n extract_inference_type: \"metadata\",\n timestamp: metadataCallTimestamp,\n LLM_input_file: metadataCallFile,\n LLM_output_file: metadataResponseFile,\n prompt_tokens: metadataResponseUsage?.prompt_tokens ?? 0,\n completion_tokens: metadataResponseUsage?.completion_tokens ?? 0,\n reasoning_tokens: metadataResponseUsage?.reasoning_tokens ?? 0,\n cached_input_tokens: metadataResponseUsage?.cached_input_tokens ?? 0,\n inference_time_ms: metadataEndTime - metadataStartTime,\n });\n }\n\n const totalPromptTokens =\n (extractUsage?.prompt_tokens ?? 0) +\n (metadataResponseUsage?.prompt_tokens ?? 0);\n\n const totalCompletionTokens =\n (extractUsage?.completion_tokens ?? 0) +\n (metadataResponseUsage?.completion_tokens ?? 0);\n\n const totalInferenceTimeMs =\n extractEndTime - extractStartTime + (metadataEndTime - metadataStartTime);\n const totalReasoningTokens =\n (extractUsage?.reasoning_tokens ?? 0) +\n (metadataResponseUsage?.reasoning_tokens ?? 0);\n const totalCachedInputTokens =\n (extractUsage?.cached_input_tokens ?? 0) +\n (metadataResponseUsage?.cached_input_tokens ?? 0);\n\n return {\n ...extractedData,\n metadata: {\n completed: metadataResponseCompleted,\n progress: metadataResponseProgress,\n },\n prompt_tokens: totalPromptTokens,\n completion_tokens: totalCompletionTokens,\n reasoning_tokens: totalReasoningTokens,\n cached_input_tokens: totalCachedInputTokens,\n inference_time_ms: totalInferenceTimeMs,\n };\n}\n\nexport async function observe({\n instruction,\n domElements,\n llmClient,\n userProvidedInstructions,\n logger,\n logInferenceToFile = false,\n supportedActions,\n variables,\n}: {\n instruction: string;\n domElements: string;\n llmClient: LLMClient;\n userProvidedInstructions?: string;\n logger: (message: LogLine) => void;\n logInferenceToFile?: boolean;\n supportedActions?: string[];\n variables?: Variables;\n}) {\n const isGPT5 = llmClient.modelName.includes(\"gpt-5\"); // TODO: remove this as we update support for gpt-5 configuration options\n\n const observeSchema = z.object({\n elements: z\n .array(\n z.object({\n elementId: z\n .string()\n .regex(/^\\d+-\\d+$/)\n .describe(\n \"the ID string associated with the element. Never include surrounding square brackets. This field must follow the format of 'number-number'.\",\n ),\n description: z\n .string()\n .describe(\n \"a description of the accessible element and its purpose\",\n ),\n method: z\n .enum(\n // Use Object.values() for Zod v3 compatibility - z.enum() in v3 doesn't accept TypeScript enums directly\n Object.values(SupportedUnderstudyAction) as unknown as readonly [\n string,\n ...string[],\n ],\n )\n .describe(\n `the candidate method/action to interact with the element. Select one of the available Understudy interaction methods.`,\n ),\n arguments: z.array(\n z\n .string()\n .describe(\n \"the arguments to pass to the method. For example, for a click, the arguments are empty, but for a fill, the arguments are the value to fill in.\",\n ),\n ),\n }),\n )\n .describe(\"an array of accessible elements that match the instruction\"),\n });\n\n type ObserveResponse = z.infer<typeof observeSchema>;\n\n const messages: ChatMessage[] = [\n buildObserveSystemPrompt(\n userProvidedInstructions,\n supportedActions,\n variables,\n ),\n buildObserveUserMessage(instruction, domElements),\n ];\n\n let callTimestamp = \"\";\n let callFile = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n `observe_summary`,\n `observe_call`,\n {\n modelCall: \"observe\",\n messages,\n },\n );\n callFile = fileName;\n callTimestamp = timestamp;\n }\n\n const start = Date.now();\n const rawResponse = await llmClient.createChatCompletion<ObserveResponse>({\n options: {\n messages,\n response_model: {\n schema: observeSchema,\n name: \"Observation\",\n },\n temperature: isGPT5 ? 1 : 0.1,\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n });\n const end = Date.now();\n const usageTimeMs = end - start;\n\n const { data: observeData, usage: observeUsage } = rawResponse;\n const promptTokens = observeUsage?.prompt_tokens ?? 0;\n const completionTokens = observeUsage?.completion_tokens ?? 0;\n const reasoningTokens = observeUsage?.reasoning_tokens ?? 0;\n const cachedInputTokens = observeUsage?.cached_input_tokens ?? 0;\n\n let responseFile: string;\n if (logInferenceToFile) {\n const { fileName: responseFileName } = writeTimestampedTxtFile(\n `observe_summary`,\n `observe_response`,\n {\n modelResponse: \"observe\",\n rawResponse: observeData,\n },\n );\n responseFile = responseFileName;\n\n appendSummary(\"observe\", {\n [`observe_inference_type`]: \"observe\",\n timestamp: callTimestamp,\n LLM_input_file: callFile,\n LLM_output_file: responseFile,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n });\n }\n\n const parsedElements =\n observeData.elements?.map((el) => {\n const base = {\n elementId: el.elementId,\n description: String(el.description),\n method: String(el.method),\n arguments: el.arguments,\n };\n return base;\n }) ?? [];\n\n return {\n elements: parsedElements,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n };\n}\n\nexport async function act({\n instruction,\n domElements,\n llmClient,\n userProvidedInstructions,\n logger,\n logInferenceToFile = false,\n}: {\n instruction: string;\n domElements: string;\n llmClient: LLMClient;\n userProvidedInstructions?: string;\n logger: (message: LogLine) => void;\n logInferenceToFile?: boolean;\n}) {\n const isGPT5 = llmClient.modelName.includes(\"gpt-5\"); // TODO: remove this as we update support for gpt-5 configuration options\n\n const actSchema = z.object({\n elementId: z\n .string()\n .regex(/^\\d+-\\d+$/)\n .describe(\n \"the ID string associated with the element. Never include surrounding square brackets. This field must follow the format of 'number-number'. for example, '0-76' or '16-21'\",\n ),\n description: z\n .string()\n .describe(\"a description of the accessible element and its purpose\"),\n method: z\n .enum(\n // Use Object.values() for Zod v3 compatibility - z.enum() in v3 doesn't accept TypeScript enums directly\n Object.values(SupportedUnderstudyAction) as unknown as readonly [\n string,\n ...string[],\n ],\n )\n .describe(\n \"the candidate method/action to interact with the element. Select one of the available Understudy interaction methods.\",\n ),\n arguments: z.array(\n z\n .string()\n .describe(\n \"the arguments to pass to the method. For example, for a click, the arguments are empty, but for a fill, the arguments are the value to fill in.\",\n ),\n ),\n twoStep: z.boolean(),\n });\n\n type ActResponse = z.infer<typeof actSchema>;\n\n const messages: ChatMessage[] = [\n buildActSystemPrompt(userProvidedInstructions),\n buildObserveUserMessage(instruction, domElements),\n ];\n\n let callTimestamp = \"\";\n let callFile = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n `act_summary`,\n `act_call`,\n {\n modelCall: \"act\",\n messages,\n },\n );\n callFile = fileName;\n callTimestamp = timestamp;\n }\n\n const start = Date.now();\n const rawResponse = await llmClient.createChatCompletion<ActResponse>({\n options: {\n messages,\n response_model: {\n schema: actSchema,\n name: \"act\",\n },\n temperature: isGPT5 ? 1 : 0.1,\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n });\n const end = Date.now();\n const usageTimeMs = end - start;\n\n const { data: actData, usage: actUsage } = rawResponse;\n const promptTokens = actUsage?.prompt_tokens ?? 0;\n const completionTokens = actUsage?.completion_tokens ?? 0;\n const reasoningTokens = actUsage?.reasoning_tokens ?? 0;\n const cachedInputTokens = actUsage?.cached_input_tokens ?? 0;\n\n let responseFile: string;\n if (logInferenceToFile) {\n const { fileName: responseFileName } = writeTimestampedTxtFile(\n `act_summary`,\n `act_response`,\n {\n modelResponse: \"act\",\n rawResponse: actData,\n },\n );\n responseFile = responseFileName;\n\n appendSummary(\"act\", {\n [`act_inference_type`]: \"act\",\n timestamp: callTimestamp,\n LLM_input_file: callFile,\n LLM_output_file: responseFile,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n });\n }\n\n const parsedElement = {\n elementId: actData.elementId,\n description: String(actData.description),\n method: String(actData.method),\n arguments: actData.arguments,\n };\n\n return {\n element: parsedElement,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n twoStep: actData.twoStep,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"inference.js","sourceRoot":"","sources":["../../../lib/inference.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport { LogLine } from \"./v3/types/public/logs.js\";\nimport { ChatMessage, LLMClient } from \"./v3/llm/LLMClient.js\";\nimport { getEnvTimeoutMs, withTimeout } from \"./v3/timeoutConfig.js\";\nimport {\n buildActSystemPrompt,\n buildExtractSystemPrompt,\n buildExtractUserPrompt,\n buildMetadataPrompt,\n buildMetadataSystemPrompt,\n buildObserveSystemPrompt,\n buildObserveUserMessage,\n} from \"./prompt.js\";\nimport { appendSummary, writeTimestampedTxtFile } from \"./inferenceLogUtils.js\";\nimport type {\n InferStagehandSchema,\n StagehandZodObject,\n} from \"./v3/zodCompat.js\";\nimport { SupportedUnderstudyAction } from \"./v3/types/private/handlers.js\";\nimport type { Variables } from \"./v3/types/public/agent.js\";\n\n// Re-export for backward compatibility\nexport type { LLMParsedResponse, LLMUsage } from \"./v3/llm/LLMClient.js\";\n\nfunction withLlmTimeout<T>(promise: Promise<T>, operation: string): Promise<T> {\n return withTimeout(\n promise,\n getEnvTimeoutMs(\"LLM_MAX_MS\"),\n `LLM ${operation}`,\n );\n}\n\nexport async function extract<T extends StagehandZodObject>({\n instruction,\n domElements,\n schema,\n llmClient,\n logger,\n userProvidedInstructions,\n logInferenceToFile = false,\n}: {\n instruction: string;\n domElements: string;\n schema: T;\n llmClient: LLMClient;\n userProvidedInstructions?: string;\n logger: (message: LogLine) => void;\n logInferenceToFile?: boolean;\n}) {\n const metadataSchema = z.object({\n progress: z\n .string()\n .describe(\n \"progress of what has been extracted so far, as concise as possible\",\n ),\n completed: z\n .boolean()\n .describe(\n \"true if the goal is now accomplished. Use this conservatively, only when sure that the goal has been completed.\",\n ),\n });\n\n type ExtractionResponse = InferStagehandSchema<T>;\n type MetadataResponse = z.infer<typeof metadataSchema>;\n\n const isUsingAnthropic = llmClient.type === \"anthropic\";\n const isGPT5 = llmClient.modelName.includes(\"gpt-5\"); // TODO: remove this as we update support for gpt-5 configuration options\n\n const extractCallMessages: ChatMessage[] = [\n buildExtractSystemPrompt(isUsingAnthropic, userProvidedInstructions),\n buildExtractUserPrompt(instruction, domElements, isUsingAnthropic),\n ];\n\n let extractCallFile = \"\";\n let extractCallTimestamp = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"extract_call\",\n {\n modelCall: \"extract\",\n messages: extractCallMessages,\n },\n );\n extractCallFile = fileName;\n extractCallTimestamp = timestamp;\n }\n\n const extractStartTime = Date.now();\n const extractionResponse = await withLlmTimeout(\n llmClient.createChatCompletion<ExtractionResponse>({\n options: {\n messages: extractCallMessages,\n response_model: {\n schema,\n name: \"Extraction\",\n },\n temperature: isGPT5 ? 1 : 0.1,\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n }),\n \"extract\",\n );\n const extractEndTime = Date.now();\n\n const { data: extractedData, usage: extractUsage } = extractionResponse;\n\n let extractResponseFile: string;\n if (logInferenceToFile) {\n const { fileName } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"extract_response\",\n {\n modelResponse: \"extract\",\n rawResponse: extractedData,\n },\n );\n extractResponseFile = fileName;\n\n appendSummary(\"extract\", {\n extract_inference_type: \"extract\",\n timestamp: extractCallTimestamp,\n LLM_input_file: extractCallFile,\n LLM_output_file: extractResponseFile,\n prompt_tokens: extractUsage?.prompt_tokens ?? 0,\n completion_tokens: extractUsage?.completion_tokens ?? 0,\n reasoning_tokens: extractUsage?.reasoning_tokens ?? 0,\n cached_input_tokens: extractUsage?.cached_input_tokens ?? 0,\n inference_time_ms: extractEndTime - extractStartTime,\n });\n }\n\n const metadataCallMessages: ChatMessage[] = [\n buildMetadataSystemPrompt(),\n buildMetadataPrompt(instruction, extractedData),\n ];\n\n let metadataCallFile = \"\";\n let metadataCallTimestamp = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"metadata_call\",\n {\n modelCall: \"metadata\",\n messages: metadataCallMessages,\n },\n );\n metadataCallFile = fileName;\n metadataCallTimestamp = timestamp;\n }\n\n const metadataStartTime = Date.now();\n const metadataResponse = await withLlmTimeout(\n llmClient.createChatCompletion<MetadataResponse>({\n options: {\n messages: metadataCallMessages,\n response_model: {\n name: \"Metadata\",\n schema: metadataSchema,\n },\n temperature: isGPT5 ? 1 : 0.1,\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n }),\n \"extract metadata\",\n );\n const metadataEndTime = Date.now();\n\n const {\n data: {\n completed: metadataResponseCompleted,\n progress: metadataResponseProgress,\n },\n usage: metadataResponseUsage,\n } = metadataResponse;\n\n let metadataResponseFile: string;\n if (logInferenceToFile) {\n const { fileName } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"metadata_response\",\n {\n modelResponse: \"metadata\",\n completed: metadataResponseCompleted,\n progress: metadataResponseProgress,\n },\n );\n metadataResponseFile = fileName;\n\n appendSummary(\"extract\", {\n extract_inference_type: \"metadata\",\n timestamp: metadataCallTimestamp,\n LLM_input_file: metadataCallFile,\n LLM_output_file: metadataResponseFile,\n prompt_tokens: metadataResponseUsage?.prompt_tokens ?? 0,\n completion_tokens: metadataResponseUsage?.completion_tokens ?? 0,\n reasoning_tokens: metadataResponseUsage?.reasoning_tokens ?? 0,\n cached_input_tokens: metadataResponseUsage?.cached_input_tokens ?? 0,\n inference_time_ms: metadataEndTime - metadataStartTime,\n });\n }\n\n const totalPromptTokens =\n (extractUsage?.prompt_tokens ?? 0) +\n (metadataResponseUsage?.prompt_tokens ?? 0);\n\n const totalCompletionTokens =\n (extractUsage?.completion_tokens ?? 0) +\n (metadataResponseUsage?.completion_tokens ?? 0);\n\n const totalInferenceTimeMs =\n extractEndTime - extractStartTime + (metadataEndTime - metadataStartTime);\n const totalReasoningTokens =\n (extractUsage?.reasoning_tokens ?? 0) +\n (metadataResponseUsage?.reasoning_tokens ?? 0);\n const totalCachedInputTokens =\n (extractUsage?.cached_input_tokens ?? 0) +\n (metadataResponseUsage?.cached_input_tokens ?? 0);\n\n return {\n ...extractedData,\n metadata: {\n completed: metadataResponseCompleted,\n progress: metadataResponseProgress,\n },\n prompt_tokens: totalPromptTokens,\n completion_tokens: totalCompletionTokens,\n reasoning_tokens: totalReasoningTokens,\n cached_input_tokens: totalCachedInputTokens,\n inference_time_ms: totalInferenceTimeMs,\n };\n}\n\nexport async function observe({\n instruction,\n domElements,\n llmClient,\n userProvidedInstructions,\n logger,\n logInferenceToFile = false,\n supportedActions,\n variables,\n}: {\n instruction: string;\n domElements: string;\n llmClient: LLMClient;\n userProvidedInstructions?: string;\n logger: (message: LogLine) => void;\n logInferenceToFile?: boolean;\n supportedActions?: string[];\n variables?: Variables;\n}) {\n const isGPT5 = llmClient.modelName.includes(\"gpt-5\"); // TODO: remove this as we update support for gpt-5 configuration options\n\n const observeSchema = z.object({\n elements: z\n .array(\n z.object({\n elementId: z\n .string()\n .regex(/^\\d+-\\d+$/)\n .describe(\n \"the ID string associated with the element. Never include surrounding square brackets. This field must follow the format of 'number-number'.\",\n ),\n description: z\n .string()\n .describe(\n \"a description of the accessible element and its purpose\",\n ),\n method: z\n .enum(\n // Use Object.values() for Zod v3 compatibility - z.enum() in v3 doesn't accept TypeScript enums directly\n Object.values(SupportedUnderstudyAction) as unknown as readonly [\n string,\n ...string[],\n ],\n )\n .describe(\n `the candidate method/action to interact with the element. Select one of the available Understudy interaction methods.`,\n ),\n arguments: z.array(\n z\n .string()\n .describe(\n \"the arguments to pass to the method. For example, for a click, the arguments are empty, but for a fill, the arguments are the value to fill in.\",\n ),\n ),\n }),\n )\n .describe(\"an array of accessible elements that match the instruction\"),\n });\n\n type ObserveResponse = z.infer<typeof observeSchema>;\n\n const messages: ChatMessage[] = [\n buildObserveSystemPrompt(\n userProvidedInstructions,\n supportedActions,\n variables,\n ),\n buildObserveUserMessage(instruction, domElements),\n ];\n\n let callTimestamp = \"\";\n let callFile = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n `observe_summary`,\n `observe_call`,\n {\n modelCall: \"observe\",\n messages,\n },\n );\n callFile = fileName;\n callTimestamp = timestamp;\n }\n\n const start = Date.now();\n const rawResponse = await llmClient.createChatCompletion<ObserveResponse>({\n options: {\n messages,\n response_model: {\n schema: observeSchema,\n name: \"Observation\",\n },\n temperature: isGPT5 ? 1 : 0.1,\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n });\n const end = Date.now();\n const usageTimeMs = end - start;\n\n const { data: observeData, usage: observeUsage } = rawResponse;\n const promptTokens = observeUsage?.prompt_tokens ?? 0;\n const completionTokens = observeUsage?.completion_tokens ?? 0;\n const reasoningTokens = observeUsage?.reasoning_tokens ?? 0;\n const cachedInputTokens = observeUsage?.cached_input_tokens ?? 0;\n\n let responseFile: string;\n if (logInferenceToFile) {\n const { fileName: responseFileName } = writeTimestampedTxtFile(\n `observe_summary`,\n `observe_response`,\n {\n modelResponse: \"observe\",\n rawResponse: observeData,\n },\n );\n responseFile = responseFileName;\n\n appendSummary(\"observe\", {\n [`observe_inference_type`]: \"observe\",\n timestamp: callTimestamp,\n LLM_input_file: callFile,\n LLM_output_file: responseFile,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n });\n }\n\n const parsedElements =\n observeData.elements?.map((el) => {\n const base = {\n elementId: el.elementId,\n description: String(el.description),\n method: String(el.method),\n arguments: el.arguments,\n };\n return base;\n }) ?? [];\n\n return {\n elements: parsedElements,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n };\n}\n\nexport async function act({\n instruction,\n domElements,\n llmClient,\n userProvidedInstructions,\n logger,\n logInferenceToFile = false,\n}: {\n instruction: string;\n domElements: string;\n llmClient: LLMClient;\n userProvidedInstructions?: string;\n logger: (message: LogLine) => void;\n logInferenceToFile?: boolean;\n}) {\n const isGPT5 = llmClient.modelName.includes(\"gpt-5\"); // TODO: remove this as we update support for gpt-5 configuration options\n\n const actSchema = z.object({\n action: z\n .object({\n elementId: z\n .string()\n .regex(/^\\d+-\\d+$/)\n .describe(\n \"the ID string associated with the element. Never include surrounding square brackets. This field must follow the format of 'number-number'. for example, '0-76' or '16-21'\",\n ),\n description: z\n .string()\n .describe(\"a description of the accessible element and its purpose\"),\n method: z\n .enum(\n // Use Object.values() for Zod v3 compatibility - z.enum() in v3 doesn't accept TypeScript enums directly\n Object.values(SupportedUnderstudyAction) as unknown as readonly [\n string,\n ...string[],\n ],\n )\n .describe(\n \"the candidate method/action to interact with the element. Select one of the available Understudy interaction methods.\",\n ),\n arguments: z.array(\n z\n .string()\n .describe(\n \"the arguments to pass to the method. For example, for a click, the arguments are empty, but for a fill, the arguments are the value to fill in.\",\n ),\n ),\n })\n .nullable()\n .describe(\n \"The element to act on. Return null if no element on the page matches the instruction — do NOT fabricate or guess an element, and never emit empty strings or placeholder values.\",\n ),\n twoStep: z.boolean().default(false),\n });\n\n type ActResponse = z.infer<typeof actSchema>;\n\n const messages: ChatMessage[] = [\n buildActSystemPrompt(userProvidedInstructions),\n buildObserveUserMessage(instruction, domElements),\n ];\n\n let callTimestamp = \"\";\n let callFile = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n `act_summary`,\n `act_call`,\n {\n modelCall: \"act\",\n messages,\n },\n );\n callFile = fileName;\n callTimestamp = timestamp;\n }\n\n const start = Date.now();\n const rawResponse = await llmClient.createChatCompletion<ActResponse>({\n options: {\n messages,\n response_model: {\n schema: actSchema,\n name: \"act\",\n },\n temperature: isGPT5 ? 1 : 0.1,\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n });\n const end = Date.now();\n const usageTimeMs = end - start;\n\n const { data: actData, usage: actUsage } = rawResponse;\n const promptTokens = actUsage?.prompt_tokens ?? 0;\n const completionTokens = actUsage?.completion_tokens ?? 0;\n const reasoningTokens = actUsage?.reasoning_tokens ?? 0;\n const cachedInputTokens = actUsage?.cached_input_tokens ?? 0;\n\n let responseFile: string;\n if (logInferenceToFile) {\n const { fileName: responseFileName } = writeTimestampedTxtFile(\n `act_summary`,\n `act_response`,\n {\n modelResponse: \"act\",\n rawResponse: actData,\n },\n );\n responseFile = responseFileName;\n\n appendSummary(\"act\", {\n [`act_inference_type`]: \"act\",\n timestamp: callTimestamp,\n LLM_input_file: callFile,\n LLM_output_file: responseFile,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n });\n }\n\n const parsedElement = actData.action\n ? {\n elementId: actData.action.elementId,\n description: String(actData.action.description),\n method: String(actData.action.method),\n arguments: actData.action.arguments,\n }\n : undefined;\n\n return {\n element: parsedElement,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n twoStep: actData.twoStep,\n };\n}\n"]}
|
package/dist/esm/lib/prompt.js
CHANGED
|
@@ -117,7 +117,7 @@ You will be given:
|
|
|
117
117
|
1. a user defined instruction about what action to take
|
|
118
118
|
2. a hierarchical accessibility tree showing the semantic structure of the page. The tree is a hybrid of the DOM and the accessibility tree.
|
|
119
119
|
|
|
120
|
-
Return the element that matches the instruction if it exists.
|
|
120
|
+
Return the element that matches the instruction if it exists. If no element on the page matches the instruction, set \`action\` to null. Do not fabricate or guess an element — empty strings or placeholder values for elementId/description/method are not acceptable.`;
|
|
121
121
|
const content = actSystemPrompt.replace(/\s+/g, " ");
|
|
122
122
|
return {
|
|
123
123
|
role: "system",
|
|
@@ -145,8 +145,8 @@ export function buildActPrompt(action, supportedActions, variables) {
|
|
|
145
145
|
General Instructions:
|
|
146
146
|
Provide an action for this element such as ${supportedActions.join(", ")}. Remember that to users, buttons and links look the same in most cases.
|
|
147
147
|
When choosing non-left click actions, provide right or middle as the argument
|
|
148
|
-
If the action is completely unrelated to a potential action to be taken on the page,
|
|
149
|
-
ONLY return one action. If multiple actions are relevant, return the most relevant one.
|
|
148
|
+
If the action is completely unrelated to a potential action to be taken on the page, or no matching element exists, set \`action\` to null. Do not fabricate or guess an element.
|
|
149
|
+
ONLY return one action. If multiple actions are relevant, return the most relevant one.
|
|
150
150
|
If the user is asking to scroll to a position on the page, e.g., 'halfway' or 0.75, etc, you must return the argument formatted as the correct percentage, e.g., '50%' or '75%', etc.
|
|
151
151
|
If the user is asking to scroll to the next chunk/previous chunk, choose the nextChunk/prevChunk method. No arguments are required here.
|
|
152
152
|
If the action implies a key press, e.g., 'press enter', 'press a', 'press space', etc., always choose the press method with the appropriate key as argument — e.g. 'a', 'Enter', 'Space'. Do not choose a click action on an on-screen keyboard. Capitalize the first character like 'Enter', 'Tab', 'Escape' only for special keys.
|
|
@@ -177,8 +177,8 @@ export function buildStepTwoPrompt(originalUserAction, previousAction, supported
|
|
|
177
177
|
|
|
178
178
|
General Instructions:
|
|
179
179
|
Provide an action for this element such as ${supportedActions.join(", ")}. Remember that to users, buttons and links look the same in most cases.
|
|
180
|
-
If the action is completely unrelated to a potential action to be taken on the page,
|
|
181
|
-
ONLY return one action. If multiple actions are relevant, return the most relevant one.
|
|
180
|
+
If the action is completely unrelated to a potential action to be taken on the page, or no matching element exists, set \`action\` to null. Do not fabricate or guess an element.
|
|
181
|
+
ONLY return one action. If multiple actions are relevant, return the most relevant one.
|
|
182
182
|
If the user is asking to scroll to a position on the page, e.g., 'halfway' or 0.75, etc, you must return the argument formatted as the correct percentage, e.g., '50%' or '75%', etc.
|
|
183
183
|
If the user is asking to scroll to the next chunk/previous chunk, choose the nextChunk/prevChunk method. No arguments are required here.
|
|
184
184
|
If the action implies a key press, e.g., 'press enter', 'press a', 'press space', etc., always choose the press method with the appropriate key as argument — e.g. 'a', 'Enter', 'Space'. Do not choose a click action on an on-screen keyboard. Capitalize the first character like 'Enter', 'Tab', 'Escape' only for special keys.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../lib/prompt.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChatMessage } from \"./v3/llm/LLMClient.js\";\nimport type { Variables } from \"./v3/types/public/agent.js\";\nimport { getVariablePromptEntries } from \"./v3/agent/utils/variables.js\";\n\nexport function buildUserInstructionsString(\n userProvidedInstructions?: string,\n): string {\n if (!userProvidedInstructions) {\n return \"\";\n }\n\n return `\\n\\n# Custom Instructions Provided by the User\n \nPlease keep the user's instructions in mind when performing actions. If the user's instructions are not relevant to the current task, ignore them.\n\nUser Instructions:\n${userProvidedInstructions}`;\n}\n\n// extract\nexport function buildExtractSystemPrompt(\n isUsingPrintExtractedDataTool: boolean = false,\n userProvidedInstructions?: string,\n): ChatMessage {\n const baseContent = `You are extracting content on behalf of a user.\n If a user asks you to extract a 'list' of information, or 'all' information, \n YOU MUST EXTRACT ALL OF THE INFORMATION THAT THE USER REQUESTS.\n \n You will be given:\n1. An instruction\n2. `;\n\n const contentDetail = `A list of DOM elements to extract from.`;\n\n const instructions = `\nPrint the exact text from the DOM elements with all symbols, characters, and endlines as is.\nPrint null or an empty string if no new information is found.\n `.trim();\n\n const toolInstructions = isUsingPrintExtractedDataTool\n ? `\nONLY print the content using the print_extracted_data tool provided.\nONLY print the content using the print_extracted_data tool provided.\n `.trim()\n : \"\";\n\n const additionalInstructions =\n \"If a user is attempting to extract links or URLs, you MUST respond with ONLY the IDs of the link elements. \\n\" +\n \"Do not attempt to extract links directly from the text unless absolutely necessary. \";\n\n const userInstructions = buildUserInstructionsString(\n userProvidedInstructions,\n );\n\n const content =\n `${baseContent}${contentDetail}\\n\\n${instructions}\\n${toolInstructions}${\n additionalInstructions ? `\\n\\n${additionalInstructions}` : \"\"\n }${userInstructions ? `\\n\\n${userInstructions}` : \"\"}`.replace(/\\s+/g, \" \");\n\n return {\n role: \"system\",\n content,\n };\n}\n\nexport function buildExtractUserPrompt(\n instruction: string,\n domElements: string,\n isUsingPrintExtractedDataTool: boolean = false,\n): ChatMessage {\n let content = `Instruction: ${instruction}\nDOM: ${domElements}`;\n\n if (isUsingPrintExtractedDataTool) {\n content += `\nONLY print the content using the print_extracted_data tool provided.\nONLY print the content using the print_extracted_data tool provided.`;\n }\n\n return {\n role: \"user\",\n content,\n };\n}\n\nconst metadataSystemPrompt = `You are an AI assistant tasked with evaluating the progress and completion status of an extraction task.\nAnalyze the extraction response and determine if the task is completed or if more information is needed.\nStrictly abide by the following criteria:\n1. Once the instruction has been satisfied by the current extraction response, ALWAYS set completion status to true and stop processing, regardless of remaining chunks.\n2. Only set completion status to false if BOTH of these conditions are true:\n - The instruction has not been satisfied yet\n - There are still chunks left to process (chunksTotal > chunksSeen)`;\n\nexport function buildMetadataSystemPrompt(): ChatMessage {\n return {\n role: \"system\",\n content: metadataSystemPrompt,\n };\n}\n\nexport function buildMetadataPrompt(\n instruction: string,\n extractionResponse: object,\n): ChatMessage {\n return {\n role: \"user\",\n content: `Instruction: ${instruction}\nExtracted content: ${JSON.stringify(extractionResponse, null, 2)}`,\n };\n}\n\n// observe\nexport function buildObserveSystemPrompt(\n userProvidedInstructions?: string,\n supportedActions?: string[],\n variables?: Variables,\n): ChatMessage {\n const actionsString = supportedActions?.length\n ? `\\n\\nSupported actions: ${supportedActions.join(\", \")}`\n : \"\";\n const variableEntries = getVariablePromptEntries(variables);\n const variablesString = variableEntries.length\n ? `\\n\\nAvailable variables: ${variableEntries\n .map(({ name, description }) => {\n return description ? `%${name}% (${description})` : `%${name}%`;\n })\n .join(\n \", \",\n )}. When an action needs a dynamic or sensitive value, return the matching %variableName% placeholder in the action arguments instead of a literal value`\n : \"\";\n\n const observeSystemPrompt = `\nYou are helping the user automate the browser by finding elements based on what the user wants to observe in the page.\n\nYou will be given:\n1. a instruction of elements to observe\n2. a hierarchical accessibility tree showing the semantic structure of the page. The tree is a hybrid of the DOM and the accessibility tree.\n\nReturn an array of elements that match the instruction if they exist, otherwise return an empty array.\nWhen returning elements, include the appropriate method from the supported actions list.${actionsString}${variablesString}. When choosing non-left click actions, provide right or middle as the argument.`;\n const content = observeSystemPrompt.replace(/\\s+/g, \" \");\n\n return {\n role: \"system\",\n content: [content, buildUserInstructionsString(userProvidedInstructions)]\n .filter(Boolean)\n .join(\"\\n\\n\"),\n };\n}\n\nexport function buildObserveUserMessage(\n instruction: string,\n domElements: string,\n): ChatMessage {\n return {\n role: \"user\",\n content: `instruction: ${instruction}\nAccessibility Tree: \\n${domElements}\\n`,\n };\n}\n\nexport function buildActSystemPrompt(\n userProvidedInstructions?: string,\n): ChatMessage {\n const actSystemPrompt = `\nYou are helping the user automate the browser by finding elements based on what action the user wants to take on the page\n\nYou will be given:\n1. a user defined instruction about what action to take\n2. a hierarchical accessibility tree showing the semantic structure of the page. The tree is a hybrid of the DOM and the accessibility tree.\n\nReturn the element that matches the instruction if it exists. Otherwise, return an empty object.`;\n const content = actSystemPrompt.replace(/\\s+/g, \" \");\n\n return {\n role: \"system\",\n content: [content, buildUserInstructionsString(userProvidedInstructions)]\n .filter(Boolean)\n .join(\"\\n\\n\"),\n };\n}\n\nfunction buildActVariablesPrompt(variables?: Variables): string {\n if (!variables || Object.keys(variables).length === 0) {\n return \"\";\n }\n\n const variableNames = Object.keys(variables)\n .map((key) => `%${key}%`)\n .join(\", \");\n\n return ` The user has provided the following variables to be used in the action: ${variableNames} \\n\n Note that these are the variable names/keys, and not the actual variable values. \\n\n To use the variables in the action, you must respond with the variable name inside the 'arguments' array. The variable name must be wrapped in percentage signs (eg, %variableNameHere%) so that it can be replaced with the actual variable value before the action is taken. \\n`;\n}\n\nexport function buildActPrompt(\n action: string,\n supportedActions: string[],\n variables?: Variables,\n): string {\n // Base instruction\n let instruction = `Find the most relevant element to perform an action on given the following action: ${action}. \n IF AND ONLY IF the action EXPLICITLY includes the word 'dropdown' and implies choosing/selecting an option from a dropdown, ignore the 'General Instructions' section, and follow the 'Dropdown Specific Instructions' section carefully.\n \n General Instructions: \n Provide an action for this element such as ${supportedActions.join(\", \")}. Remember that to users, buttons and links look the same in most cases.\n When choosing non-left click actions, provide right or middle as the argument\n If the action is completely unrelated to a potential action to be taken on the page, return an empty object. \n ONLY return one action. If multiple actions are relevant, return the most relevant one. \n If the user is asking to scroll to a position on the page, e.g., 'halfway' or 0.75, etc, you must return the argument formatted as the correct percentage, e.g., '50%' or '75%', etc.\n If the user is asking to scroll to the next chunk/previous chunk, choose the nextChunk/prevChunk method. No arguments are required here.\n If the action implies a key press, e.g., 'press enter', 'press a', 'press space', etc., always choose the press method with the appropriate key as argument — e.g. 'a', 'Enter', 'Space'. Do not choose a click action on an on-screen keyboard. Capitalize the first character like 'Enter', 'Tab', 'Escape' only for special keys. \n \n Dropdown Specific Instructions:\n For interacting with dropdowns, there are two specific cases that you need to handle. \n \n CASE 1: the element is a 'select' element. \n - choose the selectOptionFromDropdown method,\n - set the argument to the exact text of the option that should be selected,\n - set twoStep to false.\n CASE 2: the element is NOT a 'select' element:\n - do not attempt to directly choose the element from the dropdown. You will need to click to expand the dropdown first. You will achieve this by following these instructions:\n - choose the node that most closely corresponds to the given instruction EVEN if it is a 'StaticText' element, or otherwise does not appear to be interactable. \n - choose the 'click' method\n - set twoStep to true.\n `;\n\n instruction += buildActVariablesPrompt(variables);\n\n return instruction;\n}\n\nexport function buildStepTwoPrompt(\n originalUserAction: string,\n previousAction: string,\n supportedActions: string[],\n variables?: Variables,\n): string {\n // Base instruction\n let instruction = `\n The original user action was: ${originalUserAction}.\n You have just taken the following action which completed step 1 of 2: ${previousAction}.\n \n Now, you must find the most relevant element to perform an action on in order to complete step 2 of 2. \n \n General Instructions: \n Provide an action for this element such as ${supportedActions.join(\", \")}. Remember that to users, buttons and links look the same in most cases.\n If the action is completely unrelated to a potential action to be taken on the page, return an empty object. \n ONLY return one action. If multiple actions are relevant, return the most relevant one. \n If the user is asking to scroll to a position on the page, e.g., 'halfway' or 0.75, etc, you must return the argument formatted as the correct percentage, e.g., '50%' or '75%', etc.\n If the user is asking to scroll to the next chunk/previous chunk, choose the nextChunk/prevChunk method. No arguments are required here.\n If the action implies a key press, e.g., 'press enter', 'press a', 'press space', etc., always choose the press method with the appropriate key as argument — e.g. 'a', 'Enter', 'Space'. Do not choose a click action on an on-screen keyboard. Capitalize the first character like 'Enter', 'Tab', 'Escape' only for special keys. \n `;\n\n instruction += buildActVariablesPrompt(variables);\n\n return instruction;\n}\n\nexport function buildOperatorSystemPrompt(goal: string): ChatMessage {\n return {\n role: \"system\",\n content: `You are a general-purpose agent whose job is to accomplish the user's goal across multiple model calls by running actions on the page.\n\nYou will be given a goal and a list of steps that have been taken so far. Your job is to determine if either the user's goal has been completed or if there are still steps that need to be taken.\n\n# Your current goal\n${goal}\n\n# CRITICAL: You MUST use the provided tools to take actions. Do not just describe what you want to do - actually call the appropriate tools.\n\n# Available tools and when to use them:\n- \\`act\\`: Use this to interact with the page (click, type, navigate, etc.)\n- \\`extract\\`: Use this to get information from the page\n- \\`goto\\`: Use this to navigate to a specific URL\n- \\`wait\\`: Use this to wait for a period of time\n- \\`navback\\`: Use this to go back to the previous page\n- \\`refresh\\`: Use this to refresh the current page\n- \\`close\\`: Use this ONLY when the task is complete or cannot be achieved\n- External tools: Use any additional tools (like search tools) as needed for your goal\n\n# Important guidelines\n1. ALWAYS use tools - never just provide text responses about what you plan to do\n2. Break down complex actions into individual atomic steps\n3. For \\`act\\` commands, use only one action at a time, such as:\n - Single click on a specific element\n - Type into a single input field\n - Select a single option\n4. Avoid combining multiple actions in one instruction\n5. If multiple actions are needed, they should be separate steps\n6. Only use \\`close\\` when the task is genuinely complete or impossible to achieve`,\n };\n}\n\nexport function buildCuaDefaultSystemPrompt(): string {\n return `You are a helpful assistant that can use a web browser.\\nDo not ask follow up questions, the user will trust your judgement. Today's date is ${new Date().toISOString().split(\"T\")[0]}.`;\n}\n\nexport function buildGoogleCUASystemPrompt(): ChatMessage {\n return {\n role: \"system\",\n content: `You are a general-purpose browser agent whose job is to accomplish the user's goal.\nToday's date is ${new Date().toISOString().split(\"T\")[0]}.\nYou have access to a search tool; however, in most cases you should operate within the page/url the user has provided. ONLY use the search tool if you're stuck or the task is impossible to complete within the current page.\nYou will be given a goal and a list of steps that have been taken so far. Avoid requesting the user for input as much as possible. Good luck!\n`,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../lib/prompt.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChatMessage } from \"./v3/llm/LLMClient.js\";\nimport type { Variables } from \"./v3/types/public/agent.js\";\nimport { getVariablePromptEntries } from \"./v3/agent/utils/variables.js\";\n\nexport function buildUserInstructionsString(\n userProvidedInstructions?: string,\n): string {\n if (!userProvidedInstructions) {\n return \"\";\n }\n\n return `\\n\\n# Custom Instructions Provided by the User\n \nPlease keep the user's instructions in mind when performing actions. If the user's instructions are not relevant to the current task, ignore them.\n\nUser Instructions:\n${userProvidedInstructions}`;\n}\n\n// extract\nexport function buildExtractSystemPrompt(\n isUsingPrintExtractedDataTool: boolean = false,\n userProvidedInstructions?: string,\n): ChatMessage {\n const baseContent = `You are extracting content on behalf of a user.\n If a user asks you to extract a 'list' of information, or 'all' information, \n YOU MUST EXTRACT ALL OF THE INFORMATION THAT THE USER REQUESTS.\n \n You will be given:\n1. An instruction\n2. `;\n\n const contentDetail = `A list of DOM elements to extract from.`;\n\n const instructions = `\nPrint the exact text from the DOM elements with all symbols, characters, and endlines as is.\nPrint null or an empty string if no new information is found.\n `.trim();\n\n const toolInstructions = isUsingPrintExtractedDataTool\n ? `\nONLY print the content using the print_extracted_data tool provided.\nONLY print the content using the print_extracted_data tool provided.\n `.trim()\n : \"\";\n\n const additionalInstructions =\n \"If a user is attempting to extract links or URLs, you MUST respond with ONLY the IDs of the link elements. \\n\" +\n \"Do not attempt to extract links directly from the text unless absolutely necessary. \";\n\n const userInstructions = buildUserInstructionsString(\n userProvidedInstructions,\n );\n\n const content =\n `${baseContent}${contentDetail}\\n\\n${instructions}\\n${toolInstructions}${\n additionalInstructions ? `\\n\\n${additionalInstructions}` : \"\"\n }${userInstructions ? `\\n\\n${userInstructions}` : \"\"}`.replace(/\\s+/g, \" \");\n\n return {\n role: \"system\",\n content,\n };\n}\n\nexport function buildExtractUserPrompt(\n instruction: string,\n domElements: string,\n isUsingPrintExtractedDataTool: boolean = false,\n): ChatMessage {\n let content = `Instruction: ${instruction}\nDOM: ${domElements}`;\n\n if (isUsingPrintExtractedDataTool) {\n content += `\nONLY print the content using the print_extracted_data tool provided.\nONLY print the content using the print_extracted_data tool provided.`;\n }\n\n return {\n role: \"user\",\n content,\n };\n}\n\nconst metadataSystemPrompt = `You are an AI assistant tasked with evaluating the progress and completion status of an extraction task.\nAnalyze the extraction response and determine if the task is completed or if more information is needed.\nStrictly abide by the following criteria:\n1. Once the instruction has been satisfied by the current extraction response, ALWAYS set completion status to true and stop processing, regardless of remaining chunks.\n2. Only set completion status to false if BOTH of these conditions are true:\n - The instruction has not been satisfied yet\n - There are still chunks left to process (chunksTotal > chunksSeen)`;\n\nexport function buildMetadataSystemPrompt(): ChatMessage {\n return {\n role: \"system\",\n content: metadataSystemPrompt,\n };\n}\n\nexport function buildMetadataPrompt(\n instruction: string,\n extractionResponse: object,\n): ChatMessage {\n return {\n role: \"user\",\n content: `Instruction: ${instruction}\nExtracted content: ${JSON.stringify(extractionResponse, null, 2)}`,\n };\n}\n\n// observe\nexport function buildObserveSystemPrompt(\n userProvidedInstructions?: string,\n supportedActions?: string[],\n variables?: Variables,\n): ChatMessage {\n const actionsString = supportedActions?.length\n ? `\\n\\nSupported actions: ${supportedActions.join(\", \")}`\n : \"\";\n const variableEntries = getVariablePromptEntries(variables);\n const variablesString = variableEntries.length\n ? `\\n\\nAvailable variables: ${variableEntries\n .map(({ name, description }) => {\n return description ? `%${name}% (${description})` : `%${name}%`;\n })\n .join(\n \", \",\n )}. When an action needs a dynamic or sensitive value, return the matching %variableName% placeholder in the action arguments instead of a literal value`\n : \"\";\n\n const observeSystemPrompt = `\nYou are helping the user automate the browser by finding elements based on what the user wants to observe in the page.\n\nYou will be given:\n1. a instruction of elements to observe\n2. a hierarchical accessibility tree showing the semantic structure of the page. The tree is a hybrid of the DOM and the accessibility tree.\n\nReturn an array of elements that match the instruction if they exist, otherwise return an empty array.\nWhen returning elements, include the appropriate method from the supported actions list.${actionsString}${variablesString}. When choosing non-left click actions, provide right or middle as the argument.`;\n const content = observeSystemPrompt.replace(/\\s+/g, \" \");\n\n return {\n role: \"system\",\n content: [content, buildUserInstructionsString(userProvidedInstructions)]\n .filter(Boolean)\n .join(\"\\n\\n\"),\n };\n}\n\nexport function buildObserveUserMessage(\n instruction: string,\n domElements: string,\n): ChatMessage {\n return {\n role: \"user\",\n content: `instruction: ${instruction}\nAccessibility Tree: \\n${domElements}\\n`,\n };\n}\n\nexport function buildActSystemPrompt(\n userProvidedInstructions?: string,\n): ChatMessage {\n const actSystemPrompt = `\nYou are helping the user automate the browser by finding elements based on what action the user wants to take on the page\n\nYou will be given:\n1. a user defined instruction about what action to take\n2. a hierarchical accessibility tree showing the semantic structure of the page. The tree is a hybrid of the DOM and the accessibility tree.\n\nReturn the element that matches the instruction if it exists. If no element on the page matches the instruction, set \\`action\\` to null. Do not fabricate or guess an element — empty strings or placeholder values for elementId/description/method are not acceptable.`;\n const content = actSystemPrompt.replace(/\\s+/g, \" \");\n\n return {\n role: \"system\",\n content: [content, buildUserInstructionsString(userProvidedInstructions)]\n .filter(Boolean)\n .join(\"\\n\\n\"),\n };\n}\n\nfunction buildActVariablesPrompt(variables?: Variables): string {\n if (!variables || Object.keys(variables).length === 0) {\n return \"\";\n }\n\n const variableNames = Object.keys(variables)\n .map((key) => `%${key}%`)\n .join(\", \");\n\n return ` The user has provided the following variables to be used in the action: ${variableNames} \\n\n Note that these are the variable names/keys, and not the actual variable values. \\n\n To use the variables in the action, you must respond with the variable name inside the 'arguments' array. The variable name must be wrapped in percentage signs (eg, %variableNameHere%) so that it can be replaced with the actual variable value before the action is taken. \\n`;\n}\n\nexport function buildActPrompt(\n action: string,\n supportedActions: string[],\n variables?: Variables,\n): string {\n // Base instruction\n let instruction = `Find the most relevant element to perform an action on given the following action: ${action}. \n IF AND ONLY IF the action EXPLICITLY includes the word 'dropdown' and implies choosing/selecting an option from a dropdown, ignore the 'General Instructions' section, and follow the 'Dropdown Specific Instructions' section carefully.\n \n General Instructions: \n Provide an action for this element such as ${supportedActions.join(\", \")}. Remember that to users, buttons and links look the same in most cases.\n When choosing non-left click actions, provide right or middle as the argument\n If the action is completely unrelated to a potential action to be taken on the page, or no matching element exists, set \\`action\\` to null. Do not fabricate or guess an element.\n ONLY return one action. If multiple actions are relevant, return the most relevant one.\n If the user is asking to scroll to a position on the page, e.g., 'halfway' or 0.75, etc, you must return the argument formatted as the correct percentage, e.g., '50%' or '75%', etc.\n If the user is asking to scroll to the next chunk/previous chunk, choose the nextChunk/prevChunk method. No arguments are required here.\n If the action implies a key press, e.g., 'press enter', 'press a', 'press space', etc., always choose the press method with the appropriate key as argument — e.g. 'a', 'Enter', 'Space'. Do not choose a click action on an on-screen keyboard. Capitalize the first character like 'Enter', 'Tab', 'Escape' only for special keys. \n \n Dropdown Specific Instructions:\n For interacting with dropdowns, there are two specific cases that you need to handle. \n \n CASE 1: the element is a 'select' element. \n - choose the selectOptionFromDropdown method,\n - set the argument to the exact text of the option that should be selected,\n - set twoStep to false.\n CASE 2: the element is NOT a 'select' element:\n - do not attempt to directly choose the element from the dropdown. You will need to click to expand the dropdown first. You will achieve this by following these instructions:\n - choose the node that most closely corresponds to the given instruction EVEN if it is a 'StaticText' element, or otherwise does not appear to be interactable. \n - choose the 'click' method\n - set twoStep to true.\n `;\n\n instruction += buildActVariablesPrompt(variables);\n\n return instruction;\n}\n\nexport function buildStepTwoPrompt(\n originalUserAction: string,\n previousAction: string,\n supportedActions: string[],\n variables?: Variables,\n): string {\n // Base instruction\n let instruction = `\n The original user action was: ${originalUserAction}.\n You have just taken the following action which completed step 1 of 2: ${previousAction}.\n \n Now, you must find the most relevant element to perform an action on in order to complete step 2 of 2. \n \n General Instructions: \n Provide an action for this element such as ${supportedActions.join(\", \")}. Remember that to users, buttons and links look the same in most cases.\n If the action is completely unrelated to a potential action to be taken on the page, or no matching element exists, set \\`action\\` to null. Do not fabricate or guess an element.\n ONLY return one action. If multiple actions are relevant, return the most relevant one.\n If the user is asking to scroll to a position on the page, e.g., 'halfway' or 0.75, etc, you must return the argument formatted as the correct percentage, e.g., '50%' or '75%', etc.\n If the user is asking to scroll to the next chunk/previous chunk, choose the nextChunk/prevChunk method. No arguments are required here.\n If the action implies a key press, e.g., 'press enter', 'press a', 'press space', etc., always choose the press method with the appropriate key as argument — e.g. 'a', 'Enter', 'Space'. Do not choose a click action on an on-screen keyboard. Capitalize the first character like 'Enter', 'Tab', 'Escape' only for special keys. \n `;\n\n instruction += buildActVariablesPrompt(variables);\n\n return instruction;\n}\n\nexport function buildOperatorSystemPrompt(goal: string): ChatMessage {\n return {\n role: \"system\",\n content: `You are a general-purpose agent whose job is to accomplish the user's goal across multiple model calls by running actions on the page.\n\nYou will be given a goal and a list of steps that have been taken so far. Your job is to determine if either the user's goal has been completed or if there are still steps that need to be taken.\n\n# Your current goal\n${goal}\n\n# CRITICAL: You MUST use the provided tools to take actions. Do not just describe what you want to do - actually call the appropriate tools.\n\n# Available tools and when to use them:\n- \\`act\\`: Use this to interact with the page (click, type, navigate, etc.)\n- \\`extract\\`: Use this to get information from the page\n- \\`goto\\`: Use this to navigate to a specific URL\n- \\`wait\\`: Use this to wait for a period of time\n- \\`navback\\`: Use this to go back to the previous page\n- \\`refresh\\`: Use this to refresh the current page\n- \\`close\\`: Use this ONLY when the task is complete or cannot be achieved\n- External tools: Use any additional tools (like search tools) as needed for your goal\n\n# Important guidelines\n1. ALWAYS use tools - never just provide text responses about what you plan to do\n2. Break down complex actions into individual atomic steps\n3. For \\`act\\` commands, use only one action at a time, such as:\n - Single click on a specific element\n - Type into a single input field\n - Select a single option\n4. Avoid combining multiple actions in one instruction\n5. If multiple actions are needed, they should be separate steps\n6. Only use \\`close\\` when the task is genuinely complete or impossible to achieve`,\n };\n}\n\nexport function buildCuaDefaultSystemPrompt(): string {\n return `You are a helpful assistant that can use a web browser.\\nDo not ask follow up questions, the user will trust your judgement. Today's date is ${new Date().toISOString().split(\"T\")[0]}.`;\n}\n\nexport function buildGoogleCUASystemPrompt(): ChatMessage {\n return {\n role: \"system\",\n content: `You are a general-purpose browser agent whose job is to accomplish the user's goal.\nToday's date is ${new Date().toISOString().split(\"T\")[0]}.\nYou have access to a search tool; however, in most cases you should operate within the page/url the user has provided. ONLY use the search tool if you're stuck or the task is impossible to complete within the current page.\nYou will be given a goal and a list of steps that have been taken so far. Avoid requesting the user for input as much as possible. Good luck!\n`,\n };\n}\n"]}
|
|
@@ -132,10 +132,12 @@ test.describe("flow logger integration", () => {
|
|
|
132
132
|
const llmClient = createScriptedAisdkTestLlmClient({
|
|
133
133
|
jsonResponses: {
|
|
134
134
|
act: (options) => ({
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
135
|
+
action: {
|
|
136
|
+
elementId: findLastEncodedId(options),
|
|
137
|
+
description: `click ${buttonText}`,
|
|
138
|
+
method: "click",
|
|
139
|
+
arguments: [],
|
|
140
|
+
},
|
|
139
141
|
twoStep: false,
|
|
140
142
|
}),
|
|
141
143
|
},
|
|
@@ -296,10 +298,12 @@ test.describe("flow logger integration", () => {
|
|
|
296
298
|
const llmClient = createScriptedAisdkTestLlmClient({
|
|
297
299
|
jsonResponses: {
|
|
298
300
|
act: (options) => ({
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
301
|
+
action: {
|
|
302
|
+
elementId: findLastEncodedId(options),
|
|
303
|
+
description: `click ${buttonText}`,
|
|
304
|
+
method: "click",
|
|
305
|
+
arguments: [],
|
|
306
|
+
},
|
|
303
307
|
twoStep: false,
|
|
304
308
|
}),
|
|
305
309
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flowLogger.spec.js","sourceRoot":"","sources":["../../../../tests/integration/flowLogger.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uDAAuD,CAAC;AAChG,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACxC,OAAO,EACL,gCAAgC,EAChC,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,kBAAkB,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;AACtD,CAAC;AAED,SAAS,0BAA0B,CACjC,YAAmD,EAAE;IAErD,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,IAAI,iBAAiB,EAAE,CAAC;IACrC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAc,EAAE,EAAE;QAChC,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;YAC/B,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,KAAK,EAAE,EAAE,CAC9B,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,CAAC;IAC/D,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,EAAM;IAC1C,OAAO,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACjC,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,EAAM;IAC5C,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,EAAE,CAAC,CAAC;IAChD,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AACvD,CAAC;AAED,KAAK,UAAU,2BAA2B,CACxC,EAAM,EACN,QAAqB;IAErB,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,EAAE,CAAC,CAAC;IAChD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,YAAY,CAAC,MAAmB,EAAE,SAAiB;IAC1D,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAmB,EAAE,SAAiB;IAChE,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChD,MAAM,CAAC,OAAO,EAAE,qBAAqB,SAAS,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAClE,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED,SAAS,eAAe,CAAC,KAAgB;IACvC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAgB,EAAE,MAAiB;IAC7D,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC;QACnC,GAAG,MAAM,CAAC,cAAc;QACxB,MAAM,CAAC,OAAO;KACf,CAAC,CAAC;AACL,CAAC;AAED,SAAS,yBAAyB,CAAC,MAAmB;IACpD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAE/D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;YAC5C,MAAM,CACJ,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EACtB,GAAG,KAAK,CAAC,SAAS,8BAA8B,QAAQ,EAAE,CAC3D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAmB,EAAE,SAAiB;IAC9D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAC3B,MAAmB,EACnB,MAAiB,EACjB,SAAiB;IAEjB,MAAM,iBAAiB,GAAG,CAAC,GAAG,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,MAAM,CAClB,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,SAAS,KAAK,SAAS;QAC7B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,cAAc,CAAC;YAClC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CACtC,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAC9B,MAAmB,EACnB,SAAiB,EACjB,kBAAkB,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,gBAAgB;IAEvE,MAAM,IAAI,GAAG,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACjE,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,yBAAyB,CAAC,MAAmB;IACpD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAC7B,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,SAAS,KAAK,iBAAiB;QACrC,KAAK,CAAC,SAAS,KAAK,kBAAkB,CACzC,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAEpE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAE5C,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,MAAM,CACJ,KAAK,CAAC,cAAc,CAAC,MAAM,EAC3B,GAAG,KAAK,CAAC,SAAS,cAAc,CACjC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,YAAY,GAAG,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACrE,MAAM,CACJ,UAAU,EACV,GAAG,KAAK,CAAC,SAAS,yBAAyB,CAC5C,CAAC,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC;AAED,SAAS,yBAAyB,CAAC,MAAmB;IACpD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9E,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAEpE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAE5C,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,MAAM,CACJ,KAAK,CAAC,cAAc,CAAC,MAAM,EAC3B,GAAG,KAAK,CAAC,SAAS,cAAc,CACjC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,YAAY,GAAG,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACrE,MAAM,CACJ,UAAU,EACV,GAAG,KAAK,CAAC,SAAS,yBAAyB,CAC5C,CAAC,WAAW,EAAE,CAAC;QAEhB,IAAI,KAAK,CAAC,SAAS,KAAK,cAAc,EAAE,CAAC;YACvC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,yBAAyB,CAChC,MAAmB,EACnB,SAAiB;IAEjB,MAAM,IAAI,GAAG,kBAAkB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACxD,MAAM,aAAa,GAAG,CAAC,kBAAkB,EAAE,uBAAuB,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CACrC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CACxC,CAAC;IAEF,MAAM,CAAC,QAAQ,EAAE,sCAAsC,CAAC,CAAC,WAAW,EAAE,CAAC;IACvE,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,eAAe,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,eAAe,CACtB,KAA6B;IAE7B,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAC3E,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAC9B,MAAmB,EACnB,QAAgC;IAEhC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAyB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QACrE,IAAI,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,IAAI,CAAC,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IAC5C,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAE5C,IAAI,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,UAAU,GAAG,wBAAwB,CAAC;QAC5C,MAAM,SAAS,GAAG,gCAAgC,CAAC;YACjD,aAAa,EAAE;gBACb,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBACjB,SAAS,EAAE,iBAAiB,CAAC,OAAO,CAAC;oBACrC,WAAW,EAAE,SAAS,UAAU,EAAE;oBAClC,MAAM,EAAE,OAAO;oBACf,SAAS,EAAE,EAAE;oBACb,OAAO,EAAE,KAAK;iBACf,CAAC;aACH;SACF,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,0BAA0B,CAAC;YACpC,SAAS;SACV,CAAC,CAAC;QAEH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAEhB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,IAAI,CAAC,IAAI,CACb,UAAU,CAAC;;;;;;;;kBAQD,UAAU;;;;SAInB,CAAC,CACH,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,EAAE,CAAC,CAAC;YACpD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,aAAa,UAAU,EAAE,CAAC,CAAC;YACvD,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YAE/D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CACJ,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAC/D,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACf,MAAM,IAAI,GAAG,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;YAC7D,MAAM,SAAS,GAAG,kBAAkB,CAClC,MAAM,EACN,4BAA4B,CAC7B,CAAC;YACF,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;YACjE,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;YACnE,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;YACtE,MAAM,mBAAmB,GAAG,kBAAkB,CAC5C,MAAM,EACN,+BAA+B,CAChC,CAAC;YAEF,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,uBAAuB,CAAC,MAAM,EAAE;gBAC9B,eAAe,EAAE,CAAC;gBAClB,gBAAgB,EAAE,CAAC;gBACnB,0BAA0B,EAAE,CAAC;gBAC7B,iBAAiB,EAAE,CAAC;gBACpB,6BAA6B,EAAE,CAAC;gBAChC,oBAAoB,EAAE,CAAC;aACxB,CAAC,CAAC;YACH,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YACzD,eAAe,CAAC,IAAI,CAAC,CAAC;YACtB,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACpC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YAC1D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YAC3D,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YAC1D,kBAAkB,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;YACpD,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,WAAW,GAAG,4BAA4B,CAAC;QACjD,MAAM,YAAY,GAAG,2BAA2B,CAAC;QACjD,MAAM,SAAS,GAAG,gCAAgC,CAAC;YACjD,aAAa,EAAE;gBACb,WAAW,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBACzB,QAAQ,EAAE;wBACR;4BACE,SAAS,EAAE,iBAAiB,CAAC,OAAO,CAAC;4BACrC,WAAW,EAAE,WAAW;4BACxB,MAAM,EAAE,OAAO;4BACf,SAAS,EAAE,EAAE;yBACd;qBACF;iBACF,CAAC;gBACF,UAAU,EAAE;oBACV,KAAK,EAAE,YAAY;iBACpB;gBACD,QAAQ,EAAE;oBACR,SAAS,EAAE,IAAI;oBACf,QAAQ,EAAE,MAAM;iBACjB;aACF;SACF,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,0BAA0B,CAAC;YACpC,SAAS;SACV,CAAC,CAAC;QAEH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAEhB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,IAAI,CAAC,IAAI,CACb,UAAU,CAAC;;;;4CAIyB,WAAW;oBACnC,YAAY;;;SAGvB,CAAC,CACH,CAAC;YAEF,MAAM,eAAe,GAAG,MAAM,wBAAwB,CAAC,EAAE,CAAC,CAAC;YAC3D,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,YAAY,WAAW,EAAE,CAAC,CAAC;YAElE,MAAM,CAAC,aAAa,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACtC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE9C,MAAM,aAAa,GAAG,MAAM,2BAA2B,CACrD,EAAE,EACF,eAAe,CAChB,CAAC;YACF,MAAM,WAAW,GAAG,kBAAkB,CACpC,aAAa,EACb,uBAAuB,CACxB,CAAC;YACF,MAAM,gBAAgB,GAAG,kBAAkB,CACzC,aAAa,EACb,gCAAgC,CACjC,CAAC;YACF,MAAM,kBAAkB,GAAG,YAAY,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;YAC1E,MAAM,mBAAmB,GAAG,YAAY,CACtC,aAAa,EACb,kBAAkB,CACnB,CAAC;YAEF,yBAAyB,CAAC,aAAa,CAAC,CAAC;YACzC,uBAAuB,CAAC,aAAa,EAAE;gBACrC,eAAe,EAAE,CAAC;gBAClB,gBAAgB,EAAE,CAAC;gBACnB,8BAA8B,EAAE,CAAC;gBACjC,qBAAqB,EAAE,CAAC;aACzB,CAAC,CAAC;YACH,gBAAgB,CAAC,aAAa,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YAChE,eAAe,CAAC,WAAW,CAAC,CAAC;YAC7B,kBAAkB,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;YAClD,MAAM,CAAC,kBAAkB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,CAAC,mBAAmB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC;gBACnD,WAAW,CAAC,OAAO;aACpB,CAAC,CAAC;YACH,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC;gBACpD,WAAW,CAAC,OAAO;aACpB,CAAC,CAAC;YACH,yBAAyB,CAAC,aAAa,CAAC,CAAC;YACzC,yBAAyB,CAAC,aAAa,CAAC,CAAC;YAEzC,MAAM,eAAe,GAAG,MAAM,wBAAwB,CAAC,EAAE,CAAC,CAAC;YAC3D,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,OAAO,CACpC,mBAAmB,EACnB,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAChC,CAAC;YAEF,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;YAEvD,MAAM,aAAa,GAAG,MAAM,2BAA2B,CACrD,EAAE,EACF,eAAe,CAChB,CAAC;YACF,MAAM,WAAW,GAAG,kBAAkB,CACpC,aAAa,EACb,uBAAuB,CACxB,CAAC;YACF,MAAM,gBAAgB,GAAG,kBAAkB,CACzC,aAAa,EACb,gCAAgC,CACjC,CAAC;YACF,MAAM,kBAAkB,GAAG,YAAY,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;YAC1E,MAAM,mBAAmB,GAAG,YAAY,CACtC,aAAa,EACb,kBAAkB,CACnB,CAAC;YAEF,yBAAyB,CAAC,aAAa,CAAC,CAAC;YACzC,uBAAuB,CAAC,aAAa,EAAE;gBACrC,eAAe,EAAE,CAAC;gBAClB,gBAAgB,EAAE,CAAC;gBACnB,8BAA8B,EAAE,CAAC;gBACjC,qBAAqB,EAAE,CAAC;aACzB,CAAC,CAAC;YACH,gBAAgB,CAAC,aAAa,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YAChE,eAAe,CAAC,WAAW,CAAC,CAAC;YAC7B,kBAAkB,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;YAClD,MAAM,CAAC,kBAAkB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,CAAC,mBAAmB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAE5C,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,kBAAkB,EAAE,GAAG,mBAAmB,CAAC,EAAE,CAAC;gBACpE,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;YAC9D,CAAC;YAED,yBAAyB,CAAC,aAAa,CAAC,CAAC;YACzC,yBAAyB,CAAC,aAAa,CAAC,CAAC;QAC3C,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,+FAA+F,EAAE,KAAK,IAAI,EAAE;QAC/G,MAAM,UAAU,GAAG,kBAAkB,CAAC;QACtC,MAAM,SAAS,GAAG,gCAAgC,CAAC;YACjD,aAAa,EAAE;gBACb,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBACjB,SAAS,EAAE,iBAAiB,CAAC,OAAO,CAAC;oBACrC,WAAW,EAAE,SAAS,UAAU,EAAE;oBAClC,MAAM,EAAE,OAAO;oBACf,SAAS,EAAE,EAAE;oBACb,OAAO,EAAE,KAAK;iBACf,CAAC;aACH;YACD,iBAAiB,EAAE;gBACjB,gBAAgB,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,aAAa,UAAU,EAAE,EAAE,EAAE,OAAO,CAAC;gBACvE,gBAAgB,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC;aAC7C;SACF,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,0BAA0B,CAAC;YACpC,YAAY,EAAE,IAAI;YAClB,SAAS;SACV,CAAC,CAAC;QAEH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAEhB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,IAAI,CAAC,IAAI,CACb,UAAU,CAAC;;;;;;;;kBAQD,UAAU;;;;SAInB,CAAC,CACH,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,EAAE,CAAC,CAAC;YACpD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC;gBACtC,WAAW,EAAE,aAAa,UAAU,cAAc;gBAClD,QAAQ,EAAE,CAAC;aACZ,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YAE/D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CACJ,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAChE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACf,MAAM,SAAS,GAAG,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;YACvE,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;YAChE,MAAM,YAAY,GAAG,kBAAkB,CACrC,MAAM,EACN,4BAA4B,CAC7B,CAAC;YACF,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;YACtE,MAAM,mBAAmB,GAAG,kBAAkB,CAC5C,MAAM,EACN,+BAA+B,CAChC,CAAC;YAEF,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,uBAAuB,CAAC,MAAM,EAAE;gBAC9B,0BAA0B,EAAE,CAAC;gBAC7B,iBAAiB,EAAE,CAAC;gBACpB,eAAe,EAAE,CAAC;gBAClB,gBAAgB,EAAE,CAAC;gBACnB,0BAA0B,EAAE,CAAC;gBAC7B,iBAAiB,EAAE,CAAC;gBACpB,6BAA6B,EAAE,CAAC;gBAChC,oBAAoB,EAAE,CAAC;aACxB,CAAC,CAAC;YACH,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YACzD,eAAe,CAAC,SAAS,CAAC,CAAC;YAC3B,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YAC5D,kBAAkB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAC1C,kBAAkB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACxC,kBAAkB,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;YACpD,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAC3D,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAC5D,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,iBAAiB,CAAC,CACzD,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAC1D,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,qGAAqG,EAAE,KAAK,IAAI,EAAE;QACrH,MAAM,SAAS,GAAG,gCAAgC,CAAC;YACjD,aAAa,EAAE;gBACb,WAAW,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBACzB,QAAQ,EAAE;wBACR;4BACE,SAAS,EAAE,iBAAiB,CAAC,OAAO,CAAC;4BACrC,WAAW,EAAE,YAAY;4BACzB,MAAM,EAAE,MAAM;4BACd,SAAS,EAAE,CAAC,OAAO,CAAC;yBACrB;qBACF;iBACF,CAAC;aACH;YACD,iBAAiB,EAAE;gBACjB,gBAAgB,CACd,UAAU,EACV;oBACE,MAAM,EAAE;wBACN;4BACE,MAAM,EAAE,gCAAgC;4BACxC,KAAK,EAAE,OAAO;yBACf;qBACF;iBACF,EACD,YAAY,CACb;gBACD,gBAAgB,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC;aAC7C;SACF,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,0BAA0B,CAAC;YACpC,YAAY,EAAE,IAAI;YAClB,SAAS;SACV,CAAC,CAAC;QAEH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAEhB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,IAAI,CAAC,IAAI,CACb,UAAU,CAAC;;;;;;;SAOV,CAAC,CACH,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,EAAE,CAAC,CAAC;YACpD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC;gBACtC,WAAW,EAAE,2BAA2B;gBACxC,QAAQ,EAAE,CAAC;aACZ,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YAE/D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE/D,MAAM,SAAS,GAAG,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;YACvE,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;YACxE,MAAM,gBAAgB,GAAG,kBAAkB,CACzC,MAAM,EACN,gCAAgC,CACjC,CAAC;YACF,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;YAChE,MAAM,YAAY,GAAG,kBAAkB,CACrC,MAAM,EACN,4BAA4B,CAC7B,CAAC;YACF,MAAM,cAAc,GAAG,kBAAkB,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;YACzE,MAAM,uBAAuB,GAAG,kBAAkB,CAChD,MAAM,EACN,8BAA8B,CAC/B,CAAC;YAEF,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,uBAAuB,CAAC,MAAM,EAAE;gBAC9B,0BAA0B,EAAE,CAAC;gBAC7B,iBAAiB,EAAE,CAAC;gBACpB,eAAe,EAAE,CAAC;gBAClB,gBAAgB,EAAE,CAAC;gBACnB,0BAA0B,EAAE,CAAC;gBAC7B,iBAAiB,EAAE,CAAC;gBACpB,8BAA8B,EAAE,CAAC;gBACjC,qBAAqB,EAAE,CAAC;gBACxB,4BAA4B,EAAE,CAAC;gBAC/B,mBAAmB,EAAE,CAAC;aACvB,CAAC,CAAC;YACH,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YACzD,eAAe,CAAC,SAAS,CAAC,CAAC;YAC3B,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YAChE,kBAAkB,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;YAClD,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YAC5D,kBAAkB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAC1C,kBAAkB,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;YAC5C,kBAAkB,CAAC,uBAAuB,EAAE,cAAc,CAAC,CAAC;YAC5D,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAC7D,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAC9D,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAC3D,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAC5D,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,iBAAiB,CAAC,CACzD,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAC1D,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,mFAAmF,EAAE,KAAK,IAAI,EAAE;QACnG,MAAM,YAAY,GAAG,qBAAqB,CAAC;QAC3C,MAAM,SAAS,GAAG,gCAAgC,CAAC;YACjD,aAAa,EAAE;gBACb,UAAU,EAAE;oBACV,KAAK,EAAE,YAAY;iBACpB;gBACD,QAAQ,EAAE;oBACR,SAAS,EAAE,IAAI;oBACf,QAAQ,EAAE,MAAM;iBACjB;aACF;YACD,iBAAiB,EAAE;gBACjB,gBAAgB,CACd,SAAS,EACT;oBACE,WAAW,EAAE,mBAAmB;oBAChC,MAAM,EAAE;wBACN,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;yBAC1B;qBACF;iBACF,EACD,WAAW,CACZ;gBACD,gBAAgB,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC;aAC7C;SACF,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,0BAA0B,CAAC;YACpC,YAAY,EAAE,IAAI;YAClB,SAAS;SACV,CAAC,CAAC;QAEH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAEhB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,IAAI,CAAC,IAAI,CACb,UAAU,CAAC;;;;oBAIC,YAAY;;;SAGvB,CAAC,CACH,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,EAAE,CAAC,CAAC;YACpD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC;gBACtC,WAAW,EAAE,+BAA+B;gBAC5C,QAAQ,EAAE,CAAC;aACZ,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAElC,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YAC/D,MAAM,SAAS,GAAG,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;YACvE,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;YACxE,MAAM,gBAAgB,GAAG,kBAAkB,CACzC,MAAM,EACN,gCAAgC,CACjC,CAAC;YAEF,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,uBAAuB,CAAC,MAAM,EAAE;gBAC9B,0BAA0B,EAAE,CAAC;gBAC7B,iBAAiB,EAAE,CAAC;gBACpB,eAAe,EAAE,CAAC;gBAClB,gBAAgB,EAAE,CAAC;gBACnB,8BAA8B,EAAE,CAAC;gBACjC,qBAAqB,EAAE,CAAC;aACzB,CAAC,CAAC;YACH,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YACzD,eAAe,CAAC,SAAS,CAAC,CAAC;YAC3B,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YAChE,kBAAkB,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;YAClD,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAC3D,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAC5D,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAC7D,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAC9D,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,4FAA4F,EAAE,KAAK,IAAI,EAAE;QAC5G,MAAM,YAAY,GAAG,UAAU,CAAC;;;;;;;KAO/B,CAAC,CAAC;QACH,MAAM,cAAc,GAAG,gCAAgC,CAAC;YACtD,iBAAiB,EAAE;gBACjB,gBAAgB,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE,QAAQ,CAAC;gBACzD,gBAAgB,CAAC,YAAY,EAAE,EAAE,EAAE,cAAc,CAAC;gBAClD,gBAAgB,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC;aAC7C;SACF,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,0BAA0B,CAAC;YACzC,YAAY,EAAE,IAAI;YAClB,SAAS,EAAE,cAAc;SAC1B,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QAErB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,OAAO,CAAC,CAAC;YACzD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC;gBAC3C,WAAW,EAAE,qDAAqD;gBAClE,QAAQ,EAAE,CAAC;aACZ,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACpE,MAAM,IAAI,GAAG,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;YAClE,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;YAC7D,MAAM,iBAAiB,GAAG,kBAAkB,CAC1C,MAAM,EACN,wBAAwB,CACzB,CAAC;YACF,MAAM,cAAc,GAAG,kBAAkB,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;YACzE,MAAM,uBAAuB,GAAG,kBAAkB,CAChD,MAAM,EACN,8BAA8B,CAC/B,CAAC;YACF,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;YAC5D,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;YAE9D,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,uBAAuB,CAAC,MAAM,EAAE;gBAC9B,0BAA0B,EAAE,CAAC;gBAC7B,iBAAiB,EAAE,CAAC;gBACpB,eAAe,EAAE,CAAC;gBAClB,gBAAgB,EAAE,CAAC;gBACnB,sBAAsB,EAAE,CAAC;gBACzB,aAAa,EAAE,CAAC;gBAChB,4BAA4B,EAAE,CAAC;gBAC/B,mBAAmB,EAAE,CAAC;aACvB,CAAC,CAAC;YACH,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YAC9D,eAAe,CAAC,IAAI,CAAC,CAAC;YACtB,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YACxD,kBAAkB,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;YAChD,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YAC9D,kBAAkB,CAAC,uBAAuB,EAAE,cAAc,CAAC,CAAC;YAC5D,MAAM,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACpC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAErC,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,WAAW,EAAE,GAAG,YAAY,CAAC,EAAE,CAAC;gBACtD,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YACvD,CAAC;YAED,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QAED,MAAM,QAAQ,GAAG,0BAA0B,EAAE,CAAC;QAC9C,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEtB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,QAAQ,CAAC,CAAC;YAE1D,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC9B,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YAE3C,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACrE,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;YAC7D,MAAM,iBAAiB,GAAG,kBAAkB,CAC1C,MAAM,EACN,wBAAwB,CACzB,CAAC;YACF,MAAM,cAAc,GAAG,kBAAkB,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;YACzE,MAAM,uBAAuB,GAAG,kBAAkB,CAChD,MAAM,EACN,8BAA8B,CAC/B,CAAC;YAEF,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,uBAAuB,CAAC,MAAM,EAAE;gBAC9B,sBAAsB,EAAE,CAAC;gBACzB,aAAa,EAAE,CAAC;gBAChB,4BAA4B,EAAE,CAAC;gBAC/B,mBAAmB,EAAE,CAAC;aACvB,CAAC,CAAC;YACH,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YAC/D,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC1B,kBAAkB,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;YAChD,eAAe,CAAC,cAAc,CAAC,CAAC;YAChC,kBAAkB,CAAC,uBAAuB,EAAE,cAAc,CAAC,CAAC;YAC5D,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjE,yBAAyB,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,iHAAiH,EAAE,KAAK,IAAI,EAAE;QACjI,MAAM,EAAE,GAAG,0BAA0B,EAAE,CAAC;QACxC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAEhB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,IAAI,CAAC,IAAI,CACb,UAAU,CAAC;;;;;;;;;;;;;SAaV,CAAC,CACH,CAAC;YAEF,IAAI,QAAQ,GAAG,MAAM,wBAAwB,CAAC,EAAE,CAAC,CAAC;YAClD,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC;YACzE,IAAI,MAAM,GAAG,MAAM,2BAA2B,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YAC7D,IAAI,IAAI,GAAG,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;YAChE,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,uBAAuB,CAAC,MAAM,EAAE;gBAC9B,0BAA0B,EAAE,CAAC;gBAC7B,iBAAiB,EAAE,CAAC;aACrB,CAAC,CAAC;YACH,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YACzD,eAAe,CAAC,IAAI,CAAC,CAAC;YACtB,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjE,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAElC,QAAQ,GAAG,MAAM,wBAAwB,CAAC,EAAE,CAAC,CAAC;YAC9C,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YACtB,MAAM,GAAG,MAAM,2BAA2B,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YACzD,IAAI,GAAG,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;YAC5D,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,uBAAuB,CAAC,MAAM,EAAE;gBAC9B,0BAA0B,EAAE,CAAC;gBAC7B,iBAAiB,EAAE,CAAC;aACrB,CAAC,CAAC;YACH,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YACzD,eAAe,CAAC,IAAI,CAAC,CAAC;YACtB,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjE,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAElC,QAAQ,GAAG,MAAM,wBAAwB,CAAC,EAAE,CAAC,CAAC;YAC9C,MAAM,uBAAuB,CAC3B,IAAI,EACJ,IAAI,CAAC,SAAS,EAAE,EAChB,OAAO,EACP,mBAAmB,EACnB,EAAE,EACF,MAAM,CACP,CAAC;YACF,MAAM,GAAG,MAAM,2BAA2B,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YACzD,IAAI,GAAG,uBAAuB,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;YAC/D,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,uBAAuB,CAAC,MAAM,EAAE;gBAC9B,6BAA6B,EAAE,CAAC;gBAChC,oBAAoB,EAAE,CAAC;aACxB,CAAC,CAAC;YACH,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YACzD,eAAe,CAAC,IAAI,CAAC,CAAC;YACtB,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjE,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,MAAM,CACJ,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CACnE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAEf,QAAQ,GAAG,MAAM,wBAAwB,CAAC,EAAE,CAAC,CAAC;YAC9C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAEjC,kBAAkB,EAAE;gBACrB,UAAU,EAAE,OAAO;gBACnB,aAAa,EAAE,IAAI;aACpB,CAAC,CAAC;YACH,MAAM,GAAG,MAAM,2BAA2B,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YACzD,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjE,yBAAyB,CAAC,MAAM,CAAC,CAAC;YAClC,yBAAyB,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACpE,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect, test } from \"@playwright/test\";\nimport { z } from \"zod\";\nimport { InMemoryEventSink } from \"../../lib/v3/flowlogger/EventSink.js\";\nimport { FlowEvent } from \"../../lib/v3/flowlogger/FlowLogger.js\";\nimport { performUnderstudyMethod } from \"../../lib/v3/handlers/handlerUtils/actHandlerUtils.js\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport {\n createScriptedAisdkTestLlmClient,\n closeV3,\n doneToolResponse,\n findLastEncodedId,\n toolCallResponse,\n} from \"./testUtils.js\";\nimport { getV3TestConfig } from \"./v3.config.js\";\n\nfunction encodeHtml(html: string): string {\n return `data:text/html,${encodeURIComponent(html)}`;\n}\n\nfunction createRecordedFlowLoggerV3(\n overrides: Parameters<typeof getV3TestConfig>[0] = {},\n): V3 {\n const v3 = new V3(getV3TestConfig(overrides));\n const sink = new InMemoryEventSink();\n v3.bus.on(\"*\", (event: unknown) => {\n if (event instanceof FlowEvent) {\n void sink.emit(event);\n }\n });\n v3.eventStore.query = (query) =>\n sink.query({ ...query, sessionId: v3.eventStore.sessionId });\n return v3;\n}\n\nasync function listRecordedFlowEvents(v3: V3): Promise<FlowEvent[]> {\n return v3.eventStore.query({});\n}\n\nasync function captureFlowEventBaseline(v3: V3): Promise<Set<string>> {\n const events = await listRecordedFlowEvents(v3);\n return new Set(events.map((event) => event.eventId));\n}\n\nasync function listRecordedFlowEventsSince(\n v3: V3,\n baseline: Set<string>,\n): Promise<FlowEvent[]> {\n const events = await listRecordedFlowEvents(v3);\n return events.filter((event) => !baseline.has(event.eventId));\n}\n\nfunction eventsOfType(events: FlowEvent[], eventType: string): FlowEvent[] {\n return events.filter((event) => event.eventType === eventType);\n}\n\nfunction requireSingleEvent(events: FlowEvent[], eventType: string): FlowEvent {\n const matches = eventsOfType(events, eventType);\n expect(matches, `expected a single ${eventType}`).toHaveLength(1);\n return matches[0];\n}\n\nfunction expectRootEvent(event: FlowEvent): void {\n expect(event.eventParentIds).toEqual([]);\n}\n\nfunction expectDirectParent(child: FlowEvent, parent: FlowEvent): void {\n expect(child.eventParentIds).toEqual([\n ...parent.eventParentIds,\n parent.eventId,\n ]);\n}\n\nfunction assertAllParentIdsResolve(events: FlowEvent[]): void {\n const eventIds = new Set(events.map((event) => event.eventId));\n\n for (const event of events) {\n for (const parentId of event.eventParentIds) {\n expect(\n eventIds.has(parentId),\n `${event.eventType} references missing parent ${parentId}`,\n ).toBe(true);\n }\n }\n}\n\nfunction assertSessionIds(events: FlowEvent[], sessionId: string): void {\n for (const event of events) {\n expect(event.sessionId).toBe(sessionId);\n }\n}\n\nfunction directChildrenOfType(\n events: FlowEvent[],\n parent: FlowEvent,\n eventType: string,\n): FlowEvent[] {\n const expectedParentIds = [...parent.eventParentIds, parent.eventId];\n return events.filter(\n (event) =>\n event.eventType === eventType &&\n JSON.stringify(event.eventParentIds) ===\n JSON.stringify(expectedParentIds),\n );\n}\n\nfunction assertCompletedEnvelope(\n events: FlowEvent[],\n eventType: string,\n completedEventType = `${eventType.replace(/Event$/, \"\")}CompletedEvent`,\n): FlowEvent {\n const root = requireSingleEvent(events, eventType);\n const completed = requireSingleEvent(events, completedEventType);\n expectDirectParent(completed, root);\n return root;\n}\n\nfunction assertNoFloatingLlmEvents(events: FlowEvent[]): void {\n const llmEvents = events.filter(\n (event) =>\n event.eventType === \"LlmRequestEvent\" ||\n event.eventType === \"LlmResponseEvent\",\n );\n const byId = new Map(events.map((event) => [event.eventId, event]));\n\n expect(llmEvents.length).toBeGreaterThan(0);\n\n for (const event of llmEvents) {\n expect(\n event.eventParentIds.length,\n `${event.eventType} is floating`,\n ).toBeGreaterThan(0);\n const lastParentId = event.eventParentIds.at(-1);\n const lastParent = lastParentId ? byId.get(lastParentId) : undefined;\n expect(\n lastParent,\n `${event.eventType} has no resolved parent`,\n ).toBeDefined();\n expect(lastParent?.eventType.startsWith(\"Llm\")).toBe(false);\n }\n}\n\nfunction assertNoFloatingCdpEvents(events: FlowEvent[]): void {\n const cdpEvents = events.filter((event) => event.eventType.startsWith(\"Cdp\"));\n const byId = new Map(events.map((event) => [event.eventId, event]));\n\n expect(cdpEvents.length).toBeGreaterThan(0);\n\n for (const event of cdpEvents) {\n expect(\n event.eventParentIds.length,\n `${event.eventType} is floating`,\n ).toBeGreaterThan(0);\n const lastParentId = event.eventParentIds.at(-1);\n const lastParent = lastParentId ? byId.get(lastParentId) : undefined;\n expect(\n lastParent,\n `${event.eventType} has no resolved parent`,\n ).toBeDefined();\n\n if (event.eventType === \"CdpCallEvent\") {\n expect(lastParent?.eventType.startsWith(\"Cdp\")).toBe(false);\n } else {\n expect(lastParent?.eventType).toBe(\"CdpCallEvent\");\n }\n }\n}\n\nfunction assertDirectRootCdpEvents(\n events: FlowEvent[],\n sessionId: string,\n): void {\n const call = requireSingleEvent(events, \"CdpCallEvent\");\n const responseTypes = [\"CdpResponseEvent\", \"CdpResponseErrorEvent\"];\n const response = events.find((event) =>\n responseTypes.includes(event.eventType),\n );\n\n expect(response, \"expected a direct CDP response event\").toBeDefined();\n assertSessionIds(events, sessionId);\n expectRootEvent(call);\n expect(response?.eventParentIds).toEqual([call.eventId]);\n}\n\nfunction sortCountRecord(\n input: Record<string, number>,\n): Record<string, number> {\n return Object.fromEntries(\n Object.entries(input).sort(([left], [right]) => left.localeCompare(right)),\n );\n}\n\nfunction assertNonCdpEventCounts(\n events: FlowEvent[],\n expected: Record<string, number>,\n): void {\n const actual = events.reduce<Record<string, number>>((counts, event) => {\n if (event.eventType.startsWith(\"Cdp\")) {\n return counts;\n }\n\n counts[event.eventType] = (counts[event.eventType] ?? 0) + 1;\n return counts;\n }, {});\n\n expect(sortCountRecord(actual)).toEqual(sortCountRecord(expected));\n}\n\ntest.describe(\"flow logger integration\", () => {\n test.describe.configure({ mode: \"serial\" });\n\n test(\"act emits a rooted tree with nested understudy, llm, and cdp events\", async () => {\n const buttonText = \"Flow Logger Act Button\";\n const llmClient = createScriptedAisdkTestLlmClient({\n jsonResponses: {\n act: (options) => ({\n elementId: findLastEncodedId(options),\n description: `click ${buttonText}`,\n method: \"click\",\n arguments: [],\n twoStep: false,\n }),\n },\n });\n\n const v3 = createRecordedFlowLoggerV3({\n llmClient,\n });\n\n await v3.init();\n\n try {\n const page = v3.context.pages()[0];\n await page.goto(\n encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <button\n id=\"act-target\"\n onclick=\"document.body.dataset.clicked='true'\"\n >\n ${buttonText}\n </button>\n </body>\n </html>\n `),\n );\n\n const baseline = await captureFlowEventBaseline(v3);\n const result = await v3.act(`Click the ${buttonText}`);\n const events = await listRecordedFlowEventsSince(v3, baseline);\n\n expect(result.success).toBe(true);\n expect(\n await page.evaluate(() => document.body.dataset.clicked ?? \"\"),\n ).toBe(\"true\");\n const root = requireSingleEvent(events, \"StagehandActEvent\");\n const completed = requireSingleEvent(\n events,\n \"StagehandActCompletedEvent\",\n );\n const llmRequest = requireSingleEvent(events, \"LlmRequestEvent\");\n const llmResponse = requireSingleEvent(events, \"LlmResponseEvent\");\n const understudy = requireSingleEvent(events, \"UnderstudyClickEvent\");\n const understudyCompleted = requireSingleEvent(\n events,\n \"UnderstudyClickCompletedEvent\",\n );\n\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n LlmRequestEvent: 1,\n LlmResponseEvent: 1,\n StagehandActCompletedEvent: 1,\n StagehandActEvent: 1,\n UnderstudyClickCompletedEvent: 1,\n UnderstudyClickEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(root);\n expectDirectParent(completed, root);\n expect(llmRequest.eventParentIds).toEqual([root.eventId]);\n expect(llmResponse.eventParentIds).toEqual([root.eventId]);\n expect(understudy.eventParentIds).toEqual([root.eventId]);\n expectDirectParent(understudyCompleted, understudy);\n assertNoFloatingLlmEvents(events);\n assertNoFloatingCdpEvents(events);\n } finally {\n await closeV3(v3);\n }\n });\n\n test(\"observe and extract emit rooted trees with complete nested llm and cdp events\", async () => {\n const observeText = \"Flow Logger Observe Button\";\n const extractTitle = \"Flow Logger Extract Title\";\n const llmClient = createScriptedAisdkTestLlmClient({\n jsonResponses: {\n Observation: (options) => ({\n elements: [\n {\n elementId: findLastEncodedId(options),\n description: observeText,\n method: \"click\",\n arguments: [],\n },\n ],\n }),\n Extraction: {\n title: extractTitle,\n },\n Metadata: {\n completed: true,\n progress: \"done\",\n },\n },\n });\n\n const v3 = createRecordedFlowLoggerV3({\n llmClient,\n });\n\n await v3.init();\n\n try {\n const page = v3.context.pages()[0];\n await page.goto(\n encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <button id=\"observe-target\">${observeText}</button>\n <h1>${extractTitle}</h1>\n </body>\n </html>\n `),\n );\n\n const observeBaseline = await captureFlowEventBaseline(v3);\n const observeResult = await v3.observe(`Find the ${observeText}`);\n\n expect(observeResult).toHaveLength(1);\n expect(observeResult[0].method).toBe(\"click\");\n\n const observeEvents = await listRecordedFlowEventsSince(\n v3,\n observeBaseline,\n );\n const observeRoot = requireSingleEvent(\n observeEvents,\n \"StagehandObserveEvent\",\n );\n const observeCompleted = requireSingleEvent(\n observeEvents,\n \"StagehandObserveCompletedEvent\",\n );\n const observeLlmRequests = eventsOfType(observeEvents, \"LlmRequestEvent\");\n const observeLlmResponses = eventsOfType(\n observeEvents,\n \"LlmResponseEvent\",\n );\n\n assertAllParentIdsResolve(observeEvents);\n assertNonCdpEventCounts(observeEvents, {\n LlmRequestEvent: 1,\n LlmResponseEvent: 1,\n StagehandObserveCompletedEvent: 1,\n StagehandObserveEvent: 1,\n });\n assertSessionIds(observeEvents, v3.flowLoggerContext.sessionId);\n expectRootEvent(observeRoot);\n expectDirectParent(observeCompleted, observeRoot);\n expect(observeLlmRequests).toHaveLength(1);\n expect(observeLlmResponses).toHaveLength(1);\n expect(observeLlmRequests[0].eventParentIds).toEqual([\n observeRoot.eventId,\n ]);\n expect(observeLlmResponses[0].eventParentIds).toEqual([\n observeRoot.eventId,\n ]);\n assertNoFloatingLlmEvents(observeEvents);\n assertNoFloatingCdpEvents(observeEvents);\n\n const extractBaseline = await captureFlowEventBaseline(v3);\n const extractResult = await v3.extract(\n \"Extract the title\",\n z.object({ title: z.string() }),\n );\n\n expect(extractResult).toEqual({ title: extractTitle });\n\n const extractEvents = await listRecordedFlowEventsSince(\n v3,\n extractBaseline,\n );\n const extractRoot = requireSingleEvent(\n extractEvents,\n \"StagehandExtractEvent\",\n );\n const extractCompleted = requireSingleEvent(\n extractEvents,\n \"StagehandExtractCompletedEvent\",\n );\n const extractLlmRequests = eventsOfType(extractEvents, \"LlmRequestEvent\");\n const extractLlmResponses = eventsOfType(\n extractEvents,\n \"LlmResponseEvent\",\n );\n\n assertAllParentIdsResolve(extractEvents);\n assertNonCdpEventCounts(extractEvents, {\n LlmRequestEvent: 2,\n LlmResponseEvent: 2,\n StagehandExtractCompletedEvent: 1,\n StagehandExtractEvent: 1,\n });\n assertSessionIds(extractEvents, v3.flowLoggerContext.sessionId);\n expectRootEvent(extractRoot);\n expectDirectParent(extractCompleted, extractRoot);\n expect(extractLlmRequests).toHaveLength(2);\n expect(extractLlmResponses).toHaveLength(2);\n\n for (const event of [...extractLlmRequests, ...extractLlmResponses]) {\n expect(event.eventParentIds).toEqual([extractRoot.eventId]);\n }\n\n assertNoFloatingLlmEvents(extractEvents);\n assertNoFloatingCdpEvents(extractEvents);\n } finally {\n await closeV3(v3);\n }\n });\n\n test(\"agent.execute -> act carries the full agent -> stagehand -> understudy -> cdp + llm hierarchy\", async () => {\n const buttonText = \"Agent Act Button\";\n const llmClient = createScriptedAisdkTestLlmClient({\n jsonResponses: {\n act: (options) => ({\n elementId: findLastEncodedId(options),\n description: `click ${buttonText}`,\n method: \"click\",\n arguments: [],\n twoStep: false,\n }),\n },\n generateResponses: [\n toolCallResponse(\"act\", { action: `click the ${buttonText}` }, \"act-1\"),\n doneToolResponse(\"finished\", true, \"done-1\"),\n ],\n });\n\n const v3 = createRecordedFlowLoggerV3({\n experimental: true,\n llmClient,\n });\n\n await v3.init();\n\n try {\n const page = v3.context.pages()[0];\n await page.goto(\n encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <button\n id=\"agent-act-target\"\n onclick=\"document.body.dataset.agentAct='true'\"\n >\n ${buttonText}\n </button>\n </body>\n </html>\n `),\n );\n\n const baseline = await captureFlowEventBaseline(v3);\n const result = await v3.agent().execute({\n instruction: `Click the ${buttonText} and finish.`,\n maxSteps: 2,\n });\n const events = await listRecordedFlowEventsSince(v3, baseline);\n\n expect(result.success).toBe(true);\n expect(\n await page.evaluate(() => document.body.dataset.agentAct ?? \"\"),\n ).toBe(\"true\");\n const agentRoot = assertCompletedEnvelope(events, \"AgentExecuteEvent\");\n const actRoot = requireSingleEvent(events, \"StagehandActEvent\");\n const actCompleted = requireSingleEvent(\n events,\n \"StagehandActCompletedEvent\",\n );\n const understudy = requireSingleEvent(events, \"UnderstudyClickEvent\");\n const understudyCompleted = requireSingleEvent(\n events,\n \"UnderstudyClickCompletedEvent\",\n );\n\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n AgentExecuteCompletedEvent: 1,\n AgentExecuteEvent: 1,\n LlmRequestEvent: 3,\n LlmResponseEvent: 3,\n StagehandActCompletedEvent: 1,\n StagehandActEvent: 1,\n UnderstudyClickCompletedEvent: 1,\n UnderstudyClickEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(agentRoot);\n expect(actRoot.eventParentIds).toEqual([agentRoot.eventId]);\n expectDirectParent(actCompleted, actRoot);\n expectDirectParent(understudy, actRoot);\n expectDirectParent(understudyCompleted, understudy);\n expect(\n directChildrenOfType(events, agentRoot, \"LlmRequestEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, agentRoot, \"LlmResponseEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, actRoot, \"LlmRequestEvent\"),\n ).toHaveLength(1);\n expect(\n directChildrenOfType(events, actRoot, \"LlmResponseEvent\"),\n ).toHaveLength(1);\n assertNoFloatingLlmEvents(events);\n assertNoFloatingCdpEvents(events);\n } finally {\n await closeV3(v3);\n }\n });\n\n test(\"agent.execute -> fillForm carries the observe -> act -> understudy hierarchy with no missing layers\", async () => {\n const llmClient = createScriptedAisdkTestLlmClient({\n jsonResponses: {\n Observation: (options) => ({\n elements: [\n {\n elementId: findLastEncodedId(options),\n description: \"name input\",\n method: \"fill\",\n arguments: [\"hello\"],\n },\n ],\n }),\n },\n generateResponses: [\n toolCallResponse(\n \"fillForm\",\n {\n fields: [\n {\n action: \"type hello into the name field\",\n value: \"hello\",\n },\n ],\n },\n \"fillform-1\",\n ),\n doneToolResponse(\"finished\", true, \"done-1\"),\n ],\n });\n\n const v3 = createRecordedFlowLoggerV3({\n experimental: true,\n llmClient,\n });\n\n await v3.init();\n\n try {\n const page = v3.context.pages()[0];\n await page.goto(\n encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <input id=\"name\" />\n </body>\n </html>\n `),\n );\n\n const baseline = await captureFlowEventBaseline(v3);\n const result = await v3.agent().execute({\n instruction: \"Fill the form and finish.\",\n maxSteps: 2,\n });\n const events = await listRecordedFlowEventsSince(v3, baseline);\n\n expect(result.success).toBe(true);\n expect(await page.locator(\"#name\").inputValue()).toBe(\"hello\");\n\n const agentRoot = assertCompletedEnvelope(events, \"AgentExecuteEvent\");\n const observeRoot = requireSingleEvent(events, \"StagehandObserveEvent\");\n const observeCompleted = requireSingleEvent(\n events,\n \"StagehandObserveCompletedEvent\",\n );\n const actRoot = requireSingleEvent(events, \"StagehandActEvent\");\n const actCompleted = requireSingleEvent(\n events,\n \"StagehandActCompletedEvent\",\n );\n const understudyFill = requireSingleEvent(events, \"UnderstudyFillEvent\");\n const understudyFillCompleted = requireSingleEvent(\n events,\n \"UnderstudyFillCompletedEvent\",\n );\n\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n AgentExecuteCompletedEvent: 1,\n AgentExecuteEvent: 1,\n LlmRequestEvent: 3,\n LlmResponseEvent: 3,\n StagehandActCompletedEvent: 1,\n StagehandActEvent: 1,\n StagehandObserveCompletedEvent: 1,\n StagehandObserveEvent: 1,\n UnderstudyFillCompletedEvent: 1,\n UnderstudyFillEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(agentRoot);\n expect(observeRoot.eventParentIds).toEqual([agentRoot.eventId]);\n expectDirectParent(observeCompleted, observeRoot);\n expect(actRoot.eventParentIds).toEqual([agentRoot.eventId]);\n expectDirectParent(actCompleted, actRoot);\n expectDirectParent(understudyFill, actRoot);\n expectDirectParent(understudyFillCompleted, understudyFill);\n expect(\n directChildrenOfType(events, observeRoot, \"LlmRequestEvent\"),\n ).toHaveLength(1);\n expect(\n directChildrenOfType(events, observeRoot, \"LlmResponseEvent\"),\n ).toHaveLength(1);\n expect(\n directChildrenOfType(events, agentRoot, \"LlmRequestEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, agentRoot, \"LlmResponseEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, actRoot, \"LlmRequestEvent\"),\n ).toHaveLength(0);\n expect(\n directChildrenOfType(events, actRoot, \"LlmResponseEvent\"),\n ).toHaveLength(0);\n assertNoFloatingLlmEvents(events);\n assertNoFloatingCdpEvents(events);\n } finally {\n await closeV3(v3);\n }\n });\n\n test(\"agent.execute -> extract carries the full agent -> extract -> cdp + llm hierarchy\", async () => {\n const extractTitle = \"Agent Extract Title\";\n const llmClient = createScriptedAisdkTestLlmClient({\n jsonResponses: {\n Extraction: {\n title: extractTitle,\n },\n Metadata: {\n completed: true,\n progress: \"done\",\n },\n },\n generateResponses: [\n toolCallResponse(\n \"extract\",\n {\n instruction: \"extract the title\",\n schema: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n },\n },\n },\n \"extract-1\",\n ),\n doneToolResponse(\"finished\", true, \"done-1\"),\n ],\n });\n\n const v3 = createRecordedFlowLoggerV3({\n experimental: true,\n llmClient,\n });\n\n await v3.init();\n\n try {\n const page = v3.context.pages()[0];\n await page.goto(\n encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <h1>${extractTitle}</h1>\n </body>\n </html>\n `),\n );\n\n const baseline = await captureFlowEventBaseline(v3);\n const result = await v3.agent().execute({\n instruction: \"Extract the title and finish.\",\n maxSteps: 2,\n });\n\n expect(result.success).toBe(true);\n\n const events = await listRecordedFlowEventsSince(v3, baseline);\n const agentRoot = assertCompletedEnvelope(events, \"AgentExecuteEvent\");\n const extractRoot = requireSingleEvent(events, \"StagehandExtractEvent\");\n const extractCompleted = requireSingleEvent(\n events,\n \"StagehandExtractCompletedEvent\",\n );\n\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n AgentExecuteCompletedEvent: 1,\n AgentExecuteEvent: 1,\n LlmRequestEvent: 4,\n LlmResponseEvent: 4,\n StagehandExtractCompletedEvent: 1,\n StagehandExtractEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(agentRoot);\n expect(extractRoot.eventParentIds).toEqual([agentRoot.eventId]);\n expectDirectParent(extractCompleted, extractRoot);\n expect(\n directChildrenOfType(events, agentRoot, \"LlmRequestEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, agentRoot, \"LlmResponseEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, extractRoot, \"LlmRequestEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, extractRoot, \"LlmResponseEvent\"),\n ).toHaveLength(2);\n assertNoFloatingLlmEvents(events);\n assertNoFloatingCdpEvents(events);\n } finally {\n await closeV3(v3);\n }\n });\n\n test(\"agent.execute nests page events under the agent root and direct page calls root themselves\", async () => {\n const agentPageUrl = encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <h1>Agent Flow Logger Page</h1>\n </body>\n </html>\n `);\n const agentLlmClient = createScriptedAisdkTestLlmClient({\n generateResponses: [\n toolCallResponse(\"goto\", { url: agentPageUrl }, \"goto-1\"),\n toolCallResponse(\"screenshot\", {}, \"screenshot-1\"),\n doneToolResponse(\"finished\", true, \"done-1\"),\n ],\n });\n\n const agentV3 = createRecordedFlowLoggerV3({\n experimental: true,\n llmClient: agentLlmClient,\n });\n\n await agentV3.init();\n\n try {\n const baseline = await captureFlowEventBaseline(agentV3);\n const result = await agentV3.agent().execute({\n instruction: \"Go to the test page, take a screenshot, and finish.\",\n maxSteps: 3,\n });\n\n expect(result.success).toBe(true);\n expect(result.completed).toBe(true);\n\n const events = await listRecordedFlowEventsSince(agentV3, baseline);\n const root = assertCompletedEnvelope(events, \"AgentExecuteEvent\");\n const pageGoto = requireSingleEvent(events, \"PageGotoEvent\");\n const pageGotoCompleted = requireSingleEvent(\n events,\n \"PageGotoCompletedEvent\",\n );\n const pageScreenshot = requireSingleEvent(events, \"PageScreenshotEvent\");\n const pageScreenshotCompleted = requireSingleEvent(\n events,\n \"PageScreenshotCompletedEvent\",\n );\n const llmRequests = eventsOfType(events, \"LlmRequestEvent\");\n const llmResponses = eventsOfType(events, \"LlmResponseEvent\");\n\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n AgentExecuteCompletedEvent: 1,\n AgentExecuteEvent: 1,\n LlmRequestEvent: 3,\n LlmResponseEvent: 3,\n PageGotoCompletedEvent: 1,\n PageGotoEvent: 1,\n PageScreenshotCompletedEvent: 1,\n PageScreenshotEvent: 1,\n });\n assertSessionIds(events, agentV3.flowLoggerContext.sessionId);\n expectRootEvent(root);\n expect(pageGoto.eventParentIds).toEqual([root.eventId]);\n expectDirectParent(pageGotoCompleted, pageGoto);\n expect(pageScreenshot.eventParentIds).toEqual([root.eventId]);\n expectDirectParent(pageScreenshotCompleted, pageScreenshot);\n expect(llmRequests).toHaveLength(3);\n expect(llmResponses).toHaveLength(3);\n\n for (const event of [...llmRequests, ...llmResponses]) {\n expect(event.eventParentIds).toEqual([root.eventId]);\n }\n\n assertNoFloatingLlmEvents(events);\n assertNoFloatingCdpEvents(events);\n } finally {\n await closeV3(agentV3);\n }\n\n const directV3 = createRecordedFlowLoggerV3();\n await directV3.init();\n\n try {\n const page = directV3.context.pages()[0];\n const baseline = await captureFlowEventBaseline(directV3);\n\n await page.goto(agentPageUrl);\n await page.screenshot({ fullPage: false });\n\n const events = await listRecordedFlowEventsSince(directV3, baseline);\n const pageGoto = requireSingleEvent(events, \"PageGotoEvent\");\n const pageGotoCompleted = requireSingleEvent(\n events,\n \"PageGotoCompletedEvent\",\n );\n const pageScreenshot = requireSingleEvent(events, \"PageScreenshotEvent\");\n const pageScreenshotCompleted = requireSingleEvent(\n events,\n \"PageScreenshotCompletedEvent\",\n );\n\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n PageGotoCompletedEvent: 1,\n PageGotoEvent: 1,\n PageScreenshotCompletedEvent: 1,\n PageScreenshotEvent: 1,\n });\n assertSessionIds(events, directV3.flowLoggerContext.sessionId);\n expectRootEvent(pageGoto);\n expectDirectParent(pageGotoCompleted, pageGoto);\n expectRootEvent(pageScreenshot);\n expectDirectParent(pageScreenshotCompleted, pageScreenshot);\n expect(eventsOfType(events, \"LlmRequestEvent\")).toHaveLength(0);\n expect(eventsOfType(events, \"LlmResponseEvent\")).toHaveLength(0);\n assertNoFloatingCdpEvents(events);\n } finally {\n await closeV3(directV3);\n }\n });\n\n test(\"direct page methods, direct understudy calls, and direct sendCDP all attach complete event trees to the session\", async () => {\n const v3 = createRecordedFlowLoggerV3();\n await v3.init();\n\n try {\n const page = v3.context.pages()[0];\n await page.goto(\n encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <button\n id=\"direct-click\"\n onclick=\"document.body.dataset.directClick='true'\"\n >\n Direct Click\n </button>\n <div id=\"ready\">ready</div>\n </body>\n </html>\n `),\n );\n\n let baseline = await captureFlowEventBaseline(v3);\n await page.evaluate(() => document.getElementById(\"ready\")?.textContent);\n let events = await listRecordedFlowEventsSince(v3, baseline);\n let root = assertCompletedEnvelope(events, \"PageEvaluateEvent\");\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n PageEvaluateCompletedEvent: 1,\n PageEvaluateEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(root);\n expect(eventsOfType(events, \"LlmRequestEvent\")).toHaveLength(0);\n expect(eventsOfType(events, \"LlmResponseEvent\")).toHaveLength(0);\n assertNoFloatingCdpEvents(events);\n\n baseline = await captureFlowEventBaseline(v3);\n await page.snapshot();\n events = await listRecordedFlowEventsSince(v3, baseline);\n root = assertCompletedEnvelope(events, \"PageSnapshotEvent\");\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n PageSnapshotCompletedEvent: 1,\n PageSnapshotEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(root);\n expect(eventsOfType(events, \"LlmRequestEvent\")).toHaveLength(0);\n expect(eventsOfType(events, \"LlmResponseEvent\")).toHaveLength(0);\n assertNoFloatingCdpEvents(events);\n\n baseline = await captureFlowEventBaseline(v3);\n await performUnderstudyMethod(\n page,\n page.mainFrame(),\n \"click\",\n \"/html/body/button\",\n [],\n 30_000,\n );\n events = await listRecordedFlowEventsSince(v3, baseline);\n root = assertCompletedEnvelope(events, \"UnderstudyClickEvent\");\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n UnderstudyClickCompletedEvent: 1,\n UnderstudyClickEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(root);\n expect(eventsOfType(events, \"LlmRequestEvent\")).toHaveLength(0);\n expect(eventsOfType(events, \"LlmResponseEvent\")).toHaveLength(0);\n assertNoFloatingCdpEvents(events);\n expect(\n await page.evaluate(() => document.body.dataset.directClick ?? \"\"),\n ).toBe(\"true\");\n\n baseline = await captureFlowEventBaseline(v3);\n const cdpResult = await page.sendCDP<{\n result?: { value?: number };\n }>(\"Runtime.evaluate\", {\n expression: \"2 + 2\",\n returnByValue: true,\n });\n events = await listRecordedFlowEventsSince(v3, baseline);\n expect(cdpResult.result?.value).toBe(4);\n expect(eventsOfType(events, \"LlmRequestEvent\")).toHaveLength(0);\n expect(eventsOfType(events, \"LlmResponseEvent\")).toHaveLength(0);\n assertAllParentIdsResolve(events);\n assertDirectRootCdpEvents(events, v3.flowLoggerContext.sessionId);\n } finally {\n await closeV3(v3);\n }\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"flowLogger.spec.js","sourceRoot":"","sources":["../../../../tests/integration/flowLogger.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, test } from \"@playwright/test\";\nimport { z } from \"zod\";\nimport { InMemoryEventSink } from \"../../lib/v3/flowlogger/EventSink.js\";\nimport { FlowEvent } from \"../../lib/v3/flowlogger/FlowLogger.js\";\nimport { performUnderstudyMethod } from \"../../lib/v3/handlers/handlerUtils/actHandlerUtils.js\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport {\n createScriptedAisdkTestLlmClient,\n closeV3,\n doneToolResponse,\n findLastEncodedId,\n toolCallResponse,\n} from \"./testUtils.js\";\nimport { getV3TestConfig } from \"./v3.config.js\";\n\nfunction encodeHtml(html: string): string {\n return `data:text/html,${encodeURIComponent(html)}`;\n}\n\nfunction createRecordedFlowLoggerV3(\n overrides: Parameters<typeof getV3TestConfig>[0] = {},\n): V3 {\n const v3 = new V3(getV3TestConfig(overrides));\n const sink = new InMemoryEventSink();\n v3.bus.on(\"*\", (event: unknown) => {\n if (event instanceof FlowEvent) {\n void sink.emit(event);\n }\n });\n v3.eventStore.query = (query) =>\n sink.query({ ...query, sessionId: v3.eventStore.sessionId });\n return v3;\n}\n\nasync function listRecordedFlowEvents(v3: V3): Promise<FlowEvent[]> {\n return v3.eventStore.query({});\n}\n\nasync function captureFlowEventBaseline(v3: V3): Promise<Set<string>> {\n const events = await listRecordedFlowEvents(v3);\n return new Set(events.map((event) => event.eventId));\n}\n\nasync function listRecordedFlowEventsSince(\n v3: V3,\n baseline: Set<string>,\n): Promise<FlowEvent[]> {\n const events = await listRecordedFlowEvents(v3);\n return events.filter((event) => !baseline.has(event.eventId));\n}\n\nfunction eventsOfType(events: FlowEvent[], eventType: string): FlowEvent[] {\n return events.filter((event) => event.eventType === eventType);\n}\n\nfunction requireSingleEvent(events: FlowEvent[], eventType: string): FlowEvent {\n const matches = eventsOfType(events, eventType);\n expect(matches, `expected a single ${eventType}`).toHaveLength(1);\n return matches[0];\n}\n\nfunction expectRootEvent(event: FlowEvent): void {\n expect(event.eventParentIds).toEqual([]);\n}\n\nfunction expectDirectParent(child: FlowEvent, parent: FlowEvent): void {\n expect(child.eventParentIds).toEqual([\n ...parent.eventParentIds,\n parent.eventId,\n ]);\n}\n\nfunction assertAllParentIdsResolve(events: FlowEvent[]): void {\n const eventIds = new Set(events.map((event) => event.eventId));\n\n for (const event of events) {\n for (const parentId of event.eventParentIds) {\n expect(\n eventIds.has(parentId),\n `${event.eventType} references missing parent ${parentId}`,\n ).toBe(true);\n }\n }\n}\n\nfunction assertSessionIds(events: FlowEvent[], sessionId: string): void {\n for (const event of events) {\n expect(event.sessionId).toBe(sessionId);\n }\n}\n\nfunction directChildrenOfType(\n events: FlowEvent[],\n parent: FlowEvent,\n eventType: string,\n): FlowEvent[] {\n const expectedParentIds = [...parent.eventParentIds, parent.eventId];\n return events.filter(\n (event) =>\n event.eventType === eventType &&\n JSON.stringify(event.eventParentIds) ===\n JSON.stringify(expectedParentIds),\n );\n}\n\nfunction assertCompletedEnvelope(\n events: FlowEvent[],\n eventType: string,\n completedEventType = `${eventType.replace(/Event$/, \"\")}CompletedEvent`,\n): FlowEvent {\n const root = requireSingleEvent(events, eventType);\n const completed = requireSingleEvent(events, completedEventType);\n expectDirectParent(completed, root);\n return root;\n}\n\nfunction assertNoFloatingLlmEvents(events: FlowEvent[]): void {\n const llmEvents = events.filter(\n (event) =>\n event.eventType === \"LlmRequestEvent\" ||\n event.eventType === \"LlmResponseEvent\",\n );\n const byId = new Map(events.map((event) => [event.eventId, event]));\n\n expect(llmEvents.length).toBeGreaterThan(0);\n\n for (const event of llmEvents) {\n expect(\n event.eventParentIds.length,\n `${event.eventType} is floating`,\n ).toBeGreaterThan(0);\n const lastParentId = event.eventParentIds.at(-1);\n const lastParent = lastParentId ? byId.get(lastParentId) : undefined;\n expect(\n lastParent,\n `${event.eventType} has no resolved parent`,\n ).toBeDefined();\n expect(lastParent?.eventType.startsWith(\"Llm\")).toBe(false);\n }\n}\n\nfunction assertNoFloatingCdpEvents(events: FlowEvent[]): void {\n const cdpEvents = events.filter((event) => event.eventType.startsWith(\"Cdp\"));\n const byId = new Map(events.map((event) => [event.eventId, event]));\n\n expect(cdpEvents.length).toBeGreaterThan(0);\n\n for (const event of cdpEvents) {\n expect(\n event.eventParentIds.length,\n `${event.eventType} is floating`,\n ).toBeGreaterThan(0);\n const lastParentId = event.eventParentIds.at(-1);\n const lastParent = lastParentId ? byId.get(lastParentId) : undefined;\n expect(\n lastParent,\n `${event.eventType} has no resolved parent`,\n ).toBeDefined();\n\n if (event.eventType === \"CdpCallEvent\") {\n expect(lastParent?.eventType.startsWith(\"Cdp\")).toBe(false);\n } else {\n expect(lastParent?.eventType).toBe(\"CdpCallEvent\");\n }\n }\n}\n\nfunction assertDirectRootCdpEvents(\n events: FlowEvent[],\n sessionId: string,\n): void {\n const call = requireSingleEvent(events, \"CdpCallEvent\");\n const responseTypes = [\"CdpResponseEvent\", \"CdpResponseErrorEvent\"];\n const response = events.find((event) =>\n responseTypes.includes(event.eventType),\n );\n\n expect(response, \"expected a direct CDP response event\").toBeDefined();\n assertSessionIds(events, sessionId);\n expectRootEvent(call);\n expect(response?.eventParentIds).toEqual([call.eventId]);\n}\n\nfunction sortCountRecord(\n input: Record<string, number>,\n): Record<string, number> {\n return Object.fromEntries(\n Object.entries(input).sort(([left], [right]) => left.localeCompare(right)),\n );\n}\n\nfunction assertNonCdpEventCounts(\n events: FlowEvent[],\n expected: Record<string, number>,\n): void {\n const actual = events.reduce<Record<string, number>>((counts, event) => {\n if (event.eventType.startsWith(\"Cdp\")) {\n return counts;\n }\n\n counts[event.eventType] = (counts[event.eventType] ?? 0) + 1;\n return counts;\n }, {});\n\n expect(sortCountRecord(actual)).toEqual(sortCountRecord(expected));\n}\n\ntest.describe(\"flow logger integration\", () => {\n test.describe.configure({ mode: \"serial\" });\n\n test(\"act emits a rooted tree with nested understudy, llm, and cdp events\", async () => {\n const buttonText = \"Flow Logger Act Button\";\n const llmClient = createScriptedAisdkTestLlmClient({\n jsonResponses: {\n act: (options) => ({\n action: {\n elementId: findLastEncodedId(options),\n description: `click ${buttonText}`,\n method: \"click\",\n arguments: [],\n },\n twoStep: false,\n }),\n },\n });\n\n const v3 = createRecordedFlowLoggerV3({\n llmClient,\n });\n\n await v3.init();\n\n try {\n const page = v3.context.pages()[0];\n await page.goto(\n encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <button\n id=\"act-target\"\n onclick=\"document.body.dataset.clicked='true'\"\n >\n ${buttonText}\n </button>\n </body>\n </html>\n `),\n );\n\n const baseline = await captureFlowEventBaseline(v3);\n const result = await v3.act(`Click the ${buttonText}`);\n const events = await listRecordedFlowEventsSince(v3, baseline);\n\n expect(result.success).toBe(true);\n expect(\n await page.evaluate(() => document.body.dataset.clicked ?? \"\"),\n ).toBe(\"true\");\n const root = requireSingleEvent(events, \"StagehandActEvent\");\n const completed = requireSingleEvent(\n events,\n \"StagehandActCompletedEvent\",\n );\n const llmRequest = requireSingleEvent(events, \"LlmRequestEvent\");\n const llmResponse = requireSingleEvent(events, \"LlmResponseEvent\");\n const understudy = requireSingleEvent(events, \"UnderstudyClickEvent\");\n const understudyCompleted = requireSingleEvent(\n events,\n \"UnderstudyClickCompletedEvent\",\n );\n\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n LlmRequestEvent: 1,\n LlmResponseEvent: 1,\n StagehandActCompletedEvent: 1,\n StagehandActEvent: 1,\n UnderstudyClickCompletedEvent: 1,\n UnderstudyClickEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(root);\n expectDirectParent(completed, root);\n expect(llmRequest.eventParentIds).toEqual([root.eventId]);\n expect(llmResponse.eventParentIds).toEqual([root.eventId]);\n expect(understudy.eventParentIds).toEqual([root.eventId]);\n expectDirectParent(understudyCompleted, understudy);\n assertNoFloatingLlmEvents(events);\n assertNoFloatingCdpEvents(events);\n } finally {\n await closeV3(v3);\n }\n });\n\n test(\"observe and extract emit rooted trees with complete nested llm and cdp events\", async () => {\n const observeText = \"Flow Logger Observe Button\";\n const extractTitle = \"Flow Logger Extract Title\";\n const llmClient = createScriptedAisdkTestLlmClient({\n jsonResponses: {\n Observation: (options) => ({\n elements: [\n {\n elementId: findLastEncodedId(options),\n description: observeText,\n method: \"click\",\n arguments: [],\n },\n ],\n }),\n Extraction: {\n title: extractTitle,\n },\n Metadata: {\n completed: true,\n progress: \"done\",\n },\n },\n });\n\n const v3 = createRecordedFlowLoggerV3({\n llmClient,\n });\n\n await v3.init();\n\n try {\n const page = v3.context.pages()[0];\n await page.goto(\n encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <button id=\"observe-target\">${observeText}</button>\n <h1>${extractTitle}</h1>\n </body>\n </html>\n `),\n );\n\n const observeBaseline = await captureFlowEventBaseline(v3);\n const observeResult = await v3.observe(`Find the ${observeText}`);\n\n expect(observeResult).toHaveLength(1);\n expect(observeResult[0].method).toBe(\"click\");\n\n const observeEvents = await listRecordedFlowEventsSince(\n v3,\n observeBaseline,\n );\n const observeRoot = requireSingleEvent(\n observeEvents,\n \"StagehandObserveEvent\",\n );\n const observeCompleted = requireSingleEvent(\n observeEvents,\n \"StagehandObserveCompletedEvent\",\n );\n const observeLlmRequests = eventsOfType(observeEvents, \"LlmRequestEvent\");\n const observeLlmResponses = eventsOfType(\n observeEvents,\n \"LlmResponseEvent\",\n );\n\n assertAllParentIdsResolve(observeEvents);\n assertNonCdpEventCounts(observeEvents, {\n LlmRequestEvent: 1,\n LlmResponseEvent: 1,\n StagehandObserveCompletedEvent: 1,\n StagehandObserveEvent: 1,\n });\n assertSessionIds(observeEvents, v3.flowLoggerContext.sessionId);\n expectRootEvent(observeRoot);\n expectDirectParent(observeCompleted, observeRoot);\n expect(observeLlmRequests).toHaveLength(1);\n expect(observeLlmResponses).toHaveLength(1);\n expect(observeLlmRequests[0].eventParentIds).toEqual([\n observeRoot.eventId,\n ]);\n expect(observeLlmResponses[0].eventParentIds).toEqual([\n observeRoot.eventId,\n ]);\n assertNoFloatingLlmEvents(observeEvents);\n assertNoFloatingCdpEvents(observeEvents);\n\n const extractBaseline = await captureFlowEventBaseline(v3);\n const extractResult = await v3.extract(\n \"Extract the title\",\n z.object({ title: z.string() }),\n );\n\n expect(extractResult).toEqual({ title: extractTitle });\n\n const extractEvents = await listRecordedFlowEventsSince(\n v3,\n extractBaseline,\n );\n const extractRoot = requireSingleEvent(\n extractEvents,\n \"StagehandExtractEvent\",\n );\n const extractCompleted = requireSingleEvent(\n extractEvents,\n \"StagehandExtractCompletedEvent\",\n );\n const extractLlmRequests = eventsOfType(extractEvents, \"LlmRequestEvent\");\n const extractLlmResponses = eventsOfType(\n extractEvents,\n \"LlmResponseEvent\",\n );\n\n assertAllParentIdsResolve(extractEvents);\n assertNonCdpEventCounts(extractEvents, {\n LlmRequestEvent: 2,\n LlmResponseEvent: 2,\n StagehandExtractCompletedEvent: 1,\n StagehandExtractEvent: 1,\n });\n assertSessionIds(extractEvents, v3.flowLoggerContext.sessionId);\n expectRootEvent(extractRoot);\n expectDirectParent(extractCompleted, extractRoot);\n expect(extractLlmRequests).toHaveLength(2);\n expect(extractLlmResponses).toHaveLength(2);\n\n for (const event of [...extractLlmRequests, ...extractLlmResponses]) {\n expect(event.eventParentIds).toEqual([extractRoot.eventId]);\n }\n\n assertNoFloatingLlmEvents(extractEvents);\n assertNoFloatingCdpEvents(extractEvents);\n } finally {\n await closeV3(v3);\n }\n });\n\n test(\"agent.execute -> act carries the full agent -> stagehand -> understudy -> cdp + llm hierarchy\", async () => {\n const buttonText = \"Agent Act Button\";\n const llmClient = createScriptedAisdkTestLlmClient({\n jsonResponses: {\n act: (options) => ({\n action: {\n elementId: findLastEncodedId(options),\n description: `click ${buttonText}`,\n method: \"click\",\n arguments: [],\n },\n twoStep: false,\n }),\n },\n generateResponses: [\n toolCallResponse(\"act\", { action: `click the ${buttonText}` }, \"act-1\"),\n doneToolResponse(\"finished\", true, \"done-1\"),\n ],\n });\n\n const v3 = createRecordedFlowLoggerV3({\n experimental: true,\n llmClient,\n });\n\n await v3.init();\n\n try {\n const page = v3.context.pages()[0];\n await page.goto(\n encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <button\n id=\"agent-act-target\"\n onclick=\"document.body.dataset.agentAct='true'\"\n >\n ${buttonText}\n </button>\n </body>\n </html>\n `),\n );\n\n const baseline = await captureFlowEventBaseline(v3);\n const result = await v3.agent().execute({\n instruction: `Click the ${buttonText} and finish.`,\n maxSteps: 2,\n });\n const events = await listRecordedFlowEventsSince(v3, baseline);\n\n expect(result.success).toBe(true);\n expect(\n await page.evaluate(() => document.body.dataset.agentAct ?? \"\"),\n ).toBe(\"true\");\n const agentRoot = assertCompletedEnvelope(events, \"AgentExecuteEvent\");\n const actRoot = requireSingleEvent(events, \"StagehandActEvent\");\n const actCompleted = requireSingleEvent(\n events,\n \"StagehandActCompletedEvent\",\n );\n const understudy = requireSingleEvent(events, \"UnderstudyClickEvent\");\n const understudyCompleted = requireSingleEvent(\n events,\n \"UnderstudyClickCompletedEvent\",\n );\n\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n AgentExecuteCompletedEvent: 1,\n AgentExecuteEvent: 1,\n LlmRequestEvent: 3,\n LlmResponseEvent: 3,\n StagehandActCompletedEvent: 1,\n StagehandActEvent: 1,\n UnderstudyClickCompletedEvent: 1,\n UnderstudyClickEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(agentRoot);\n expect(actRoot.eventParentIds).toEqual([agentRoot.eventId]);\n expectDirectParent(actCompleted, actRoot);\n expectDirectParent(understudy, actRoot);\n expectDirectParent(understudyCompleted, understudy);\n expect(\n directChildrenOfType(events, agentRoot, \"LlmRequestEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, agentRoot, \"LlmResponseEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, actRoot, \"LlmRequestEvent\"),\n ).toHaveLength(1);\n expect(\n directChildrenOfType(events, actRoot, \"LlmResponseEvent\"),\n ).toHaveLength(1);\n assertNoFloatingLlmEvents(events);\n assertNoFloatingCdpEvents(events);\n } finally {\n await closeV3(v3);\n }\n });\n\n test(\"agent.execute -> fillForm carries the observe -> act -> understudy hierarchy with no missing layers\", async () => {\n const llmClient = createScriptedAisdkTestLlmClient({\n jsonResponses: {\n Observation: (options) => ({\n elements: [\n {\n elementId: findLastEncodedId(options),\n description: \"name input\",\n method: \"fill\",\n arguments: [\"hello\"],\n },\n ],\n }),\n },\n generateResponses: [\n toolCallResponse(\n \"fillForm\",\n {\n fields: [\n {\n action: \"type hello into the name field\",\n value: \"hello\",\n },\n ],\n },\n \"fillform-1\",\n ),\n doneToolResponse(\"finished\", true, \"done-1\"),\n ],\n });\n\n const v3 = createRecordedFlowLoggerV3({\n experimental: true,\n llmClient,\n });\n\n await v3.init();\n\n try {\n const page = v3.context.pages()[0];\n await page.goto(\n encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <input id=\"name\" />\n </body>\n </html>\n `),\n );\n\n const baseline = await captureFlowEventBaseline(v3);\n const result = await v3.agent().execute({\n instruction: \"Fill the form and finish.\",\n maxSteps: 2,\n });\n const events = await listRecordedFlowEventsSince(v3, baseline);\n\n expect(result.success).toBe(true);\n expect(await page.locator(\"#name\").inputValue()).toBe(\"hello\");\n\n const agentRoot = assertCompletedEnvelope(events, \"AgentExecuteEvent\");\n const observeRoot = requireSingleEvent(events, \"StagehandObserveEvent\");\n const observeCompleted = requireSingleEvent(\n events,\n \"StagehandObserveCompletedEvent\",\n );\n const actRoot = requireSingleEvent(events, \"StagehandActEvent\");\n const actCompleted = requireSingleEvent(\n events,\n \"StagehandActCompletedEvent\",\n );\n const understudyFill = requireSingleEvent(events, \"UnderstudyFillEvent\");\n const understudyFillCompleted = requireSingleEvent(\n events,\n \"UnderstudyFillCompletedEvent\",\n );\n\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n AgentExecuteCompletedEvent: 1,\n AgentExecuteEvent: 1,\n LlmRequestEvent: 3,\n LlmResponseEvent: 3,\n StagehandActCompletedEvent: 1,\n StagehandActEvent: 1,\n StagehandObserveCompletedEvent: 1,\n StagehandObserveEvent: 1,\n UnderstudyFillCompletedEvent: 1,\n UnderstudyFillEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(agentRoot);\n expect(observeRoot.eventParentIds).toEqual([agentRoot.eventId]);\n expectDirectParent(observeCompleted, observeRoot);\n expect(actRoot.eventParentIds).toEqual([agentRoot.eventId]);\n expectDirectParent(actCompleted, actRoot);\n expectDirectParent(understudyFill, actRoot);\n expectDirectParent(understudyFillCompleted, understudyFill);\n expect(\n directChildrenOfType(events, observeRoot, \"LlmRequestEvent\"),\n ).toHaveLength(1);\n expect(\n directChildrenOfType(events, observeRoot, \"LlmResponseEvent\"),\n ).toHaveLength(1);\n expect(\n directChildrenOfType(events, agentRoot, \"LlmRequestEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, agentRoot, \"LlmResponseEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, actRoot, \"LlmRequestEvent\"),\n ).toHaveLength(0);\n expect(\n directChildrenOfType(events, actRoot, \"LlmResponseEvent\"),\n ).toHaveLength(0);\n assertNoFloatingLlmEvents(events);\n assertNoFloatingCdpEvents(events);\n } finally {\n await closeV3(v3);\n }\n });\n\n test(\"agent.execute -> extract carries the full agent -> extract -> cdp + llm hierarchy\", async () => {\n const extractTitle = \"Agent Extract Title\";\n const llmClient = createScriptedAisdkTestLlmClient({\n jsonResponses: {\n Extraction: {\n title: extractTitle,\n },\n Metadata: {\n completed: true,\n progress: \"done\",\n },\n },\n generateResponses: [\n toolCallResponse(\n \"extract\",\n {\n instruction: \"extract the title\",\n schema: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n },\n },\n },\n \"extract-1\",\n ),\n doneToolResponse(\"finished\", true, \"done-1\"),\n ],\n });\n\n const v3 = createRecordedFlowLoggerV3({\n experimental: true,\n llmClient,\n });\n\n await v3.init();\n\n try {\n const page = v3.context.pages()[0];\n await page.goto(\n encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <h1>${extractTitle}</h1>\n </body>\n </html>\n `),\n );\n\n const baseline = await captureFlowEventBaseline(v3);\n const result = await v3.agent().execute({\n instruction: \"Extract the title and finish.\",\n maxSteps: 2,\n });\n\n expect(result.success).toBe(true);\n\n const events = await listRecordedFlowEventsSince(v3, baseline);\n const agentRoot = assertCompletedEnvelope(events, \"AgentExecuteEvent\");\n const extractRoot = requireSingleEvent(events, \"StagehandExtractEvent\");\n const extractCompleted = requireSingleEvent(\n events,\n \"StagehandExtractCompletedEvent\",\n );\n\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n AgentExecuteCompletedEvent: 1,\n AgentExecuteEvent: 1,\n LlmRequestEvent: 4,\n LlmResponseEvent: 4,\n StagehandExtractCompletedEvent: 1,\n StagehandExtractEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(agentRoot);\n expect(extractRoot.eventParentIds).toEqual([agentRoot.eventId]);\n expectDirectParent(extractCompleted, extractRoot);\n expect(\n directChildrenOfType(events, agentRoot, \"LlmRequestEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, agentRoot, \"LlmResponseEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, extractRoot, \"LlmRequestEvent\"),\n ).toHaveLength(2);\n expect(\n directChildrenOfType(events, extractRoot, \"LlmResponseEvent\"),\n ).toHaveLength(2);\n assertNoFloatingLlmEvents(events);\n assertNoFloatingCdpEvents(events);\n } finally {\n await closeV3(v3);\n }\n });\n\n test(\"agent.execute nests page events under the agent root and direct page calls root themselves\", async () => {\n const agentPageUrl = encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <h1>Agent Flow Logger Page</h1>\n </body>\n </html>\n `);\n const agentLlmClient = createScriptedAisdkTestLlmClient({\n generateResponses: [\n toolCallResponse(\"goto\", { url: agentPageUrl }, \"goto-1\"),\n toolCallResponse(\"screenshot\", {}, \"screenshot-1\"),\n doneToolResponse(\"finished\", true, \"done-1\"),\n ],\n });\n\n const agentV3 = createRecordedFlowLoggerV3({\n experimental: true,\n llmClient: agentLlmClient,\n });\n\n await agentV3.init();\n\n try {\n const baseline = await captureFlowEventBaseline(agentV3);\n const result = await agentV3.agent().execute({\n instruction: \"Go to the test page, take a screenshot, and finish.\",\n maxSteps: 3,\n });\n\n expect(result.success).toBe(true);\n expect(result.completed).toBe(true);\n\n const events = await listRecordedFlowEventsSince(agentV3, baseline);\n const root = assertCompletedEnvelope(events, \"AgentExecuteEvent\");\n const pageGoto = requireSingleEvent(events, \"PageGotoEvent\");\n const pageGotoCompleted = requireSingleEvent(\n events,\n \"PageGotoCompletedEvent\",\n );\n const pageScreenshot = requireSingleEvent(events, \"PageScreenshotEvent\");\n const pageScreenshotCompleted = requireSingleEvent(\n events,\n \"PageScreenshotCompletedEvent\",\n );\n const llmRequests = eventsOfType(events, \"LlmRequestEvent\");\n const llmResponses = eventsOfType(events, \"LlmResponseEvent\");\n\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n AgentExecuteCompletedEvent: 1,\n AgentExecuteEvent: 1,\n LlmRequestEvent: 3,\n LlmResponseEvent: 3,\n PageGotoCompletedEvent: 1,\n PageGotoEvent: 1,\n PageScreenshotCompletedEvent: 1,\n PageScreenshotEvent: 1,\n });\n assertSessionIds(events, agentV3.flowLoggerContext.sessionId);\n expectRootEvent(root);\n expect(pageGoto.eventParentIds).toEqual([root.eventId]);\n expectDirectParent(pageGotoCompleted, pageGoto);\n expect(pageScreenshot.eventParentIds).toEqual([root.eventId]);\n expectDirectParent(pageScreenshotCompleted, pageScreenshot);\n expect(llmRequests).toHaveLength(3);\n expect(llmResponses).toHaveLength(3);\n\n for (const event of [...llmRequests, ...llmResponses]) {\n expect(event.eventParentIds).toEqual([root.eventId]);\n }\n\n assertNoFloatingLlmEvents(events);\n assertNoFloatingCdpEvents(events);\n } finally {\n await closeV3(agentV3);\n }\n\n const directV3 = createRecordedFlowLoggerV3();\n await directV3.init();\n\n try {\n const page = directV3.context.pages()[0];\n const baseline = await captureFlowEventBaseline(directV3);\n\n await page.goto(agentPageUrl);\n await page.screenshot({ fullPage: false });\n\n const events = await listRecordedFlowEventsSince(directV3, baseline);\n const pageGoto = requireSingleEvent(events, \"PageGotoEvent\");\n const pageGotoCompleted = requireSingleEvent(\n events,\n \"PageGotoCompletedEvent\",\n );\n const pageScreenshot = requireSingleEvent(events, \"PageScreenshotEvent\");\n const pageScreenshotCompleted = requireSingleEvent(\n events,\n \"PageScreenshotCompletedEvent\",\n );\n\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n PageGotoCompletedEvent: 1,\n PageGotoEvent: 1,\n PageScreenshotCompletedEvent: 1,\n PageScreenshotEvent: 1,\n });\n assertSessionIds(events, directV3.flowLoggerContext.sessionId);\n expectRootEvent(pageGoto);\n expectDirectParent(pageGotoCompleted, pageGoto);\n expectRootEvent(pageScreenshot);\n expectDirectParent(pageScreenshotCompleted, pageScreenshot);\n expect(eventsOfType(events, \"LlmRequestEvent\")).toHaveLength(0);\n expect(eventsOfType(events, \"LlmResponseEvent\")).toHaveLength(0);\n assertNoFloatingCdpEvents(events);\n } finally {\n await closeV3(directV3);\n }\n });\n\n test(\"direct page methods, direct understudy calls, and direct sendCDP all attach complete event trees to the session\", async () => {\n const v3 = createRecordedFlowLoggerV3();\n await v3.init();\n\n try {\n const page = v3.context.pages()[0];\n await page.goto(\n encodeHtml(`\n <!doctype html>\n <html>\n <body>\n <button\n id=\"direct-click\"\n onclick=\"document.body.dataset.directClick='true'\"\n >\n Direct Click\n </button>\n <div id=\"ready\">ready</div>\n </body>\n </html>\n `),\n );\n\n let baseline = await captureFlowEventBaseline(v3);\n await page.evaluate(() => document.getElementById(\"ready\")?.textContent);\n let events = await listRecordedFlowEventsSince(v3, baseline);\n let root = assertCompletedEnvelope(events, \"PageEvaluateEvent\");\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n PageEvaluateCompletedEvent: 1,\n PageEvaluateEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(root);\n expect(eventsOfType(events, \"LlmRequestEvent\")).toHaveLength(0);\n expect(eventsOfType(events, \"LlmResponseEvent\")).toHaveLength(0);\n assertNoFloatingCdpEvents(events);\n\n baseline = await captureFlowEventBaseline(v3);\n await page.snapshot();\n events = await listRecordedFlowEventsSince(v3, baseline);\n root = assertCompletedEnvelope(events, \"PageSnapshotEvent\");\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n PageSnapshotCompletedEvent: 1,\n PageSnapshotEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(root);\n expect(eventsOfType(events, \"LlmRequestEvent\")).toHaveLength(0);\n expect(eventsOfType(events, \"LlmResponseEvent\")).toHaveLength(0);\n assertNoFloatingCdpEvents(events);\n\n baseline = await captureFlowEventBaseline(v3);\n await performUnderstudyMethod(\n page,\n page.mainFrame(),\n \"click\",\n \"/html/body/button\",\n [],\n 30_000,\n );\n events = await listRecordedFlowEventsSince(v3, baseline);\n root = assertCompletedEnvelope(events, \"UnderstudyClickEvent\");\n assertAllParentIdsResolve(events);\n assertNonCdpEventCounts(events, {\n UnderstudyClickCompletedEvent: 1,\n UnderstudyClickEvent: 1,\n });\n assertSessionIds(events, v3.flowLoggerContext.sessionId);\n expectRootEvent(root);\n expect(eventsOfType(events, \"LlmRequestEvent\")).toHaveLength(0);\n expect(eventsOfType(events, \"LlmResponseEvent\")).toHaveLength(0);\n assertNoFloatingCdpEvents(events);\n expect(\n await page.evaluate(() => document.body.dataset.directClick ?? \"\"),\n ).toBe(\"true\");\n\n baseline = await captureFlowEventBaseline(v3);\n const cdpResult = await page.sendCDP<{\n result?: { value?: number };\n }>(\"Runtime.evaluate\", {\n expression: \"2 + 2\",\n returnByValue: true,\n });\n events = await listRecordedFlowEventsSince(v3, baseline);\n expect(cdpResult.result?.value).toBe(4);\n expect(eventsOfType(events, \"LlmRequestEvent\")).toHaveLength(0);\n expect(eventsOfType(events, \"LlmResponseEvent\")).toHaveLength(0);\n assertAllParentIdsResolve(events);\n assertDirectRootCdpEvents(events, v3.flowLoggerContext.sessionId);\n } finally {\n await closeV3(v3);\n }\n });\n});\n"]}
|
|
@@ -65,7 +65,7 @@ function resolveJsonResponseKey(options) {
|
|
|
65
65
|
}
|
|
66
66
|
const schema = responseFormat.schema;
|
|
67
67
|
const properties = schema?.properties ?? {};
|
|
68
|
-
if ("
|
|
68
|
+
if ("action" in properties && "twoStep" in properties) {
|
|
69
69
|
return "act";
|
|
70
70
|
}
|
|
71
71
|
if ("elements" in properties) {
|