@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
@@ -0,0 +1,139 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { actTool } from "../lib/v3/agent/tools/act.js";
3
+ import { extractTool } from "../lib/v3/agent/tools/extract.js";
4
+ import { fillFormTool } from "../lib/v3/agent/tools/fillform.js";
5
+ function createMockV3() {
6
+ const calls = [];
7
+ const mock = {
8
+ logger: vi.fn(),
9
+ recordAgentReplayStep: vi.fn(),
10
+ act: vi.fn(async (_instruction, options) => {
11
+ calls.push({ method: "act", model: options?.model });
12
+ return {
13
+ success: true,
14
+ message: "ok",
15
+ actionDescription: "clicked",
16
+ actions: []
17
+ };
18
+ }),
19
+ extract: vi.fn(
20
+ async (_instruction, _schema, options) => {
21
+ calls.push({ method: "extract", model: options?.model });
22
+ return { extraction: "data" };
23
+ }
24
+ ),
25
+ observe: vi.fn(
26
+ async (_instruction, options) => {
27
+ calls.push({ method: "observe", model: options?.model });
28
+ return [];
29
+ }
30
+ ),
31
+ calls
32
+ };
33
+ return mock;
34
+ }
35
+ describe("agent tools pass full executionModel config to v3 methods", () => {
36
+ const modelConfig = {
37
+ modelName: "openai/gpt-4o-mini",
38
+ apiKey: "sk-test-key",
39
+ baseURL: "https://custom.api"
40
+ };
41
+ it("actTool passes AgentModelConfig object to v3.act()", async () => {
42
+ const v3 = createMockV3();
43
+ const tool = actTool(v3, modelConfig);
44
+ await tool.execute(
45
+ { action: "click the button" },
46
+ {
47
+ toolCallId: "t1",
48
+ messages: [],
49
+ abortSignal: new AbortController().signal
50
+ }
51
+ );
52
+ expect(v3.calls).toHaveLength(1);
53
+ expect(v3.calls[0].method).toBe("act");
54
+ expect(v3.calls[0].model).toBe(modelConfig);
55
+ });
56
+ it("extractTool passes AgentModelConfig object to v3.extract()", async () => {
57
+ const v3 = createMockV3();
58
+ const tool = extractTool(v3, modelConfig);
59
+ await tool.execute(
60
+ { instruction: "get the title", schema: void 0 },
61
+ {
62
+ toolCallId: "t2",
63
+ messages: [],
64
+ abortSignal: new AbortController().signal
65
+ }
66
+ );
67
+ expect(v3.calls).toHaveLength(1);
68
+ expect(v3.calls[0].method).toBe("extract");
69
+ expect(v3.calls[0].model).toBe(modelConfig);
70
+ });
71
+ it("fillFormTool passes AgentModelConfig object to v3.observe()", async () => {
72
+ const v3 = createMockV3();
73
+ const tool = fillFormTool(v3, modelConfig);
74
+ await tool.execute(
75
+ { fields: [{ action: "type hello into name", value: "hello" }] },
76
+ {
77
+ toolCallId: "t3",
78
+ messages: [],
79
+ abortSignal: new AbortController().signal
80
+ }
81
+ );
82
+ expect(v3.calls).toHaveLength(1);
83
+ expect(v3.calls[0].method).toBe("observe");
84
+ expect(v3.calls[0].model).toBe(modelConfig);
85
+ });
86
+ it("actTool passes undefined when no executionModel is set", async () => {
87
+ const v3 = createMockV3();
88
+ const tool = actTool(v3, void 0);
89
+ await tool.execute(
90
+ { action: "click the button" },
91
+ {
92
+ toolCallId: "t4",
93
+ messages: [],
94
+ abortSignal: new AbortController().signal
95
+ }
96
+ );
97
+ expect(v3.calls).toHaveLength(1);
98
+ expect(v3.calls[0].model).toBeUndefined();
99
+ });
100
+ it("actTool passes plain string executionModel to v3.act()", async () => {
101
+ const v3 = createMockV3();
102
+ const tool = actTool(v3, "openai/gpt-4o-mini");
103
+ await tool.execute(
104
+ { action: "click the button" },
105
+ {
106
+ toolCallId: "t5",
107
+ messages: [],
108
+ abortSignal: new AbortController().signal
109
+ }
110
+ );
111
+ expect(v3.calls).toHaveLength(1);
112
+ expect(v3.calls[0].model).toBe("openai/gpt-4o-mini");
113
+ });
114
+ });
115
+ describe("executionModel fallback logic", () => {
116
+ function resolveExecutionModel(options) {
117
+ return options?.executionModel ?? options?.model;
118
+ }
119
+ it("prefers explicit executionModel over model", () => {
120
+ const result = resolveExecutionModel({
121
+ executionModel: "openai/gpt-4o-mini",
122
+ model: "anthropic/claude-sonnet-4-20250514"
123
+ });
124
+ expect(result).toBe("openai/gpt-4o-mini");
125
+ });
126
+ it("falls back to model when executionModel is not set", () => {
127
+ const modelConfig = {
128
+ modelName: "anthropic/claude-sonnet-4-20250514",
129
+ apiKey: "sk-test"
130
+ };
131
+ const result = resolveExecutionModel({ model: modelConfig });
132
+ expect(result).toBe(modelConfig);
133
+ });
134
+ it("returns undefined when neither is set", () => {
135
+ expect(resolveExecutionModel({})).toBeUndefined();
136
+ expect(resolveExecutionModel(void 0)).toBeUndefined();
137
+ });
138
+ });
139
+ //# sourceMappingURL=agent-execution-model.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../tests/agent-execution-model.test.ts"],
4
+ "sourcesContent": ["import { describe, expect, it, vi } from \"vitest\";\nimport { actTool } from \"../lib/v3/agent/tools/act.js\";\nimport { extractTool } from \"../lib/v3/agent/tools/extract.js\";\nimport { fillFormTool } from \"../lib/v3/agent/tools/fillform.js\";\nimport type { V3 } from \"../lib/v3/v3.js\";\n\n/**\n * Minimal mock of V3 that captures how tools pass `model` options\n * into v3.act(), v3.extract(), and v3.observe().\n */\nfunction createMockV3() {\n const calls: { method: string; model: unknown }[] = [];\n\n const mock = {\n logger: vi.fn(),\n recordAgentReplayStep: vi.fn(),\n act: vi.fn(async (_instruction: unknown, options?: { model?: unknown }) => {\n calls.push({ method: \"act\", model: options?.model });\n return {\n success: true,\n message: \"ok\",\n actionDescription: \"clicked\",\n actions: [],\n };\n }),\n extract: vi.fn(\n async (\n _instruction: unknown,\n _schema: unknown,\n options?: { model?: unknown },\n ) => {\n calls.push({ method: \"extract\", model: options?.model });\n return { extraction: \"data\" };\n },\n ),\n observe: vi.fn(\n async (_instruction: unknown, options?: { model?: unknown }) => {\n calls.push({ method: \"observe\", model: options?.model });\n return [];\n },\n ),\n calls,\n };\n\n return mock as unknown as V3 & { calls: typeof calls };\n}\n\ndescribe(\"agent tools pass full executionModel config to v3 methods\", () => {\n const modelConfig = {\n modelName: \"openai/gpt-4o-mini\",\n apiKey: \"sk-test-key\",\n baseURL: \"https://custom.api\",\n };\n\n it(\"actTool passes AgentModelConfig object to v3.act()\", async () => {\n const v3 = createMockV3();\n const tool = actTool(v3, modelConfig);\n await tool.execute!(\n { action: \"click the button\" },\n {\n toolCallId: \"t1\",\n messages: [],\n abortSignal: new AbortController().signal,\n },\n );\n\n expect(v3.calls).toHaveLength(1);\n expect(v3.calls[0].method).toBe(\"act\");\n expect(v3.calls[0].model).toBe(modelConfig);\n });\n\n it(\"extractTool passes AgentModelConfig object to v3.extract()\", async () => {\n const v3 = createMockV3();\n const tool = extractTool(v3, modelConfig);\n await tool.execute!(\n { instruction: \"get the title\", schema: undefined },\n {\n toolCallId: \"t2\",\n messages: [],\n abortSignal: new AbortController().signal,\n },\n );\n\n expect(v3.calls).toHaveLength(1);\n expect(v3.calls[0].method).toBe(\"extract\");\n expect(v3.calls[0].model).toBe(modelConfig);\n });\n\n it(\"fillFormTool passes AgentModelConfig object to v3.observe()\", async () => {\n const v3 = createMockV3();\n const tool = fillFormTool(v3, modelConfig);\n await tool.execute!(\n { fields: [{ action: \"type hello into name\", value: \"hello\" }] },\n {\n toolCallId: \"t3\",\n messages: [],\n abortSignal: new AbortController().signal,\n },\n );\n\n expect(v3.calls).toHaveLength(1);\n expect(v3.calls[0].method).toBe(\"observe\");\n expect(v3.calls[0].model).toBe(modelConfig);\n });\n\n it(\"actTool passes undefined when no executionModel is set\", async () => {\n const v3 = createMockV3();\n const tool = actTool(v3, undefined);\n await tool.execute!(\n { action: \"click the button\" },\n {\n toolCallId: \"t4\",\n messages: [],\n abortSignal: new AbortController().signal,\n },\n );\n\n expect(v3.calls).toHaveLength(1);\n expect(v3.calls[0].model).toBeUndefined();\n });\n\n it(\"actTool passes plain string executionModel to v3.act()\", async () => {\n const v3 = createMockV3();\n const tool = actTool(v3, \"openai/gpt-4o-mini\");\n await tool.execute!(\n { action: \"click the button\" },\n {\n toolCallId: \"t5\",\n messages: [],\n abortSignal: new AbortController().signal,\n },\n );\n\n expect(v3.calls).toHaveLength(1);\n expect(v3.calls[0].model).toBe(\"openai/gpt-4o-mini\");\n });\n});\n\ndescribe(\"executionModel fallback logic\", () => {\n // This mirrors the resolution in V3.prepareAgentExecution (v3.ts:1682):\n // const resolvedExecutionModel = options?.executionModel ?? options?.model;\n function resolveExecutionModel(options?: {\n executionModel?: string | { modelName: string };\n model?: string | { modelName: string };\n }) {\n return options?.executionModel ?? options?.model;\n }\n\n it(\"prefers explicit executionModel over model\", () => {\n const result = resolveExecutionModel({\n executionModel: \"openai/gpt-4o-mini\",\n model: \"anthropic/claude-sonnet-4-20250514\",\n });\n expect(result).toBe(\"openai/gpt-4o-mini\");\n });\n\n it(\"falls back to model when executionModel is not set\", () => {\n const modelConfig = {\n modelName: \"anthropic/claude-sonnet-4-20250514\",\n apiKey: \"sk-test\",\n };\n const result = resolveExecutionModel({ model: modelConfig });\n expect(result).toBe(modelConfig);\n });\n\n it(\"returns undefined when neither is set\", () => {\n expect(resolveExecutionModel({})).toBeUndefined();\n expect(resolveExecutionModel(undefined)).toBeUndefined();\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,73 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { getApiUrlForRegion, REGION_API_URLS } from "../lib/v3/api";
3
+ describe("Multi-region API URL mapping", () => {
4
+ describe("REGION_API_URLS constant", () => {
5
+ it("should have the correct URL for us-west-2 (default)", () => {
6
+ expect(REGION_API_URLS["us-west-2"]).toBe(
7
+ "https://api.stagehand.browserbase.com"
8
+ );
9
+ });
10
+ it("should have the correct URL for us-east-1", () => {
11
+ expect(REGION_API_URLS["us-east-1"]).toBe(
12
+ "https://api.use1.stagehand.browserbase.com"
13
+ );
14
+ });
15
+ it("should have the correct URL for eu-central-1", () => {
16
+ expect(REGION_API_URLS["eu-central-1"]).toBe(
17
+ "https://api.euc1.stagehand.browserbase.com"
18
+ );
19
+ });
20
+ it("should have the correct URL for ap-southeast-1", () => {
21
+ expect(REGION_API_URLS["ap-southeast-1"]).toBe(
22
+ "https://api.apse1.stagehand.browserbase.com"
23
+ );
24
+ });
25
+ });
26
+ describe("getApiUrlForRegion", () => {
27
+ it("should return the correct URL for us-west-2", () => {
28
+ expect(getApiUrlForRegion("us-west-2")).toBe(
29
+ "https://api.stagehand.browserbase.com/v1"
30
+ );
31
+ });
32
+ it("should return the correct URL for us-east-1", () => {
33
+ expect(getApiUrlForRegion("us-east-1")).toBe(
34
+ "https://api.use1.stagehand.browserbase.com/v1"
35
+ );
36
+ });
37
+ it("should return the correct URL for eu-central-1", () => {
38
+ expect(getApiUrlForRegion("eu-central-1")).toBe(
39
+ "https://api.euc1.stagehand.browserbase.com/v1"
40
+ );
41
+ });
42
+ it("should return the correct URL for ap-southeast-1", () => {
43
+ expect(getApiUrlForRegion("ap-southeast-1")).toBe(
44
+ "https://api.apse1.stagehand.browserbase.com/v1"
45
+ );
46
+ });
47
+ it("should return the default us-west-2 URL when no region is specified", () => {
48
+ expect(getApiUrlForRegion(void 0)).toBe(
49
+ "https://api.stagehand.browserbase.com/v1"
50
+ );
51
+ });
52
+ it("should return the default us-west-2 URL for unknown regions", () => {
53
+ expect(getApiUrlForRegion("invalid-region")).toBe(
54
+ "https://api.stagehand.browserbase.com/v1"
55
+ );
56
+ });
57
+ });
58
+ describe("URL /v1 suffix handling", () => {
59
+ it("getApiUrlForRegion always includes /v1 suffix for consistency", () => {
60
+ const url = getApiUrlForRegion("us-west-2");
61
+ expect(url.endsWith("/v1")).toBe(true);
62
+ });
63
+ it("all regional URLs should be base URLs without /v1 in REGION_API_URLS", () => {
64
+ for (const [region, baseUrl] of Object.entries(REGION_API_URLS)) {
65
+ expect(baseUrl.endsWith("/v1")).toBe(false);
66
+ expect(getApiUrlForRegion(region)).toBe(
67
+ `${baseUrl}/v1`
68
+ );
69
+ }
70
+ });
71
+ });
72
+ });
73
+ //# sourceMappingURL=api-multiregion.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../tests/api-multiregion.test.ts"],
4
+ "sourcesContent": ["import { describe, expect, it } from \"vitest\";\nimport { getApiUrlForRegion, REGION_API_URLS } from \"../lib/v3/api\";\n\ndescribe(\"Multi-region API URL mapping\", () => {\n describe(\"REGION_API_URLS constant\", () => {\n it(\"should have the correct URL for us-west-2 (default)\", () => {\n expect(REGION_API_URLS[\"us-west-2\"]).toBe(\n \"https://api.stagehand.browserbase.com\",\n );\n });\n\n it(\"should have the correct URL for us-east-1\", () => {\n expect(REGION_API_URLS[\"us-east-1\"]).toBe(\n \"https://api.use1.stagehand.browserbase.com\",\n );\n });\n\n it(\"should have the correct URL for eu-central-1\", () => {\n expect(REGION_API_URLS[\"eu-central-1\"]).toBe(\n \"https://api.euc1.stagehand.browserbase.com\",\n );\n });\n\n it(\"should have the correct URL for ap-southeast-1\", () => {\n expect(REGION_API_URLS[\"ap-southeast-1\"]).toBe(\n \"https://api.apse1.stagehand.browserbase.com\",\n );\n });\n });\n\n describe(\"getApiUrlForRegion\", () => {\n it(\"should return the correct URL for us-west-2\", () => {\n expect(getApiUrlForRegion(\"us-west-2\")).toBe(\n \"https://api.stagehand.browserbase.com/v1\",\n );\n });\n\n it(\"should return the correct URL for us-east-1\", () => {\n expect(getApiUrlForRegion(\"us-east-1\")).toBe(\n \"https://api.use1.stagehand.browserbase.com/v1\",\n );\n });\n\n it(\"should return the correct URL for eu-central-1\", () => {\n expect(getApiUrlForRegion(\"eu-central-1\")).toBe(\n \"https://api.euc1.stagehand.browserbase.com/v1\",\n );\n });\n\n it(\"should return the correct URL for ap-southeast-1\", () => {\n expect(getApiUrlForRegion(\"ap-southeast-1\")).toBe(\n \"https://api.apse1.stagehand.browserbase.com/v1\",\n );\n });\n\n it(\"should return the default us-west-2 URL when no region is specified\", () => {\n expect(getApiUrlForRegion(undefined)).toBe(\n \"https://api.stagehand.browserbase.com/v1\",\n );\n });\n\n it(\"should return the default us-west-2 URL for unknown regions\", () => {\n // @ts-expect-error - testing invalid region\n expect(getApiUrlForRegion(\"invalid-region\")).toBe(\n \"https://api.stagehand.browserbase.com/v1\",\n );\n });\n });\n\n describe(\"URL /v1 suffix handling\", () => {\n it(\"getApiUrlForRegion always includes /v1 suffix for consistency\", () => {\n // getApiUrlForRegion returns a URL with /v1\n // This documents the expected contract that all API base URLs include /v1\n const url = getApiUrlForRegion(\"us-west-2\");\n expect(url.endsWith(\"/v1\")).toBe(true);\n });\n\n it(\"all regional URLs should be base URLs without /v1 in REGION_API_URLS\", () => {\n // Verify REGION_API_URLS contains base URLs (without /v1)\n // The /v1 suffix is added by getApiUrlForRegion\n for (const [region, baseUrl] of Object.entries(REGION_API_URLS)) {\n expect(baseUrl.endsWith(\"/v1\")).toBe(false);\n expect(getApiUrlForRegion(region as keyof typeof REGION_API_URLS)).toBe(\n `${baseUrl}/v1`,\n );\n }\n });\n });\n});\n"],
5
+ "mappings": "AAAA,SAAS,UAAU,QAAQ,UAAU;AACrC,SAAS,oBAAoB,uBAAuB;AAEpD,SAAS,gCAAgC,MAAM;AAC7C,WAAS,4BAA4B,MAAM;AACzC,OAAG,uDAAuD,MAAM;AAC9D,aAAO,gBAAgB,WAAW,CAAC,EAAE;AAAA,QACnC;AAAA,MACF;AAAA,IACF,CAAC;AAED,OAAG,6CAA6C,MAAM;AACpD,aAAO,gBAAgB,WAAW,CAAC,EAAE;AAAA,QACnC;AAAA,MACF;AAAA,IACF,CAAC;AAED,OAAG,gDAAgD,MAAM;AACvD,aAAO,gBAAgB,cAAc,CAAC,EAAE;AAAA,QACtC;AAAA,MACF;AAAA,IACF,CAAC;AAED,OAAG,kDAAkD,MAAM;AACzD,aAAO,gBAAgB,gBAAgB,CAAC,EAAE;AAAA,QACxC;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,WAAS,sBAAsB,MAAM;AACnC,OAAG,+CAA+C,MAAM;AACtD,aAAO,mBAAmB,WAAW,CAAC,EAAE;AAAA,QACtC;AAAA,MACF;AAAA,IACF,CAAC;AAED,OAAG,+CAA+C,MAAM;AACtD,aAAO,mBAAmB,WAAW,CAAC,EAAE;AAAA,QACtC;AAAA,MACF;AAAA,IACF,CAAC;AAED,OAAG,kDAAkD,MAAM;AACzD,aAAO,mBAAmB,cAAc,CAAC,EAAE;AAAA,QACzC;AAAA,MACF;AAAA,IACF,CAAC;AAED,OAAG,oDAAoD,MAAM;AAC3D,aAAO,mBAAmB,gBAAgB,CAAC,EAAE;AAAA,QAC3C;AAAA,MACF;AAAA,IACF,CAAC;AAED,OAAG,uEAAuE,MAAM;AAC9E,aAAO,mBAAmB,MAAS,CAAC,EAAE;AAAA,QACpC;AAAA,MACF;AAAA,IACF,CAAC;AAED,OAAG,+DAA+D,MAAM;AAEtE,aAAO,mBAAmB,gBAAgB,CAAC,EAAE;AAAA,QAC3C;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,WAAS,2BAA2B,MAAM;AACxC,OAAG,iEAAiE,MAAM;AAGxE,YAAM,MAAM,mBAAmB,WAAW;AAC1C,aAAO,IAAI,SAAS,KAAK,CAAC,EAAE,KAAK,IAAI;AAAA,IACvC,CAAC;AAED,OAAG,wEAAwE,MAAM;AAG/E,iBAAW,CAAC,QAAQ,OAAO,KAAK,OAAO,QAAQ,eAAe,GAAG;AAC/D,eAAO,QAAQ,SAAS,KAAK,CAAC,EAAE,KAAK,KAAK;AAC1C,eAAO,mBAAmB,MAAsC,CAAC,EAAE;AAAA,UACjE,GAAG,OAAO;AAAA,QACZ;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,43 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { extractModelName, resolveModel } from "../lib/modelUtils.js";
3
+ describe("extractModelName", () => {
4
+ it("returns undefined for undefined input", () => {
5
+ expect(extractModelName(void 0)).toBeUndefined();
6
+ });
7
+ it("returns the string as-is for a string input", () => {
8
+ expect(extractModelName("openai/gpt-4o")).toBe("openai/gpt-4o");
9
+ });
10
+ it("returns modelName from an object input", () => {
11
+ expect(
12
+ extractModelName({ modelName: "anthropic/claude-sonnet-4-20250514" })
13
+ ).toBe("anthropic/claude-sonnet-4-20250514");
14
+ });
15
+ it("returns modelName from an object with extra properties", () => {
16
+ expect(
17
+ extractModelName({
18
+ modelName: "openai/gpt-4o-mini",
19
+ apiKey: "sk-test",
20
+ baseURL: "https://custom.endpoint"
21
+ })
22
+ ).toBe("openai/gpt-4o-mini");
23
+ });
24
+ });
25
+ describe("resolveModel", () => {
26
+ it("extracts provider and modelName from a string", () => {
27
+ const result = resolveModel("openai/gpt-4o");
28
+ expect(result.provider).toBe("openai");
29
+ expect(result.modelName).toBe("gpt-4o");
30
+ expect(result.clientOptions).toEqual({});
31
+ });
32
+ it("extracts clientOptions from an object config", () => {
33
+ const result = resolveModel({
34
+ modelName: "openai/gpt-4o",
35
+ apiKey: "sk-test"
36
+ });
37
+ expect(result.provider).toBe("openai");
38
+ expect(result.modelName).toBe("gpt-4o");
39
+ expect(result.clientOptions).toMatchObject({ apiKey: "sk-test" });
40
+ expect(result.clientOptions).not.toHaveProperty("modelName");
41
+ });
42
+ });
43
+ //# sourceMappingURL=model-utils.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../tests/model-utils.test.ts"],
4
+ "sourcesContent": ["import { describe, expect, it } from \"vitest\";\nimport { extractModelName, resolveModel } from \"../lib/modelUtils.js\";\n\ndescribe(\"extractModelName\", () => {\n it(\"returns undefined for undefined input\", () => {\n expect(extractModelName(undefined)).toBeUndefined();\n });\n\n it(\"returns the string as-is for a string input\", () => {\n expect(extractModelName(\"openai/gpt-4o\")).toBe(\"openai/gpt-4o\");\n });\n\n it(\"returns modelName from an object input\", () => {\n expect(\n extractModelName({ modelName: \"anthropic/claude-sonnet-4-20250514\" }),\n ).toBe(\"anthropic/claude-sonnet-4-20250514\");\n });\n\n it(\"returns modelName from an object with extra properties\", () => {\n expect(\n extractModelName({\n modelName: \"openai/gpt-4o-mini\",\n apiKey: \"sk-test\",\n baseURL: \"https://custom.endpoint\",\n }),\n ).toBe(\"openai/gpt-4o-mini\");\n });\n});\n\ndescribe(\"resolveModel\", () => {\n it(\"extracts provider and modelName from a string\", () => {\n const result = resolveModel(\"openai/gpt-4o\");\n expect(result.provider).toBe(\"openai\");\n expect(result.modelName).toBe(\"gpt-4o\");\n expect(result.clientOptions).toEqual({});\n });\n\n it(\"extracts clientOptions from an object config\", () => {\n const result = resolveModel({\n modelName: \"openai/gpt-4o\" as never,\n apiKey: \"sk-test\",\n });\n expect(result.provider).toBe(\"openai\");\n expect(result.modelName).toBe(\"gpt-4o\");\n expect(result.clientOptions).toMatchObject({ apiKey: \"sk-test\" });\n // modelName should not leak into clientOptions\n expect(result.clientOptions).not.toHaveProperty(\"modelName\");\n });\n});\n"],
5
+ "mappings": "AAAA,SAAS,UAAU,QAAQ,UAAU;AACrC,SAAS,kBAAkB,oBAAoB;AAE/C,SAAS,oBAAoB,MAAM;AACjC,KAAG,yCAAyC,MAAM;AAChD,WAAO,iBAAiB,MAAS,CAAC,EAAE,cAAc;AAAA,EACpD,CAAC;AAED,KAAG,+CAA+C,MAAM;AACtD,WAAO,iBAAiB,eAAe,CAAC,EAAE,KAAK,eAAe;AAAA,EAChE,CAAC;AAED,KAAG,0CAA0C,MAAM;AACjD;AAAA,MACE,iBAAiB,EAAE,WAAW,qCAAqC,CAAC;AAAA,IACtE,EAAE,KAAK,oCAAoC;AAAA,EAC7C,CAAC;AAED,KAAG,0DAA0D,MAAM;AACjE;AAAA,MACE,iBAAiB;AAAA,QACf,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAAA,IACH,EAAE,KAAK,oBAAoB;AAAA,EAC7B,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,MAAM;AAC7B,KAAG,iDAAiD,MAAM;AACxD,UAAM,SAAS,aAAa,eAAe;AAC3C,WAAO,OAAO,QAAQ,EAAE,KAAK,QAAQ;AACrC,WAAO,OAAO,SAAS,EAAE,KAAK,QAAQ;AACtC,WAAO,OAAO,aAAa,EAAE,QAAQ,CAAC,CAAC;AAAA,EACzC,CAAC;AAED,KAAG,gDAAgD,MAAM;AACvD,UAAM,SAAS,aAAa;AAAA,MAC1B,WAAW;AAAA,MACX,QAAQ;AAAA,IACV,CAAC;AACD,WAAO,OAAO,QAAQ,EAAE,KAAK,QAAQ;AACrC,WAAO,OAAO,SAAS,EAAE,KAAK,QAAQ;AACtC,WAAO,OAAO,aAAa,EAAE,cAAc,EAAE,QAAQ,UAAU,CAAC;AAEhE,WAAO,OAAO,aAAa,EAAE,IAAI,eAAe,WAAW;AAAA,EAC7D,CAAC;AACH,CAAC;",
6
+ "names": []
7
+ }
@@ -2,7 +2,6 @@ import { describe, expect, it } from "vitest";
2
2
  import StagehandDefaultExport, * as Stagehand from "@browserbasehq/stagehand";
3
3
  import { publicErrorTypes } from "./public-error-types.test.js";
4
4
  const publicApiShape = {
5
- __internalMaybeRunShutdownSupervisorFromArgv: Stagehand.__internalMaybeRunShutdownSupervisorFromArgv,
6
5
  __internalCreateInMemoryAgentCacheHandle: Stagehand.__internalCreateInMemoryAgentCacheHandle,
7
6
  AISdkClient: Stagehand.AISdkClient,
8
7
  Api: Stagehand.Api,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../tests/public-api/export-surface.test.ts"],
4
- "sourcesContent": ["import { describe, expect, it } from \"vitest\";\nimport StagehandDefaultExport, * as Stagehand from \"@browserbasehq/stagehand\";\nimport { publicErrorTypes } from \"./public-error-types.test.js\";\n\n// Type matcher guidelines:\n//\n// toEqualTypeOf \u2013 Default. Assert full, deep type equality; any type change should fail.\n// e.g. expectTypeOf<ReturnType<typeof foo>>().toEqualTypeOf<FooResult>()\n//\n// toMatchObjectType \u2013 Assert (part of) an object's shape while allowing extra fields.\n// e.g. expectTypeOf(user).toMatchObjectType<{ id: string; email: string }>()\n//\n// toExtend \u2013 Assert that a type is compatible with a broader contract (assignable/extends).\n// e.g. expectTypeOf<User>().toExtend<BaseUser>()\n\nconst publicApiShape = {\n __internalMaybeRunShutdownSupervisorFromArgv:\n Stagehand.__internalMaybeRunShutdownSupervisorFromArgv,\n __internalCreateInMemoryAgentCacheHandle:\n Stagehand.__internalCreateInMemoryAgentCacheHandle,\n AISdkClient: Stagehand.AISdkClient,\n Api: Stagehand.Api,\n AVAILABLE_CUA_MODELS: Stagehand.AVAILABLE_CUA_MODELS,\n AgentProvider: Stagehand.AgentProvider,\n AnnotatedScreenshotText: Stagehand.AnnotatedScreenshotText,\n ConsoleMessage: Stagehand.ConsoleMessage,\n CustomOpenAIClient: Stagehand.CustomOpenAIClient,\n LLMClient: Stagehand.LLMClient,\n LOG_LEVEL_NAMES: Stagehand.LOG_LEVEL_NAMES,\n Response: Stagehand.Response,\n Stagehand: Stagehand.Stagehand,\n V3: Stagehand.V3,\n V3Evaluator: Stagehand.V3Evaluator,\n V3FunctionName: Stagehand.V3FunctionName,\n connectToMCPServer: Stagehand.connectToMCPServer,\n default: StagehandDefaultExport,\n defaultExtractSchema: Stagehand.defaultExtractSchema,\n getAISDKLanguageModel: Stagehand.getAISDKLanguageModel,\n getZodType: Stagehand.getZodType,\n injectUrls: Stagehand.injectUrls,\n isRunningInBun: Stagehand.isRunningInBun,\n isZod3Schema: Stagehand.isZod3Schema,\n isZod4Schema: Stagehand.isZod4Schema,\n jsonSchemaToZod: Stagehand.jsonSchemaToZod,\n loadApiKeyFromEnv: Stagehand.loadApiKeyFromEnv,\n localBrowserLaunchOptionsSchema: Stagehand.localBrowserLaunchOptionsSchema,\n modelToAgentProviderMap: Stagehand.modelToAgentProviderMap,\n pageTextSchema: Stagehand.pageTextSchema,\n providerEnvVarMap: Stagehand.providerEnvVarMap,\n toGeminiSchema: Stagehand.toGeminiSchema,\n toJsonSchema: Stagehand.toJsonSchema,\n tool: Stagehand.tool,\n transformSchema: Stagehand.transformSchema,\n trimTrailingTextNode: Stagehand.trimTrailingTextNode,\n validateZodSchema: Stagehand.validateZodSchema,\n ...publicErrorTypes,\n} as const;\n\ntype StagehandExports = typeof Stagehand & {\n default: typeof StagehandDefaultExport;\n};\n\ntype PublicAPI = {\n [K in keyof typeof publicApiShape]: StagehandExports[K];\n};\n\ndescribe(\"Stagehand public API export surface\", () => {\n it(\"public API shape matches module exports\", () => {\n const _check: PublicAPI = publicApiShape;\n void _check;\n });\n\n it(\"does not expose unexpected top-level exports\", () => {\n const expected = Object.keys(publicApiShape).sort();\n const actual = Object.keys(Stagehand).sort();\n expect(actual).toStrictEqual(expected);\n });\n});\n"],
5
- "mappings": "AAAA,SAAS,UAAU,QAAQ,UAAU;AACrC,OAAO,6BAA6B,eAAe;AACnD,SAAS,wBAAwB;AAajC,MAAM,iBAAiB;AAAA,EACrB,8CACE,UAAU;AAAA,EACZ,0CACE,UAAU;AAAA,EACZ,aAAa,UAAU;AAAA,EACvB,KAAK,UAAU;AAAA,EACf,sBAAsB,UAAU;AAAA,EAChC,eAAe,UAAU;AAAA,EACzB,yBAAyB,UAAU;AAAA,EACnC,gBAAgB,UAAU;AAAA,EAC1B,oBAAoB,UAAU;AAAA,EAC9B,WAAW,UAAU;AAAA,EACrB,iBAAiB,UAAU;AAAA,EAC3B,UAAU,UAAU;AAAA,EACpB,WAAW,UAAU;AAAA,EACrB,IAAI,UAAU;AAAA,EACd,aAAa,UAAU;AAAA,EACvB,gBAAgB,UAAU;AAAA,EAC1B,oBAAoB,UAAU;AAAA,EAC9B,SAAS;AAAA,EACT,sBAAsB,UAAU;AAAA,EAChC,uBAAuB,UAAU;AAAA,EACjC,YAAY,UAAU;AAAA,EACtB,YAAY,UAAU;AAAA,EACtB,gBAAgB,UAAU;AAAA,EAC1B,cAAc,UAAU;AAAA,EACxB,cAAc,UAAU;AAAA,EACxB,iBAAiB,UAAU;AAAA,EAC3B,mBAAmB,UAAU;AAAA,EAC7B,iCAAiC,UAAU;AAAA,EAC3C,yBAAyB,UAAU;AAAA,EACnC,gBAAgB,UAAU;AAAA,EAC1B,mBAAmB,UAAU;AAAA,EAC7B,gBAAgB,UAAU;AAAA,EAC1B,cAAc,UAAU;AAAA,EACxB,MAAM,UAAU;AAAA,EAChB,iBAAiB,UAAU;AAAA,EAC3B,sBAAsB,UAAU;AAAA,EAChC,mBAAmB,UAAU;AAAA,EAC7B,GAAG;AACL;AAUA,SAAS,uCAAuC,MAAM;AACpD,KAAG,2CAA2C,MAAM;AAClD,UAAM,SAAoB;AAAA,EAE5B,CAAC;AAED,KAAG,gDAAgD,MAAM;AACvD,UAAM,WAAW,OAAO,KAAK,cAAc,EAAE,KAAK;AAClD,UAAM,SAAS,OAAO,KAAK,SAAS,EAAE,KAAK;AAC3C,WAAO,MAAM,EAAE,cAAc,QAAQ;AAAA,EACvC,CAAC;AACH,CAAC;",
4
+ "sourcesContent": ["import { describe, expect, it } from \"vitest\";\nimport StagehandDefaultExport, * as Stagehand from \"@browserbasehq/stagehand\";\nimport { publicErrorTypes } from \"./public-error-types.test.js\";\n\n// Type matcher guidelines:\n//\n// toEqualTypeOf \u2013 Default. Assert full, deep type equality; any type change should fail.\n// e.g. expectTypeOf<ReturnType<typeof foo>>().toEqualTypeOf<FooResult>()\n//\n// toMatchObjectType \u2013 Assert (part of) an object's shape while allowing extra fields.\n// e.g. expectTypeOf(user).toMatchObjectType<{ id: string; email: string }>()\n//\n// toExtend \u2013 Assert that a type is compatible with a broader contract (assignable/extends).\n// e.g. expectTypeOf<User>().toExtend<BaseUser>()\n\nconst publicApiShape = {\n __internalCreateInMemoryAgentCacheHandle:\n Stagehand.__internalCreateInMemoryAgentCacheHandle,\n AISdkClient: Stagehand.AISdkClient,\n Api: Stagehand.Api,\n AVAILABLE_CUA_MODELS: Stagehand.AVAILABLE_CUA_MODELS,\n AgentProvider: Stagehand.AgentProvider,\n AnnotatedScreenshotText: Stagehand.AnnotatedScreenshotText,\n ConsoleMessage: Stagehand.ConsoleMessage,\n CustomOpenAIClient: Stagehand.CustomOpenAIClient,\n LLMClient: Stagehand.LLMClient,\n LOG_LEVEL_NAMES: Stagehand.LOG_LEVEL_NAMES,\n Response: Stagehand.Response,\n Stagehand: Stagehand.Stagehand,\n V3: Stagehand.V3,\n V3Evaluator: Stagehand.V3Evaluator,\n V3FunctionName: Stagehand.V3FunctionName,\n connectToMCPServer: Stagehand.connectToMCPServer,\n default: StagehandDefaultExport,\n defaultExtractSchema: Stagehand.defaultExtractSchema,\n getAISDKLanguageModel: Stagehand.getAISDKLanguageModel,\n getZodType: Stagehand.getZodType,\n injectUrls: Stagehand.injectUrls,\n isRunningInBun: Stagehand.isRunningInBun,\n isZod3Schema: Stagehand.isZod3Schema,\n isZod4Schema: Stagehand.isZod4Schema,\n jsonSchemaToZod: Stagehand.jsonSchemaToZod,\n loadApiKeyFromEnv: Stagehand.loadApiKeyFromEnv,\n localBrowserLaunchOptionsSchema: Stagehand.localBrowserLaunchOptionsSchema,\n modelToAgentProviderMap: Stagehand.modelToAgentProviderMap,\n pageTextSchema: Stagehand.pageTextSchema,\n providerEnvVarMap: Stagehand.providerEnvVarMap,\n toGeminiSchema: Stagehand.toGeminiSchema,\n toJsonSchema: Stagehand.toJsonSchema,\n tool: Stagehand.tool,\n transformSchema: Stagehand.transformSchema,\n trimTrailingTextNode: Stagehand.trimTrailingTextNode,\n validateZodSchema: Stagehand.validateZodSchema,\n ...publicErrorTypes,\n} as const;\n\ntype StagehandExports = typeof Stagehand & {\n default: typeof StagehandDefaultExport;\n};\n\ntype PublicAPI = {\n [K in keyof typeof publicApiShape]: StagehandExports[K];\n};\n\ndescribe(\"Stagehand public API export surface\", () => {\n it(\"public API shape matches module exports\", () => {\n const _check: PublicAPI = publicApiShape;\n void _check;\n });\n\n it(\"does not expose unexpected top-level exports\", () => {\n const expected = Object.keys(publicApiShape).sort();\n const actual = Object.keys(Stagehand).sort();\n expect(actual).toStrictEqual(expected);\n });\n});\n"],
5
+ "mappings": "AAAA,SAAS,UAAU,QAAQ,UAAU;AACrC,OAAO,6BAA6B,eAAe;AACnD,SAAS,wBAAwB;AAajC,MAAM,iBAAiB;AAAA,EACrB,0CACE,UAAU;AAAA,EACZ,aAAa,UAAU;AAAA,EACvB,KAAK,UAAU;AAAA,EACf,sBAAsB,UAAU;AAAA,EAChC,eAAe,UAAU;AAAA,EACzB,yBAAyB,UAAU;AAAA,EACnC,gBAAgB,UAAU;AAAA,EAC1B,oBAAoB,UAAU;AAAA,EAC9B,WAAW,UAAU;AAAA,EACrB,iBAAiB,UAAU;AAAA,EAC3B,UAAU,UAAU;AAAA,EACpB,WAAW,UAAU;AAAA,EACrB,IAAI,UAAU;AAAA,EACd,aAAa,UAAU;AAAA,EACvB,gBAAgB,UAAU;AAAA,EAC1B,oBAAoB,UAAU;AAAA,EAC9B,SAAS;AAAA,EACT,sBAAsB,UAAU;AAAA,EAChC,uBAAuB,UAAU;AAAA,EACjC,YAAY,UAAU;AAAA,EACtB,YAAY,UAAU;AAAA,EACtB,gBAAgB,UAAU;AAAA,EAC1B,cAAc,UAAU;AAAA,EACxB,cAAc,UAAU;AAAA,EACxB,iBAAiB,UAAU;AAAA,EAC3B,mBAAmB,UAAU;AAAA,EAC7B,iCAAiC,UAAU;AAAA,EAC3C,yBAAyB,UAAU;AAAA,EACnC,gBAAgB,UAAU;AAAA,EAC1B,mBAAmB,UAAU;AAAA,EAC7B,gBAAgB,UAAU;AAAA,EAC1B,cAAc,UAAU;AAAA,EACxB,MAAM,UAAU;AAAA,EAChB,iBAAiB,UAAU;AAAA,EAC3B,sBAAsB,UAAU;AAAA,EAChC,mBAAmB,UAAU;AAAA,EAC7B,GAAG;AACL;AAUA,SAAS,uCAAuC,MAAM;AACpD,KAAG,2CAA2C,MAAM;AAClD,UAAM,SAAoB;AAAA,EAE5B,CAAC;AAED,KAAG,gDAAgD,MAAM;AACvD,UAAM,WAAW,OAAO,KAAK,cAAc,EAAE,KAAK;AAClD,UAAM,SAAS,OAAO,KAAK,SAAS,EAAE,KAAK;AAC3C,WAAO,MAAM,EAAE,cAAc,QAAQ;AAAA,EACvC,CAAC;AACH,CAAC;",
6
6
  "names": []
7
7
  }
@@ -54,7 +54,8 @@ const publicErrorTypes = {
54
54
  ZodSchemaValidationError: Stagehand.ZodSchemaValidationError,
55
55
  ActTimeoutError: Stagehand.ActTimeoutError,
56
56
  ObserveTimeoutError: Stagehand.ObserveTimeoutError,
57
- ExtractTimeoutError: Stagehand.ExtractTimeoutError
57
+ ExtractTimeoutError: Stagehand.ExtractTimeoutError,
58
+ UnderstudyCommandException: Stagehand.UnderstudyCommandException
58
59
  };
59
60
  const errorTypes = Object.keys(publicErrorTypes);
60
61
  describe("Stagehand public error types", () => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../tests/public-api/public-error-types.test.ts"],
4
- "sourcesContent": ["import { describe, expectTypeOf, it } from \"vitest\";\nimport * as Stagehand from \"@browserbasehq/stagehand\";\n\nexport const publicErrorTypes = {\n AgentAbortError: Stagehand.AgentAbortError,\n AgentScreenshotProviderError: Stagehand.AgentScreenshotProviderError,\n BrowserbaseSessionNotFoundError: Stagehand.BrowserbaseSessionNotFoundError,\n CaptchaTimeoutError: Stagehand.CaptchaTimeoutError,\n ConnectionTimeoutError: Stagehand.ConnectionTimeoutError,\n ContentFrameNotFoundError: Stagehand.ContentFrameNotFoundError,\n CreateChatCompletionResponseError:\n Stagehand.CreateChatCompletionResponseError,\n CuaModelRequiredError: Stagehand.CuaModelRequiredError,\n ElementNotVisibleError: Stagehand.ElementNotVisibleError,\n ExperimentalApiConflictError: Stagehand.ExperimentalApiConflictError,\n ExperimentalNotConfiguredError: Stagehand.ExperimentalNotConfiguredError,\n HandlerNotInitializedError: Stagehand.HandlerNotInitializedError,\n InvalidAISDKModelFormatError: Stagehand.InvalidAISDKModelFormatError,\n LLMResponseError: Stagehand.LLMResponseError,\n MCPConnectionError: Stagehand.MCPConnectionError,\n MissingEnvironmentVariableError: Stagehand.MissingEnvironmentVariableError,\n MissingLLMConfigurationError: Stagehand.MissingLLMConfigurationError,\n PageNotFoundError: Stagehand.PageNotFoundError,\n ResponseBodyError: Stagehand.ResponseBodyError,\n ResponseParseError: Stagehand.ResponseParseError,\n StagehandAPIError: Stagehand.StagehandAPIError,\n StagehandAPIUnauthorizedError: Stagehand.StagehandAPIUnauthorizedError,\n StagehandClickError: Stagehand.StagehandClickError,\n StagehandClosedError: Stagehand.StagehandClosedError,\n StagehandDefaultError: Stagehand.StagehandDefaultError,\n StagehandDomProcessError: Stagehand.StagehandDomProcessError,\n StagehandElementNotFoundError: Stagehand.StagehandElementNotFoundError,\n StagehandEnvironmentError: Stagehand.StagehandEnvironmentError,\n StagehandError: Stagehand.StagehandError,\n StagehandEvalError: Stagehand.StagehandEvalError,\n StagehandHttpError: Stagehand.StagehandHttpError,\n StagehandIframeError: Stagehand.StagehandIframeError,\n StagehandInitError: Stagehand.StagehandInitError,\n StagehandInvalidArgumentError: Stagehand.StagehandInvalidArgumentError,\n StagehandLocatorError: Stagehand.StagehandLocatorError,\n StagehandMissingArgumentError: Stagehand.StagehandMissingArgumentError,\n StagehandNotInitializedError: Stagehand.StagehandNotInitializedError,\n StagehandResponseBodyError: Stagehand.StagehandResponseBodyError,\n StagehandResponseParseError: Stagehand.StagehandResponseParseError,\n StagehandServerError: Stagehand.StagehandServerError,\n StagehandShadowRootMissingError: Stagehand.StagehandShadowRootMissingError,\n StagehandShadowSegmentEmptyError: Stagehand.StagehandShadowSegmentEmptyError,\n StagehandShadowSegmentNotFoundError:\n Stagehand.StagehandShadowSegmentNotFoundError,\n StreamingCallbacksInNonStreamingModeError:\n Stagehand.StreamingCallbacksInNonStreamingModeError,\n StagehandSnapshotError: Stagehand.StagehandSnapshotError,\n TimeoutError: Stagehand.TimeoutError,\n UnsupportedAISDKModelProviderError:\n Stagehand.UnsupportedAISDKModelProviderError,\n UnsupportedModelError: Stagehand.UnsupportedModelError,\n UnsupportedModelProviderError: Stagehand.UnsupportedModelProviderError,\n XPathResolutionError: Stagehand.XPathResolutionError,\n ZodSchemaValidationError: Stagehand.ZodSchemaValidationError,\n ActTimeoutError: Stagehand.ActTimeoutError,\n ObserveTimeoutError: Stagehand.ObserveTimeoutError,\n ExtractTimeoutError: Stagehand.ExtractTimeoutError,\n} as const;\n\nconst errorTypes = Object.keys(publicErrorTypes) as Array<\n keyof typeof publicErrorTypes\n>;\n\ndescribe(\"Stagehand public error types\", () => {\n describe(\"errors\", () => {\n it.each(errorTypes)(\"%s extends Error\", (errorTypeName) => {\n const ErrorClass = Stagehand[errorTypeName];\n type ErrorClassType = typeof ErrorClass;\n expectTypeOf<InstanceType<ErrorClassType>>().toExtend<Error>();\n void ErrorClass; // Mark as used to satisfy ESLint\n });\n });\n});\n"],
5
- "mappings": "AAAA,SAAS,UAAU,cAAc,UAAU;AAC3C,YAAY,eAAe;AAEpB,MAAM,mBAAmB;AAAA,EAC9B,iBAAiB,UAAU;AAAA,EAC3B,8BAA8B,UAAU;AAAA,EACxC,iCAAiC,UAAU;AAAA,EAC3C,qBAAqB,UAAU;AAAA,EAC/B,wBAAwB,UAAU;AAAA,EAClC,2BAA2B,UAAU;AAAA,EACrC,mCACE,UAAU;AAAA,EACZ,uBAAuB,UAAU;AAAA,EACjC,wBAAwB,UAAU;AAAA,EAClC,8BAA8B,UAAU;AAAA,EACxC,gCAAgC,UAAU;AAAA,EAC1C,4BAA4B,UAAU;AAAA,EACtC,8BAA8B,UAAU;AAAA,EACxC,kBAAkB,UAAU;AAAA,EAC5B,oBAAoB,UAAU;AAAA,EAC9B,iCAAiC,UAAU;AAAA,EAC3C,8BAA8B,UAAU;AAAA,EACxC,mBAAmB,UAAU;AAAA,EAC7B,mBAAmB,UAAU;AAAA,EAC7B,oBAAoB,UAAU;AAAA,EAC9B,mBAAmB,UAAU;AAAA,EAC7B,+BAA+B,UAAU;AAAA,EACzC,qBAAqB,UAAU;AAAA,EAC/B,sBAAsB,UAAU;AAAA,EAChC,uBAAuB,UAAU;AAAA,EACjC,0BAA0B,UAAU;AAAA,EACpC,+BAA+B,UAAU;AAAA,EACzC,2BAA2B,UAAU;AAAA,EACrC,gBAAgB,UAAU;AAAA,EAC1B,oBAAoB,UAAU;AAAA,EAC9B,oBAAoB,UAAU;AAAA,EAC9B,sBAAsB,UAAU;AAAA,EAChC,oBAAoB,UAAU;AAAA,EAC9B,+BAA+B,UAAU;AAAA,EACzC,uBAAuB,UAAU;AAAA,EACjC,+BAA+B,UAAU;AAAA,EACzC,8BAA8B,UAAU;AAAA,EACxC,4BAA4B,UAAU;AAAA,EACtC,6BAA6B,UAAU;AAAA,EACvC,sBAAsB,UAAU;AAAA,EAChC,iCAAiC,UAAU;AAAA,EAC3C,kCAAkC,UAAU;AAAA,EAC5C,qCACE,UAAU;AAAA,EACZ,2CACE,UAAU;AAAA,EACZ,wBAAwB,UAAU;AAAA,EAClC,cAAc,UAAU;AAAA,EACxB,oCACE,UAAU;AAAA,EACZ,uBAAuB,UAAU;AAAA,EACjC,+BAA+B,UAAU;AAAA,EACzC,sBAAsB,UAAU;AAAA,EAChC,0BAA0B,UAAU;AAAA,EACpC,iBAAiB,UAAU;AAAA,EAC3B,qBAAqB,UAAU;AAAA,EAC/B,qBAAqB,UAAU;AACjC;AAEA,MAAM,aAAa,OAAO,KAAK,gBAAgB;AAI/C,SAAS,gCAAgC,MAAM;AAC7C,WAAS,UAAU,MAAM;AACvB,OAAG,KAAK,UAAU,EAAE,oBAAoB,CAAC,kBAAkB;AACzD,YAAM,aAAa,UAAU,aAAa;AAE1C,mBAA2C,EAAE,SAAgB;AAAA,IAE/D,CAAC;AAAA,EACH,CAAC;AACH,CAAC;",
4
+ "sourcesContent": ["import { describe, expectTypeOf, it } from \"vitest\";\nimport * as Stagehand from \"@browserbasehq/stagehand\";\n\nexport const publicErrorTypes = {\n AgentAbortError: Stagehand.AgentAbortError,\n AgentScreenshotProviderError: Stagehand.AgentScreenshotProviderError,\n BrowserbaseSessionNotFoundError: Stagehand.BrowserbaseSessionNotFoundError,\n CaptchaTimeoutError: Stagehand.CaptchaTimeoutError,\n ConnectionTimeoutError: Stagehand.ConnectionTimeoutError,\n ContentFrameNotFoundError: Stagehand.ContentFrameNotFoundError,\n CreateChatCompletionResponseError:\n Stagehand.CreateChatCompletionResponseError,\n CuaModelRequiredError: Stagehand.CuaModelRequiredError,\n ElementNotVisibleError: Stagehand.ElementNotVisibleError,\n ExperimentalApiConflictError: Stagehand.ExperimentalApiConflictError,\n ExperimentalNotConfiguredError: Stagehand.ExperimentalNotConfiguredError,\n HandlerNotInitializedError: Stagehand.HandlerNotInitializedError,\n InvalidAISDKModelFormatError: Stagehand.InvalidAISDKModelFormatError,\n LLMResponseError: Stagehand.LLMResponseError,\n MCPConnectionError: Stagehand.MCPConnectionError,\n MissingEnvironmentVariableError: Stagehand.MissingEnvironmentVariableError,\n MissingLLMConfigurationError: Stagehand.MissingLLMConfigurationError,\n PageNotFoundError: Stagehand.PageNotFoundError,\n ResponseBodyError: Stagehand.ResponseBodyError,\n ResponseParseError: Stagehand.ResponseParseError,\n StagehandAPIError: Stagehand.StagehandAPIError,\n StagehandAPIUnauthorizedError: Stagehand.StagehandAPIUnauthorizedError,\n StagehandClickError: Stagehand.StagehandClickError,\n StagehandClosedError: Stagehand.StagehandClosedError,\n StagehandDefaultError: Stagehand.StagehandDefaultError,\n StagehandDomProcessError: Stagehand.StagehandDomProcessError,\n StagehandElementNotFoundError: Stagehand.StagehandElementNotFoundError,\n StagehandEnvironmentError: Stagehand.StagehandEnvironmentError,\n StagehandError: Stagehand.StagehandError,\n StagehandEvalError: Stagehand.StagehandEvalError,\n StagehandHttpError: Stagehand.StagehandHttpError,\n StagehandIframeError: Stagehand.StagehandIframeError,\n StagehandInitError: Stagehand.StagehandInitError,\n StagehandInvalidArgumentError: Stagehand.StagehandInvalidArgumentError,\n StagehandLocatorError: Stagehand.StagehandLocatorError,\n StagehandMissingArgumentError: Stagehand.StagehandMissingArgumentError,\n StagehandNotInitializedError: Stagehand.StagehandNotInitializedError,\n StagehandResponseBodyError: Stagehand.StagehandResponseBodyError,\n StagehandResponseParseError: Stagehand.StagehandResponseParseError,\n StagehandServerError: Stagehand.StagehandServerError,\n StagehandShadowRootMissingError: Stagehand.StagehandShadowRootMissingError,\n StagehandShadowSegmentEmptyError: Stagehand.StagehandShadowSegmentEmptyError,\n StagehandShadowSegmentNotFoundError:\n Stagehand.StagehandShadowSegmentNotFoundError,\n StreamingCallbacksInNonStreamingModeError:\n Stagehand.StreamingCallbacksInNonStreamingModeError,\n StagehandSnapshotError: Stagehand.StagehandSnapshotError,\n TimeoutError: Stagehand.TimeoutError,\n UnsupportedAISDKModelProviderError:\n Stagehand.UnsupportedAISDKModelProviderError,\n UnsupportedModelError: Stagehand.UnsupportedModelError,\n UnsupportedModelProviderError: Stagehand.UnsupportedModelProviderError,\n XPathResolutionError: Stagehand.XPathResolutionError,\n ZodSchemaValidationError: Stagehand.ZodSchemaValidationError,\n ActTimeoutError: Stagehand.ActTimeoutError,\n ObserveTimeoutError: Stagehand.ObserveTimeoutError,\n ExtractTimeoutError: Stagehand.ExtractTimeoutError,\n UnderstudyCommandException: Stagehand.UnderstudyCommandException,\n} as const;\n\nconst errorTypes = Object.keys(publicErrorTypes) as Array<\n keyof typeof publicErrorTypes\n>;\n\ndescribe(\"Stagehand public error types\", () => {\n describe(\"errors\", () => {\n it.each(errorTypes)(\"%s extends Error\", (errorTypeName) => {\n const ErrorClass = Stagehand[errorTypeName];\n type ErrorClassType = typeof ErrorClass;\n expectTypeOf<InstanceType<ErrorClassType>>().toExtend<Error>();\n void ErrorClass; // Mark as used to satisfy ESLint\n });\n });\n});\n"],
5
+ "mappings": "AAAA,SAAS,UAAU,cAAc,UAAU;AAC3C,YAAY,eAAe;AAEpB,MAAM,mBAAmB;AAAA,EAC9B,iBAAiB,UAAU;AAAA,EAC3B,8BAA8B,UAAU;AAAA,EACxC,iCAAiC,UAAU;AAAA,EAC3C,qBAAqB,UAAU;AAAA,EAC/B,wBAAwB,UAAU;AAAA,EAClC,2BAA2B,UAAU;AAAA,EACrC,mCACE,UAAU;AAAA,EACZ,uBAAuB,UAAU;AAAA,EACjC,wBAAwB,UAAU;AAAA,EAClC,8BAA8B,UAAU;AAAA,EACxC,gCAAgC,UAAU;AAAA,EAC1C,4BAA4B,UAAU;AAAA,EACtC,8BAA8B,UAAU;AAAA,EACxC,kBAAkB,UAAU;AAAA,EAC5B,oBAAoB,UAAU;AAAA,EAC9B,iCAAiC,UAAU;AAAA,EAC3C,8BAA8B,UAAU;AAAA,EACxC,mBAAmB,UAAU;AAAA,EAC7B,mBAAmB,UAAU;AAAA,EAC7B,oBAAoB,UAAU;AAAA,EAC9B,mBAAmB,UAAU;AAAA,EAC7B,+BAA+B,UAAU;AAAA,EACzC,qBAAqB,UAAU;AAAA,EAC/B,sBAAsB,UAAU;AAAA,EAChC,uBAAuB,UAAU;AAAA,EACjC,0BAA0B,UAAU;AAAA,EACpC,+BAA+B,UAAU;AAAA,EACzC,2BAA2B,UAAU;AAAA,EACrC,gBAAgB,UAAU;AAAA,EAC1B,oBAAoB,UAAU;AAAA,EAC9B,oBAAoB,UAAU;AAAA,EAC9B,sBAAsB,UAAU;AAAA,EAChC,oBAAoB,UAAU;AAAA,EAC9B,+BAA+B,UAAU;AAAA,EACzC,uBAAuB,UAAU;AAAA,EACjC,+BAA+B,UAAU;AAAA,EACzC,8BAA8B,UAAU;AAAA,EACxC,4BAA4B,UAAU;AAAA,EACtC,6BAA6B,UAAU;AAAA,EACvC,sBAAsB,UAAU;AAAA,EAChC,iCAAiC,UAAU;AAAA,EAC3C,kCAAkC,UAAU;AAAA,EAC5C,qCACE,UAAU;AAAA,EACZ,2CACE,UAAU;AAAA,EACZ,wBAAwB,UAAU;AAAA,EAClC,cAAc,UAAU;AAAA,EACxB,oCACE,UAAU;AAAA,EACZ,uBAAuB,UAAU;AAAA,EACjC,+BAA+B,UAAU;AAAA,EACzC,sBAAsB,UAAU;AAAA,EAChC,0BAA0B,UAAU;AAAA,EACpC,iBAAiB,UAAU;AAAA,EAC3B,qBAAqB,UAAU;AAAA,EAC/B,qBAAqB,UAAU;AAAA,EAC/B,4BAA4B,UAAU;AACxC;AAEA,MAAM,aAAa,OAAO,KAAK,gBAAgB;AAI/C,SAAS,gCAAgC,MAAM;AAC7C,WAAS,UAAU,MAAM;AACvB,OAAG,KAAK,UAAU,EAAE,oBAAoB,CAAC,kBAAkB;AACzD,YAAM,aAAa,UAAU,aAAa;AAE1C,mBAA2C,EAAE,SAAgB;AAAA,IAE/D,CAAC;AAAA,EACH,CAAC;AACH,CAAC;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,55 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ UnderstudyCommandException,
4
+ StagehandError
5
+ } from "../lib/v3/types/public/sdkErrors.js";
6
+ describe("UnderstudyCommandException", () => {
7
+ it("extends StagehandError", () => {
8
+ const err = new UnderstudyCommandException("test");
9
+ expect(err).toBeInstanceOf(StagehandError);
10
+ expect(err).toBeInstanceOf(Error);
11
+ });
12
+ it("has the correct name", () => {
13
+ const err = new UnderstudyCommandException("test");
14
+ expect(err.name).toBe("UnderstudyCommandException");
15
+ });
16
+ it("preserves the message", () => {
17
+ const err = new UnderstudyCommandException("something broke");
18
+ expect(err.message).toBe("something broke");
19
+ });
20
+ it("stores the original error as cause when provided", () => {
21
+ const original = new Error("root cause");
22
+ const err = new UnderstudyCommandException("wrapper message", original);
23
+ expect(err.cause).toBe(original);
24
+ expect(err.cause.message).toBe("root cause");
25
+ expect(err.cause.stack).toBeDefined();
26
+ });
27
+ it("stores non-Error cause values", () => {
28
+ const err = new UnderstudyCommandException("failed", "string cause");
29
+ expect(err.cause).toBe("string cause");
30
+ });
31
+ it("has undefined cause when none is provided", () => {
32
+ const err = new UnderstudyCommandException("no cause");
33
+ expect(err.cause).toBeUndefined();
34
+ });
35
+ it("generates its own stack trace", () => {
36
+ const err = new UnderstudyCommandException("test");
37
+ expect(err.stack).toBeDefined();
38
+ expect(err.stack).toContain("UnderstudyCommandException");
39
+ });
40
+ it("preserves the original stack via cause for debugging", () => {
41
+ function deepFunction() {
42
+ throw new Error("deep error");
43
+ }
44
+ let original;
45
+ try {
46
+ deepFunction();
47
+ } catch (e) {
48
+ original = e;
49
+ }
50
+ const wrapped = new UnderstudyCommandException(original.message, original);
51
+ expect(wrapped.stack).toBeDefined();
52
+ expect(wrapped.cause.stack).toContain("deepFunction");
53
+ });
54
+ });
55
+ //# sourceMappingURL=understudy-command-exception.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../tests/understudy-command-exception.test.ts"],
4
+ "sourcesContent": ["import { describe, expect, it } from \"vitest\";\nimport {\n UnderstudyCommandException,\n StagehandError,\n} from \"../lib/v3/types/public/sdkErrors.js\";\n\ndescribe(\"UnderstudyCommandException\", () => {\n it(\"extends StagehandError\", () => {\n const err = new UnderstudyCommandException(\"test\");\n expect(err).toBeInstanceOf(StagehandError);\n expect(err).toBeInstanceOf(Error);\n });\n\n it(\"has the correct name\", () => {\n const err = new UnderstudyCommandException(\"test\");\n expect(err.name).toBe(\"UnderstudyCommandException\");\n });\n\n it(\"preserves the message\", () => {\n const err = new UnderstudyCommandException(\"something broke\");\n expect(err.message).toBe(\"something broke\");\n });\n\n it(\"stores the original error as cause when provided\", () => {\n const original = new Error(\"root cause\");\n const err = new UnderstudyCommandException(\"wrapper message\", original);\n\n expect(err.cause).toBe(original);\n expect((err.cause as Error).message).toBe(\"root cause\");\n expect((err.cause as Error).stack).toBeDefined();\n });\n\n it(\"stores non-Error cause values\", () => {\n const err = new UnderstudyCommandException(\"failed\", \"string cause\");\n expect(err.cause).toBe(\"string cause\");\n });\n\n it(\"has undefined cause when none is provided\", () => {\n const err = new UnderstudyCommandException(\"no cause\");\n expect(err.cause).toBeUndefined();\n });\n\n it(\"generates its own stack trace\", () => {\n const err = new UnderstudyCommandException(\"test\");\n expect(err.stack).toBeDefined();\n expect(err.stack).toContain(\"UnderstudyCommandException\");\n });\n\n it(\"preserves the original stack via cause for debugging\", () => {\n function deepFunction() {\n throw new Error(\"deep error\");\n }\n\n let original: Error;\n try {\n deepFunction();\n } catch (e) {\n original = e as Error;\n }\n\n const wrapped = new UnderstudyCommandException(original!.message, original);\n\n // The wrapper has its own stack\n expect(wrapped.stack).toBeDefined();\n // The original stack is accessible via cause\n expect((wrapped.cause as Error).stack).toContain(\"deepFunction\");\n });\n});\n"],
5
+ "mappings": "AAAA,SAAS,UAAU,QAAQ,UAAU;AACrC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEP,SAAS,8BAA8B,MAAM;AAC3C,KAAG,0BAA0B,MAAM;AACjC,UAAM,MAAM,IAAI,2BAA2B,MAAM;AACjD,WAAO,GAAG,EAAE,eAAe,cAAc;AACzC,WAAO,GAAG,EAAE,eAAe,KAAK;AAAA,EAClC,CAAC;AAED,KAAG,wBAAwB,MAAM;AAC/B,UAAM,MAAM,IAAI,2BAA2B,MAAM;AACjD,WAAO,IAAI,IAAI,EAAE,KAAK,4BAA4B;AAAA,EACpD,CAAC;AAED,KAAG,yBAAyB,MAAM;AAChC,UAAM,MAAM,IAAI,2BAA2B,iBAAiB;AAC5D,WAAO,IAAI,OAAO,EAAE,KAAK,iBAAiB;AAAA,EAC5C,CAAC;AAED,KAAG,oDAAoD,MAAM;AAC3D,UAAM,WAAW,IAAI,MAAM,YAAY;AACvC,UAAM,MAAM,IAAI,2BAA2B,mBAAmB,QAAQ;AAEtE,WAAO,IAAI,KAAK,EAAE,KAAK,QAAQ;AAC/B,WAAQ,IAAI,MAAgB,OAAO,EAAE,KAAK,YAAY;AACtD,WAAQ,IAAI,MAAgB,KAAK,EAAE,YAAY;AAAA,EACjD,CAAC;AAED,KAAG,iCAAiC,MAAM;AACxC,UAAM,MAAM,IAAI,2BAA2B,UAAU,cAAc;AACnE,WAAO,IAAI,KAAK,EAAE,KAAK,cAAc;AAAA,EACvC,CAAC;AAED,KAAG,6CAA6C,MAAM;AACpD,UAAM,MAAM,IAAI,2BAA2B,UAAU;AACrD,WAAO,IAAI,KAAK,EAAE,cAAc;AAAA,EAClC,CAAC;AAED,KAAG,iCAAiC,MAAM;AACxC,UAAM,MAAM,IAAI,2BAA2B,MAAM;AACjD,WAAO,IAAI,KAAK,EAAE,YAAY;AAC9B,WAAO,IAAI,KAAK,EAAE,UAAU,4BAA4B;AAAA,EAC1D,CAAC;AAED,KAAG,wDAAwD,MAAM;AAC/D,aAAS,eAAe;AACtB,YAAM,IAAI,MAAM,YAAY;AAAA,IAC9B;AAEA,QAAI;AACJ,QAAI;AACF,mBAAa;AAAA,IACf,SAAS,GAAG;AACV,iBAAW;AAAA,IACb;AAEA,UAAM,UAAU,IAAI,2BAA2B,SAAU,SAAS,QAAQ;AAG1E,WAAO,QAAQ,KAAK,EAAE,YAAY;AAElC,WAAQ,QAAQ,MAAgB,KAAK,EAAE,UAAU,cAAc;AAAA,EACjE,CAAC;AACH,CAAC;",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@browserbasehq/orca",
3
- "version": "3.1.0-patch.1",
3
+ "version": "3.1.0-patch.2",
4
4
  "description": "An AI web browsing framework focused on simplicity and extensibility.",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -12,7 +12,6 @@
12
12
  "import": "./dist/esm/index.js",
13
13
  "require": "./dist/cjs/index.js"
14
14
  },
15
- "./cli": "./dist/esm/lib/v3/cli.js",
16
15
  "./*.js": {
17
16
  "types": "./dist/esm/*.d.ts",
18
17
  "import": "./dist/esm/*.js"
@@ -23,27 +22,24 @@
23
22
  },
24
23
  "./package.json": "./package.json"
25
24
  },
26
- "engines": {
27
- "node": "^20.19.0 || >=22.12.0"
28
- },
29
25
  "scripts": {
30
26
  "gen-version": "tsx scripts/gen-version.ts",
31
- "build-dom-scripts": "tsx lib/v3/dom/genDomScripts.ts && tsx lib/v3/dom/genLocatorScripts.ts && tsx lib/v3/dom/genScreenshotScripts.ts && tsx lib/v3/dom/genA11yScripts.ts",
32
27
  "build:cjs": "tsx scripts/build-cjs.ts",
33
28
  "build:esm": "tsx scripts/build-esm.ts",
34
- "build": "pnpm run build:esm && pnpm run build:cjs",
29
+ "build-dom-scripts": "tsx lib/v3/dom/genDomScripts.ts && tsx lib/v3/dom/genLocatorScripts.ts && tsx lib/v3/dom/genScreenshotScripts.ts && tsx lib/v3/dom/genA11yScripts.ts",
30
+ "typecheck": "pnpm -w --dir ../.. exec tsc -p packages/core/tsconfig.json --noEmit",
31
+ "build": "pnpm run build:esm && pnpm run typecheck",
35
32
  "example": "node --import tsx -e \"const args=process.argv.slice(1).filter(a=>a!=='--'); const [p]=args; const n=(p||'example').replace(/^\\.\\//,'').replace(/\\.ts$/i,''); import('node:path').then(path=>import(new URL(path.resolve('examples', n + '.ts'), 'file:')));\" --",
36
- "test": "pnpm -w --dir ../.. exec turbo run test:core test:e2e --filter=@browserbasehq/stagehand --",
33
+ "test": "pnpm run test:core --",
37
34
  "test:core": "tsx scripts/test-core.ts",
38
35
  "test:e2e": "tsx scripts/test-e2e.ts",
39
- "format": "prettier --write .",
40
- "typecheck": "pnpm -w --dir ../.. exec tsc -p packages/core/tsconfig.json --noEmit",
41
- "eslint": "eslint .",
42
- "lint": "cd ../.. && prettier --check packages/core && cd packages/core && pnpm run eslint && pnpm run typecheck"
36
+ "lint": "cd ../.. && prettier --check packages/core && cd packages/core && eslint . && pnpm run typecheck",
37
+ "format": "prettier --write ."
43
38
  },
44
39
  "files": [
45
40
  "dist/esm",
46
- "dist/cjs"
41
+ "dist/cjs",
42
+ "dist/stagehand.config.d.ts"
47
43
  ],
48
44
  "keywords": [
49
45
  "ai",
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env node
2
- import process from "node:process";
3
- import { maybeRunShutdownSupervisorFromArgv } from "./shutdown/supervisor.js";
4
- // currently the CLI is only used to spawn the shutdown supervisor
5
- // in the future, we may want to add more CLI commands here
6
- if (!maybeRunShutdownSupervisorFromArgv(process.argv.slice(2))) {
7
- console.error("Unsupported stagehand CLI invocation. Expected --supervisor with valid args.");
8
- process.exit(1);
9
- }
10
- //# sourceMappingURL=cli.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../../lib/v3/cli.js"],"names":[],"mappings":";AAEA,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,kCAAkC,EAAE,MAAM,0BAA0B,CAAC;AAE9E,kEAAkE;AAClE,2DAA2D;AAC3D,IAAI,CAAC,kCAAkC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/D,OAAO,CAAC,KAAK,CACX,8EAA8E,CAC/E,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC","sourcesContent":["#!/usr/bin/env node\n\nimport process from \"node:process\";\nimport { maybeRunShutdownSupervisorFromArgv } from \"./shutdown/supervisor.js\";\n\n// currently the CLI is only used to spawn the shutdown supervisor\n// in the future, we may want to add more CLI commands here\nif (!maybeRunShutdownSupervisorFromArgv(process.argv.slice(2))) {\n console.error(\n \"Unsupported stagehand CLI invocation. Expected --supervisor with valid args.\",\n );\n process.exit(1);\n}\n"]}
File without changes
@@ -1 +0,0 @@
1
- {"version":3,"file":"rerender-index.js","sourceRoot":"","sources":["../../../../../../lib/v3/dom/build/rerender-index.js"],"names":[],"mappings":"AAAA,CAAC,GAAE,EAAE,GAAC,SAAS,CAAC,KAAG,IAAG,CAAC;IAAA,IAAI,CAAC,GAAC,MAAM,CAAC,eAAe,CAAC;IAAA,IAAG,CAAC,CAAC,IAAE,OAAO,CAAC,CAAC,aAAa,IAAE,UAAU;QAAC,OAAO;IAAA,IAAI,CAAC,GAAC,EAAE,EAAC,CAAC,GAAC,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAAA,OAAK,CAAC,CAAC,QAAQ,EAAE,GAAE,CAAC;QAAA,IAAI,CAAC,GAAC,CAAC,CAAC,WAAW,EAAC,CAAC,GAAC,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,IAAE,EAAE,CAAC;QAAA,IAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAE,OAAO,cAAc,EAAE,GAAG,IAAE,UAAU,IAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;YAAC,SAAS;QAAA,IAAI,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QAAA,CAAC,IAAE,CAAC,IAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAAA,CAAC;IAAA,KAAI,IAAI,CAAC,IAAI,CAAC;QAAC,IAAG,CAAC;YAAA,IAAI,CAAC,GAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAAA,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;QAAA,CAAC;QAAA,MAAK,CAAC,CAAA,CAAC;IAAA,CAAC,CAAC,KAAK,IAAE,CAAC,CAAC,MAAM,IAAE,OAAO,CAAC,IAAI,CAAC,uBAAuB,EAAC,EAAC,KAAK,EAAC,CAAC,CAAC,MAAM,EAAC,CAAC,CAAA;AAAA,CAAC;AAAA,OAAM,CAAC,EAAC,CAAC;IAAA,OAAO,CAAC,IAAI,CAAC,6BAA6B,EAAC,EAAC,OAAO,EAAC,MAAM,CAAC,CAAC,IAAE,EAAE,CAAC,EAAC,CAAC,CAAA;AAAA,CAAC,CAAA,CAAC,CAAA,CAAC,EAAE,CAAC,CAAA,CAAC,CAAC,EAAE,CAAC","sourcesContent":["(()=>{function s(){try{let o=window.__stagehandV3__;if(!o||typeof o.getClosedRoot!=\"function\")return;let t=[],r=document.createTreeWalker(document,NodeFilter.SHOW_ELEMENT);for(;r.nextNode();){let e=r.currentNode,n=e.tagName?.toLowerCase()??\"\";if(!n.includes(\"-\")||typeof customElements?.get!=\"function\"||!customElements.get(n))continue;let c=!!e.shadowRoot,i=!!o.getClosedRoot(e);c||i||t.push(e)}for(let e of t)try{let n=e.cloneNode(!0);e.replaceWith(n)}catch{}o.stats&&t.length&&console.info(\"[v3-piercer] rerender\",{count:t.length})}catch(o){console.info(\"[v3-piercer] rerender error\",{message:String(o??\"\")})}}s();})();\n"]}
File without changes
@@ -1 +0,0 @@
1
- {"version":3,"file":"v3-index.js","sourceRoot":"","sources":["../../../../../../lib/v3/dom/build/v3-index.js"],"names":[],"mappings":"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","sourcesContent":["(()=>{function s(c={}){let r=e=>{let{hostToRoot:o}=e;window.__stagehandV3__={getClosedRoot:a=>o.get(a),stats:()=>({installed:!0,url:location.href,isTop:window.top===window,open:e.openCount,closed:e.closedCount})}},n=Element.prototype.attachShadow;if(n.__v3Patched&&n.__v3State){n.__v3State.debug=!0,r(n.__v3State);return}let t={hostToRoot:new WeakMap,openCount:0,closedCount:0,debug:!0},l=n,d=function(e){let o=e?.mode??\"open\",a=l.call(this,e);try{t.hostToRoot.set(this,a),o===\"closed\"?t.closedCount++:t.openCount++,t.debug&&console.info(\"[v3-piercer] attachShadow\",{tag:this.tagName?.toLowerCase()??\"\",mode:o,url:location.href})}catch{}return a};if(d.__v3Patched=!0,d.__v3State=t,Object.defineProperty(Element.prototype,\"attachShadow\",{configurable:!0,writable:!0,value:d}),c.tagExisting)try{let e=document.createTreeWalker(document,NodeFilter.SHOW_ELEMENT);for(;e.nextNode();){let o=e.currentNode;o.shadowRoot&&(t.hostToRoot.set(o,o.shadowRoot),t.openCount++)}}catch{}window.__stagehandV3Injected=!0,r(t),t.debug&&console.info(\"[v3-piercer] installed\",{url:location.href,isTop:window.top===window,readyState:document.readyState})}s({debug:!0,tagExisting:!1});})();\n"]}