@browserbasehq/orca 3.2.0-preview.2 → 3.2.0-preview.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js +5 -5
  2. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  3. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js +5 -5
  4. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  5. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js +5 -5
  6. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  7. package/dist/cjs/lib/v3/agent/tools/act.js +1 -10
  8. package/dist/cjs/lib/v3/agent/tools/act.js.map +1 -1
  9. package/dist/cjs/lib/v3/agent/tools/ariaTree.js +1 -12
  10. package/dist/cjs/lib/v3/agent/tools/ariaTree.js.map +1 -1
  11. package/dist/cjs/lib/v3/agent/tools/braveSearch.js.map +1 -1
  12. package/dist/cjs/lib/v3/agent/tools/browserbaseSearch.js.map +1 -1
  13. package/dist/cjs/lib/v3/agent/tools/click.js.map +1 -1
  14. package/dist/cjs/lib/v3/agent/tools/clickAndHold.js.map +1 -1
  15. package/dist/cjs/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  16. package/dist/cjs/lib/v3/agent/tools/extract.js +1 -10
  17. package/dist/cjs/lib/v3/agent/tools/extract.js.map +1 -1
  18. package/dist/cjs/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  19. package/dist/cjs/lib/v3/agent/tools/fillform.js +1 -10
  20. package/dist/cjs/lib/v3/agent/tools/fillform.js.map +1 -1
  21. package/dist/cjs/lib/v3/agent/tools/index.d.ts +2 -2
  22. package/dist/cjs/lib/v3/agent/tools/index.js +53 -5
  23. package/dist/cjs/lib/v3/agent/tools/index.js.map +1 -1
  24. package/dist/cjs/lib/v3/agent/tools/keys.d.ts +1 -1
  25. package/dist/cjs/lib/v3/agent/tools/keys.js.map +1 -1
  26. package/dist/cjs/lib/v3/agent/tools/type.js.map +1 -1
  27. package/dist/cjs/lib/v3/api.js +9 -2
  28. package/dist/cjs/lib/v3/api.js.map +1 -1
  29. package/dist/cjs/lib/v3/flowlogger/EventEmitter.d.ts +7 -0
  30. package/dist/cjs/lib/v3/flowlogger/EventEmitter.js +30 -0
  31. package/dist/cjs/lib/v3/flowlogger/EventEmitter.js.map +1 -0
  32. package/dist/cjs/lib/v3/flowlogger/EventSink.d.ts +44 -0
  33. package/dist/cjs/lib/v3/flowlogger/EventSink.js +217 -0
  34. package/dist/cjs/lib/v3/flowlogger/EventSink.js.map +1 -0
  35. package/dist/cjs/lib/v3/flowlogger/EventStore.d.ts +26 -0
  36. package/dist/cjs/lib/v3/flowlogger/EventStore.js +135 -0
  37. package/dist/cjs/lib/v3/flowlogger/EventStore.js.map +1 -0
  38. package/dist/{esm/lib/v3/flowLogger.d.ts → cjs/lib/v3/flowlogger/FlowLogger.d.ts} +32 -31
  39. package/dist/cjs/lib/v3/flowlogger/FlowLogger.js +591 -0
  40. package/dist/cjs/lib/v3/flowlogger/FlowLogger.js.map +1 -0
  41. package/dist/cjs/lib/v3/flowlogger/prettify.d.ts +6 -0
  42. package/dist/cjs/lib/v3/flowlogger/prettify.js +395 -0
  43. package/dist/cjs/lib/v3/flowlogger/prettify.js.map +1 -0
  44. package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js +26 -28
  45. package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
  46. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +2 -2
  47. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  48. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js +3 -5
  49. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  50. package/dist/cjs/lib/v3/llm/aisdk.js +9 -9
  51. package/dist/cjs/lib/v3/llm/aisdk.js.map +1 -1
  52. package/dist/cjs/lib/v3/types/public/options.d.ts +2 -0
  53. package/dist/cjs/lib/v3/types/public/options.js.map +1 -1
  54. package/dist/cjs/lib/v3/understudy/cdp.d.ts +1 -1
  55. package/dist/cjs/lib/v3/understudy/cdp.js +83 -43
  56. package/dist/cjs/lib/v3/understudy/cdp.js.map +1 -1
  57. package/dist/cjs/lib/v3/understudy/page.js +18 -23
  58. package/dist/cjs/lib/v3/understudy/page.js.map +1 -1
  59. package/dist/cjs/lib/v3/v3.d.ts +5 -5
  60. package/dist/cjs/lib/v3/v3.js +48 -46
  61. package/dist/cjs/lib/v3/v3.js.map +1 -1
  62. package/dist/cjs/tests/integration/flowLogger.spec.d.ts +1 -0
  63. package/dist/cjs/tests/integration/flowLogger.spec.js +714 -0
  64. package/dist/cjs/tests/integration/flowLogger.spec.js.map +1 -0
  65. package/dist/cjs/tests/integration/testUtils.d.ts +33 -0
  66. package/dist/cjs/tests/integration/testUtils.js +144 -0
  67. package/dist/cjs/tests/integration/testUtils.js.map +1 -1
  68. package/dist/cjs/tests/integration/timeouts.spec.js +112 -2
  69. package/dist/cjs/tests/integration/timeouts.spec.js.map +1 -1
  70. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.d.ts +1 -0
  71. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.js +95 -0
  72. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.js.map +1 -0
  73. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.d.ts +1 -0
  74. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.js +43 -0
  75. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.js.map +1 -0
  76. package/dist/cjs/tests/unit/flowlogger-eventstore.test.d.ts +1 -0
  77. package/dist/cjs/tests/unit/flowlogger-eventstore.test.js +250 -0
  78. package/dist/cjs/tests/unit/flowlogger-eventstore.test.js.map +1 -0
  79. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js +1 -1
  80. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  81. package/dist/esm/lib/v3/agent/GoogleCUAClient.js +1 -1
  82. package/dist/esm/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  83. package/dist/esm/lib/v3/agent/OpenAICUAClient.js +1 -1
  84. package/dist/esm/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  85. package/dist/esm/lib/v3/agent/tools/act.js +1 -10
  86. package/dist/esm/lib/v3/agent/tools/act.js.map +1 -1
  87. package/dist/esm/lib/v3/agent/tools/ariaTree.js +1 -12
  88. package/dist/esm/lib/v3/agent/tools/ariaTree.js.map +1 -1
  89. package/dist/esm/lib/v3/agent/tools/braveSearch.js.map +1 -1
  90. package/dist/esm/lib/v3/agent/tools/browserbaseSearch.js.map +1 -1
  91. package/dist/esm/lib/v3/agent/tools/click.js.map +1 -1
  92. package/dist/esm/lib/v3/agent/tools/clickAndHold.js.map +1 -1
  93. package/dist/esm/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  94. package/dist/esm/lib/v3/agent/tools/extract.js +1 -10
  95. package/dist/esm/lib/v3/agent/tools/extract.js.map +1 -1
  96. package/dist/esm/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  97. package/dist/esm/lib/v3/agent/tools/fillform.js +1 -10
  98. package/dist/esm/lib/v3/agent/tools/fillform.js.map +1 -1
  99. package/dist/esm/lib/v3/agent/tools/index.d.ts +2 -2
  100. package/dist/esm/lib/v3/agent/tools/index.js +53 -5
  101. package/dist/esm/lib/v3/agent/tools/index.js.map +1 -1
  102. package/dist/esm/lib/v3/agent/tools/keys.d.ts +1 -1
  103. package/dist/esm/lib/v3/agent/tools/keys.js.map +1 -1
  104. package/dist/esm/lib/v3/agent/tools/type.js.map +1 -1
  105. package/dist/esm/lib/v3/api.js +9 -2
  106. package/dist/esm/lib/v3/api.js.map +1 -1
  107. package/dist/esm/lib/v3/flowlogger/EventEmitter.d.ts +7 -0
  108. package/dist/esm/lib/v3/flowlogger/EventEmitter.js +26 -0
  109. package/dist/esm/lib/v3/flowlogger/EventEmitter.js.map +1 -0
  110. package/dist/esm/lib/v3/flowlogger/EventSink.d.ts +44 -0
  111. package/dist/esm/lib/v3/flowlogger/EventSink.js +206 -0
  112. package/dist/esm/lib/v3/flowlogger/EventSink.js.map +1 -0
  113. package/dist/esm/lib/v3/flowlogger/EventStore.d.ts +26 -0
  114. package/dist/esm/lib/v3/flowlogger/EventStore.js +127 -0
  115. package/dist/esm/lib/v3/flowlogger/EventStore.js.map +1 -0
  116. package/dist/{cjs/lib/v3/flowLogger.d.ts → esm/lib/v3/flowlogger/FlowLogger.d.ts} +32 -31
  117. package/dist/esm/lib/v3/flowlogger/FlowLogger.js +583 -0
  118. package/dist/esm/lib/v3/flowlogger/FlowLogger.js.map +1 -0
  119. package/dist/esm/lib/v3/flowlogger/prettify.d.ts +6 -0
  120. package/dist/esm/lib/v3/flowlogger/prettify.js +389 -0
  121. package/dist/esm/lib/v3/flowlogger/prettify.js.map +1 -0
  122. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js +25 -27
  123. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
  124. package/dist/esm/lib/v3/handlers/v3AgentHandler.js +1 -1
  125. package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  126. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js +2 -4
  127. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  128. package/dist/esm/lib/v3/llm/aisdk.js +1 -1
  129. package/dist/esm/lib/v3/llm/aisdk.js.map +1 -1
  130. package/dist/esm/lib/v3/types/public/options.d.ts +2 -0
  131. package/dist/esm/lib/v3/types/public/options.js.map +1 -1
  132. package/dist/esm/lib/v3/understudy/cdp.d.ts +1 -1
  133. package/dist/esm/lib/v3/understudy/cdp.js +78 -38
  134. package/dist/esm/lib/v3/understudy/cdp.js.map +1 -1
  135. package/dist/esm/lib/v3/understudy/page.js +13 -18
  136. package/dist/esm/lib/v3/understudy/page.js.map +1 -1
  137. package/dist/esm/lib/v3/v3.d.ts +5 -5
  138. package/dist/esm/lib/v3/v3.js +43 -41
  139. package/dist/esm/lib/v3/v3.js.map +1 -1
  140. package/dist/esm/tests/integration/flowLogger.spec.d.ts +1 -0
  141. package/dist/esm/tests/integration/flowLogger.spec.js +712 -0
  142. package/dist/esm/tests/integration/flowLogger.spec.js.map +1 -0
  143. package/dist/esm/tests/integration/testUtils.d.ts +33 -0
  144. package/dist/esm/tests/integration/testUtils.js +138 -0
  145. package/dist/esm/tests/integration/testUtils.js.map +1 -1
  146. package/dist/esm/tests/integration/timeouts.spec.js +112 -2
  147. package/dist/esm/tests/integration/timeouts.spec.js.map +1 -1
  148. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.d.ts +1 -0
  149. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.js +93 -0
  150. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.js.map +1 -0
  151. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.d.ts +1 -0
  152. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.js +41 -0
  153. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.js.map +1 -0
  154. package/dist/esm/tests/unit/flowlogger-eventstore.test.d.ts +1 -0
  155. package/dist/esm/tests/unit/flowlogger-eventstore.test.js +248 -0
  156. package/dist/esm/tests/unit/flowlogger-eventstore.test.js.map +1 -0
  157. package/package.json +3 -1
  158. package/dist/cjs/lib/v3/eventStore.d.ts +0 -41
  159. package/dist/cjs/lib/v3/eventStore.js +0 -375
  160. package/dist/cjs/lib/v3/eventStore.js.map +0 -1
  161. package/dist/cjs/lib/v3/flowLogger.js +0 -470
  162. package/dist/cjs/lib/v3/flowLogger.js.map +0 -1
  163. package/dist/esm/lib/v3/eventStore.d.ts +0 -41
  164. package/dist/esm/lib/v3/eventStore.js +0 -363
  165. package/dist/esm/lib/v3/eventStore.js.map +0 -1
  166. package/dist/esm/lib/v3/flowLogger.js +0 -462
  167. package/dist/esm/lib/v3/flowLogger.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"timeouts.spec.js","sourceRoot":"","sources":["../../../../tests/integration/timeouts.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { v3DynamicTestConfig } from \"./v3.dynamic.config.js\";\nimport { z } from \"zod\";\nimport { closeV3 } from \"./testUtils.js\";\nimport type { LLMClient } from \"../../lib/v3/llm/LLMClient.js\";\nimport { generateText } from \"ai\";\n\ntype AgentToolNameWithTimeout = \"act\" | \"extract\" | \"fillForm\" | \"ariaTree\";\n\ntype ToolTimeoutTestModel = {\n provider: string;\n modelId: string;\n specificationVersion: \"v2\";\n supportedUrls: Record<string, RegExp[]>;\n doGenerate: () => Promise<{\n content: Array<{\n type: \"tool-call\";\n toolCallId: string;\n toolName: string;\n input: string;\n }>;\n finishReason: \"tool-calls\";\n usage: { inputTokens: number; outputTokens: number; totalTokens: number };\n warnings: [];\n }>;\n doStream: (_options: unknown) => Promise<never>;\n};\n\ntype ToolTimeoutTestLLMClient = LLMClient & {\n model: ToolTimeoutTestModel;\n};\n\nfunction createToolTimeoutTestLlmClient(\n toolName: AgentToolNameWithTimeout,\n toolInput: Record<string, unknown>,\n): ToolTimeoutTestLLMClient {\n const usage = {\n prompt_tokens: 0,\n completion_tokens: 0,\n reasoning_tokens: 0,\n cached_input_tokens: 0,\n total_tokens: 0,\n };\n let generateCallCount = 0;\n\n const model: ToolTimeoutTestModel = {\n provider: \"mock\",\n modelId: \"mock/tool-timeout-test\",\n specificationVersion: \"v2\",\n supportedUrls: {},\n doGenerate: async () => {\n generateCallCount += 1;\n if (generateCallCount === 1) {\n return {\n content: [\n {\n type: \"tool-call\",\n toolCallId: \"tool-1\",\n toolName,\n input: JSON.stringify(toolInput),\n },\n ],\n finishReason: \"tool-calls\",\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n warnings: [],\n };\n }\n\n return {\n content: [\n {\n type: \"tool-call\",\n toolCallId: \"done-1\",\n toolName: \"done\",\n input: JSON.stringify({ reasoning: \"done\", taskComplete: true }),\n },\n ],\n finishReason: \"tool-calls\",\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n warnings: [],\n };\n },\n doStream: async () => {\n throw new Error(\"doStream not implemented in timeout test model\");\n },\n };\n\n const llm = {\n type: \"openai\",\n modelName: \"openai/gpt-4.1-mini\",\n hasVision: false,\n clientOptions: {},\n model,\n getLanguageModel: () => model,\n generateText,\n createChatCompletion: async <T = unknown>(options: unknown): Promise<T> => {\n const responseModelName = (\n options as { options?: { response_model?: { name?: string } } }\n )?.options?.response_model?.name;\n\n if (responseModelName === \"act\") {\n return {\n data: {\n elementId: \"1-0\",\n description: \"click body\",\n method: \"click\",\n arguments: [],\n twoStep: false,\n },\n usage,\n } as T;\n }\n if (responseModelName === \"Observation\") {\n return { data: { elements: [] }, usage } as T;\n }\n if (responseModelName === \"Extraction\") {\n return { data: {}, usage } as T;\n }\n if (responseModelName === \"Metadata\") {\n return { data: { completed: true, progress: \"\" }, usage } as T;\n }\n return { data: {}, usage } as T;\n },\n };\n\n return llm as unknown as ToolTimeoutTestLLMClient;\n}\n\nfunction findToolOutput(\n stepEvents: Array<{\n toolCalls?: Array<{ toolName?: string }>;\n toolResults?: Array<{ output?: unknown }>;\n }>,\n toolName: string,\n) {\n for (const event of stepEvents) {\n if (!event.toolCalls || !event.toolResults) continue;\n const toolIndex = event.toolCalls.findIndex(\n (tc) => tc.toolName === toolName,\n );\n if (toolIndex !== -1) {\n return event.toolResults[toolIndex]?.output;\n }\n }\n return undefined;\n}\n\nasync function runAgentToolTimeoutScenario(\n toolName: AgentToolNameWithTimeout,\n toolInput: Record<string, unknown>,\n) {\n const llmClient = createToolTimeoutTestLlmClient(toolName, toolInput);\n const stepEvents: Array<{\n toolCalls?: Array<{ toolName?: string }>;\n toolResults?: Array<{ output?: unknown }>;\n }> = [];\n const v3 = new V3({\n ...v3DynamicTestConfig,\n experimental: true,\n llmClient,\n });\n await v3.init();\n try {\n const page = v3.context.pages()[0];\n await page.goto(\"https://example.com\");\n const agent = v3.agent();\n await agent.execute({\n instruction: `Use ${toolName} and then finish`,\n maxSteps: 2,\n toolTimeout: 1,\n callbacks: {\n onStepFinish: (event) => {\n stepEvents.push({\n toolCalls: event.toolCalls?.map((tc) => ({\n toolName: tc.toolName,\n })),\n toolResults: event.toolResults?.map((tr) => ({\n output: tr.output,\n })),\n });\n },\n },\n });\n const toolOutput = findToolOutput(stepEvents, toolName);\n if (!toolOutput) {\n throw new Error(`No tool output captured for ${toolName}`);\n }\n return { toolOutput };\n } finally {\n await closeV3(v3);\n }\n}\n\ntest.describe(\"V3 hard timeouts\", () => {\n let v3: V3;\n\n test.beforeEach(async () => {\n v3 = new V3(v3DynamicTestConfig);\n await v3.init();\n });\n\n test.afterEach(async () => {\n await closeV3(v3);\n });\n\n test(\"observe() enforces timeoutMs\", async () => {\n // Tiny timeout to force the race to hit the timeout branch\n await expect(v3.observe(\"find something\", { timeout: 5 })).rejects.toThrow(\n /timed out/i,\n );\n });\n\n test(\"extract() enforces timeoutMs\", async () => {\n const schema = z.object({ title: z.string().optional() });\n await expect(\n v3.extract(\"Extract title\", schema, { timeout: 5 }),\n ).rejects.toThrow(/timed out/i);\n });\n\n test(\"act() enforces timeoutMs\", async () => {\n await expect(v3.act(\"do nothing\", { timeout: 5 })).rejects.toThrow(\n /timed out/i,\n );\n });\n\n test(\"agent toolTimeout enforces timeout for act tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"act\", {\n action: \"click somewhere\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n });\n\n test(\"agent toolTimeout enforces timeout for extract tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"extract\", {\n instruction: \"extract the page title\",\n schema: { type: \"object\", properties: { title: { type: \"string\" } } },\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n });\n\n test(\"agent toolTimeout enforces timeout for fillForm tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"fillForm\", {\n fields: [{ action: \"type hello into name\", value: \"hello\" }],\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n });\n\n test(\"agent toolTimeout enforces timeout for ariaTree\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"ariaTree\", {});\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n });\n});\n"]}
1
+ {"version":3,"file":"timeouts.spec.js","sourceRoot":"","sources":["../../../../tests/integration/timeouts.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { v3DynamicTestConfig } from \"./v3.dynamic.config.js\";\nimport { z } from \"zod\";\nimport { closeV3 } from \"./testUtils.js\";\nimport type { LLMClient } from \"../../lib/v3/llm/LLMClient.js\";\nimport { generateText } from \"ai\";\n\ntype AgentToolNameWithTimeout =\n | \"act\"\n | \"extract\"\n | \"fillForm\"\n | \"ariaTree\"\n | \"click\"\n | \"type\"\n | \"dragAndDrop\"\n | \"clickAndHold\"\n | \"fillFormVision\"\n | \"goto\"\n | \"navback\"\n | \"screenshot\"\n | \"scroll\"\n | \"keys\";\n\ntype ToolTimeoutTestModel = {\n provider: string;\n modelId: string;\n specificationVersion: \"v2\";\n supportedUrls: Record<string, RegExp[]>;\n doGenerate: () => Promise<{\n content: Array<{\n type: \"tool-call\";\n toolCallId: string;\n toolName: string;\n input: string;\n }>;\n finishReason: \"tool-calls\";\n usage: { inputTokens: number; outputTokens: number; totalTokens: number };\n warnings: [];\n }>;\n doStream: (_options: unknown) => Promise<never>;\n};\n\ntype ToolTimeoutTestLLMClient = LLMClient & {\n model: ToolTimeoutTestModel;\n};\n\nfunction createToolTimeoutTestLlmClient(\n toolName: AgentToolNameWithTimeout,\n toolInput: Record<string, unknown>,\n): ToolTimeoutTestLLMClient {\n const usage = {\n prompt_tokens: 0,\n completion_tokens: 0,\n reasoning_tokens: 0,\n cached_input_tokens: 0,\n total_tokens: 0,\n };\n let generateCallCount = 0;\n\n const model: ToolTimeoutTestModel = {\n provider: \"mock\",\n modelId: \"mock/tool-timeout-test\",\n specificationVersion: \"v2\",\n supportedUrls: {},\n doGenerate: async () => {\n generateCallCount += 1;\n if (generateCallCount === 1) {\n return {\n content: [\n {\n type: \"tool-call\",\n toolCallId: \"tool-1\",\n toolName,\n input: JSON.stringify(toolInput),\n },\n ],\n finishReason: \"tool-calls\",\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n warnings: [],\n };\n }\n\n return {\n content: [\n {\n type: \"tool-call\",\n toolCallId: \"done-1\",\n toolName: \"done\",\n input: JSON.stringify({ reasoning: \"done\", taskComplete: true }),\n },\n ],\n finishReason: \"tool-calls\",\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n warnings: [],\n };\n },\n doStream: async () => {\n throw new Error(\"doStream not implemented in timeout test model\");\n },\n };\n\n const llm = {\n type: \"openai\",\n modelName: \"openai/gpt-4.1-mini\",\n hasVision: false,\n clientOptions: {},\n model,\n getLanguageModel: () => model,\n generateText,\n createChatCompletion: async <T = unknown>(options: unknown): Promise<T> => {\n const responseModelName = (\n options as { options?: { response_model?: { name?: string } } }\n )?.options?.response_model?.name;\n\n if (responseModelName === \"act\") {\n return {\n data: {\n elementId: \"1-0\",\n description: \"click body\",\n method: \"click\",\n arguments: [],\n twoStep: false,\n },\n usage,\n } as T;\n }\n if (responseModelName === \"Observation\") {\n return { data: { elements: [] }, usage } as T;\n }\n if (responseModelName === \"Extraction\") {\n return { data: {}, usage } as T;\n }\n if (responseModelName === \"Metadata\") {\n return { data: { completed: true, progress: \"\" }, usage } as T;\n }\n return { data: {}, usage } as T;\n },\n };\n\n return llm as unknown as ToolTimeoutTestLLMClient;\n}\n\nfunction findToolOutput(\n stepEvents: Array<{\n toolCalls?: Array<{ toolName?: string }>;\n toolResults?: Array<{ output?: unknown }>;\n }>,\n toolName: string,\n) {\n for (const event of stepEvents) {\n if (!event.toolCalls || !event.toolResults) continue;\n const toolIndex = event.toolCalls.findIndex(\n (tc) => tc.toolName === toolName,\n );\n if (toolIndex !== -1) {\n return event.toolResults[toolIndex]?.output;\n }\n }\n return undefined;\n}\n\nasync function runAgentToolTimeoutScenario(\n toolName: AgentToolNameWithTimeout,\n toolInput: Record<string, unknown>,\n options?: { mode?: \"dom\" | \"hybrid\" },\n) {\n const llmClient = createToolTimeoutTestLlmClient(toolName, toolInput);\n const stepEvents: Array<{\n toolCalls?: Array<{ toolName?: string }>;\n toolResults?: Array<{ output?: unknown }>;\n }> = [];\n const v3 = new V3({\n ...v3DynamicTestConfig,\n experimental: true,\n llmClient,\n });\n await v3.init();\n try {\n const page = v3.context.pages()[0];\n await page.goto(\"https://example.com\");\n const agent = v3.agent({\n ...(options?.mode ? { mode: options.mode } : {}),\n });\n await agent.execute({\n instruction: `Use ${toolName} and then finish`,\n maxSteps: 2,\n toolTimeout: 1,\n callbacks: {\n onStepFinish: (event) => {\n stepEvents.push({\n toolCalls: event.toolCalls?.map((tc) => ({\n toolName: tc.toolName,\n })),\n toolResults: event.toolResults?.map((tr) => ({\n output: tr.output,\n })),\n });\n },\n },\n });\n const toolOutput = findToolOutput(stepEvents, toolName);\n if (!toolOutput) {\n throw new Error(`No tool output captured for ${toolName}`);\n }\n return { toolOutput };\n } finally {\n await closeV3(v3);\n }\n}\n\ntest.describe(\"V3 hard timeouts\", () => {\n let v3: V3;\n\n test.beforeEach(async () => {\n v3 = new V3(v3DynamicTestConfig);\n await v3.init();\n });\n\n test.afterEach(async () => {\n await closeV3(v3);\n });\n\n test(\"observe() enforces timeoutMs\", async () => {\n // Tiny timeout to force the race to hit the timeout branch\n await expect(v3.observe(\"find something\", { timeout: 5 })).rejects.toThrow(\n /timed out/i,\n );\n });\n\n test(\"extract() enforces timeoutMs\", async () => {\n const schema = z.object({ title: z.string().optional() });\n await expect(\n v3.extract(\"Extract title\", schema, { timeout: 5 }),\n ).rejects.toThrow(/timed out/i);\n });\n\n test(\"act() enforces timeoutMs\", async () => {\n await expect(v3.act(\"do nothing\", { timeout: 5 })).rejects.toThrow(\n /timed out/i,\n );\n });\n\n test(\"agent toolTimeout enforces timeout for act tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"act\", {\n action: \"click somewhere\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for extract tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"extract\", {\n instruction: \"extract the page title\",\n schema: { type: \"object\", properties: { title: { type: \"string\" } } },\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for fillForm tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"fillForm\", {\n fields: [{ action: \"type hello into name\", value: \"hello\" }],\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for ariaTree\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"ariaTree\", {});\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for goto tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"goto\", {\n url: \"https://example.com/slow\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for navback tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"navback\", {\n reasoningText: \"going back\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for screenshot tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"screenshot\", {});\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for scroll tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"scroll\", {\n direction: \"down\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for keys tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"keys\", {\n method: \"press\",\n value: \"Enter\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for click tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"click\",\n { describe: \"click element\", coordinates: [100, 100] },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for type tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"type\",\n {\n describe: \"type into field\",\n text: \"hello\",\n coordinates: [100, 100],\n },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for dragAndDrop tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"dragAndDrop\",\n {\n describe: \"drag element\",\n startCoordinates: [100, 100],\n endCoordinates: [200, 200],\n },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for clickAndHold tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"clickAndHold\",\n {\n describe: \"hold element\",\n coordinates: [100, 100],\n duration: 1000,\n },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for fillFormVision tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"fillFormVision\",\n {\n fields: [\n {\n action: \"type hello into name\",\n value: \"hello\",\n coordinates: { x: 100, y: 100 },\n },\n {\n action: \"type world into email\",\n value: \"world\",\n coordinates: { x: 100, y: 200 },\n },\n ],\n },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n});\n"]}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_events_1 = require("node:events");
4
+ const vitest_1 = require("vitest");
5
+ const cdp_js_1 = require("../../lib/v3/understudy/cdp.js");
6
+ const EventSink_js_1 = require("../../lib/v3/flowlogger/EventSink.js");
7
+ const EventEmitter_js_1 = require("../../lib/v3/flowlogger/EventEmitter.js");
8
+ const EventStore_js_1 = require("../../lib/v3/flowlogger/EventStore.js");
9
+ const FlowLogger_js_1 = require("../../lib/v3/flowlogger/FlowLogger.js");
10
+ function attachEventStoreToBus(store, bus) {
11
+ const onFlowEvent = (event) => {
12
+ if (event instanceof FlowLogger_js_1.FlowEvent) {
13
+ void store.emit(event);
14
+ }
15
+ };
16
+ bus.on("*", onFlowEvent);
17
+ return () => {
18
+ bus.off("*", onFlowEvent);
19
+ };
20
+ }
21
+ class FakeSocket extends node_events_1.EventEmitter {
22
+ sentPayloads = [];
23
+ readyState = 1;
24
+ send(payload) {
25
+ this.sentPayloads.push(payload);
26
+ }
27
+ close() {
28
+ this.readyState = 3;
29
+ this.emit("close", 1000, "");
30
+ }
31
+ }
32
+ function createConnection(socket) {
33
+ // The production constructor is private; tests instantiate it directly so
34
+ // they can drive raw websocket messages without a real browser.
35
+ const ConnectionCtor = cdp_js_1.CdpConnection;
36
+ return new ConnectionCtor(socket);
37
+ }
38
+ function requireEvent(events, predicate, description) {
39
+ const match = events.find(predicate);
40
+ (0, vitest_1.expect)(match, `missing ${description}`).toBeDefined();
41
+ return match;
42
+ }
43
+ (0, vitest_1.describe)("flow logger cdp context", () => {
44
+ (0, vitest_1.it)("preserves the active parent chain when a session event handler issues a nested CDP call", async () => {
45
+ const sessionId = "session-test";
46
+ const socket = new FakeSocket();
47
+ const eventBus = new EventEmitter_js_1.EventEmitterWithWildcardSupport();
48
+ const sink = new EventSink_js_1.InMemoryEventSink();
49
+ const eventStore = new EventStore_js_1.EventStore(sessionId, undefined, sink);
50
+ const detachBus = attachEventStoreToBus(eventStore, eventBus);
51
+ const conn = createConnection(socket);
52
+ conn.flowLoggerContext = FlowLogger_js_1.FlowLogger.init(sessionId, eventBus);
53
+ // Seed the target/session mapping the same way a real attach flow would
54
+ // before any session-scoped messages are dispatched.
55
+ conn.onMessage(JSON.stringify({
56
+ method: "Target.attachedToTarget",
57
+ params: {
58
+ sessionId: "target-session",
59
+ targetInfo: { targetId: "target-1" },
60
+ },
61
+ }));
62
+ const session = conn.getSession("target-session");
63
+ (0, vitest_1.expect)(session).toBeDefined();
64
+ session.on("Runtime.consoleAPICalled", () => {
65
+ // This nested send used to lose its parent chain because the callback ran
66
+ // after the original ALS scope had already unwound.
67
+ void session.send("Runtime.evaluate", {
68
+ expression: "2 + 2",
69
+ });
70
+ });
71
+ await FlowLogger_js_1.FlowLogger.runWithLogging({
72
+ context: conn.flowLoggerContext,
73
+ eventType: "SyntheticParentEvent",
74
+ }, async () => {
75
+ void session.send("Page.navigate", {
76
+ url: "https://example.com",
77
+ });
78
+ }, []);
79
+ conn.onMessage(JSON.stringify({
80
+ method: "Runtime.consoleAPICalled",
81
+ sessionId: "target-session",
82
+ params: { type: "log" },
83
+ }));
84
+ // The nested Runtime.evaluate call should still attach under the synthetic
85
+ // parent event even though it was triggered by a later session callback.
86
+ const events = await eventStore.query({});
87
+ const parentEvent = requireEvent(events, (event) => event.eventType === "SyntheticParentEvent", "SyntheticParentEvent");
88
+ const nestedCallEvent = requireEvent(events, (event) => event.eventType === "CdpCallEvent" &&
89
+ String(event.data.method) === "Runtime.evaluate", "nested Runtime.evaluate CdpCallEvent");
90
+ (0, vitest_1.expect)(nestedCallEvent.eventParentIds).toEqual([parentEvent.eventId]);
91
+ detachBus();
92
+ await eventStore.destroy();
93
+ });
94
+ });
95
+ //# sourceMappingURL=flowlogger-capturing-cdp.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flowlogger-capturing-cdp.test.js","sourceRoot":"","sources":["../../../../tests/unit/flowlogger-capturing-cdp.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventEmitter } from \"node:events\";\nimport { describe, it, expect } from \"vitest\";\nimport { CdpConnection } from \"../../lib/v3/understudy/cdp.js\";\nimport { InMemoryEventSink } from \"../../lib/v3/flowlogger/EventSink.js\";\nimport { EventEmitterWithWildcardSupport } from \"../../lib/v3/flowlogger/EventEmitter.js\";\nimport { EventStore } from \"../../lib/v3/flowlogger/EventStore.js\";\nimport { FlowEvent, FlowLogger } from \"../../lib/v3/flowlogger/FlowLogger.js\";\n\nfunction attachEventStoreToBus(\n store: EventStore,\n bus: EventEmitterWithWildcardSupport,\n): () => void {\n const onFlowEvent = (event: unknown) => {\n if (event instanceof FlowEvent) {\n void store.emit(event);\n }\n };\n\n bus.on(\"*\", onFlowEvent);\n return () => {\n bus.off(\"*\", onFlowEvent);\n };\n}\n\nclass FakeSocket extends EventEmitter {\n sentPayloads: string[] = [];\n readyState = 1;\n\n send(payload: string): void {\n this.sentPayloads.push(payload);\n }\n\n close(): void {\n this.readyState = 3;\n this.emit(\"close\", 1000, \"\");\n }\n}\n\nfunction createConnection(socket: FakeSocket): CdpConnection {\n // The production constructor is private; tests instantiate it directly so\n // they can drive raw websocket messages without a real browser.\n const ConnectionCtor = CdpConnection as unknown as {\n new (ws: FakeSocket): CdpConnection;\n };\n return new ConnectionCtor(socket);\n}\n\nfunction requireEvent(\n events: FlowEvent[],\n predicate: (event: FlowEvent) => boolean,\n description: string,\n): FlowEvent {\n const match = events.find(predicate);\n expect(match, `missing ${description}`).toBeDefined();\n return match as FlowEvent;\n}\n\ndescribe(\"flow logger cdp context\", () => {\n it(\"preserves the active parent chain when a session event handler issues a nested CDP call\", async () => {\n const sessionId = \"session-test\";\n const socket = new FakeSocket();\n const eventBus = new EventEmitterWithWildcardSupport();\n const sink = new InMemoryEventSink();\n const eventStore = new EventStore(sessionId, undefined, sink);\n\n const detachBus = attachEventStoreToBus(eventStore, eventBus);\n\n const conn = createConnection(socket);\n conn.flowLoggerContext = FlowLogger.init(sessionId, eventBus);\n\n // Seed the target/session mapping the same way a real attach flow would\n // before any session-scoped messages are dispatched.\n (conn as unknown as { onMessage(json: string): void }).onMessage(\n JSON.stringify({\n method: \"Target.attachedToTarget\",\n params: {\n sessionId: \"target-session\",\n targetInfo: { targetId: \"target-1\" },\n },\n }),\n );\n\n const session = conn.getSession(\"target-session\");\n expect(session).toBeDefined();\n\n session!.on(\"Runtime.consoleAPICalled\", () => {\n // This nested send used to lose its parent chain because the callback ran\n // after the original ALS scope had already unwound.\n void session!.send(\"Runtime.evaluate\", {\n expression: \"2 + 2\",\n });\n });\n\n await FlowLogger.runWithLogging(\n {\n context: conn.flowLoggerContext,\n eventType: \"SyntheticParentEvent\",\n },\n async () => {\n void session!.send(\"Page.navigate\", {\n url: \"https://example.com\",\n });\n },\n [],\n );\n\n (conn as unknown as { onMessage(json: string): void }).onMessage(\n JSON.stringify({\n method: \"Runtime.consoleAPICalled\",\n sessionId: \"target-session\",\n params: { type: \"log\" },\n }),\n );\n\n // The nested Runtime.evaluate call should still attach under the synthetic\n // parent event even though it was triggered by a later session callback.\n const events = await eventStore.query({});\n const parentEvent = requireEvent(\n events,\n (event) => event.eventType === \"SyntheticParentEvent\",\n \"SyntheticParentEvent\",\n );\n const nestedCallEvent = requireEvent(\n events,\n (event) =>\n event.eventType === \"CdpCallEvent\" &&\n String(event.data.method) === \"Runtime.evaluate\",\n \"nested Runtime.evaluate CdpCallEvent\",\n );\n\n expect(nestedCallEvent.eventParentIds).toEqual([parentEvent.eventId]);\n\n detachBus();\n await eventStore.destroy();\n });\n});\n"]}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const FlowLogger_js_1 = require("../../lib/v3/flowlogger/FlowLogger.js");
5
+ (0, vitest_1.describe)("flow logger llm logging", () => {
6
+ (0, vitest_1.it)("no-ops direct llm logging calls when no flow context is active", () => {
7
+ // These helpers are called from multiple model adapters, so they must stay
8
+ // safe even when a test or utility invokes them outside any ALS flow scope.
9
+ (0, vitest_1.expect)(() => FlowLogger_js_1.FlowLogger.logLlmRequest({
10
+ requestId: "req-1",
11
+ model: "mock-model",
12
+ prompt: "hello",
13
+ })).not.toThrow();
14
+ (0, vitest_1.expect)(() => FlowLogger_js_1.FlowLogger.logLlmResponse({
15
+ requestId: "req-1",
16
+ model: "mock-model",
17
+ output: "world",
18
+ inputTokens: 1,
19
+ outputTokens: 1,
20
+ })).not.toThrow();
21
+ });
22
+ (0, vitest_1.it)("does not throw from llm middleware when no flow context is active", async () => {
23
+ const middleware = FlowLogger_js_1.FlowLogger.createLlmLoggingMiddleware("mock-model");
24
+ // Missing flow context should degrade to a silent no-op and preserve the
25
+ // underlying model result.
26
+ await (0, vitest_1.expect)(middleware.wrapGenerate({
27
+ doGenerate: async () => ({
28
+ text: "done",
29
+ usage: {
30
+ inputTokens: 1,
31
+ outputTokens: 1,
32
+ totalTokens: 2,
33
+ },
34
+ }),
35
+ params: {
36
+ prompt: [],
37
+ },
38
+ })).resolves.toMatchObject({
39
+ text: "done",
40
+ });
41
+ });
42
+ });
43
+ //# sourceMappingURL=flowlogger-capturing-llm.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flowlogger-capturing-llm.test.js","sourceRoot":"","sources":["../../../../tests/unit/flowlogger-capturing-llm.test.ts"],"names":[],"mappings":";;AAAA,mCAA8C;AAC9C,yEAAmE;AAEnE,IAAA,iBAAQ,EAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,IAAA,WAAE,EAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,2EAA2E;QAC3E,4EAA4E;QAC5E,IAAA,eAAM,EAAC,GAAG,EAAE,CACV,0BAAU,CAAC,aAAa,CAAC;YACvB,SAAS,EAAE,OAAO;YAClB,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,OAAO;SAChB,CAAC,CACH,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAEhB,IAAA,eAAM,EAAC,GAAG,EAAE,CACV,0BAAU,CAAC,cAAc,CAAC;YACxB,SAAS,EAAE,OAAO;YAClB,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,OAAO;YACf,WAAW,EAAE,CAAC;YACd,YAAY,EAAE,CAAC;SAChB,CAAC,CACH,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,UAAU,GAAG,0BAAU,CAAC,0BAA0B,CAAC,YAAY,CAAC,CAAC;QAEvE,yEAAyE;QACzE,2BAA2B;QAC3B,MAAM,IAAA,eAAM,EACV,UAAU,CAAC,YAAY,CAAC;YACtB,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;gBACvB,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE;oBACL,WAAW,EAAE,CAAC;oBACd,YAAY,EAAE,CAAC;oBACf,WAAW,EAAE,CAAC;iBACf;aACF,CAAC;YACF,MAAM,EAAE;gBACN,MAAM,EAAE,EAAE;aACX;SACO,CAAC,CACZ,CAAC,QAAQ,CAAC,aAAa,CAAC;YACvB,IAAI,EAAE,MAAM;SACb,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { FlowLogger } from \"../../lib/v3/flowlogger/FlowLogger.js\";\n\ndescribe(\"flow logger llm logging\", () => {\n it(\"no-ops direct llm logging calls when no flow context is active\", () => {\n // These helpers are called from multiple model adapters, so they must stay\n // safe even when a test or utility invokes them outside any ALS flow scope.\n expect(() =>\n FlowLogger.logLlmRequest({\n requestId: \"req-1\",\n model: \"mock-model\",\n prompt: \"hello\",\n }),\n ).not.toThrow();\n\n expect(() =>\n FlowLogger.logLlmResponse({\n requestId: \"req-1\",\n model: \"mock-model\",\n output: \"world\",\n inputTokens: 1,\n outputTokens: 1,\n }),\n ).not.toThrow();\n });\n\n it(\"does not throw from llm middleware when no flow context is active\", async () => {\n const middleware = FlowLogger.createLlmLoggingMiddleware(\"mock-model\");\n\n // Missing flow context should degrade to a silent no-op and preserve the\n // underlying model result.\n await expect(\n middleware.wrapGenerate({\n doGenerate: async () => ({\n text: \"done\",\n usage: {\n inputTokens: 1,\n outputTokens: 1,\n totalTokens: 2,\n },\n }),\n params: {\n prompt: [],\n },\n } as never),\n ).resolves.toMatchObject({\n text: \"done\",\n });\n });\n});\n"]}
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const EventStore_js_1 = require("../../lib/v3/flowlogger/EventStore.js");
5
+ const EventEmitter_js_1 = require("../../lib/v3/flowlogger/EventEmitter.js");
6
+ const FlowLogger_js_1 = require("../../lib/v3/flowlogger/FlowLogger.js");
7
+ function attachEventStoreToBus(store, bus) {
8
+ const onFlowEvent = (event) => {
9
+ if (event instanceof FlowLogger_js_1.FlowEvent) {
10
+ void store.emit(event);
11
+ }
12
+ };
13
+ bus.on("*", onFlowEvent);
14
+ return () => {
15
+ bus.off("*", onFlowEvent);
16
+ };
17
+ }
18
+ function createVerboseStoreHarness() {
19
+ const writes = [];
20
+ process.stderr.write = ((chunk, cb) => {
21
+ writes.push(String(chunk));
22
+ cb?.(null);
23
+ return true;
24
+ });
25
+ const store = new EventStore_js_1.EventStore("session-test", { verbose: 2 });
26
+ const bus = new EventEmitter_js_1.EventEmitterWithWildcardSupport();
27
+ const detachBus = attachEventStoreToBus(store, bus);
28
+ return { writes, store, bus, detachBus };
29
+ }
30
+ (0, vitest_1.describe)("flow logger event store", () => {
31
+ const stderrWrite = process.stderr.write.bind(process.stderr);
32
+ (0, vitest_1.afterEach)(() => {
33
+ process.stderr.write = stderrWrite;
34
+ });
35
+ (0, vitest_1.it)("queries recent events from the default in-memory sink", async () => {
36
+ const store = new EventStore_js_1.EventStore("session-test");
37
+ await store.emit(new FlowLogger_js_1.FlowEvent({
38
+ eventType: "StagehandExtractEvent",
39
+ sessionId: "session-test",
40
+ eventId: "stagehand-1234",
41
+ eventCreatedAt: "2026-03-16T21:45:00.000Z",
42
+ data: { params: ["grab title"] },
43
+ }));
44
+ const events = await store.query({});
45
+ (0, vitest_1.expect)(events).toHaveLength(1);
46
+ (0, vitest_1.expect)(events[0].eventType).toBe("StagehandExtractEvent");
47
+ await store.destroy();
48
+ });
49
+ (0, vitest_1.it)("drops payloads from the default in-memory sink", async () => {
50
+ const store = new EventStore_js_1.EventStore("session-test");
51
+ await store.emit(new FlowLogger_js_1.FlowEvent({
52
+ eventType: "LlmRequestEvent",
53
+ sessionId: "session-test",
54
+ eventId: "llm-1234",
55
+ eventCreatedAt: "2026-03-16T21:45:00.000Z",
56
+ data: {
57
+ prompt: [{ type: "image_url", image_url: { url: "huge" } }],
58
+ output: "huge",
59
+ },
60
+ }));
61
+ const [event] = await store.query({});
62
+ (0, vitest_1.expect)(event.eventType).toBe("LlmRequestEvent");
63
+ (0, vitest_1.expect)(event.eventId).toBe("llm-1234");
64
+ (0, vitest_1.expect)(event.data).toEqual({});
65
+ await store.destroy();
66
+ });
67
+ (0, vitest_1.it)("renders semantic hierarchy tags for non-cdp stderr events only", async () => {
68
+ // Intercept stderr so the pretty sink can be asserted without polluting the
69
+ // real test runner output.
70
+ const { writes, store, bus, detachBus } = createVerboseStoreHarness();
71
+ const stepEvent = new FlowLogger_js_1.FlowEvent({
72
+ eventType: "StagehandExtractEvent",
73
+ sessionId: "session-test",
74
+ eventId: "stagehand-1234",
75
+ eventCreatedAt: "2026-03-16T21:45:00.000Z",
76
+ data: { params: ["grab title"] },
77
+ });
78
+ const cdpEvent = new FlowLogger_js_1.FlowEvent({
79
+ eventType: "CdpCallEvent",
80
+ sessionId: "session-test",
81
+ eventId: "cdp-call-5678",
82
+ eventCreatedAt: "2026-03-16T21:45:00.100Z",
83
+ eventParentIds: [stepEvent.eventId],
84
+ data: {
85
+ method: "Runtime.evaluate",
86
+ params: { expression: "2 + 2" },
87
+ targetId: "1234567890ABCDEF1234567890ABCDEF",
88
+ },
89
+ });
90
+ // The stderr sink intentionally suppresses CDP noise even though the event
91
+ // still exists for in-memory and file-backed sinks.
92
+ bus.emit(stepEvent.eventType, stepEvent);
93
+ bus.emit(cdpEvent.eventType, cdpEvent);
94
+ await new Promise((resolve) => setTimeout(resolve, 0));
95
+ (0, vitest_1.expect)(writes).toHaveLength(1);
96
+ (0, vitest_1.expect)(writes[0]).toContain("[🆂 #1234 EXTRACT]");
97
+ (0, vitest_1.expect)(writes[0]).toContain("Stagehand.extract");
98
+ (0, vitest_1.expect)(writes[0]).not.toContain("Runtime.evaluate");
99
+ detachBus();
100
+ await store.destroy();
101
+ });
102
+ (0, vitest_1.it)("renders generic stagehand events without crashing the stderr sink", async () => {
103
+ const { writes, store, bus, detachBus } = createVerboseStoreHarness();
104
+ // `StagehandEvent` has no action suffix, so this guards the formatter path
105
+ // that cannot assume a method name exists.
106
+ bus.emit("StagehandEvent", new FlowLogger_js_1.FlowEvent({
107
+ eventType: "StagehandEvent",
108
+ sessionId: "session-test",
109
+ eventId: "stagehand-0001",
110
+ eventCreatedAt: "2026-03-16T21:45:00.000Z",
111
+ data: { params: ["noop"] },
112
+ }));
113
+ await new Promise((resolve) => setTimeout(resolve, 0));
114
+ (0, vitest_1.expect)(writes).toHaveLength(1);
115
+ (0, vitest_1.expect)(writes[0]).toContain("[🆂 #0001");
116
+ (0, vitest_1.expect)(writes[0]).toContain("Stagehand(");
117
+ detachBus();
118
+ await store.destroy();
119
+ });
120
+ (0, vitest_1.it)("colorizes pretty stderr output with ansi escapes when enabled", async () => {
121
+ const previousForceColor = process.env.FORCE_COLOR;
122
+ const previousNoColor = process.env.NO_COLOR;
123
+ delete process.env.NO_COLOR;
124
+ process.env.FORCE_COLOR = "1";
125
+ const { writes, store, bus, detachBus } = createVerboseStoreHarness();
126
+ try {
127
+ bus.emit("StagehandActEvent", new FlowLogger_js_1.FlowEvent({
128
+ eventType: "StagehandActEvent",
129
+ sessionId: "session-test",
130
+ eventId: "stagehand-0002",
131
+ eventCreatedAt: "2026-03-16T21:45:00.000Z",
132
+ data: { params: ["click submit"] },
133
+ }));
134
+ await new Promise((resolve) => setTimeout(resolve, 0));
135
+ (0, vitest_1.expect)(writes).toHaveLength(1);
136
+ (0, vitest_1.expect)(writes[0]).toContain("\u001B[");
137
+ }
138
+ finally {
139
+ if (previousNoColor === undefined) {
140
+ delete process.env.NO_COLOR;
141
+ }
142
+ else {
143
+ process.env.NO_COLOR = previousNoColor;
144
+ }
145
+ if (previousForceColor === undefined) {
146
+ delete process.env.FORCE_COLOR;
147
+ }
148
+ else {
149
+ process.env.FORCE_COLOR = previousForceColor;
150
+ }
151
+ detachBus();
152
+ await store.destroy();
153
+ }
154
+ });
155
+ (0, vitest_1.it)("keeps agent ancestry and start ids for completion events after many child events", async () => {
156
+ const { writes, store, bus, detachBus } = createVerboseStoreHarness();
157
+ const agentEvent = new FlowLogger_js_1.FlowEvent({
158
+ eventType: "AgentExecuteEvent",
159
+ sessionId: "session-test",
160
+ eventId: "agent-1234",
161
+ eventCreatedAt: "2026-03-16T21:45:00.000Z",
162
+ data: { params: [{ instruction: "click the button" }] },
163
+ });
164
+ const actEvent = new FlowLogger_js_1.FlowEvent({
165
+ eventType: "StagehandActEvent",
166
+ sessionId: "session-test",
167
+ eventId: "stagehand-2222",
168
+ eventCreatedAt: "2026-03-16T21:45:00.001Z",
169
+ eventParentIds: [agentEvent.eventId],
170
+ data: { params: ["click the button"] },
171
+ });
172
+ const clickEvent = new FlowLogger_js_1.FlowEvent({
173
+ eventType: "UnderstudyClickEvent",
174
+ sessionId: "session-test",
175
+ eventId: "action-3333",
176
+ eventCreatedAt: "2026-03-16T21:45:00.002Z",
177
+ eventParentIds: [agentEvent.eventId, actEvent.eventId],
178
+ data: { target: "xpath=/button[1]" },
179
+ });
180
+ bus.emit(agentEvent.eventType, agentEvent);
181
+ bus.emit(actEvent.eventType, actEvent);
182
+ bus.emit(clickEvent.eventType, clickEvent);
183
+ // Flood the retained history with child events so the completion lines have
184
+ // to recover their displayed ancestry from the queryable sink.
185
+ for (let index = 0; index < 150; index += 1) {
186
+ bus.emit("CdpCallEvent", new FlowLogger_js_1.FlowEvent({
187
+ eventType: "CdpCallEvent",
188
+ sessionId: "session-test",
189
+ eventId: `cdp-${String(index).padStart(4, "0")}`,
190
+ eventCreatedAt: `2026-03-16T21:45:00.${String(index + 10).padStart(3, "0")}Z`,
191
+ eventParentIds: [
192
+ agentEvent.eventId,
193
+ actEvent.eventId,
194
+ clickEvent.eventId,
195
+ ],
196
+ data: {
197
+ method: "Runtime.evaluate",
198
+ params: { expression: `${index}` },
199
+ targetId: "1234567890ABCDEF1234567890ABCDEF",
200
+ },
201
+ }));
202
+ }
203
+ bus.emit("UnderstudyClickCompletedEvent", new FlowLogger_js_1.FlowEvent({
204
+ eventType: "UnderstudyClickCompletedEvent",
205
+ sessionId: "session-test",
206
+ eventId: "done-4444",
207
+ eventCreatedAt: "2026-03-16T21:45:01.000Z",
208
+ eventParentIds: [
209
+ agentEvent.eventId,
210
+ actEvent.eventId,
211
+ clickEvent.eventId,
212
+ ],
213
+ data: { durationMs: 250 },
214
+ }));
215
+ bus.emit("StagehandActCompletedEvent", new FlowLogger_js_1.FlowEvent({
216
+ eventType: "StagehandActCompletedEvent",
217
+ sessionId: "session-test",
218
+ eventId: "done-5555",
219
+ eventCreatedAt: "2026-03-16T21:45:01.001Z",
220
+ eventParentIds: [agentEvent.eventId, actEvent.eventId],
221
+ data: { durationMs: 500 },
222
+ }));
223
+ bus.emit("AgentExecuteCompletedEvent", new FlowLogger_js_1.FlowEvent({
224
+ eventType: "AgentExecuteCompletedEvent",
225
+ sessionId: "session-test",
226
+ eventId: "done-6666",
227
+ eventCreatedAt: "2026-03-16T21:45:01.002Z",
228
+ eventParentIds: [agentEvent.eventId],
229
+ data: { durationMs: 750 },
230
+ }));
231
+ await new Promise((resolve) => setTimeout(resolve, 0));
232
+ // Completion lines should reference the original started-event ids, not the
233
+ // synthetic completed-event ids emitted at the end of the lifecycle.
234
+ const clickCompletedLine = writes.find((line) => line.includes("CLICK completed"));
235
+ const actCompletedLine = writes.find((line) => line.includes("ACT completed"));
236
+ const agentCompletedLine = writes.find((line) => line.includes("Agent.execute() completed"));
237
+ (0, vitest_1.expect)(clickCompletedLine).toContain("[🅰 #1234]");
238
+ (0, vitest_1.expect)(clickCompletedLine).toContain("[🆂 #2222 ACT]");
239
+ (0, vitest_1.expect)(clickCompletedLine).toContain("[🆄 #3333 CLICK]");
240
+ (0, vitest_1.expect)(clickCompletedLine).not.toContain("#4444");
241
+ (0, vitest_1.expect)(actCompletedLine).toContain("[🅰 #1234]");
242
+ (0, vitest_1.expect)(actCompletedLine).toContain("[🆂 #2222 ACT]");
243
+ (0, vitest_1.expect)(actCompletedLine).not.toContain("#5555");
244
+ (0, vitest_1.expect)(agentCompletedLine).toContain("[🅰 #1234]");
245
+ (0, vitest_1.expect)(agentCompletedLine).not.toContain("#6666");
246
+ detachBus();
247
+ await store.destroy();
248
+ });
249
+ });
250
+ //# sourceMappingURL=flowlogger-eventstore.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flowlogger-eventstore.test.js","sourceRoot":"","sources":["../../../../tests/unit/flowlogger-eventstore.test.ts"],"names":[],"mappings":";;AAAA,mCAAyD;AACzD,yEAAmE;AACnE,6EAA0F;AAC1F,yEAAkE;AAElE,SAAS,qBAAqB,CAC5B,KAAiB,EACjB,GAAoC;IAEpC,MAAM,WAAW,GAAG,CAAC,KAAc,EAAE,EAAE;QACrC,IAAI,KAAK,YAAY,yBAAS,EAAE,CAAC;YAC/B,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC,CAAC;IAEF,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACzB,OAAO,GAAG,EAAE;QACV,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC5B,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB;IAMhC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CACtB,KAAa,EACb,EAAmC,EACnC,EAAE;QACF,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3B,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC,CAAgC,CAAC;IAElC,MAAM,KAAK,GAAG,IAAI,0BAAU,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,CAAC,EAAW,CAAC,CAAC;IACtE,MAAM,GAAG,GAAG,IAAI,iDAA+B,EAAE,CAAC;IAClD,MAAM,SAAS,GAAG,qBAAqB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAEpD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;AAC3C,CAAC;AAED,IAAA,iBAAQ,EAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAE9D,IAAA,kBAAS,EAAC,GAAG,EAAE;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,WAAW,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,KAAK,GAAG,IAAI,0BAAU,CAAC,cAAc,CAAC,CAAC;QAE7C,MAAM,KAAK,CAAC,IAAI,CACd,IAAI,yBAAS,CAAC;YACZ,SAAS,EAAE,uBAAuB;YAClC,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,gBAAgB;YACzB,cAAc,EAAE,0BAA0B;YAC1C,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,YAAY,CAAC,EAAE;SACjC,CAAC,CACH,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACrC,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAE1D,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,KAAK,GAAG,IAAI,0BAAU,CAAC,cAAc,CAAC,CAAC;QAE7C,MAAM,KAAK,CAAC,IAAI,CACd,IAAI,yBAAS,CAAC;YACZ,SAAS,EAAE,iBAAiB;YAC5B,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,UAAU;YACnB,cAAc,EAAE,0BAA0B;YAC1C,IAAI,EAAE;gBACJ,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC;gBAC3D,MAAM,EAAE,MAAM;aACf;SACF,CAAC,CACH,CAAC;QAEF,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACtC,IAAA,eAAM,EAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAChD,IAAA,eAAM,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,IAAA,eAAM,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAE/B,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC9E,4EAA4E;QAC5E,2BAA2B;QAC3B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,yBAAyB,EAAE,CAAC;QAEtE,MAAM,SAAS,GAAG,IAAI,yBAAS,CAAC;YAC9B,SAAS,EAAE,uBAAuB;YAClC,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,gBAAgB;YACzB,cAAc,EAAE,0BAA0B;YAC1C,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,YAAY,CAAC,EAAE;SACjC,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,yBAAS,CAAC;YAC7B,SAAS,EAAE,cAAc;YACzB,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,eAAe;YACxB,cAAc,EAAE,0BAA0B;YAC1C,cAAc,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC;YACnC,IAAI,EAAE;gBACJ,MAAM,EAAE,kBAAkB;gBAC1B,MAAM,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE;gBAC/B,QAAQ,EAAE,kCAAkC;aAC7C;SACF,CAAC,CAAC;QAEH,2EAA2E;QAC3E,oDAAoD;QACpD,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACzC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACvC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAEvD,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAClD,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACjD,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAEpD,SAAS,EAAE,CAAC;QACZ,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,yBAAyB,EAAE,CAAC;QAEtE,2EAA2E;QAC3E,2CAA2C;QAC3C,GAAG,CAAC,IAAI,CACN,gBAAgB,EAChB,IAAI,yBAAS,CAAC;YACZ,SAAS,EAAE,gBAAgB;YAC3B,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,gBAAgB;YACzB,cAAc,EAAE,0BAA0B;YAC1C,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE;SAC3B,CAAC,CACH,CAAC;QACF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAEvD,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACzC,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAE1C,SAAS,EAAE,CAAC;QACZ,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QACnD,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC7C,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,GAAG,CAAC;QAE9B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,yBAAyB,EAAE,CAAC;QAEtE,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CACN,mBAAmB,EACnB,IAAI,yBAAS,CAAC;gBACZ,SAAS,EAAE,mBAAmB;gBAC9B,SAAS,EAAE,cAAc;gBACzB,OAAO,EAAE,gBAAgB;gBACzB,cAAc,EAAE,0BAA0B;gBAC1C,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,CAAC,EAAE;aACnC,CAAC,CACH,CAAC;YACF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;YAEvD,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACzC,CAAC;gBAAS,CAAC;YACT,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;gBAClC,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,eAAe,CAAC;YACzC,CAAC;YAED,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;gBACrC,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,kBAAkB,CAAC;YAC/C,CAAC;YAED,SAAS,EAAE,CAAC;YACZ,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,kFAAkF,EAAE,KAAK,IAAI,EAAE;QAChG,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,yBAAyB,EAAE,CAAC;QAEtE,MAAM,UAAU,GAAG,IAAI,yBAAS,CAAC;YAC/B,SAAS,EAAE,mBAAmB;YAC9B,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,YAAY;YACrB,cAAc,EAAE,0BAA0B;YAC1C,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC,EAAE;SACxD,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,yBAAS,CAAC;YAC7B,SAAS,EAAE,mBAAmB;YAC9B,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,gBAAgB;YACzB,cAAc,EAAE,0BAA0B;YAC1C,cAAc,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;YACpC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,kBAAkB,CAAC,EAAE;SACvC,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,yBAAS,CAAC;YAC/B,SAAS,EAAE,sBAAsB;YACjC,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,aAAa;YACtB,cAAc,EAAE,0BAA0B;YAC1C,cAAc,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC;YACtD,IAAI,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;SACrC,CAAC,CAAC;QAEH,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC3C,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACvC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAE3C,4EAA4E;QAC5E,+DAA+D;QAC/D,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;YAC5C,GAAG,CAAC,IAAI,CACN,cAAc,EACd,IAAI,yBAAS,CAAC;gBACZ,SAAS,EAAE,cAAc;gBACzB,SAAS,EAAE,cAAc;gBACzB,OAAO,EAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;gBAChD,cAAc,EAAE,uBAAuB,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG;gBAC7E,cAAc,EAAE;oBACd,UAAU,CAAC,OAAO;oBAClB,QAAQ,CAAC,OAAO;oBAChB,UAAU,CAAC,OAAO;iBACnB;gBACD,IAAI,EAAE;oBACJ,MAAM,EAAE,kBAAkB;oBAC1B,MAAM,EAAE,EAAE,UAAU,EAAE,GAAG,KAAK,EAAE,EAAE;oBAClC,QAAQ,EAAE,kCAAkC;iBAC7C;aACF,CAAC,CACH,CAAC;QACJ,CAAC;QAED,GAAG,CAAC,IAAI,CACN,+BAA+B,EAC/B,IAAI,yBAAS,CAAC;YACZ,SAAS,EAAE,+BAA+B;YAC1C,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,WAAW;YACpB,cAAc,EAAE,0BAA0B;YAC1C,cAAc,EAAE;gBACd,UAAU,CAAC,OAAO;gBAClB,QAAQ,CAAC,OAAO;gBAChB,UAAU,CAAC,OAAO;aACnB;YACD,IAAI,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE;SAC1B,CAAC,CACH,CAAC;QACF,GAAG,CAAC,IAAI,CACN,4BAA4B,EAC5B,IAAI,yBAAS,CAAC;YACZ,SAAS,EAAE,4BAA4B;YACvC,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,WAAW;YACpB,cAAc,EAAE,0BAA0B;YAC1C,cAAc,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC;YACtD,IAAI,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE;SAC1B,CAAC,CACH,CAAC;QACF,GAAG,CAAC,IAAI,CACN,4BAA4B,EAC5B,IAAI,yBAAS,CAAC;YACZ,SAAS,EAAE,4BAA4B;YACvC,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,WAAW;YACpB,cAAc,EAAE,0BAA0B;YAC1C,cAAc,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;YACpC,IAAI,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE;SAC1B,CAAC,CACH,CAAC;QACF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAEvD,4EAA4E;QAC5E,qEAAqE;QACrE,MAAM,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAC9C,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CACjC,CAAC;QACF,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAC5C,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAC/B,CAAC;QACF,MAAM,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAC9C,IAAI,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAC3C,CAAC;QAEF,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACnD,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QACvD,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QACzD,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAElD,IAAA,eAAM,EAAC,gBAAgB,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACjD,IAAA,eAAM,EAAC,gBAAgB,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QACrD,IAAA,eAAM,EAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAEhD,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACnD,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAElD,SAAS,EAAE,CAAC;QACZ,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { afterEach, describe, expect, it } from \"vitest\";\nimport { EventStore } from \"../../lib/v3/flowlogger/EventStore.js\";\nimport { EventEmitterWithWildcardSupport } from \"../../lib/v3/flowlogger/EventEmitter.js\";\nimport { FlowEvent } from \"../../lib/v3/flowlogger/FlowLogger.js\";\n\nfunction attachEventStoreToBus(\n store: EventStore,\n bus: EventEmitterWithWildcardSupport,\n): () => void {\n const onFlowEvent = (event: unknown) => {\n if (event instanceof FlowEvent) {\n void store.emit(event);\n }\n };\n\n bus.on(\"*\", onFlowEvent);\n return () => {\n bus.off(\"*\", onFlowEvent);\n };\n}\n\nfunction createVerboseStoreHarness(): {\n writes: string[];\n store: EventStore;\n bus: EventEmitterWithWildcardSupport;\n detachBus: () => void;\n} {\n const writes: string[] = [];\n process.stderr.write = ((\n chunk: string,\n cb?: (error?: Error | null) => void,\n ) => {\n writes.push(String(chunk));\n cb?.(null);\n return true;\n }) as typeof process.stderr.write;\n\n const store = new EventStore(\"session-test\", { verbose: 2 } as never);\n const bus = new EventEmitterWithWildcardSupport();\n const detachBus = attachEventStoreToBus(store, bus);\n\n return { writes, store, bus, detachBus };\n}\n\ndescribe(\"flow logger event store\", () => {\n const stderrWrite = process.stderr.write.bind(process.stderr);\n\n afterEach(() => {\n process.stderr.write = stderrWrite;\n });\n\n it(\"queries recent events from the default in-memory sink\", async () => {\n const store = new EventStore(\"session-test\");\n\n await store.emit(\n new FlowEvent({\n eventType: \"StagehandExtractEvent\",\n sessionId: \"session-test\",\n eventId: \"stagehand-1234\",\n eventCreatedAt: \"2026-03-16T21:45:00.000Z\",\n data: { params: [\"grab title\"] },\n }),\n );\n\n const events = await store.query({});\n expect(events).toHaveLength(1);\n expect(events[0].eventType).toBe(\"StagehandExtractEvent\");\n\n await store.destroy();\n });\n\n it(\"drops payloads from the default in-memory sink\", async () => {\n const store = new EventStore(\"session-test\");\n\n await store.emit(\n new FlowEvent({\n eventType: \"LlmRequestEvent\",\n sessionId: \"session-test\",\n eventId: \"llm-1234\",\n eventCreatedAt: \"2026-03-16T21:45:00.000Z\",\n data: {\n prompt: [{ type: \"image_url\", image_url: { url: \"huge\" } }],\n output: \"huge\",\n },\n }),\n );\n\n const [event] = await store.query({});\n expect(event.eventType).toBe(\"LlmRequestEvent\");\n expect(event.eventId).toBe(\"llm-1234\");\n expect(event.data).toEqual({});\n\n await store.destroy();\n });\n\n it(\"renders semantic hierarchy tags for non-cdp stderr events only\", async () => {\n // Intercept stderr so the pretty sink can be asserted without polluting the\n // real test runner output.\n const { writes, store, bus, detachBus } = createVerboseStoreHarness();\n\n const stepEvent = new FlowEvent({\n eventType: \"StagehandExtractEvent\",\n sessionId: \"session-test\",\n eventId: \"stagehand-1234\",\n eventCreatedAt: \"2026-03-16T21:45:00.000Z\",\n data: { params: [\"grab title\"] },\n });\n const cdpEvent = new FlowEvent({\n eventType: \"CdpCallEvent\",\n sessionId: \"session-test\",\n eventId: \"cdp-call-5678\",\n eventCreatedAt: \"2026-03-16T21:45:00.100Z\",\n eventParentIds: [stepEvent.eventId],\n data: {\n method: \"Runtime.evaluate\",\n params: { expression: \"2 + 2\" },\n targetId: \"1234567890ABCDEF1234567890ABCDEF\",\n },\n });\n\n // The stderr sink intentionally suppresses CDP noise even though the event\n // still exists for in-memory and file-backed sinks.\n bus.emit(stepEvent.eventType, stepEvent);\n bus.emit(cdpEvent.eventType, cdpEvent);\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n expect(writes).toHaveLength(1);\n expect(writes[0]).toContain(\"[🆂 #1234 EXTRACT]\");\n expect(writes[0]).toContain(\"Stagehand.extract\");\n expect(writes[0]).not.toContain(\"Runtime.evaluate\");\n\n detachBus();\n await store.destroy();\n });\n\n it(\"renders generic stagehand events without crashing the stderr sink\", async () => {\n const { writes, store, bus, detachBus } = createVerboseStoreHarness();\n\n // `StagehandEvent` has no action suffix, so this guards the formatter path\n // that cannot assume a method name exists.\n bus.emit(\n \"StagehandEvent\",\n new FlowEvent({\n eventType: \"StagehandEvent\",\n sessionId: \"session-test\",\n eventId: \"stagehand-0001\",\n eventCreatedAt: \"2026-03-16T21:45:00.000Z\",\n data: { params: [\"noop\"] },\n }),\n );\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n expect(writes).toHaveLength(1);\n expect(writes[0]).toContain(\"[🆂 #0001\");\n expect(writes[0]).toContain(\"Stagehand(\");\n\n detachBus();\n await store.destroy();\n });\n\n it(\"colorizes pretty stderr output with ansi escapes when enabled\", async () => {\n const previousForceColor = process.env.FORCE_COLOR;\n const previousNoColor = process.env.NO_COLOR;\n delete process.env.NO_COLOR;\n process.env.FORCE_COLOR = \"1\";\n\n const { writes, store, bus, detachBus } = createVerboseStoreHarness();\n\n try {\n bus.emit(\n \"StagehandActEvent\",\n new FlowEvent({\n eventType: \"StagehandActEvent\",\n sessionId: \"session-test\",\n eventId: \"stagehand-0002\",\n eventCreatedAt: \"2026-03-16T21:45:00.000Z\",\n data: { params: [\"click submit\"] },\n }),\n );\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n expect(writes).toHaveLength(1);\n expect(writes[0]).toContain(\"\\u001B[\");\n } finally {\n if (previousNoColor === undefined) {\n delete process.env.NO_COLOR;\n } else {\n process.env.NO_COLOR = previousNoColor;\n }\n\n if (previousForceColor === undefined) {\n delete process.env.FORCE_COLOR;\n } else {\n process.env.FORCE_COLOR = previousForceColor;\n }\n\n detachBus();\n await store.destroy();\n }\n });\n\n it(\"keeps agent ancestry and start ids for completion events after many child events\", async () => {\n const { writes, store, bus, detachBus } = createVerboseStoreHarness();\n\n const agentEvent = new FlowEvent({\n eventType: \"AgentExecuteEvent\",\n sessionId: \"session-test\",\n eventId: \"agent-1234\",\n eventCreatedAt: \"2026-03-16T21:45:00.000Z\",\n data: { params: [{ instruction: \"click the button\" }] },\n });\n const actEvent = new FlowEvent({\n eventType: \"StagehandActEvent\",\n sessionId: \"session-test\",\n eventId: \"stagehand-2222\",\n eventCreatedAt: \"2026-03-16T21:45:00.001Z\",\n eventParentIds: [agentEvent.eventId],\n data: { params: [\"click the button\"] },\n });\n const clickEvent = new FlowEvent({\n eventType: \"UnderstudyClickEvent\",\n sessionId: \"session-test\",\n eventId: \"action-3333\",\n eventCreatedAt: \"2026-03-16T21:45:00.002Z\",\n eventParentIds: [agentEvent.eventId, actEvent.eventId],\n data: { target: \"xpath=/button[1]\" },\n });\n\n bus.emit(agentEvent.eventType, agentEvent);\n bus.emit(actEvent.eventType, actEvent);\n bus.emit(clickEvent.eventType, clickEvent);\n\n // Flood the retained history with child events so the completion lines have\n // to recover their displayed ancestry from the queryable sink.\n for (let index = 0; index < 150; index += 1) {\n bus.emit(\n \"CdpCallEvent\",\n new FlowEvent({\n eventType: \"CdpCallEvent\",\n sessionId: \"session-test\",\n eventId: `cdp-${String(index).padStart(4, \"0\")}`,\n eventCreatedAt: `2026-03-16T21:45:00.${String(index + 10).padStart(3, \"0\")}Z`,\n eventParentIds: [\n agentEvent.eventId,\n actEvent.eventId,\n clickEvent.eventId,\n ],\n data: {\n method: \"Runtime.evaluate\",\n params: { expression: `${index}` },\n targetId: \"1234567890ABCDEF1234567890ABCDEF\",\n },\n }),\n );\n }\n\n bus.emit(\n \"UnderstudyClickCompletedEvent\",\n new FlowEvent({\n eventType: \"UnderstudyClickCompletedEvent\",\n sessionId: \"session-test\",\n eventId: \"done-4444\",\n eventCreatedAt: \"2026-03-16T21:45:01.000Z\",\n eventParentIds: [\n agentEvent.eventId,\n actEvent.eventId,\n clickEvent.eventId,\n ],\n data: { durationMs: 250 },\n }),\n );\n bus.emit(\n \"StagehandActCompletedEvent\",\n new FlowEvent({\n eventType: \"StagehandActCompletedEvent\",\n sessionId: \"session-test\",\n eventId: \"done-5555\",\n eventCreatedAt: \"2026-03-16T21:45:01.001Z\",\n eventParentIds: [agentEvent.eventId, actEvent.eventId],\n data: { durationMs: 500 },\n }),\n );\n bus.emit(\n \"AgentExecuteCompletedEvent\",\n new FlowEvent({\n eventType: \"AgentExecuteCompletedEvent\",\n sessionId: \"session-test\",\n eventId: \"done-6666\",\n eventCreatedAt: \"2026-03-16T21:45:01.002Z\",\n eventParentIds: [agentEvent.eventId],\n data: { durationMs: 750 },\n }),\n );\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n // Completion lines should reference the original started-event ids, not the\n // synthetic completed-event ids emitted at the end of the lifecycle.\n const clickCompletedLine = writes.find((line) =>\n line.includes(\"CLICK completed\"),\n );\n const actCompletedLine = writes.find((line) =>\n line.includes(\"ACT completed\"),\n );\n const agentCompletedLine = writes.find((line) =>\n line.includes(\"Agent.execute() completed\"),\n );\n\n expect(clickCompletedLine).toContain(\"[🅰 #1234]\");\n expect(clickCompletedLine).toContain(\"[🆂 #2222 ACT]\");\n expect(clickCompletedLine).toContain(\"[🆄 #3333 CLICK]\");\n expect(clickCompletedLine).not.toContain(\"#4444\");\n\n expect(actCompletedLine).toContain(\"[🅰 #1234]\");\n expect(actCompletedLine).toContain(\"[🆂 #2222 ACT]\");\n expect(actCompletedLine).not.toContain(\"#5555\");\n\n expect(agentCompletedLine).toContain(\"[🅰 #1234]\");\n expect(agentCompletedLine).not.toContain(\"#6666\");\n\n detachBus();\n await store.destroy();\n });\n});\n"]}
@@ -3,7 +3,7 @@ import Anthropic from "@anthropic-ai/sdk";
3
3
  import { AgentClient } from "./AgentClient.js";
4
4
  import { compressConversationImages } from "./utils/imageCompression.js";
5
5
  import { toJsonSchema } from "../zodCompat.js";
6
- import { FlowLogger, extractLlmCuaPromptSummary, extractLlmCuaResponseSummary, } from "../flowLogger.js";
6
+ import { FlowLogger, extractLlmCuaPromptSummary, extractLlmCuaResponseSummary, } from "../flowlogger/FlowLogger.js";
7
7
  import { v7 as uuidv7 } from "uuid";
8
8
  /**
9
9
  * Client for Anthropic's Computer Use API