@browserbasehq/orca 3.1.0-patch.1 → 3.1.0-patch.2

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 (76) hide show
  1. package/dist/esm/index.d.ts +2 -2
  2. package/dist/esm/lib/modelUtils.d.ts +3 -0
  3. package/dist/esm/lib/modelUtils.js +7 -2
  4. package/dist/esm/lib/modelUtils.js.map +1 -1
  5. package/dist/esm/lib/v3/agent/tools/act.d.ts +2 -1
  6. package/dist/esm/lib/v3/agent/tools/act.js.map +1 -1
  7. package/dist/esm/lib/v3/agent/tools/extract.d.ts +2 -1
  8. package/dist/esm/lib/v3/agent/tools/extract.js.map +1 -1
  9. package/dist/esm/lib/v3/agent/tools/fillform.d.ts +2 -1
  10. package/dist/esm/lib/v3/agent/tools/fillform.js.map +1 -1
  11. package/dist/esm/lib/v3/agent/tools/index.d.ts +2 -2
  12. package/dist/esm/lib/v3/agent/tools/index.js.map +1 -1
  13. package/dist/esm/lib/v3/api.d.ts +16 -1
  14. package/dist/esm/lib/v3/api.js +41 -5
  15. package/dist/esm/lib/v3/api.js.map +1 -1
  16. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.d.ts +0 -3
  17. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js +22 -20
  18. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
  19. package/dist/esm/lib/v3/handlers/v3AgentHandler.d.ts +2 -2
  20. package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  21. package/dist/esm/lib/v3/index.d.ts +0 -1
  22. package/dist/esm/lib/v3/index.js +0 -1
  23. package/dist/esm/lib/v3/index.js.map +1 -1
  24. package/dist/esm/lib/v3/llm/aisdk.js +5 -2
  25. package/dist/esm/lib/v3/llm/aisdk.js.map +1 -1
  26. package/dist/esm/lib/v3/shutdown/supervisor.d.ts +5 -7
  27. package/dist/esm/lib/v3/shutdown/supervisor.js +52 -62
  28. package/dist/esm/lib/v3/shutdown/supervisor.js.map +1 -1
  29. package/dist/esm/lib/v3/shutdown/supervisorClient.js +52 -48
  30. package/dist/esm/lib/v3/shutdown/supervisorClient.js.map +1 -1
  31. package/dist/esm/lib/v3/tests/click-count.spec.js +12 -47
  32. package/dist/esm/lib/v3/tests/click-count.spec.js.map +2 -2
  33. package/dist/esm/lib/v3/tests/envReporter.js +57 -0
  34. package/dist/esm/lib/v3/tests/envReporter.js.map +7 -0
  35. package/dist/esm/lib/v3/tests/iframe-ctx-addInitScript.spec.js +21 -67
  36. package/dist/esm/lib/v3/tests/iframe-ctx-addInitScript.spec.js.map +2 -2
  37. package/dist/esm/lib/v3/tests/v3.playwright.config.js +60 -3
  38. package/dist/esm/lib/v3/tests/v3.playwright.config.js.map +2 -2
  39. package/dist/esm/lib/v3/types/private/shutdown.d.ts +13 -1
  40. package/dist/esm/lib/v3/types/private/shutdown.js.map +1 -1
  41. package/dist/esm/lib/v3/types/public/api.d.ts +8 -0
  42. package/dist/esm/lib/v3/types/public/api.js +5 -3
  43. package/dist/esm/lib/v3/types/public/api.js.map +1 -1
  44. package/dist/esm/lib/v3/types/public/index.d.ts +1 -0
  45. package/dist/esm/lib/v3/types/public/index.js.map +1 -1
  46. package/dist/esm/lib/v3/types/public/sdkErrors.d.ts +3 -0
  47. package/dist/esm/lib/v3/types/public/sdkErrors.js +12 -6
  48. package/dist/esm/lib/v3/types/public/sdkErrors.js.map +1 -1
  49. package/dist/esm/lib/v3/understudy/context.js +1 -10
  50. package/dist/esm/lib/v3/understudy/context.js.map +1 -1
  51. package/dist/esm/lib/v3/understudy/locator.js +2 -2
  52. package/dist/esm/lib/v3/understudy/locator.js.map +1 -1
  53. package/dist/esm/lib/v3/understudy/page.js +1 -2
  54. package/dist/esm/lib/v3/understudy/page.js.map +1 -1
  55. package/dist/esm/lib/v3/v3.js +13 -10
  56. package/dist/esm/lib/v3/v3.js.map +1 -1
  57. package/dist/esm/tests/agent-execution-model.test.js +139 -0
  58. package/dist/esm/tests/agent-execution-model.test.js.map +7 -0
  59. package/dist/esm/tests/api-multiregion.test.js +73 -0
  60. package/dist/esm/tests/api-multiregion.test.js.map +7 -0
  61. package/dist/esm/tests/model-utils.test.js +43 -0
  62. package/dist/esm/tests/model-utils.test.js.map +7 -0
  63. package/dist/esm/tests/public-api/export-surface.test.js +0 -1
  64. package/dist/esm/tests/public-api/export-surface.test.js.map +2 -2
  65. package/dist/esm/tests/public-api/public-error-types.test.js +2 -1
  66. package/dist/esm/tests/public-api/public-error-types.test.js.map +2 -2
  67. package/dist/esm/tests/understudy-command-exception.test.js +55 -0
  68. package/dist/esm/tests/understudy-command-exception.test.js.map +7 -0
  69. package/package.json +9 -13
  70. package/dist/esm/lib/v3/cli.d.ts +0 -2
  71. package/dist/esm/lib/v3/cli.js +0 -10
  72. package/dist/esm/lib/v3/cli.js.map +0 -1
  73. package/dist/esm/lib/v3/dom/build/rerender-index.d.ts +0 -0
  74. package/dist/esm/lib/v3/dom/build/rerender-index.js.map +0 -1
  75. package/dist/esm/lib/v3/dom/build/v3-index.d.ts +0 -0
  76. package/dist/esm/lib/v3/dom/build/v3-index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"aisdk.js","sourceRoot":"","sources":["../../../../../lib/v3/llm/aisdk.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CoreAssistantMessage,\n ModelMessage,\n CoreSystemMessage,\n CoreUserMessage,\n generateObject,\n generateText,\n ImagePart,\n NoObjectGeneratedError,\n TextPart,\n ToolSet,\n Tool,\n} from \"ai\";\nimport type { LanguageModelV2 } from \"@ai-sdk/provider\";\nimport { ChatCompletion } from \"openai/resources\";\nimport { v7 as uuidv7 } from \"uuid\";\nimport { LogLine } from \"../types/public/logs.js\";\nimport { AvailableModel } from \"../types/public/model.js\";\nimport { CreateChatCompletionOptions, LLMClient } from \"./LLMClient.js\";\nimport { SessionFileLogger, formatLlmPromptPreview } from \"../flowLogger.js\";\nimport { toJsonSchema } from \"../zodCompat.js\";\n\nexport class AISdkClient extends LLMClient {\n public type = \"aisdk\" as const;\n private model: LanguageModelV2;\n private logger?: (message: LogLine) => void;\n\n constructor({\n model,\n logger,\n }: {\n model: LanguageModelV2;\n logger?: (message: LogLine) => void;\n }) {\n super(model.modelId as AvailableModel);\n this.model = model;\n this.logger = logger;\n }\n\n public getLanguageModel(): LanguageModelV2 {\n return this.model;\n }\n\n async createChatCompletion<T = ChatCompletion>({\n options,\n }: CreateChatCompletionOptions): Promise<T> {\n this.logger?.({\n category: \"aisdk\",\n message: \"creating chat completion\",\n level: 2,\n auxiliary: {\n options: {\n value: JSON.stringify({\n ...options,\n image: undefined,\n messages: options.messages.map((msg) => ({\n ...msg,\n content: Array.isArray(msg.content)\n ? msg.content.map((c) =>\n \"image_url\" in c\n ? { ...c, image_url: { url: \"[IMAGE_REDACTED]\" } }\n : c,\n )\n : msg.content,\n })),\n }),\n type: \"object\",\n },\n modelName: {\n value: this.model.modelId,\n type: \"string\",\n },\n },\n });\n\n const formattedMessages: ModelMessage[] = options.messages.map(\n (message) => {\n if (Array.isArray(message.content)) {\n if (message.role === \"system\") {\n const systemMessage: CoreSystemMessage = {\n role: \"system\",\n content: message.content\n .map((c) => (\"text\" in c ? c.text : \"\"))\n .join(\"\\n\"),\n };\n return systemMessage;\n }\n\n const contentParts = message.content.map((content) => {\n if (\"image_url\" in content) {\n const imageContent: ImagePart = {\n type: \"image\",\n image: content.image_url.url,\n };\n return imageContent;\n } else {\n const textContent: TextPart = {\n type: \"text\",\n text: content.text,\n };\n return textContent;\n }\n });\n\n if (message.role === \"user\") {\n const userMessage: CoreUserMessage = {\n role: \"user\",\n content: contentParts,\n };\n return userMessage;\n } else {\n const textOnlyParts = contentParts.map((part) => ({\n type: \"text\" as const,\n text: part.type === \"image\" ? \"[Image]\" : part.text,\n }));\n const assistantMessage: CoreAssistantMessage = {\n role: \"assistant\",\n content: textOnlyParts,\n };\n return assistantMessage;\n }\n }\n\n return {\n role: message.role,\n content: message.content,\n };\n },\n );\n\n let objectResponse: Awaited<ReturnType<typeof generateObject>>;\n const isGPT5 = this.model.modelId.includes(\"gpt-5\");\n const isCodex = this.model.modelId.includes(\"codex\");\n const usesLowReasoningEffort =\n (this.model.modelId.includes(\"gpt-5.1\") ||\n this.model.modelId.includes(\"gpt-5.2\")) &&\n !isCodex;\n const isDeepSeek = this.model.modelId.includes(\"deepseek\");\n // Kimi models only support temperature=1\n const isKimi = this.model.modelId.includes(\"kimi\");\n const temperature = isKimi ? 1 : options.temperature;\n\n if (options.response_model) {\n // Log LLM request for generateObject (extract)\n const llmRequestId = uuidv7();\n const promptPreview = formatLlmPromptPreview(options.messages, {\n hasSchema: true,\n });\n SessionFileLogger.logLlmRequest({\n requestId: llmRequestId,\n model: this.model.modelId,\n operation: \"generateObject\",\n prompt: promptPreview,\n });\n\n // For models that don't support native structured outputs, add a prompt instruction\n if (isDeepSeek || isKimi) {\n const parsedSchema = JSON.stringify(\n toJsonSchema(options.response_model.schema),\n );\n\n formattedMessages.push({\n role: \"user\",\n content: `Respond in this zod schema format:\\n${parsedSchema}\\n\nYou must respond in JSON format. respond WITH JSON. Do not include any other text, formatting or markdown in your output. Do not include \\`\\`\\` or \\`\\`\\`json in your response. Only the JSON object itself.`,\n });\n }\n\n try {\n objectResponse = await generateObject({\n model: this.model,\n messages: formattedMessages,\n schema: options.response_model.schema,\n temperature,\n providerOptions: isGPT5\n ? {\n openai: {\n textVerbosity: isCodex ? \"medium\" : \"low\", // codex models only support 'medium'\n reasoningEffort: isCodex\n ? \"medium\"\n : usesLowReasoningEffort\n ? \"low\"\n : \"minimal\",\n },\n }\n : undefined,\n });\n } catch (err) {\n // Log error response to maintain request/response pairing\n SessionFileLogger.logLlmResponse({\n requestId: llmRequestId,\n model: this.model.modelId,\n operation: \"generateObject\",\n output: `[error: ${err instanceof Error ? err.message : \"unknown\"}]`,\n });\n\n if (NoObjectGeneratedError.isInstance(err)) {\n this.logger?.({\n category: \"AISDK error\",\n message: err.message,\n level: 0,\n auxiliary: {\n cause: {\n value: JSON.stringify(err.cause ?? {}),\n type: \"object\",\n },\n text: {\n value: err.text ?? \"\",\n type: \"string\",\n },\n response: {\n value: JSON.stringify(err.response ?? {}),\n type: \"object\",\n },\n usage: {\n value: JSON.stringify(err.usage ?? {}),\n type: \"object\",\n },\n finishReason: {\n value: err.finishReason ?? \"unknown\",\n type: \"string\",\n },\n requestId: {\n value: options.requestId,\n type: \"string\",\n },\n },\n });\n\n throw err;\n }\n throw err;\n }\n\n const result = {\n data: objectResponse.object,\n usage: {\n prompt_tokens: objectResponse.usage.inputTokens ?? 0,\n completion_tokens: objectResponse.usage.outputTokens ?? 0,\n reasoning_tokens: objectResponse.usage.reasoningTokens ?? 0,\n cached_input_tokens: objectResponse.usage.cachedInputTokens ?? 0,\n total_tokens: objectResponse.usage.totalTokens ?? 0,\n },\n } as T;\n\n // Log LLM response for generateObject\n SessionFileLogger.logLlmResponse({\n requestId: llmRequestId,\n model: this.model.modelId,\n operation: \"generateObject\",\n output: JSON.stringify(objectResponse.object),\n inputTokens: objectResponse.usage.inputTokens,\n outputTokens: objectResponse.usage.outputTokens,\n });\n\n this.logger?.({\n category: \"aisdk\",\n message: \"response\",\n level: 1,\n auxiliary: {\n response: {\n value: JSON.stringify({\n object: objectResponse.object,\n usage: objectResponse.usage,\n finishReason: objectResponse.finishReason,\n // Omit request and response properties that might contain images\n }),\n type: \"object\",\n },\n requestId: {\n value: options.requestId,\n type: \"string\",\n },\n },\n });\n\n return result;\n }\n\n const tools: ToolSet = {};\n if (options.tools && options.tools.length > 0) {\n for (const tool of options.tools) {\n tools[tool.name] = {\n description: tool.description,\n inputSchema: tool.parameters,\n } as Tool;\n }\n }\n\n // Log LLM request for generateText (act/observe)\n const llmRequestId = uuidv7();\n const toolCount = Object.keys(tools).length;\n const promptPreview = formatLlmPromptPreview(options.messages, {\n toolCount,\n });\n SessionFileLogger.logLlmRequest({\n requestId: llmRequestId,\n model: this.model.modelId,\n operation: \"generateText\",\n prompt: promptPreview,\n });\n\n let textResponse: Awaited<ReturnType<typeof generateText>>;\n try {\n textResponse = await generateText({\n model: this.model,\n messages: formattedMessages,\n tools: Object.keys(tools).length > 0 ? tools : undefined,\n toolChoice:\n Object.keys(tools).length > 0\n ? options.tool_choice === \"required\"\n ? \"required\"\n : options.tool_choice === \"none\"\n ? \"none\"\n : \"auto\"\n : undefined,\n temperature,\n });\n } catch (err) {\n // Log error response to maintain request/response pairing\n SessionFileLogger.logLlmResponse({\n requestId: llmRequestId,\n model: this.model.modelId,\n operation: \"generateText\",\n output: `[error: ${err instanceof Error ? err.message : \"unknown\"}]`,\n });\n throw err;\n }\n\n // Transform AI SDK response to match LLMResponse format expected by operator handler\n const transformedToolCalls = (textResponse.toolCalls || []).map(\n (toolCall) => ({\n id:\n toolCall.toolCallId ||\n `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n type: \"function\",\n function: {\n name: toolCall.toolName,\n arguments: JSON.stringify(toolCall.input),\n },\n }),\n );\n\n const result = {\n id: `chatcmpl_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n object: \"chat.completion\",\n created: Math.floor(Date.now() / 1000),\n model: this.model.modelId,\n choices: [\n {\n index: 0,\n message: {\n role: \"assistant\",\n content: textResponse.text || null,\n tool_calls: transformedToolCalls,\n },\n finish_reason: textResponse.finishReason || \"stop\",\n },\n ],\n usage: {\n prompt_tokens: textResponse.usage.inputTokens ?? 0,\n completion_tokens: textResponse.usage.outputTokens ?? 0,\n reasoning_tokens: textResponse.usage.reasoningTokens ?? 0,\n cached_input_tokens: textResponse.usage.cachedInputTokens ?? 0,\n total_tokens: textResponse.usage.totalTokens ?? 0,\n },\n } as T;\n\n // Log LLM response for generateText\n SessionFileLogger.logLlmResponse({\n requestId: llmRequestId,\n model: this.model.modelId,\n operation: \"generateText\",\n output:\n textResponse.text ||\n (transformedToolCalls.length > 0\n ? `[${transformedToolCalls.length} tool calls]`\n : \"\"),\n inputTokens: textResponse.usage.inputTokens,\n outputTokens: textResponse.usage.outputTokens,\n });\n\n this.logger?.({\n category: \"aisdk\",\n message: \"response\",\n level: 2,\n auxiliary: {\n response: {\n value: JSON.stringify({\n text: textResponse.text,\n usage: textResponse.usage,\n finishReason: textResponse.finishReason,\n // Omit request and response properties that might contain images\n }),\n type: \"object\",\n },\n requestId: {\n value: options.requestId,\n type: \"string\",\n },\n },\n });\n\n return result;\n }\n}\n"]}
1
+ {"version":3,"file":"aisdk.js","sourceRoot":"","sources":["../../../../../lib/v3/llm/aisdk.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CoreAssistantMessage,\n ModelMessage,\n CoreSystemMessage,\n CoreUserMessage,\n generateObject,\n generateText,\n ImagePart,\n NoObjectGeneratedError,\n TextPart,\n ToolSet,\n Tool,\n} from \"ai\";\nimport type { LanguageModelV2 } from \"@ai-sdk/provider\";\nimport { ChatCompletion } from \"openai/resources\";\nimport { v7 as uuidv7 } from \"uuid\";\nimport { LogLine } from \"../types/public/logs.js\";\nimport { AvailableModel } from \"../types/public/model.js\";\nimport { CreateChatCompletionOptions, LLMClient } from \"./LLMClient.js\";\nimport { SessionFileLogger, formatLlmPromptPreview } from \"../flowLogger.js\";\nimport { toJsonSchema } from \"../zodCompat.js\";\n\nexport class AISdkClient extends LLMClient {\n public type = \"aisdk\" as const;\n private model: LanguageModelV2;\n private logger?: (message: LogLine) => void;\n\n constructor({\n model,\n logger,\n }: {\n model: LanguageModelV2;\n logger?: (message: LogLine) => void;\n }) {\n super(model.modelId as AvailableModel);\n this.model = model;\n this.logger = logger;\n }\n\n public getLanguageModel(): LanguageModelV2 {\n return this.model;\n }\n\n async createChatCompletion<T = ChatCompletion>({\n options,\n }: CreateChatCompletionOptions): Promise<T> {\n this.logger?.({\n category: \"aisdk\",\n message: \"creating chat completion\",\n level: 2,\n auxiliary: {\n options: {\n value: JSON.stringify({\n ...options,\n image: undefined,\n messages: options.messages.map((msg) => ({\n ...msg,\n content: Array.isArray(msg.content)\n ? msg.content.map((c) =>\n \"image_url\" in c\n ? { ...c, image_url: { url: \"[IMAGE_REDACTED]\" } }\n : c,\n )\n : msg.content,\n })),\n }),\n type: \"object\",\n },\n modelName: {\n value: this.model.modelId,\n type: \"string\",\n },\n },\n });\n\n const formattedMessages: ModelMessage[] = options.messages.map(\n (message) => {\n if (Array.isArray(message.content)) {\n if (message.role === \"system\") {\n const systemMessage: CoreSystemMessage = {\n role: \"system\",\n content: message.content\n .map((c) => (\"text\" in c ? c.text : \"\"))\n .join(\"\\n\"),\n };\n return systemMessage;\n }\n\n const contentParts = message.content.map((content) => {\n if (\"image_url\" in content) {\n const imageContent: ImagePart = {\n type: \"image\",\n image: content.image_url.url,\n };\n return imageContent;\n } else {\n const textContent: TextPart = {\n type: \"text\",\n text: content.text,\n };\n return textContent;\n }\n });\n\n if (message.role === \"user\") {\n const userMessage: CoreUserMessage = {\n role: \"user\",\n content: contentParts,\n };\n return userMessage;\n } else {\n const textOnlyParts = contentParts.map((part) => ({\n type: \"text\" as const,\n text: part.type === \"image\" ? \"[Image]\" : part.text,\n }));\n const assistantMessage: CoreAssistantMessage = {\n role: \"assistant\",\n content: textOnlyParts,\n };\n return assistantMessage;\n }\n }\n\n return {\n role: message.role,\n content: message.content,\n };\n },\n );\n\n let objectResponse: Awaited<ReturnType<typeof generateObject>>;\n const isGPT5 = this.model.modelId.includes(\"gpt-5\");\n const isCodex = this.model.modelId.includes(\"codex\");\n const usesLowReasoningEffort =\n (this.model.modelId.includes(\"gpt-5.1\") ||\n this.model.modelId.includes(\"gpt-5.2\")) &&\n !isCodex;\n // Kimi models only support temperature=1\n const isKimi = this.model.modelId.includes(\"kimi\");\n const temperature = isKimi ? 1 : options.temperature;\n\n // Models that lack native structured-output support need a prompt-based\n // JSON fallback instead of response_format: { type: \"json_schema\" }.\n const PROMPT_JSON_FALLBACK_PATTERNS = [\"deepseek\", \"kimi\", \"glm\"];\n const needsPromptJsonFallback = PROMPT_JSON_FALLBACK_PATTERNS.some((p) =>\n this.model.modelId.includes(p),\n );\n\n if (options.response_model) {\n // Log LLM request for generateObject (extract)\n const llmRequestId = uuidv7();\n const promptPreview = formatLlmPromptPreview(options.messages, {\n hasSchema: true,\n });\n SessionFileLogger.logLlmRequest({\n requestId: llmRequestId,\n model: this.model.modelId,\n operation: \"generateObject\",\n prompt: promptPreview,\n });\n\n // For models that don't support native structured outputs, add a prompt instruction\n if (needsPromptJsonFallback) {\n const parsedSchema = JSON.stringify(\n toJsonSchema(options.response_model.schema),\n );\n\n formattedMessages.push({\n role: \"user\",\n content: `Respond in this zod schema format:\\n${parsedSchema}\\n\nYou must respond in JSON format. respond WITH JSON. Do not include any other text, formatting or markdown in your output. Do not include \\`\\`\\` or \\`\\`\\`json in your response. Only the JSON object itself.`,\n });\n }\n\n try {\n objectResponse = await generateObject({\n model: this.model,\n messages: formattedMessages,\n schema: options.response_model.schema,\n temperature,\n providerOptions: isGPT5\n ? {\n openai: {\n textVerbosity: isCodex ? \"medium\" : \"low\", // codex models only support 'medium'\n reasoningEffort: isCodex\n ? \"medium\"\n : usesLowReasoningEffort\n ? \"low\"\n : \"minimal\",\n },\n }\n : undefined,\n });\n } catch (err) {\n // Log error response to maintain request/response pairing\n SessionFileLogger.logLlmResponse({\n requestId: llmRequestId,\n model: this.model.modelId,\n operation: \"generateObject\",\n output: `[error: ${err instanceof Error ? err.message : \"unknown\"}]`,\n });\n\n if (NoObjectGeneratedError.isInstance(err)) {\n this.logger?.({\n category: \"AISDK error\",\n message: err.message,\n level: 0,\n auxiliary: {\n cause: {\n value: JSON.stringify(err.cause ?? {}),\n type: \"object\",\n },\n text: {\n value: err.text ?? \"\",\n type: \"string\",\n },\n response: {\n value: JSON.stringify(err.response ?? {}),\n type: \"object\",\n },\n usage: {\n value: JSON.stringify(err.usage ?? {}),\n type: \"object\",\n },\n finishReason: {\n value: err.finishReason ?? \"unknown\",\n type: \"string\",\n },\n requestId: {\n value: options.requestId,\n type: \"string\",\n },\n },\n });\n\n throw err;\n }\n throw err;\n }\n\n const result = {\n data: objectResponse.object,\n usage: {\n prompt_tokens: objectResponse.usage.inputTokens ?? 0,\n completion_tokens: objectResponse.usage.outputTokens ?? 0,\n reasoning_tokens: objectResponse.usage.reasoningTokens ?? 0,\n cached_input_tokens: objectResponse.usage.cachedInputTokens ?? 0,\n total_tokens: objectResponse.usage.totalTokens ?? 0,\n },\n } as T;\n\n // Log LLM response for generateObject\n SessionFileLogger.logLlmResponse({\n requestId: llmRequestId,\n model: this.model.modelId,\n operation: \"generateObject\",\n output: JSON.stringify(objectResponse.object),\n inputTokens: objectResponse.usage.inputTokens,\n outputTokens: objectResponse.usage.outputTokens,\n });\n\n this.logger?.({\n category: \"aisdk\",\n message: \"response\",\n level: 1,\n auxiliary: {\n response: {\n value: JSON.stringify({\n object: objectResponse.object,\n usage: objectResponse.usage,\n finishReason: objectResponse.finishReason,\n // Omit request and response properties that might contain images\n }),\n type: \"object\",\n },\n requestId: {\n value: options.requestId,\n type: \"string\",\n },\n },\n });\n\n return result;\n }\n\n const tools: ToolSet = {};\n if (options.tools && options.tools.length > 0) {\n for (const tool of options.tools) {\n tools[tool.name] = {\n description: tool.description,\n inputSchema: tool.parameters,\n } as Tool;\n }\n }\n\n // Log LLM request for generateText (act/observe)\n const llmRequestId = uuidv7();\n const toolCount = Object.keys(tools).length;\n const promptPreview = formatLlmPromptPreview(options.messages, {\n toolCount,\n });\n SessionFileLogger.logLlmRequest({\n requestId: llmRequestId,\n model: this.model.modelId,\n operation: \"generateText\",\n prompt: promptPreview,\n });\n\n let textResponse: Awaited<ReturnType<typeof generateText>>;\n try {\n textResponse = await generateText({\n model: this.model,\n messages: formattedMessages,\n tools: Object.keys(tools).length > 0 ? tools : undefined,\n toolChoice:\n Object.keys(tools).length > 0\n ? options.tool_choice === \"required\"\n ? \"required\"\n : options.tool_choice === \"none\"\n ? \"none\"\n : \"auto\"\n : undefined,\n temperature,\n });\n } catch (err) {\n // Log error response to maintain request/response pairing\n SessionFileLogger.logLlmResponse({\n requestId: llmRequestId,\n model: this.model.modelId,\n operation: \"generateText\",\n output: `[error: ${err instanceof Error ? err.message : \"unknown\"}]`,\n });\n throw err;\n }\n\n // Transform AI SDK response to match LLMResponse format expected by operator handler\n const transformedToolCalls = (textResponse.toolCalls || []).map(\n (toolCall) => ({\n id:\n toolCall.toolCallId ||\n `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n type: \"function\",\n function: {\n name: toolCall.toolName,\n arguments: JSON.stringify(toolCall.input),\n },\n }),\n );\n\n const result = {\n id: `chatcmpl_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n object: \"chat.completion\",\n created: Math.floor(Date.now() / 1000),\n model: this.model.modelId,\n choices: [\n {\n index: 0,\n message: {\n role: \"assistant\",\n content: textResponse.text || null,\n tool_calls: transformedToolCalls,\n },\n finish_reason: textResponse.finishReason || \"stop\",\n },\n ],\n usage: {\n prompt_tokens: textResponse.usage.inputTokens ?? 0,\n completion_tokens: textResponse.usage.outputTokens ?? 0,\n reasoning_tokens: textResponse.usage.reasoningTokens ?? 0,\n cached_input_tokens: textResponse.usage.cachedInputTokens ?? 0,\n total_tokens: textResponse.usage.totalTokens ?? 0,\n },\n } as T;\n\n // Log LLM response for generateText\n SessionFileLogger.logLlmResponse({\n requestId: llmRequestId,\n model: this.model.modelId,\n operation: \"generateText\",\n output:\n textResponse.text ||\n (transformedToolCalls.length > 0\n ? `[${transformedToolCalls.length} tool calls]`\n : \"\"),\n inputTokens: textResponse.usage.inputTokens,\n outputTokens: textResponse.usage.outputTokens,\n });\n\n this.logger?.({\n category: \"aisdk\",\n message: \"response\",\n level: 2,\n auxiliary: {\n response: {\n value: JSON.stringify({\n text: textResponse.text,\n usage: textResponse.usage,\n finishReason: textResponse.finishReason,\n // Omit request and response properties that might contain images\n }),\n type: \"object\",\n },\n requestId: {\n value: options.requestId,\n type: \"string\",\n },\n },\n });\n\n return result;\n }\n}\n"]}
@@ -1,11 +1,9 @@
1
1
  /**
2
2
  * Shutdown supervisor process.
3
3
  *
4
- * This process watches a stdin lifeline. When the parent dies, stdin closes
5
- * and the supervisor performs best-effort cleanup:
6
- * - LOCAL: kill Chrome + remove temp profile
7
- * - STAGEHAND_API: request session release
4
+ * This process watches a lifeline (stdin/IPC). When the parent dies, the
5
+ * lifeline closes and the supervisor performs best-effort cleanup:
6
+ * - LOCAL: kill Chrome + remove temp profile (when keepAlive is false)
7
+ * - STAGEHAND_API: request session release (when keepAlive is false)
8
8
  */
9
- import type { ShutdownSupervisorConfig } from "../types/private/shutdown.js";
10
- export declare const runShutdownSupervisor: (initialConfig: ShutdownSupervisorConfig) => void;
11
- export declare const maybeRunShutdownSupervisorFromArgv: (argv?: readonly string[]) => boolean;
9
+ export {};
@@ -1,20 +1,19 @@
1
1
  /**
2
2
  * Shutdown supervisor process.
3
3
  *
4
- * This process watches a stdin lifeline. When the parent dies, stdin closes
5
- * and the supervisor performs best-effort cleanup:
6
- * - LOCAL: kill Chrome + remove temp profile
7
- * - STAGEHAND_API: request session release
4
+ * This process watches a lifeline (stdin/IPC). When the parent dies, the
5
+ * lifeline closes and the supervisor performs best-effort cleanup:
6
+ * - LOCAL: kill Chrome + remove temp profile (when keepAlive is false)
7
+ * - STAGEHAND_API: request session release (when keepAlive is false)
8
8
  */
9
9
  import Browserbase from "@browserbasehq/sdk";
10
10
  import { cleanupLocalBrowser } from "./cleanupLocal.js";
11
- const SIGKILL_POLL_MS = 250;
12
- const SIGKILL_TIMEOUT_MS = 7_000;
11
+ const SIGKILL_POLL_MS = 500;
12
+ const SIGKILL_TIMEOUT_MS = 10_000;
13
13
  const PID_POLL_INTERVAL_MS = 500;
14
- // `cleanupPromise` guarantees we execute cleanup at most once.
14
+ let armed = false;
15
15
  let config = null;
16
16
  let cleanupPromise = null;
17
- let started = false;
18
17
  const exit = (code = 0) => {
19
18
  try {
20
19
  process.exit(code);
@@ -23,18 +22,14 @@ const exit = (code = 0) => {
23
22
  // ignore
24
23
  }
25
24
  };
26
- // Best-effort two-phase kill: SIGTERM first, then SIGKILL after timeout.
27
- // Treat only ESRCH as "already gone"; other errors should not imply dead.
28
- const politeKill = async (pid) => {
25
+ const safeKill = async (pid) => {
29
26
  const isAlive = () => {
30
27
  try {
31
28
  process.kill(pid, 0);
32
29
  return true;
33
30
  }
34
- catch (error) {
35
- const err = error;
36
- // ESRCH = "No such process" (PID is already gone).
37
- return err.code !== "ESRCH";
31
+ catch {
32
+ return false;
38
33
  }
39
34
  };
40
35
  if (!isAlive())
@@ -42,11 +37,8 @@ const politeKill = async (pid) => {
42
37
  try {
43
38
  process.kill(pid, "SIGTERM");
44
39
  }
45
- catch (error) {
46
- const err = error;
47
- // ESRCH = process already exited; no further action needed.
48
- if (err.code === "ESRCH")
49
- return;
40
+ catch {
41
+ return;
50
42
  }
51
43
  const deadline = Date.now() + SIGKILL_TIMEOUT_MS;
52
44
  while (Date.now() < deadline) {
@@ -61,8 +53,8 @@ const politeKill = async (pid) => {
61
53
  // best-effort
62
54
  }
63
55
  };
56
+ let pidGone = false;
64
57
  let pidPollTimer = null;
65
- // Local-only fallback: if Chrome dies while parent still lives, run cleanup and exit.
66
58
  const startPidPolling = (pid) => {
67
59
  if (pidPollTimer)
68
60
  return;
@@ -71,23 +63,27 @@ const startPidPolling = (pid) => {
71
63
  process.kill(pid, 0);
72
64
  }
73
65
  catch {
66
+ pidGone = true;
74
67
  if (pidPollTimer) {
75
68
  clearInterval(pidPollTimer);
76
69
  pidPollTimer = null;
77
70
  }
78
- void runCleanup().finally(() => exit(0));
79
71
  }
80
72
  }, PID_POLL_INTERVAL_MS);
81
73
  };
82
74
  const cleanupLocal = async (cfg) => {
75
+ if (cfg.keepAlive)
76
+ return;
83
77
  await cleanupLocalBrowser({
84
- killChrome: cfg.pid ? () => politeKill(cfg.pid) : undefined,
78
+ killChrome: cfg.pid && !pidGone ? () => safeKill(cfg.pid) : undefined,
85
79
  userDataDir: cfg.userDataDir,
86
80
  createdTempProfile: cfg.createdTempProfile,
87
81
  preserveUserDataDir: cfg.preserveUserDataDir,
88
82
  });
89
83
  };
90
84
  const cleanupBrowserbase = async (cfg) => {
85
+ if (cfg.keepAlive)
86
+ return;
91
87
  if (!cfg.apiKey || !cfg.projectId || !cfg.sessionId)
92
88
  return;
93
89
  try {
@@ -101,13 +97,13 @@ const cleanupBrowserbase = async (cfg) => {
101
97
  // best-effort cleanup
102
98
  }
103
99
  };
104
- // Idempotent cleanup entrypoint used by all supervisor shutdown paths.
105
100
  const runCleanup = () => {
106
101
  if (!cleanupPromise) {
107
102
  cleanupPromise = (async () => {
108
103
  const cfg = config;
109
- if (!cfg)
104
+ if (!cfg || !armed)
110
105
  return;
106
+ armed = false;
111
107
  if (cfg.kind === "LOCAL") {
112
108
  await cleanupLocal(cfg);
113
109
  return;
@@ -119,48 +115,42 @@ const runCleanup = () => {
119
115
  }
120
116
  return cleanupPromise;
121
117
  };
122
- const applyConfig = (nextConfig) => {
123
- config = nextConfig;
124
- if (config.kind === "LOCAL" && config.pid) {
125
- startPidPolling(config.pid);
126
- }
127
- };
128
118
  const onLifelineClosed = () => {
129
119
  void runCleanup().finally(() => exit(0));
130
120
  };
131
- const parseConfigFromArgv = (argv = process.argv.slice(2)) => {
132
- const prefix = "--supervisor-config=";
133
- const raw = argv.find((arg) => arg.startsWith(prefix))?.slice(prefix.length);
134
- if (!argv.includes("--supervisor") || !raw)
135
- return null;
136
- try {
137
- return JSON.parse(raw);
138
- }
139
- catch {
140
- return null;
141
- }
142
- };
143
- export const runShutdownSupervisor = (initialConfig) => {
144
- if (started)
121
+ const onMessage = (raw) => {
122
+ if (!raw || typeof raw !== "object")
123
+ return;
124
+ const msg = raw;
125
+ if (msg.type === "config") {
126
+ config = msg.config ?? null;
127
+ armed = Boolean(config) && config?.keepAlive === false;
128
+ if (armed && config?.kind === "LOCAL" && config?.pid) {
129
+ startPidPolling(config.pid);
130
+ }
131
+ try {
132
+ process.send?.({ type: "ready" });
133
+ }
134
+ catch {
135
+ // ignore IPC failures
136
+ }
145
137
  return;
146
- started = true;
147
- applyConfig(initialConfig);
148
- // Stdin is the lifeline; losing it means parent is gone.
149
- try {
150
- process.stdin.resume();
151
- process.stdin.on("end", onLifelineClosed);
152
- process.stdin.on("close", onLifelineClosed);
153
- process.stdin.on("error", onLifelineClosed);
154
138
  }
155
- catch {
156
- // ignore
139
+ if (msg.type === "exit") {
140
+ armed = false;
141
+ exit(0);
157
142
  }
158
143
  };
159
- export const maybeRunShutdownSupervisorFromArgv = (argv = process.argv.slice(2)) => {
160
- const parsed = parseConfigFromArgv(argv);
161
- if (!parsed)
162
- return false;
163
- runShutdownSupervisor(parsed);
164
- return true;
165
- };
144
+ // Keep stdin open as a lifeline to the parent process.
145
+ try {
146
+ process.stdin.resume();
147
+ process.stdin.on("end", onLifelineClosed);
148
+ process.stdin.on("close", onLifelineClosed);
149
+ process.stdin.on("error", onLifelineClosed);
150
+ }
151
+ catch {
152
+ // ignore
153
+ }
154
+ process.on("disconnect", onLifelineClosed);
155
+ process.on("message", onMessage);
166
156
  //# sourceMappingURL=supervisor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../../../../../lib/v3/shutdown/supervisor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shutdown supervisor process.\n *\n * This process watches a stdin lifeline. When the parent dies, stdin closes\n * and the supervisor performs best-effort cleanup:\n * - LOCAL: kill Chrome + remove temp profile\n * - STAGEHAND_API: request session release\n */\n\nimport Browserbase from \"@browserbasehq/sdk\";\nimport type { ShutdownSupervisorConfig } from \"../types/private/shutdown.js\";\nimport { cleanupLocalBrowser } from \"./cleanupLocal.js\";\n\nconst SIGKILL_POLL_MS = 250;\nconst SIGKILL_TIMEOUT_MS = 7_000;\nconst PID_POLL_INTERVAL_MS = 500;\n\n// `cleanupPromise` guarantees we execute cleanup at most once.\nlet config: ShutdownSupervisorConfig | null = null;\nlet cleanupPromise: Promise<void> | null = null;\nlet started = false;\n\nconst exit = (code = 0): void => {\n try {\n process.exit(code);\n } catch {\n // ignore\n }\n};\n\n// Best-effort two-phase kill: SIGTERM first, then SIGKILL after timeout.\n// Treat only ESRCH as \"already gone\"; other errors should not imply dead.\nconst politeKill = async (pid: number): Promise<void> => {\n const isAlive = (): boolean => {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n // ESRCH = \"No such process\" (PID is already gone).\n return err.code !== \"ESRCH\";\n }\n };\n\n if (!isAlive()) return;\n try {\n process.kill(pid, \"SIGTERM\");\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n // ESRCH = process already exited; no further action needed.\n if (err.code === \"ESRCH\") return;\n }\n\n const deadline = Date.now() + SIGKILL_TIMEOUT_MS;\n while (Date.now() < deadline) {\n await new Promise((resolve) => setTimeout(resolve, SIGKILL_POLL_MS));\n if (!isAlive()) return;\n }\n try {\n process.kill(pid, \"SIGKILL\");\n } catch {\n // best-effort\n }\n};\n\nlet pidPollTimer: NodeJS.Timeout | null = null;\n\n// Local-only fallback: if Chrome dies while parent still lives, run cleanup and exit.\nconst startPidPolling = (pid: number): void => {\n if (pidPollTimer) return;\n pidPollTimer = setInterval(() => {\n try {\n process.kill(pid, 0);\n } catch {\n if (pidPollTimer) {\n clearInterval(pidPollTimer);\n pidPollTimer = null;\n }\n void runCleanup().finally(() => exit(0));\n }\n }, PID_POLL_INTERVAL_MS);\n};\n\nconst cleanupLocal = async (\n cfg: Extract<ShutdownSupervisorConfig, { kind: \"LOCAL\" }>,\n) => {\n await cleanupLocalBrowser({\n killChrome: cfg.pid ? () => politeKill(cfg.pid) : undefined,\n userDataDir: cfg.userDataDir,\n createdTempProfile: cfg.createdTempProfile,\n preserveUserDataDir: cfg.preserveUserDataDir,\n });\n};\n\nconst cleanupBrowserbase = async (\n cfg: Extract<ShutdownSupervisorConfig, { kind: \"STAGEHAND_API\" }>,\n) => {\n if (!cfg.apiKey || !cfg.projectId || !cfg.sessionId) return;\n try {\n const bb = new Browserbase({ apiKey: cfg.apiKey });\n await bb.sessions.update(cfg.sessionId, {\n status: \"REQUEST_RELEASE\",\n projectId: cfg.projectId,\n });\n } catch {\n // best-effort cleanup\n }\n};\n\n// Idempotent cleanup entrypoint used by all supervisor shutdown paths.\nconst runCleanup = (): Promise<void> => {\n if (!cleanupPromise) {\n cleanupPromise = (async () => {\n const cfg = config;\n if (!cfg) return;\n if (cfg.kind === \"LOCAL\") {\n await cleanupLocal(cfg);\n return;\n }\n if (cfg.kind === \"STAGEHAND_API\") {\n await cleanupBrowserbase(cfg);\n }\n })();\n }\n return cleanupPromise;\n};\n\nconst applyConfig = (nextConfig: ShutdownSupervisorConfig): void => {\n config = nextConfig;\n if (config.kind === \"LOCAL\" && config.pid) {\n startPidPolling(config.pid);\n }\n};\n\nconst onLifelineClosed = () => {\n void runCleanup().finally(() => exit(0));\n};\n\nconst parseConfigFromArgv = (\n argv: readonly string[] = process.argv.slice(2),\n): ShutdownSupervisorConfig | null => {\n const prefix = \"--supervisor-config=\";\n const raw = argv.find((arg) => arg.startsWith(prefix))?.slice(prefix.length);\n if (!argv.includes(\"--supervisor\") || !raw) return null;\n try {\n return JSON.parse(raw) as ShutdownSupervisorConfig;\n } catch {\n return null;\n }\n};\n\nexport const runShutdownSupervisor = (\n initialConfig: ShutdownSupervisorConfig,\n): void => {\n if (started) return;\n started = true;\n applyConfig(initialConfig);\n\n // Stdin is the lifeline; losing it means parent is gone.\n try {\n process.stdin.resume();\n process.stdin.on(\"end\", onLifelineClosed);\n process.stdin.on(\"close\", onLifelineClosed);\n process.stdin.on(\"error\", onLifelineClosed);\n } catch {\n // ignore\n }\n};\n\nexport const maybeRunShutdownSupervisorFromArgv = (\n argv: readonly string[] = process.argv.slice(2),\n): boolean => {\n const parsed = parseConfigFromArgv(argv);\n if (!parsed) return false;\n runShutdownSupervisor(parsed);\n return true;\n};\n"]}
1
+ {"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../../../../../lib/v3/shutdown/supervisor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shutdown supervisor process.\n *\n * This process watches a lifeline (stdin/IPC). When the parent dies, the\n * lifeline closes and the supervisor performs best-effort cleanup:\n * - LOCAL: kill Chrome + remove temp profile (when keepAlive is false)\n * - STAGEHAND_API: request session release (when keepAlive is false)\n */\n\nimport Browserbase from \"@browserbasehq/sdk\";\nimport type {\n ShutdownSupervisorConfig,\n ShutdownSupervisorMessage,\n} from \"../types/private/shutdown.js\";\nimport { cleanupLocalBrowser } from \"./cleanupLocal.js\";\n\nconst SIGKILL_POLL_MS = 500;\nconst SIGKILL_TIMEOUT_MS = 10_000;\nconst PID_POLL_INTERVAL_MS = 500;\n\nlet armed = false;\nlet config: ShutdownSupervisorConfig | null = null;\nlet cleanupPromise: Promise<void> | null = null;\n\nconst exit = (code = 0): void => {\n try {\n process.exit(code);\n } catch {\n // ignore\n }\n};\n\nconst safeKill = async (pid: number): Promise<void> => {\n const isAlive = (): boolean => {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n };\n\n if (!isAlive()) return;\n try {\n process.kill(pid, \"SIGTERM\");\n } catch {\n return;\n }\n\n const deadline = Date.now() + SIGKILL_TIMEOUT_MS;\n while (Date.now() < deadline) {\n await new Promise((resolve) => setTimeout(resolve, SIGKILL_POLL_MS));\n if (!isAlive()) return;\n }\n try {\n process.kill(pid, \"SIGKILL\");\n } catch {\n // best-effort\n }\n};\n\nlet pidGone = false;\nlet pidPollTimer: NodeJS.Timeout | null = null;\n\nconst startPidPolling = (pid: number): void => {\n if (pidPollTimer) return;\n pidPollTimer = setInterval(() => {\n try {\n process.kill(pid, 0);\n } catch {\n pidGone = true;\n if (pidPollTimer) {\n clearInterval(pidPollTimer);\n pidPollTimer = null;\n }\n }\n }, PID_POLL_INTERVAL_MS);\n};\n\nconst cleanupLocal = async (\n cfg: Extract<ShutdownSupervisorConfig, { kind: \"LOCAL\" }>,\n) => {\n if (cfg.keepAlive) return;\n await cleanupLocalBrowser({\n killChrome: cfg.pid && !pidGone ? () => safeKill(cfg.pid) : undefined,\n userDataDir: cfg.userDataDir,\n createdTempProfile: cfg.createdTempProfile,\n preserveUserDataDir: cfg.preserveUserDataDir,\n });\n};\n\nconst cleanupBrowserbase = async (\n cfg: Extract<ShutdownSupervisorConfig, { kind: \"STAGEHAND_API\" }>,\n) => {\n if (cfg.keepAlive) return;\n if (!cfg.apiKey || !cfg.projectId || !cfg.sessionId) return;\n try {\n const bb = new Browserbase({ apiKey: cfg.apiKey });\n await bb.sessions.update(cfg.sessionId, {\n status: \"REQUEST_RELEASE\",\n projectId: cfg.projectId,\n });\n } catch {\n // best-effort cleanup\n }\n};\n\nconst runCleanup = (): Promise<void> => {\n if (!cleanupPromise) {\n cleanupPromise = (async () => {\n const cfg = config;\n if (!cfg || !armed) return;\n armed = false;\n if (cfg.kind === \"LOCAL\") {\n await cleanupLocal(cfg);\n return;\n }\n if (cfg.kind === \"STAGEHAND_API\") {\n await cleanupBrowserbase(cfg);\n }\n })();\n }\n return cleanupPromise;\n};\n\nconst onLifelineClosed = () => {\n void runCleanup().finally(() => exit(0));\n};\n\nconst onMessage = (raw: unknown) => {\n if (!raw || typeof raw !== \"object\") return;\n const msg = raw as ShutdownSupervisorMessage;\n if (msg.type === \"config\") {\n config = msg.config ?? null;\n armed = Boolean(config) && config?.keepAlive === false;\n if (armed && config?.kind === \"LOCAL\" && config?.pid) {\n startPidPolling(config.pid);\n }\n try {\n process.send?.({ type: \"ready\" });\n } catch {\n // ignore IPC failures\n }\n return;\n }\n if (msg.type === \"exit\") {\n armed = false;\n exit(0);\n }\n};\n\n// Keep stdin open as a lifeline to the parent process.\ntry {\n process.stdin.resume();\n process.stdin.on(\"end\", onLifelineClosed);\n process.stdin.on(\"close\", onLifelineClosed);\n process.stdin.on(\"error\", onLifelineClosed);\n} catch {\n // ignore\n}\n\nprocess.on(\"disconnect\", onLifelineClosed);\nprocess.on(\"message\", onMessage);\n"]}
@@ -6,66 +6,37 @@
6
6
  * session release) when keepAlive is false.
7
7
  */
8
8
  import fs from "node:fs";
9
+ import path from "node:path";
9
10
  import { spawn } from "node:child_process";
10
- import { createRequire } from "node:module";
11
11
  import { fileURLToPath } from "node:url";
12
12
  import { ShutdownSupervisorResolveError, ShutdownSupervisorSpawnError, } from "../types/private/shutdownErrors.js";
13
- // Resolve module path for both CJS and ESM builds.
14
- const normalizedFilename = typeof __filename === "string" ? __filename.replaceAll("\\", "/") : "";
15
- const hasAbsoluteFilename = normalizedFilename.startsWith("/") || /^[A-Za-z]:\//.test(normalizedFilename);
16
- const modulePath = hasAbsoluteFilename
17
- ? __filename
18
- : fileURLToPath(import.meta.url);
19
- const normalizedModulePath = modulePath.replaceAll("\\", "/");
20
- const moduleDir = normalizedModulePath.slice(0, normalizedModulePath.lastIndexOf("/"));
21
- const require = createRequire(modulePath);
22
- const isSeaRuntime = () => {
23
- try {
24
- const sea = require("node:sea");
25
- return Boolean(sea.isSea?.());
26
- }
27
- catch {
28
- return false;
13
+ const READY_TIMEOUT_MS = 500;
14
+ // Prefer import.meta.url always correct per-module in ESM.
15
+ // __dirname may be an incorrect polyfill in some tsx / loader configurations.
16
+ const thisDir = path.dirname(fileURLToPath(import.meta.url));
17
+ const resolveSupervisorScript = () => {
18
+ const jsPath = path.resolve(thisDir, "supervisor.js");
19
+ if (fs.existsSync(jsPath)) {
20
+ return { command: process.execPath, args: [jsPath] };
29
21
  }
30
- };
31
- // SEA: re-exec current binary with supervisor args.
32
- // Non-SEA: execute Stagehand CLI entrypoint with supervisor args.
33
- const resolveSupervisorCommand = (config) => {
34
- const baseArgs = ["--supervisor", serializeConfigArg(config)];
35
- if (isSeaRuntime()) {
36
- return { command: process.execPath, args: baseArgs };
22
+ const tsPath = path.resolve(thisDir, "supervisor.ts");
23
+ if (fs.existsSync(tsPath)) {
24
+ return { command: process.execPath, args: ["--import", "tsx", tsPath] };
37
25
  }
38
- const cliPathCandidates = [`${moduleDir}/../cli.js`, `${moduleDir}/cli.js`];
39
- const cliPath = cliPathCandidates.find((candidate) => fs.existsSync(candidate)) ?? null;
40
- if (!cliPath)
41
- return null;
42
- const needsTsxLoader = fs.existsSync(`${moduleDir}/supervisor.ts`) &&
43
- !fs.existsSync(`${moduleDir}/supervisor.js`);
44
- return {
45
- command: process.execPath,
46
- args: needsTsxLoader
47
- ? ["--import", "tsx", cliPath, ...baseArgs]
48
- : [cliPath, ...baseArgs],
49
- };
26
+ return null;
50
27
  };
51
- // Single JSON arg keeps supervisor bootstrap parsing tiny and versionable.
52
- const serializeConfigArg = (config) => `--supervisor-config=${JSON.stringify({
53
- ...config,
54
- parentPid: process.pid,
55
- })}`;
56
28
  /**
57
29
  * Start a supervisor process for crash cleanup. Returns a handle that can
58
30
  * stop the supervisor during a normal shutdown.
59
31
  */
60
32
  export function startShutdownSupervisor(config, opts) {
61
- const resolved = resolveSupervisorCommand(config);
33
+ const resolved = resolveSupervisorScript();
62
34
  if (!resolved) {
63
- opts?.onError?.(new ShutdownSupervisorResolveError("Shutdown supervisor entry missing (expected Stagehand CLI entrypoint)."), "resolve");
35
+ opts?.onError?.(new ShutdownSupervisorResolveError(`Shutdown supervisor script missing (searched ${thisDir} for supervisor.js or supervisor.ts).`), "resolve");
64
36
  return null;
65
37
  }
66
38
  const child = spawn(resolved.command, resolved.args, {
67
- // stdin is the parent lifeline.
68
- stdio: ["pipe", "ignore", "ignore"],
39
+ stdio: ["pipe", "ignore", "ignore", "ipc"],
69
40
  detached: true,
70
41
  });
71
42
  child.on("error", (error) => {
@@ -79,15 +50,48 @@ export function startShutdownSupervisor(config, opts) {
79
50
  catch {
80
51
  // best-effort: avoid keeping the event loop alive
81
52
  }
53
+ try {
54
+ const message = { type: "config", config };
55
+ child.send?.(message);
56
+ }
57
+ catch {
58
+ // ignore IPC failures
59
+ }
60
+ const ready = new Promise((resolve) => {
61
+ let resolved = false;
62
+ const done = () => {
63
+ if (resolved)
64
+ return;
65
+ resolved = true;
66
+ clearTimeout(timer);
67
+ child.off("message", onMessage);
68
+ resolve();
69
+ };
70
+ const timer = setTimeout(done, READY_TIMEOUT_MS);
71
+ const onMessage = (msg) => {
72
+ const payload = msg;
73
+ if (payload?.type === "ready") {
74
+ done();
75
+ }
76
+ };
77
+ child.on("message", onMessage);
78
+ child.on("exit", done);
79
+ });
82
80
  const stop = () => {
83
- // Normal close path: terminate supervisor directly.
84
81
  try {
85
- child.kill("SIGTERM");
82
+ const message = { type: "exit" };
83
+ child.send?.(message);
84
+ }
85
+ catch {
86
+ // ignore
87
+ }
88
+ try {
89
+ child.disconnect?.();
86
90
  }
87
91
  catch {
88
92
  // ignore
89
93
  }
90
94
  };
91
- return { stop };
95
+ return { stop, ready };
92
96
  }
93
97
  //# sourceMappingURL=supervisorClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"supervisorClient.js","sourceRoot":"","sources":["../../../../../lib/v3/shutdown/supervisorClient.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Parent-side helper for spawning the shutdown supervisor process.\n *\n * The supervisor runs out-of-process and watches a lifeline pipe. If the parent\n * dies, the supervisor performs best-effort cleanup (Chrome kill or Browserbase\n * session release) when keepAlive is false.\n */\n\nimport fs from \"node:fs\";\nimport { spawn } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport { fileURLToPath } from \"node:url\";\nimport type {\n ShutdownSupervisorConfig,\n ShutdownSupervisorHandle,\n} from \"../types/private/shutdown.js\";\nimport {\n ShutdownSupervisorResolveError,\n ShutdownSupervisorSpawnError,\n} from \"../types/private/shutdownErrors.js\";\n// Resolve module path for both CJS and ESM builds.\nconst normalizedFilename =\n typeof __filename === \"string\" ? __filename.replaceAll(\"\\\\\", \"/\") : \"\";\nconst hasAbsoluteFilename =\n normalizedFilename.startsWith(\"/\") || /^[A-Za-z]:\\//.test(normalizedFilename);\nconst modulePath = hasAbsoluteFilename\n ? __filename\n : fileURLToPath(import.meta.url);\nconst normalizedModulePath = modulePath.replaceAll(\"\\\\\", \"/\");\nconst moduleDir = normalizedModulePath.slice(\n 0,\n normalizedModulePath.lastIndexOf(\"/\"),\n);\nconst require = createRequire(modulePath);\n\nconst isSeaRuntime = (): boolean => {\n try {\n const sea = require(\"node:sea\") as { isSea?: () => boolean };\n return Boolean(sea.isSea?.());\n } catch {\n return false;\n }\n};\n\n// SEA: re-exec current binary with supervisor args.\n// Non-SEA: execute Stagehand CLI entrypoint with supervisor args.\nconst resolveSupervisorCommand = (\n config: ShutdownSupervisorConfig,\n): {\n command: string;\n args: string[];\n} | null => {\n const baseArgs = [\"--supervisor\", serializeConfigArg(config)];\n\n if (isSeaRuntime()) {\n return { command: process.execPath, args: baseArgs };\n }\n\n const cliPathCandidates = [`${moduleDir}/../cli.js`, `${moduleDir}/cli.js`];\n const cliPath =\n cliPathCandidates.find((candidate) => fs.existsSync(candidate)) ?? null;\n if (!cliPath) return null;\n const needsTsxLoader =\n fs.existsSync(`${moduleDir}/supervisor.ts`) &&\n !fs.existsSync(`${moduleDir}/supervisor.js`);\n return {\n command: process.execPath,\n args: needsTsxLoader\n ? [\"--import\", \"tsx\", cliPath, ...baseArgs]\n : [cliPath, ...baseArgs],\n };\n};\n\n// Single JSON arg keeps supervisor bootstrap parsing tiny and versionable.\nconst serializeConfigArg = (config: ShutdownSupervisorConfig): string =>\n `--supervisor-config=${JSON.stringify({\n ...config,\n parentPid: process.pid,\n })}`;\n\n/**\n * Start a supervisor process for crash cleanup. Returns a handle that can\n * stop the supervisor during a normal shutdown.\n */\nexport function startShutdownSupervisor(\n config: ShutdownSupervisorConfig,\n opts?: { onError?: (error: Error, context: string) => void },\n): ShutdownSupervisorHandle | null {\n const resolved = resolveSupervisorCommand(config);\n if (!resolved) {\n opts?.onError?.(\n new ShutdownSupervisorResolveError(\n \"Shutdown supervisor entry missing (expected Stagehand CLI entrypoint).\",\n ),\n \"resolve\",\n );\n return null;\n }\n\n const child = spawn(resolved.command, resolved.args, {\n // stdin is the parent lifeline.\n stdio: [\"pipe\", \"ignore\", \"ignore\"],\n detached: true,\n });\n child.on(\"error\", (error) => {\n opts?.onError?.(\n new ShutdownSupervisorSpawnError(\n `Shutdown supervisor failed to start: ${error.message}`,\n ),\n \"spawn\",\n );\n });\n\n try {\n child.unref();\n const stdin = child.stdin as unknown as { unref?: () => void } | null;\n stdin?.unref?.();\n } catch {\n // best-effort: avoid keeping the event loop alive\n }\n\n const stop = () => {\n // Normal close path: terminate supervisor directly.\n try {\n child.kill(\"SIGTERM\");\n } catch {\n // ignore\n }\n };\n\n return { stop };\n}\n"]}
1
+ {"version":3,"file":"supervisorClient.js","sourceRoot":"","sources":["../../../../../lib/v3/shutdown/supervisorClient.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Parent-side helper for spawning the shutdown supervisor process.\n *\n * The supervisor runs out-of-process and watches a lifeline pipe. If the parent\n * dies, the supervisor performs best-effort cleanup (Chrome kill or Browserbase\n * session release) when keepAlive is false.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { spawn } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\nimport type {\n ShutdownSupervisorConfig,\n ShutdownSupervisorHandle,\n ShutdownSupervisorMessage,\n} from \"../types/private/shutdown.js\";\nimport {\n ShutdownSupervisorResolveError,\n ShutdownSupervisorSpawnError,\n} from \"../types/private/shutdownErrors.js\";\n\nconst READY_TIMEOUT_MS = 500;\n// Prefer import.meta.url always correct per-module in ESM.\n// __dirname may be an incorrect polyfill in some tsx / loader configurations.\nconst thisDir = path.dirname(fileURLToPath(import.meta.url));\n\nconst resolveSupervisorScript = (): {\n command: string;\n args: string[];\n} | null => {\n const jsPath = path.resolve(thisDir, \"supervisor.js\");\n if (fs.existsSync(jsPath)) {\n return { command: process.execPath, args: [jsPath] };\n }\n const tsPath = path.resolve(thisDir, \"supervisor.ts\");\n if (fs.existsSync(tsPath)) {\n return { command: process.execPath, args: [\"--import\", \"tsx\", tsPath] };\n }\n return null;\n};\n\n/**\n * Start a supervisor process for crash cleanup. Returns a handle that can\n * stop the supervisor during a normal shutdown.\n */\nexport function startShutdownSupervisor(\n config: ShutdownSupervisorConfig,\n opts?: { onError?: (error: Error, context: string) => void },\n): ShutdownSupervisorHandle | null {\n const resolved = resolveSupervisorScript();\n if (!resolved) {\n opts?.onError?.(\n new ShutdownSupervisorResolveError(\n `Shutdown supervisor script missing (searched ${thisDir} for supervisor.js or supervisor.ts).`,\n ),\n \"resolve\",\n );\n return null;\n }\n\n const child = spawn(resolved.command, resolved.args, {\n stdio: [\"pipe\", \"ignore\", \"ignore\", \"ipc\"],\n detached: true,\n });\n child.on(\"error\", (error) => {\n opts?.onError?.(\n new ShutdownSupervisorSpawnError(\n `Shutdown supervisor failed to start: ${error.message}`,\n ),\n \"spawn\",\n );\n });\n\n try {\n child.unref();\n const stdin = child.stdin as unknown as { unref?: () => void } | null;\n stdin?.unref?.();\n } catch {\n // best-effort: avoid keeping the event loop alive\n }\n\n try {\n const message: ShutdownSupervisorMessage = { type: \"config\", config };\n child.send?.(message);\n } catch {\n // ignore IPC failures\n }\n\n const ready = new Promise<void>((resolve) => {\n let resolved = false;\n const done = () => {\n if (resolved) return;\n resolved = true;\n clearTimeout(timer);\n child.off(\"message\", onMessage);\n resolve();\n };\n const timer = setTimeout(done, READY_TIMEOUT_MS);\n const onMessage = (msg: unknown) => {\n const payload = msg as ShutdownSupervisorMessage;\n if (payload?.type === \"ready\") {\n done();\n }\n };\n child.on(\"message\", onMessage);\n child.on(\"exit\", done);\n });\n\n const stop = () => {\n try {\n const message: ShutdownSupervisorMessage = { type: \"exit\" };\n child.send?.(message);\n } catch {\n // ignore\n }\n try {\n child.disconnect?.();\n } catch {\n // ignore\n }\n };\n\n return { stop, ready };\n}\n"]}