@browserbasehq/orca 3.2.0-preview.5 → 3.2.1-preview.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/lib/inference.js +29 -22
  3. package/dist/cjs/lib/inference.js.map +1 -1
  4. package/dist/cjs/lib/prompt.js +18 -21
  5. package/dist/cjs/lib/prompt.js.map +1 -1
  6. package/dist/cjs/lib/v3/agent/AgentProvider.js +1 -0
  7. package/dist/cjs/lib/v3/agent/AgentProvider.js.map +1 -1
  8. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.d.ts +3 -1
  9. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js +60 -9
  10. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  11. package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.js +15 -0
  12. package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.js.map +1 -1
  13. package/dist/cjs/lib/v3/agent/OpenAICUAClient.d.ts +8 -2
  14. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js +103 -49
  15. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  16. package/dist/cjs/lib/v3/agent/tools/index.js +1 -1
  17. package/dist/cjs/lib/v3/agent/tools/index.js.map +1 -1
  18. package/dist/cjs/lib/v3/agent/tools/keys.d.ts +2 -1
  19. package/dist/cjs/lib/v3/agent/tools/keys.js +57 -49
  20. package/dist/cjs/lib/v3/agent/tools/keys.js.map +1 -1
  21. package/dist/cjs/lib/v3/agent/utils/coordinateNormalization.js +3 -5
  22. package/dist/cjs/lib/v3/agent/utils/coordinateNormalization.js.map +1 -1
  23. package/dist/cjs/lib/v3/api.d.ts +5 -3
  24. package/dist/cjs/lib/v3/api.js +3 -6
  25. package/dist/cjs/lib/v3/api.js.map +1 -1
  26. package/dist/cjs/lib/v3/cache/AgentCache.js +5 -3
  27. package/dist/cjs/lib/v3/cache/AgentCache.js.map +1 -1
  28. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js +6 -15
  29. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  30. package/dist/cjs/lib/v3/index.d.ts +1 -1
  31. package/dist/cjs/lib/v3/llm/LLMProvider.d.ts +5 -2
  32. package/dist/cjs/lib/v3/llm/LLMProvider.js +14 -6
  33. package/dist/cjs/lib/v3/llm/LLMProvider.js.map +1 -1
  34. package/dist/cjs/lib/v3/llm/OpenAIClient.js +1 -0
  35. package/dist/cjs/lib/v3/llm/OpenAIClient.js.map +1 -1
  36. package/dist/cjs/lib/v3/llm/aisdk.d.ts +3 -1
  37. package/dist/cjs/lib/v3/llm/aisdk.js +67 -17
  38. package/dist/cjs/lib/v3/llm/aisdk.js.map +1 -1
  39. package/dist/cjs/lib/v3/types/public/agent.d.ts +8 -3
  40. package/dist/cjs/lib/v3/types/public/agent.js +1 -0
  41. package/dist/cjs/lib/v3/types/public/agent.js.map +1 -1
  42. package/dist/cjs/lib/v3/types/public/api.d.ts +30 -0
  43. package/dist/cjs/lib/v3/types/public/api.js +6 -2
  44. package/dist/cjs/lib/v3/types/public/api.js.map +1 -1
  45. package/dist/cjs/lib/v3/types/public/model.d.ts +32 -2
  46. package/dist/cjs/lib/v3/types/public/model.js.map +1 -1
  47. package/dist/cjs/lib/v3/understudy/context.js +11 -3
  48. package/dist/cjs/lib/v3/understudy/context.js.map +1 -1
  49. package/dist/cjs/lib/v3/understudy/page.js +1 -1
  50. package/dist/cjs/lib/v3/understudy/page.js.map +1 -1
  51. package/dist/cjs/lib/v3/v3.d.ts +18 -2
  52. package/dist/cjs/lib/v3/v3.js +92 -9
  53. package/dist/cjs/lib/v3/v3.js.map +1 -1
  54. package/dist/cjs/tests/integration/chrome-newtab-page-tracking.spec.d.ts +1 -0
  55. package/dist/cjs/tests/integration/chrome-newtab-page-tracking.spec.js +56 -0
  56. package/dist/cjs/tests/integration/chrome-newtab-page-tracking.spec.js.map +1 -0
  57. package/dist/cjs/tests/integration/flowLogger.spec.js +12 -8
  58. package/dist/cjs/tests/integration/flowLogger.spec.js.map +1 -1
  59. package/dist/cjs/tests/integration/testUtils.js +1 -1
  60. package/dist/cjs/tests/integration/testUtils.js.map +1 -1
  61. package/dist/cjs/tests/integration/timeouts.spec.js +6 -4
  62. package/dist/cjs/tests/integration/timeouts.spec.js.map +1 -1
  63. package/dist/cjs/tests/unit/agent-captcha-hooks.test.js +56 -0
  64. package/dist/cjs/tests/unit/agent-captcha-hooks.test.js.map +1 -1
  65. package/dist/cjs/tests/unit/agent-metrics.test.d.ts +1 -0
  66. package/dist/cjs/tests/unit/agent-metrics.test.js +112 -0
  67. package/dist/cjs/tests/unit/agent-metrics.test.js.map +1 -0
  68. package/dist/cjs/tests/unit/aisdk-clients.test.d.ts +1 -0
  69. package/dist/cjs/tests/unit/aisdk-clients.test.js +90 -0
  70. package/dist/cjs/tests/unit/aisdk-clients.test.js.map +1 -0
  71. package/dist/cjs/tests/unit/anthropic-cua-adaptive-thinking.test.d.ts +1 -0
  72. package/dist/cjs/tests/unit/anthropic-cua-adaptive-thinking.test.js +250 -0
  73. package/dist/cjs/tests/unit/anthropic-cua-adaptive-thinking.test.js.map +1 -0
  74. package/dist/cjs/tests/unit/api-optional-model-api-key.test.d.ts +1 -0
  75. package/dist/cjs/tests/unit/api-optional-model-api-key.test.js +95 -0
  76. package/dist/cjs/tests/unit/api-optional-model-api-key.test.js.map +1 -0
  77. package/dist/cjs/tests/unit/browserbase-session-accessors.test.js +20 -0
  78. package/dist/cjs/tests/unit/browserbase-session-accessors.test.js.map +1 -1
  79. package/dist/cjs/tests/unit/llm-middleware.test.d.ts +1 -0
  80. package/dist/cjs/tests/unit/llm-middleware.test.js +495 -0
  81. package/dist/cjs/tests/unit/llm-middleware.test.js.map +1 -0
  82. package/dist/cjs/tests/unit/microsoft-cua-client.test.d.ts +1 -0
  83. package/dist/cjs/tests/unit/microsoft-cua-client.test.js +86 -0
  84. package/dist/cjs/tests/unit/microsoft-cua-client.test.js.map +1 -0
  85. package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js +1 -0
  86. package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
  87. package/dist/esm/lib/inference.js +29 -22
  88. package/dist/esm/lib/inference.js.map +1 -1
  89. package/dist/esm/lib/prompt.js +18 -21
  90. package/dist/esm/lib/prompt.js.map +1 -1
  91. package/dist/esm/lib/v3/agent/AgentProvider.js +1 -0
  92. package/dist/esm/lib/v3/agent/AgentProvider.js.map +1 -1
  93. package/dist/esm/lib/v3/agent/AnthropicCUAClient.d.ts +3 -1
  94. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js +60 -9
  95. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  96. package/dist/esm/lib/v3/agent/MicrosoftCUAClient.js +15 -0
  97. package/dist/esm/lib/v3/agent/MicrosoftCUAClient.js.map +1 -1
  98. package/dist/esm/lib/v3/agent/OpenAICUAClient.d.ts +8 -2
  99. package/dist/esm/lib/v3/agent/OpenAICUAClient.js +103 -49
  100. package/dist/esm/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  101. package/dist/esm/lib/v3/agent/tools/index.js +1 -1
  102. package/dist/esm/lib/v3/agent/tools/index.js.map +1 -1
  103. package/dist/esm/lib/v3/agent/tools/keys.d.ts +2 -1
  104. package/dist/esm/lib/v3/agent/tools/keys.js +57 -49
  105. package/dist/esm/lib/v3/agent/tools/keys.js.map +1 -1
  106. package/dist/esm/lib/v3/agent/utils/coordinateNormalization.js +3 -5
  107. package/dist/esm/lib/v3/agent/utils/coordinateNormalization.js.map +1 -1
  108. package/dist/esm/lib/v3/api.d.ts +5 -3
  109. package/dist/esm/lib/v3/api.js +3 -6
  110. package/dist/esm/lib/v3/api.js.map +1 -1
  111. package/dist/esm/lib/v3/cache/AgentCache.js +5 -3
  112. package/dist/esm/lib/v3/cache/AgentCache.js.map +1 -1
  113. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js +6 -15
  114. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  115. package/dist/esm/lib/v3/index.d.ts +1 -1
  116. package/dist/esm/lib/v3/llm/LLMProvider.d.ts +5 -2
  117. package/dist/esm/lib/v3/llm/LLMProvider.js +15 -7
  118. package/dist/esm/lib/v3/llm/LLMProvider.js.map +1 -1
  119. package/dist/esm/lib/v3/llm/OpenAIClient.js +1 -0
  120. package/dist/esm/lib/v3/llm/OpenAIClient.js.map +1 -1
  121. package/dist/esm/lib/v3/llm/aisdk.d.ts +3 -1
  122. package/dist/esm/lib/v3/llm/aisdk.js +67 -17
  123. package/dist/esm/lib/v3/llm/aisdk.js.map +1 -1
  124. package/dist/esm/lib/v3/types/public/agent.d.ts +8 -3
  125. package/dist/esm/lib/v3/types/public/agent.js +1 -0
  126. package/dist/esm/lib/v3/types/public/agent.js.map +1 -1
  127. package/dist/esm/lib/v3/types/public/api.d.ts +30 -0
  128. package/dist/esm/lib/v3/types/public/api.js +6 -2
  129. package/dist/esm/lib/v3/types/public/api.js.map +1 -1
  130. package/dist/esm/lib/v3/types/public/model.d.ts +32 -2
  131. package/dist/esm/lib/v3/types/public/model.js.map +1 -1
  132. package/dist/esm/lib/v3/understudy/context.js +11 -3
  133. package/dist/esm/lib/v3/understudy/context.js.map +1 -1
  134. package/dist/esm/lib/v3/understudy/page.js +1 -1
  135. package/dist/esm/lib/v3/understudy/page.js.map +1 -1
  136. package/dist/esm/lib/v3/v3.d.ts +18 -2
  137. package/dist/esm/lib/v3/v3.js +92 -10
  138. package/dist/esm/lib/v3/v3.js.map +1 -1
  139. package/dist/esm/tests/integration/chrome-newtab-page-tracking.spec.d.ts +1 -0
  140. package/dist/esm/tests/integration/chrome-newtab-page-tracking.spec.js +54 -0
  141. package/dist/esm/tests/integration/chrome-newtab-page-tracking.spec.js.map +1 -0
  142. package/dist/esm/tests/integration/flowLogger.spec.js +12 -8
  143. package/dist/esm/tests/integration/flowLogger.spec.js.map +1 -1
  144. package/dist/esm/tests/integration/testUtils.js +1 -1
  145. package/dist/esm/tests/integration/testUtils.js.map +1 -1
  146. package/dist/esm/tests/integration/timeouts.spec.js +6 -4
  147. package/dist/esm/tests/integration/timeouts.spec.js.map +1 -1
  148. package/dist/esm/tests/unit/agent-captcha-hooks.test.js +56 -0
  149. package/dist/esm/tests/unit/agent-captcha-hooks.test.js.map +1 -1
  150. package/dist/esm/tests/unit/agent-metrics.test.d.ts +1 -0
  151. package/dist/esm/tests/unit/agent-metrics.test.js +110 -0
  152. package/dist/esm/tests/unit/agent-metrics.test.js.map +1 -0
  153. package/dist/esm/tests/unit/aisdk-clients.test.d.ts +1 -0
  154. package/dist/esm/tests/unit/aisdk-clients.test.js +88 -0
  155. package/dist/esm/tests/unit/aisdk-clients.test.js.map +1 -0
  156. package/dist/esm/tests/unit/anthropic-cua-adaptive-thinking.test.d.ts +1 -0
  157. package/dist/esm/tests/unit/anthropic-cua-adaptive-thinking.test.js +245 -0
  158. package/dist/esm/tests/unit/anthropic-cua-adaptive-thinking.test.js.map +1 -0
  159. package/dist/esm/tests/unit/api-optional-model-api-key.test.d.ts +1 -0
  160. package/dist/esm/tests/unit/api-optional-model-api-key.test.js +93 -0
  161. package/dist/esm/tests/unit/api-optional-model-api-key.test.js.map +1 -0
  162. package/dist/esm/tests/unit/browserbase-session-accessors.test.js +20 -0
  163. package/dist/esm/tests/unit/browserbase-session-accessors.test.js.map +1 -1
  164. package/dist/esm/tests/unit/llm-middleware.test.d.ts +1 -0
  165. package/dist/esm/tests/unit/llm-middleware.test.js +460 -0
  166. package/dist/esm/tests/unit/llm-middleware.test.js.map +1 -0
  167. package/dist/esm/tests/unit/microsoft-cua-client.test.d.ts +1 -0
  168. package/dist/esm/tests/unit/microsoft-cua-client.test.js +84 -0
  169. package/dist/esm/tests/unit/microsoft-cua-client.test.js.map +1 -0
  170. package/dist/esm/tests/unit/public-api/llm-and-agents.test.js +1 -0
  171. package/dist/esm/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
  172. package/package.json +4 -8
  173. package/dist/cjs/lib/v3/dom/build/rerender-index.js +0 -1
  174. package/dist/cjs/lib/v3/dom/build/v3-index.js +0 -1
  175. package/dist/esm/lib/v3/dom/build/rerender-index.js +0 -1
  176. package/dist/esm/lib/v3/dom/build/v3-index.js +0 -1
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const vitest_1 = require("vitest");
7
+ const AnthropicCUAClient_js_1 = require("../../lib/v3/agent/AnthropicCUAClient.js");
8
+ const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
9
+ // Mock the Anthropic SDK's beta.messages.create method
10
+ vitest_1.vi.mock("@anthropic-ai/sdk", () => {
11
+ const mockCreate = vitest_1.vi.fn().mockResolvedValue({
12
+ id: "test-id",
13
+ content: [{ type: "text", text: "test response" }],
14
+ usage: { input_tokens: 10, output_tokens: 20 },
15
+ });
16
+ return {
17
+ default: class MockAnthropic {
18
+ beta = {
19
+ messages: {
20
+ create: mockCreate,
21
+ },
22
+ };
23
+ },
24
+ };
25
+ });
26
+ (0, vitest_1.describe)("AnthropicCUAClient adaptive thinking", () => {
27
+ let mockCreate;
28
+ (0, vitest_1.beforeEach)(() => {
29
+ vitest_1.vi.clearAllMocks();
30
+ // Get the mock create function from a new instance
31
+ const anthropic = new sdk_1.default({ apiKey: "test" });
32
+ mockCreate = anthropic.beta.messages.create;
33
+ mockCreate.mockResolvedValue({
34
+ id: "test-id",
35
+ content: [{ type: "text", text: "test response" }],
36
+ usage: { input_tokens: 10, output_tokens: 20 },
37
+ });
38
+ });
39
+ (0, vitest_1.describe)("Claude 4.6 models (adaptive thinking)", () => {
40
+ (0, vitest_1.it)("should use thinking.type: 'adaptive' for claude-opus-4-6 when thinkingEffort is set", async () => {
41
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-opus-4-6", undefined, {
42
+ apiKey: "test-key",
43
+ thinkingEffort: "high",
44
+ });
45
+ client.setViewport(1280, 720);
46
+ await client.getAction([{ role: "user", content: "test" }]);
47
+ (0, vitest_1.expect)(mockCreate).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
48
+ thinking: { type: "adaptive" },
49
+ output_config: { effort: "high" },
50
+ temperature: 1,
51
+ }));
52
+ // Should NOT have budget_tokens
53
+ const callArgs = mockCreate.mock.calls[0][0];
54
+ (0, vitest_1.expect)(callArgs.thinking).not.toHaveProperty("budget_tokens");
55
+ });
56
+ (0, vitest_1.it)("should use thinking.type: 'adaptive' for claude-sonnet-4-6 when thinkingEffort is set", async () => {
57
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-sonnet-4-6", undefined, {
58
+ apiKey: "test-key",
59
+ thinkingEffort: "medium",
60
+ });
61
+ client.setViewport(1280, 720);
62
+ await client.getAction([{ role: "user", content: "test" }]);
63
+ (0, vitest_1.expect)(mockCreate).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
64
+ thinking: { type: "adaptive" },
65
+ output_config: { effort: "medium" },
66
+ temperature: 1,
67
+ }));
68
+ });
69
+ (0, vitest_1.it)("should support 'max' effort level for claude-opus-4-6", async () => {
70
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-opus-4-6", undefined, {
71
+ apiKey: "test-key",
72
+ thinkingEffort: "max",
73
+ });
74
+ client.setViewport(1280, 720);
75
+ await client.getAction([{ role: "user", content: "test" }]);
76
+ (0, vitest_1.expect)(mockCreate).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
77
+ thinking: { type: "adaptive" },
78
+ output_config: { effort: "max" },
79
+ temperature: 1,
80
+ }));
81
+ });
82
+ (0, vitest_1.it)("should support 'low' effort level", async () => {
83
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-sonnet-4-6", undefined, {
84
+ apiKey: "test-key",
85
+ thinkingEffort: "low",
86
+ });
87
+ client.setViewport(1280, 720);
88
+ await client.getAction([{ role: "user", content: "test" }]);
89
+ (0, vitest_1.expect)(mockCreate).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
90
+ thinking: { type: "adaptive" },
91
+ output_config: { effort: "low" },
92
+ temperature: 1,
93
+ }));
94
+ });
95
+ (0, vitest_1.it)("should default to adaptive thinking with 'medium' effort when thinkingEffort is not set for 4.6 models", async () => {
96
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-opus-4-6", undefined, {
97
+ apiKey: "test-key",
98
+ });
99
+ client.setViewport(1280, 720);
100
+ await client.getAction([{ role: "user", content: "test" }]);
101
+ (0, vitest_1.expect)(mockCreate).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
102
+ thinking: { type: "adaptive" },
103
+ output_config: { effort: "medium" },
104
+ temperature: 1,
105
+ }));
106
+ });
107
+ (0, vitest_1.it)("should set temperature to 1 when adaptive thinking is enabled", async () => {
108
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-opus-4-6", undefined, {
109
+ apiKey: "test-key",
110
+ thinkingEffort: "high",
111
+ });
112
+ client.setViewport(1280, 720);
113
+ await client.getAction([{ role: "user", content: "test" }]);
114
+ (0, vitest_1.expect)(mockCreate).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
115
+ temperature: 1,
116
+ }));
117
+ });
118
+ (0, vitest_1.it)("should set temperature to 1 for claude-sonnet-4-6 with adaptive thinking", async () => {
119
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-sonnet-4-6", undefined, {
120
+ apiKey: "test-key",
121
+ thinkingEffort: "low",
122
+ });
123
+ client.setViewport(1280, 720);
124
+ await client.getAction([{ role: "user", content: "test" }]);
125
+ (0, vitest_1.expect)(mockCreate).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
126
+ thinking: { type: "adaptive" },
127
+ output_config: { effort: "low" },
128
+ temperature: 1,
129
+ }));
130
+ });
131
+ (0, vitest_1.it)("should disable adaptive thinking when thinkingEffort is 'none'", async () => {
132
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-opus-4-6", undefined, {
133
+ apiKey: "test-key",
134
+ thinkingEffort: "none",
135
+ });
136
+ client.setViewport(1280, 720);
137
+ await client.getAction([{ role: "user", content: "test" }]);
138
+ const callArgs = mockCreate.mock.calls[0][0];
139
+ (0, vitest_1.expect)(callArgs.thinking).toBeUndefined();
140
+ (0, vitest_1.expect)(callArgs.output_config).toBeUndefined();
141
+ (0, vitest_1.expect)(callArgs.temperature).toBeUndefined();
142
+ });
143
+ (0, vitest_1.it)("should log a debug warning when thinkingBudget is set on a 4.6 model", async () => {
144
+ const logger = vitest_1.vi.fn();
145
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-opus-4-6", undefined, {
146
+ apiKey: "test-key",
147
+ thinkingBudget: 10000,
148
+ });
149
+ client.setViewport(1280, 720);
150
+ await client.getAction([{ role: "user", content: "test" }], logger);
151
+ (0, vitest_1.expect)(logger).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
152
+ category: "agent",
153
+ message: vitest_1.expect.stringContaining("thinkingBudget is ignored"),
154
+ level: 2,
155
+ }));
156
+ // Should still use adaptive thinking, not budget_tokens
157
+ const callArgs = mockCreate.mock.calls[0][0];
158
+ (0, vitest_1.expect)(callArgs.thinking).toEqual({ type: "adaptive" });
159
+ });
160
+ (0, vitest_1.it)("should log a debug warning when user-specified temperature is overridden", async () => {
161
+ const logger = vitest_1.vi.fn();
162
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-opus-4-6", undefined, {
163
+ apiKey: "test-key",
164
+ thinkingEffort: "high",
165
+ temperature: 0.5,
166
+ });
167
+ client.setViewport(1280, 720);
168
+ await client.getAction([{ role: "user", content: "test" }], logger);
169
+ (0, vitest_1.expect)(logger).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
170
+ category: "agent",
171
+ message: vitest_1.expect.stringContaining("overriding user-specified temperature=0.5"),
172
+ level: 2,
173
+ }));
174
+ // Temperature should still be forced to 1
175
+ const callArgs = mockCreate.mock.calls[0][0];
176
+ (0, vitest_1.expect)(callArgs.temperature).toBe(1);
177
+ });
178
+ });
179
+ (0, vitest_1.describe)("older Claude models (budget_tokens - deprecated)", () => {
180
+ (0, vitest_1.it)("should use thinking.type: 'enabled' with budget_tokens for claude-sonnet-4-5 when thinkingBudget is set", async () => {
181
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-sonnet-4-5-20250929", undefined, {
182
+ apiKey: "test-key",
183
+ thinkingBudget: 8000,
184
+ });
185
+ client.setViewport(1280, 720);
186
+ await client.getAction([{ role: "user", content: "test" }]);
187
+ (0, vitest_1.expect)(mockCreate).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
188
+ thinking: { type: "enabled", budget_tokens: 8000 },
189
+ }));
190
+ // Should NOT have output_config for older models
191
+ const callArgs = mockCreate.mock.calls[0][0];
192
+ (0, vitest_1.expect)(callArgs.output_config).toBeUndefined();
193
+ });
194
+ (0, vitest_1.it)("should use thinking.type: 'enabled' with budget_tokens for claude-opus-4-5 when thinkingBudget is set", async () => {
195
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-opus-4-5-20251101", undefined, {
196
+ apiKey: "test-key",
197
+ thinkingBudget: 10000,
198
+ });
199
+ client.setViewport(1280, 720);
200
+ await client.getAction([{ role: "user", content: "test" }]);
201
+ (0, vitest_1.expect)(mockCreate).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
202
+ thinking: { type: "enabled", budget_tokens: 10000 },
203
+ }));
204
+ });
205
+ (0, vitest_1.it)("should NOT force temperature to 1 for older models with budget_tokens", async () => {
206
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-sonnet-4-5-20250929", undefined, {
207
+ apiKey: "test-key",
208
+ thinkingBudget: 8000,
209
+ });
210
+ client.setViewport(1280, 720);
211
+ await client.getAction([{ role: "user", content: "test" }]);
212
+ const callArgs = mockCreate.mock.calls[0][0];
213
+ // Temperature should not be explicitly set to 1 for older models
214
+ (0, vitest_1.expect)(callArgs.temperature).toBeUndefined();
215
+ });
216
+ });
217
+ (0, vitest_1.describe)("model detection", () => {
218
+ (0, vitest_1.it)("should detect claude-opus-4-6 as a 4.6 model", async () => {
219
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-opus-4-6", undefined, {
220
+ apiKey: "test-key",
221
+ thinkingEffort: "high",
222
+ });
223
+ client.setViewport(1280, 720);
224
+ await client.getAction([{ role: "user", content: "test" }]);
225
+ const callArgs = mockCreate.mock.calls[0][0];
226
+ (0, vitest_1.expect)(callArgs.thinking.type).toBe("adaptive");
227
+ });
228
+ (0, vitest_1.it)("should detect claude-sonnet-4-6 as a 4.6 model", async () => {
229
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "claude-sonnet-4-6", undefined, {
230
+ apiKey: "test-key",
231
+ thinkingEffort: "high",
232
+ });
233
+ client.setViewport(1280, 720);
234
+ await client.getAction([{ role: "user", content: "test" }]);
235
+ const callArgs = mockCreate.mock.calls[0][0];
236
+ (0, vitest_1.expect)(callArgs.thinking.type).toBe("adaptive");
237
+ });
238
+ (0, vitest_1.it)("should handle provider-prefixed model names (anthropic/claude-opus-4-6)", async () => {
239
+ const client = new AnthropicCUAClient_js_1.AnthropicCUAClient("anthropic", "anthropic/claude-opus-4-6", undefined, {
240
+ apiKey: "test-key",
241
+ thinkingEffort: "high",
242
+ });
243
+ client.setViewport(1280, 720);
244
+ await client.getAction([{ role: "user", content: "test" }]);
245
+ const callArgs = mockCreate.mock.calls[0][0];
246
+ (0, vitest_1.expect)(callArgs.thinking.type).toBe("adaptive");
247
+ });
248
+ });
249
+ });
250
+ //# sourceMappingURL=anthropic-cua-adaptive-thinking.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-cua-adaptive-thinking.test.js","sourceRoot":"","sources":["../../../../tests/unit/anthropic-cua-adaptive-thinking.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it, vi, beforeEach } from \"vitest\";\nimport { AnthropicCUAClient } from \"../../lib/v3/agent/AnthropicCUAClient.js\";\nimport Anthropic from \"@anthropic-ai/sdk\";\n\n// Mock the Anthropic SDK's beta.messages.create method\nvi.mock(\"@anthropic-ai/sdk\", () => {\n const mockCreate = vi.fn().mockResolvedValue({\n id: \"test-id\",\n content: [{ type: \"text\", text: \"test response\" }],\n usage: { input_tokens: 10, output_tokens: 20 },\n });\n\n return {\n default: class MockAnthropic {\n beta = {\n messages: {\n create: mockCreate,\n },\n };\n },\n };\n});\n\ndescribe(\"AnthropicCUAClient adaptive thinking\", () => {\n let mockCreate: ReturnType<typeof vi.fn>;\n\n beforeEach(() => {\n vi.clearAllMocks();\n // Get the mock create function from a new instance\n const anthropic = new Anthropic({ apiKey: \"test\" });\n mockCreate = anthropic.beta.messages.create as ReturnType<typeof vi.fn>;\n mockCreate.mockResolvedValue({\n id: \"test-id\",\n content: [{ type: \"text\", text: \"test response\" }],\n usage: { input_tokens: 10, output_tokens: 20 },\n });\n });\n\n describe(\"Claude 4.6 models (adaptive thinking)\", () => {\n it(\"should use thinking.type: 'adaptive' for claude-opus-4-6 when thinkingEffort is set\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-opus-4-6\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingEffort: \"high\",\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n expect(mockCreate).toHaveBeenCalledWith(\n expect.objectContaining({\n thinking: { type: \"adaptive\" },\n output_config: { effort: \"high\" },\n temperature: 1,\n }),\n );\n\n // Should NOT have budget_tokens\n const callArgs = mockCreate.mock.calls[0][0];\n expect(callArgs.thinking).not.toHaveProperty(\"budget_tokens\");\n });\n\n it(\"should use thinking.type: 'adaptive' for claude-sonnet-4-6 when thinkingEffort is set\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-sonnet-4-6\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingEffort: \"medium\",\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n expect(mockCreate).toHaveBeenCalledWith(\n expect.objectContaining({\n thinking: { type: \"adaptive\" },\n output_config: { effort: \"medium\" },\n temperature: 1,\n }),\n );\n });\n\n it(\"should support 'max' effort level for claude-opus-4-6\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-opus-4-6\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingEffort: \"max\",\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n expect(mockCreate).toHaveBeenCalledWith(\n expect.objectContaining({\n thinking: { type: \"adaptive\" },\n output_config: { effort: \"max\" },\n temperature: 1,\n }),\n );\n });\n\n it(\"should support 'low' effort level\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-sonnet-4-6\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingEffort: \"low\",\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n expect(mockCreate).toHaveBeenCalledWith(\n expect.objectContaining({\n thinking: { type: \"adaptive\" },\n output_config: { effort: \"low\" },\n temperature: 1,\n }),\n );\n });\n\n it(\"should default to adaptive thinking with 'medium' effort when thinkingEffort is not set for 4.6 models\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-opus-4-6\",\n undefined,\n {\n apiKey: \"test-key\",\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n expect(mockCreate).toHaveBeenCalledWith(\n expect.objectContaining({\n thinking: { type: \"adaptive\" },\n output_config: { effort: \"medium\" },\n temperature: 1,\n }),\n );\n });\n\n it(\"should set temperature to 1 when adaptive thinking is enabled\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-opus-4-6\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingEffort: \"high\",\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n expect(mockCreate).toHaveBeenCalledWith(\n expect.objectContaining({\n temperature: 1,\n }),\n );\n });\n\n it(\"should set temperature to 1 for claude-sonnet-4-6 with adaptive thinking\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-sonnet-4-6\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingEffort: \"low\",\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n expect(mockCreate).toHaveBeenCalledWith(\n expect.objectContaining({\n thinking: { type: \"adaptive\" },\n output_config: { effort: \"low\" },\n temperature: 1,\n }),\n );\n });\n\n it(\"should disable adaptive thinking when thinkingEffort is 'none'\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-opus-4-6\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingEffort: \"none\",\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n const callArgs = mockCreate.mock.calls[0][0];\n expect(callArgs.thinking).toBeUndefined();\n expect(callArgs.output_config).toBeUndefined();\n expect(callArgs.temperature).toBeUndefined();\n });\n\n it(\"should log a debug warning when thinkingBudget is set on a 4.6 model\", async () => {\n const logger = vi.fn();\n\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-opus-4-6\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingBudget: 10000,\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }], logger);\n\n expect(logger).toHaveBeenCalledWith(\n expect.objectContaining({\n category: \"agent\",\n message: expect.stringContaining(\"thinkingBudget is ignored\"),\n level: 2,\n }),\n );\n\n // Should still use adaptive thinking, not budget_tokens\n const callArgs = mockCreate.mock.calls[0][0];\n expect(callArgs.thinking).toEqual({ type: \"adaptive\" });\n });\n\n it(\"should log a debug warning when user-specified temperature is overridden\", async () => {\n const logger = vi.fn();\n\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-opus-4-6\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingEffort: \"high\",\n temperature: 0.5,\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }], logger);\n\n expect(logger).toHaveBeenCalledWith(\n expect.objectContaining({\n category: \"agent\",\n message: expect.stringContaining(\n \"overriding user-specified temperature=0.5\",\n ),\n level: 2,\n }),\n );\n\n // Temperature should still be forced to 1\n const callArgs = mockCreate.mock.calls[0][0];\n expect(callArgs.temperature).toBe(1);\n });\n });\n\n describe(\"older Claude models (budget_tokens - deprecated)\", () => {\n it(\"should use thinking.type: 'enabled' with budget_tokens for claude-sonnet-4-5 when thinkingBudget is set\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-sonnet-4-5-20250929\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingBudget: 8000,\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n expect(mockCreate).toHaveBeenCalledWith(\n expect.objectContaining({\n thinking: { type: \"enabled\", budget_tokens: 8000 },\n }),\n );\n\n // Should NOT have output_config for older models\n const callArgs = mockCreate.mock.calls[0][0];\n expect(callArgs.output_config).toBeUndefined();\n });\n\n it(\"should use thinking.type: 'enabled' with budget_tokens for claude-opus-4-5 when thinkingBudget is set\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-opus-4-5-20251101\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingBudget: 10000,\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n expect(mockCreate).toHaveBeenCalledWith(\n expect.objectContaining({\n thinking: { type: \"enabled\", budget_tokens: 10000 },\n }),\n );\n });\n\n it(\"should NOT force temperature to 1 for older models with budget_tokens\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-sonnet-4-5-20250929\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingBudget: 8000,\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n const callArgs = mockCreate.mock.calls[0][0];\n // Temperature should not be explicitly set to 1 for older models\n expect(callArgs.temperature).toBeUndefined();\n });\n });\n\n describe(\"model detection\", () => {\n it(\"should detect claude-opus-4-6 as a 4.6 model\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-opus-4-6\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingEffort: \"high\",\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n const callArgs = mockCreate.mock.calls[0][0];\n expect(callArgs.thinking.type).toBe(\"adaptive\");\n });\n\n it(\"should detect claude-sonnet-4-6 as a 4.6 model\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"claude-sonnet-4-6\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingEffort: \"high\",\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n const callArgs = mockCreate.mock.calls[0][0];\n expect(callArgs.thinking.type).toBe(\"adaptive\");\n });\n\n it(\"should handle provider-prefixed model names (anthropic/claude-opus-4-6)\", async () => {\n const client = new AnthropicCUAClient(\n \"anthropic\",\n \"anthropic/claude-opus-4-6\",\n undefined,\n {\n apiKey: \"test-key\",\n thinkingEffort: \"high\",\n },\n );\n client.setViewport(1280, 720);\n\n await client.getAction([{ role: \"user\", content: \"test\" }]);\n\n const callArgs = mockCreate.mock.calls[0][0];\n expect(callArgs.thinking.type).toBe(\"adaptive\");\n });\n });\n});\n"]}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const api_1 = require("../../lib/v3/api");
5
+ /**
6
+ * Tests that modelApiKey is optional when calling StagehandAPIClient.init().
7
+ *
8
+ * Previously, init() would throw "modelApiKey is required" if the key was not
9
+ * provided. After the fix, sessions can be started without a model API key
10
+ * (the server may provide its own key or the user may not need one).
11
+ * When provided, the key should still be sent via the x-model-api-key header.
12
+ */
13
+ (0, vitest_1.describe)("StagehandAPIClient - optional modelApiKey", () => {
14
+ const logger = vitest_1.vi.fn();
15
+ // We mock fetch to avoid real network calls; we just need to verify
16
+ // that init() doesn't throw when modelApiKey is omitted and that
17
+ // the header is conditionally included.
18
+ let originalFetch;
19
+ function createSessionStartResponse(sessionId) {
20
+ return new Response(JSON.stringify({
21
+ success: true,
22
+ data: { sessionId, available: true },
23
+ }), {
24
+ status: 200,
25
+ headers: { "Content-Type": "application/json" },
26
+ });
27
+ }
28
+ (0, vitest_1.beforeEach)(() => {
29
+ originalFetch = globalThis.fetch;
30
+ });
31
+ (0, vitest_1.afterEach)(() => {
32
+ globalThis.fetch = originalFetch;
33
+ vitest_1.vi.restoreAllMocks();
34
+ });
35
+ (0, vitest_1.it)("should NOT throw when modelApiKey is omitted", async () => {
36
+ globalThis.fetch = vitest_1.vi
37
+ .fn()
38
+ .mockResolvedValue(createSessionStartResponse("sess-123"));
39
+ const client = new api_1.StagehandAPIClient({
40
+ apiKey: "test-api-key",
41
+ logger,
42
+ });
43
+ // Should not throw "modelApiKey is required"
44
+ await (0, vitest_1.expect)(client.init({
45
+ modelName: "openai/gpt-4.1-mini",
46
+ })).resolves.toBeDefined();
47
+ });
48
+ (0, vitest_1.it)("should NOT throw when modelApiKey is undefined", async () => {
49
+ globalThis.fetch = vitest_1.vi
50
+ .fn()
51
+ .mockResolvedValue(createSessionStartResponse("sess-456"));
52
+ const client = new api_1.StagehandAPIClient({
53
+ apiKey: "test-api-key",
54
+ logger,
55
+ });
56
+ await (0, vitest_1.expect)(client.init({
57
+ modelName: "openai/gpt-4.1-mini",
58
+ modelApiKey: undefined,
59
+ })).resolves.toBeDefined();
60
+ });
61
+ (0, vitest_1.it)("should send x-model-api-key header when modelApiKey IS provided", async () => {
62
+ const fetchSpy = vitest_1.vi
63
+ .fn()
64
+ .mockResolvedValue(createSessionStartResponse("sess-789"));
65
+ globalThis.fetch = fetchSpy;
66
+ const client = new api_1.StagehandAPIClient({
67
+ apiKey: "test-api-key",
68
+ logger,
69
+ });
70
+ await client.init({
71
+ modelName: "openai/gpt-4.1-mini",
72
+ modelApiKey: "my-model-key",
73
+ });
74
+ // Verify the fetch was called with x-model-api-key header
75
+ const [, requestInit] = fetchSpy.mock.calls[0];
76
+ (0, vitest_1.expect)(requestInit.headers["x-model-api-key"]).toBe("my-model-key");
77
+ });
78
+ (0, vitest_1.it)("should NOT send x-model-api-key header when modelApiKey is omitted", async () => {
79
+ const fetchSpy = vitest_1.vi
80
+ .fn()
81
+ .mockResolvedValue(createSessionStartResponse("sess-012"));
82
+ globalThis.fetch = fetchSpy;
83
+ const client = new api_1.StagehandAPIClient({
84
+ apiKey: "test-api-key",
85
+ logger,
86
+ });
87
+ await client.init({
88
+ modelName: "openai/gpt-4.1-mini",
89
+ });
90
+ // Verify x-model-api-key header is NOT present
91
+ const [, requestInit] = fetchSpy.mock.calls[0];
92
+ (0, vitest_1.expect)(requestInit.headers["x-model-api-key"]).toBeUndefined();
93
+ });
94
+ });
95
+ //# sourceMappingURL=api-optional-model-api-key.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-optional-model-api-key.test.js","sourceRoot":"","sources":["../../../../tests/unit/api-optional-model-api-key.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it, vi, beforeEach, afterEach } from \"vitest\";\nimport { StagehandAPIClient } from \"../../lib/v3/api\";\n\n/**\n * Tests that modelApiKey is optional when calling StagehandAPIClient.init().\n *\n * Previously, init() would throw \"modelApiKey is required\" if the key was not\n * provided. After the fix, sessions can be started without a model API key\n * (the server may provide its own key or the user may not need one).\n * When provided, the key should still be sent via the x-model-api-key header.\n */\ndescribe(\"StagehandAPIClient - optional modelApiKey\", () => {\n const logger = vi.fn();\n\n // We mock fetch to avoid real network calls; we just need to verify\n // that init() doesn't throw when modelApiKey is omitted and that\n // the header is conditionally included.\n let originalFetch: typeof globalThis.fetch;\n\n function createSessionStartResponse(sessionId: string) {\n return new Response(\n JSON.stringify({\n success: true,\n data: { sessionId, available: true },\n }),\n {\n status: 200,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n\n beforeEach(() => {\n originalFetch = globalThis.fetch;\n });\n\n afterEach(() => {\n globalThis.fetch = originalFetch;\n vi.restoreAllMocks();\n });\n\n it(\"should NOT throw when modelApiKey is omitted\", async () => {\n globalThis.fetch = vi\n .fn()\n .mockResolvedValue(createSessionStartResponse(\"sess-123\"));\n\n const client = new StagehandAPIClient({\n apiKey: \"test-api-key\",\n logger,\n });\n\n // Should not throw \"modelApiKey is required\"\n await expect(\n client.init({\n modelName: \"openai/gpt-4.1-mini\",\n }),\n ).resolves.toBeDefined();\n });\n\n it(\"should NOT throw when modelApiKey is undefined\", async () => {\n globalThis.fetch = vi\n .fn()\n .mockResolvedValue(createSessionStartResponse(\"sess-456\"));\n\n const client = new StagehandAPIClient({\n apiKey: \"test-api-key\",\n logger,\n });\n\n await expect(\n client.init({\n modelName: \"openai/gpt-4.1-mini\",\n modelApiKey: undefined,\n }),\n ).resolves.toBeDefined();\n });\n\n it(\"should send x-model-api-key header when modelApiKey IS provided\", async () => {\n const fetchSpy = vi\n .fn()\n .mockResolvedValue(createSessionStartResponse(\"sess-789\"));\n globalThis.fetch = fetchSpy;\n\n const client = new StagehandAPIClient({\n apiKey: \"test-api-key\",\n logger,\n });\n\n await client.init({\n modelName: \"openai/gpt-4.1-mini\",\n modelApiKey: \"my-model-key\",\n });\n\n // Verify the fetch was called with x-model-api-key header\n const [, requestInit] = fetchSpy.mock.calls[0];\n expect(requestInit.headers[\"x-model-api-key\"]).toBe(\"my-model-key\");\n });\n\n it(\"should NOT send x-model-api-key header when modelApiKey is omitted\", async () => {\n const fetchSpy = vi\n .fn()\n .mockResolvedValue(createSessionStartResponse(\"sess-012\"));\n globalThis.fetch = fetchSpy;\n\n const client = new StagehandAPIClient({\n apiKey: \"test-api-key\",\n logger,\n });\n\n await client.init({\n modelName: \"openai/gpt-4.1-mini\",\n });\n\n // Verify x-model-api-key header is NOT present\n const [, requestInit] = fetchSpy.mock.calls[0];\n expect(requestInit.headers[\"x-model-api-key\"]).toBeUndefined();\n });\n});\n"]}
@@ -98,6 +98,26 @@ vitest_1.vi.mock("../../lib/v3/launch/local", () => ({
98
98
  await v3.close().catch(() => { });
99
99
  }
100
100
  });
101
+ (0, vitest_1.it)("treats verified Browserbase sessions as managed fingerprinting mode", async () => {
102
+ const v3 = new v3_js_1.V3({
103
+ env: "BROWSERBASE",
104
+ disableAPI: true,
105
+ verbose: 0,
106
+ browserbaseSessionCreateParams: {
107
+ browserSettings: {
108
+ verified: true,
109
+ },
110
+ },
111
+ });
112
+ try {
113
+ await v3.init();
114
+ (0, vitest_1.expect)(v3.isVerified).toBe(true);
115
+ (0, vitest_1.expect)(v3.isAdvancedStealth).toBe(true);
116
+ }
117
+ finally {
118
+ await v3.close().catch(() => { });
119
+ }
120
+ });
101
121
  });
102
122
  (0, vitest_1.describe)("local accessors", () => {
103
123
  (0, vitest_1.it)("stay empty for LOCAL environments", async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"browserbase-session-accessors.test.js","sourceRoot":"","sources":["../../../../tests/unit/browserbase-session-accessors.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it, vi, beforeEach, afterEach } from \"vitest\";\nimport { V3 } from \"../../lib/v3/v3.js\";\n\nconst MOCK_SESSION_ID = \"session-123\";\nconst MOCK_SESSION_URL = `https://www.browserbase.com/sessions/${MOCK_SESSION_ID}`;\nconst MOCK_DEBUG_URL = `https://debug.browserbase.com/${MOCK_SESSION_ID}`;\n\nvi.mock(\"../../lib/v3/understudy/context\", () => {\n class MockConnection {\n onTransportClosed = vi.fn();\n offTransportClosed = vi.fn();\n send = vi.fn(async () => {});\n }\n\n class MockV3Context {\n static async create(): Promise<MockV3Context> {\n return new MockV3Context();\n }\n\n conn = new MockConnection();\n\n pages(): never[] {\n return [];\n }\n\n async close(): Promise<void> {\n // noop\n }\n }\n\n return { V3Context: MockV3Context };\n});\n\nvi.mock(\"../../lib/v3/launch/browserbase\", () => ({\n createBrowserbaseSession: vi.fn(async () => ({\n ws: \"wss://mock-browserbase\",\n sessionId: MOCK_SESSION_ID,\n bb: {\n sessions: {\n debug: vi.fn(async () => ({ debuggerUrl: MOCK_DEBUG_URL })),\n },\n },\n })),\n}));\n\nvi.mock(\"../../lib/v3/launch/local\", () => ({\n launchLocalChrome: vi.fn(async () => ({\n ws: \"ws://local-cdp\",\n chrome: { kill: vi.fn(async () => {}) },\n })),\n}));\n\ndescribe(\"browserbase accessors\", () => {\n beforeEach(() => {\n process.env.BROWSERBASE_API_KEY = \"fake-key\";\n process.env.BROWSERBASE_PROJECT_ID = \"fake-project\";\n });\n\n afterEach(() => {\n delete process.env.BROWSERBASE_API_KEY;\n delete process.env.BROWSERBASE_PROJECT_ID;\n vi.clearAllMocks();\n });\n\n it(\"exposes Browserbase session and debug URLs after init\", async () => {\n const v3 = new V3({\n env: \"BROWSERBASE\",\n disableAPI: true,\n verbose: 0,\n });\n\n try {\n await v3.init();\n\n expect(v3.browserbaseSessionURL).toBe(MOCK_SESSION_URL);\n expect(v3.browserbaseDebugURL).toBe(MOCK_DEBUG_URL);\n expect(v3.isCaptchaAutoSolveEnabled).toBe(true);\n } finally {\n await v3.close().catch(() => {});\n }\n });\n\n it(\"clears stored URLs after close\", async () => {\n const v3 = new V3({\n env: \"BROWSERBASE\",\n disableAPI: true,\n verbose: 0,\n });\n\n await v3.init();\n await v3.close();\n\n expect(v3.browserbaseSessionURL).toBeUndefined();\n expect(v3.browserbaseDebugURL).toBeUndefined();\n });\n\n it(\"disables captcha solving when solveCaptchas is explicitly false\", async () => {\n const v3 = new V3({\n env: \"BROWSERBASE\",\n disableAPI: true,\n verbose: 0,\n browserbaseSessionCreateParams: {\n browserSettings: {\n solveCaptchas: false,\n },\n },\n });\n\n try {\n await v3.init();\n expect(v3.isCaptchaAutoSolveEnabled).toBe(false);\n } finally {\n await v3.close().catch(() => {});\n }\n });\n});\n\ndescribe(\"local accessors\", () => {\n it(\"stay empty for LOCAL environments\", async () => {\n const v3 = new V3({\n env: \"LOCAL\",\n disableAPI: true,\n verbose: 0,\n localBrowserLaunchOptions: {\n cdpUrl: \"ws://local-existing-session\",\n },\n });\n\n try {\n await v3.init();\n expect(v3.browserbaseSessionURL).toBeUndefined();\n expect(v3.browserbaseDebugURL).toBeUndefined();\n } finally {\n await v3.close().catch(() => {});\n }\n });\n});\n"]}
1
+ {"version":3,"file":"browserbase-session-accessors.test.js","sourceRoot":"","sources":["../../../../tests/unit/browserbase-session-accessors.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it, vi, beforeEach, afterEach } from \"vitest\";\nimport { V3 } from \"../../lib/v3/v3.js\";\n\nconst MOCK_SESSION_ID = \"session-123\";\nconst MOCK_SESSION_URL = `https://www.browserbase.com/sessions/${MOCK_SESSION_ID}`;\nconst MOCK_DEBUG_URL = `https://debug.browserbase.com/${MOCK_SESSION_ID}`;\n\nvi.mock(\"../../lib/v3/understudy/context\", () => {\n class MockConnection {\n onTransportClosed = vi.fn();\n offTransportClosed = vi.fn();\n send = vi.fn(async () => {});\n }\n\n class MockV3Context {\n static async create(): Promise<MockV3Context> {\n return new MockV3Context();\n }\n\n conn = new MockConnection();\n\n pages(): never[] {\n return [];\n }\n\n async close(): Promise<void> {\n // noop\n }\n }\n\n return { V3Context: MockV3Context };\n});\n\nvi.mock(\"../../lib/v3/launch/browserbase\", () => ({\n createBrowserbaseSession: vi.fn(async () => ({\n ws: \"wss://mock-browserbase\",\n sessionId: MOCK_SESSION_ID,\n bb: {\n sessions: {\n debug: vi.fn(async () => ({ debuggerUrl: MOCK_DEBUG_URL })),\n },\n },\n })),\n}));\n\nvi.mock(\"../../lib/v3/launch/local\", () => ({\n launchLocalChrome: vi.fn(async () => ({\n ws: \"ws://local-cdp\",\n chrome: { kill: vi.fn(async () => {}) },\n })),\n}));\n\ndescribe(\"browserbase accessors\", () => {\n beforeEach(() => {\n process.env.BROWSERBASE_API_KEY = \"fake-key\";\n process.env.BROWSERBASE_PROJECT_ID = \"fake-project\";\n });\n\n afterEach(() => {\n delete process.env.BROWSERBASE_API_KEY;\n delete process.env.BROWSERBASE_PROJECT_ID;\n vi.clearAllMocks();\n });\n\n it(\"exposes Browserbase session and debug URLs after init\", async () => {\n const v3 = new V3({\n env: \"BROWSERBASE\",\n disableAPI: true,\n verbose: 0,\n });\n\n try {\n await v3.init();\n\n expect(v3.browserbaseSessionURL).toBe(MOCK_SESSION_URL);\n expect(v3.browserbaseDebugURL).toBe(MOCK_DEBUG_URL);\n expect(v3.isCaptchaAutoSolveEnabled).toBe(true);\n } finally {\n await v3.close().catch(() => {});\n }\n });\n\n it(\"clears stored URLs after close\", async () => {\n const v3 = new V3({\n env: \"BROWSERBASE\",\n disableAPI: true,\n verbose: 0,\n });\n\n await v3.init();\n await v3.close();\n\n expect(v3.browserbaseSessionURL).toBeUndefined();\n expect(v3.browserbaseDebugURL).toBeUndefined();\n });\n\n it(\"disables captcha solving when solveCaptchas is explicitly false\", async () => {\n const v3 = new V3({\n env: \"BROWSERBASE\",\n disableAPI: true,\n verbose: 0,\n browserbaseSessionCreateParams: {\n browserSettings: {\n solveCaptchas: false,\n },\n },\n });\n\n try {\n await v3.init();\n expect(v3.isCaptchaAutoSolveEnabled).toBe(false);\n } finally {\n await v3.close().catch(() => {});\n }\n });\n\n it(\"treats verified Browserbase sessions as managed fingerprinting mode\", async () => {\n const v3 = new V3({\n env: \"BROWSERBASE\",\n disableAPI: true,\n verbose: 0,\n browserbaseSessionCreateParams: {\n browserSettings: {\n verified: true,\n },\n },\n });\n\n try {\n await v3.init();\n expect(v3.isVerified).toBe(true);\n expect(v3.isAdvancedStealth).toBe(true);\n } finally {\n await v3.close().catch(() => {});\n }\n });\n});\n\ndescribe(\"local accessors\", () => {\n it(\"stay empty for LOCAL environments\", async () => {\n const v3 = new V3({\n env: \"LOCAL\",\n disableAPI: true,\n verbose: 0,\n localBrowserLaunchOptions: {\n cdpUrl: \"ws://local-existing-session\",\n },\n });\n\n try {\n await v3.init();\n expect(v3.browserbaseSessionURL).toBeUndefined();\n expect(v3.browserbaseDebugURL).toBeUndefined();\n } finally {\n await v3.close().catch(() => {});\n }\n });\n});\n"]}
@@ -0,0 +1 @@
1
+ export {};