@morphllm/morphsdk 0.2.171 → 0.2.173

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 (259) hide show
  1. package/dist/{chunk-SW527EQT.js → chunk-33ZRF6X3.js} +4 -4
  2. package/dist/{chunk-3BCKZKNK.js → chunk-3GNXTHHB.js} +2 -2
  3. package/dist/{chunk-IGQYZ2KH.js → chunk-3I4LCNWJ.js} +2 -2
  4. package/dist/{chunk-4324ZSCW.js → chunk-577P2AXE.js} +2 -2
  5. package/dist/{chunk-MZZMSL26.js → chunk-5RTWSAZ6.js} +2 -2
  6. package/dist/{chunk-JEDEBCZM.js → chunk-73DQQMGR.js} +8 -3
  7. package/dist/{chunk-JEDEBCZM.js.map → chunk-73DQQMGR.js.map} +1 -1
  8. package/dist/{chunk-3XRNC56L.js → chunk-7EUJ2AKS.js} +4 -4
  9. package/dist/{chunk-JLLIVBKY.js → chunk-ACWLQFYS.js} +30 -6
  10. package/dist/chunk-ACWLQFYS.js.map +1 -0
  11. package/dist/{chunk-IW4TYYG6.js → chunk-AZOSA7VT.js} +2 -2
  12. package/dist/{chunk-ZJQTTOHO.js → chunk-C3V5FHZI.js} +2 -2
  13. package/dist/{chunk-LL3EWDKD.js → chunk-CEZQSARX.js} +4 -4
  14. package/dist/{chunk-EFCDIESP.js → chunk-CV7SLK6R.js} +2 -2
  15. package/dist/{chunk-GLQWEINZ.js → chunk-EJ2CQO4V.js} +2 -2
  16. package/dist/{chunk-LE66XCOI.js → chunk-FN4ADWFQ.js} +27 -10
  17. package/dist/chunk-FN4ADWFQ.js.map +1 -0
  18. package/dist/{chunk-CMFY26F3.js → chunk-GESRH23M.js} +4 -4
  19. package/dist/{chunk-FQJCE2FX.js → chunk-I4FCFIBU.js} +29 -10
  20. package/dist/chunk-I4FCFIBU.js.map +1 -0
  21. package/dist/{chunk-JTUB5ZCT.js → chunk-JXJBF6CV.js} +2 -2
  22. package/dist/chunk-LKFZBBTD.js +12 -0
  23. package/dist/chunk-LKFZBBTD.js.map +1 -0
  24. package/dist/{chunk-2ALTBYMY.js → chunk-MQTMT4OR.js} +4 -4
  25. package/dist/{chunk-UK7TI7QY.js → chunk-NBKL7VWX.js} +101 -145
  26. package/dist/chunk-NBKL7VWX.js.map +1 -0
  27. package/dist/{chunk-C37YAYBK.js → chunk-QCFHQPHC.js} +2 -2
  28. package/dist/chunk-QE3SPHIM.js +120 -0
  29. package/dist/chunk-QE3SPHIM.js.map +1 -0
  30. package/dist/{chunk-TAS6S42A.js → chunk-QE6JHRVD.js} +2 -2
  31. package/dist/{chunk-Y6T4NA75.js → chunk-RXCHMNCY.js} +2 -2
  32. package/dist/{chunk-4MTZUTNH.js → chunk-S5R4H5HM.js} +23 -8
  33. package/dist/chunk-S5R4H5HM.js.map +1 -0
  34. package/dist/chunk-SM3OQZRS.js +142 -0
  35. package/dist/chunk-SM3OQZRS.js.map +1 -0
  36. package/dist/chunk-TS56XYWB.js +78 -0
  37. package/dist/chunk-TS56XYWB.js.map +1 -0
  38. package/dist/{chunk-5EUMJI3I.js → chunk-TW3XQET2.js} +2 -2
  39. package/dist/{chunk-OPNTDMHH.js → chunk-VLZ6PNAD.js} +4 -4
  40. package/dist/chunk-VZ7BOH2K.js +1 -0
  41. package/dist/chunk-VZ7BOH2K.js.map +1 -0
  42. package/dist/chunk-W6AGNJ5O.js +97 -0
  43. package/dist/chunk-W6AGNJ5O.js.map +1 -0
  44. package/dist/chunk-YGNPVOUO.js +158 -0
  45. package/dist/chunk-YGNPVOUO.js.map +1 -0
  46. package/dist/{chunk-2OAKX4SZ.js → chunk-Z3KRXUNG.js} +4 -4
  47. package/dist/chunk-ZFOR3LI4.js +24 -0
  48. package/dist/chunk-ZFOR3LI4.js.map +1 -0
  49. package/dist/{client-DsAAqupx.d.ts → client-Dh6yzCm4.d.ts} +14 -5
  50. package/dist/client.cjs +724 -523
  51. package/dist/client.cjs.map +1 -1
  52. package/dist/client.d.ts +5 -1
  53. package/dist/client.js +31 -27
  54. package/dist/core/client.cjs +540 -0
  55. package/dist/core/client.cjs.map +1 -0
  56. package/dist/core/client.d.ts +79 -0
  57. package/dist/core/client.js +12 -0
  58. package/dist/core/client.js.map +1 -0
  59. package/dist/core/error.cjs +309 -0
  60. package/dist/core/error.cjs.map +1 -0
  61. package/dist/core/error.d.ts +18 -0
  62. package/dist/core/error.js +10 -0
  63. package/dist/core/error.js.map +1 -0
  64. package/dist/core/index.cjs +552 -0
  65. package/dist/core/index.cjs.map +1 -0
  66. package/dist/core/index.d.ts +4 -0
  67. package/dist/core/index.js +20 -0
  68. package/dist/core/index.js.map +1 -0
  69. package/dist/core/resource.cjs +36 -0
  70. package/dist/core/resource.cjs.map +1 -0
  71. package/dist/core/resource.d.ts +18 -0
  72. package/dist/core/resource.js +8 -0
  73. package/dist/core/resource.js.map +1 -0
  74. package/dist/edge.cjs +236 -173
  75. package/dist/edge.cjs.map +1 -1
  76. package/dist/edge.d.ts +2 -0
  77. package/dist/edge.js +8 -5
  78. package/dist/git/client.cjs +529 -9
  79. package/dist/git/client.cjs.map +1 -1
  80. package/dist/git/client.d.ts +8 -2
  81. package/dist/git/client.js +7 -1
  82. package/dist/git/index.cjs +529 -9
  83. package/dist/git/index.cjs.map +1 -1
  84. package/dist/git/index.d.ts +2 -0
  85. package/dist/git/index.js +7 -1
  86. package/dist/index.cjs +672 -465
  87. package/dist/index.cjs.map +1 -1
  88. package/dist/index.d.ts +6 -2
  89. package/dist/index.js +49 -33
  90. package/dist/modelrouter/core.cjs +204 -125
  91. package/dist/modelrouter/core.cjs.map +1 -1
  92. package/dist/modelrouter/core.d.ts +36 -9
  93. package/dist/modelrouter/core.js +6 -3
  94. package/dist/modelrouter/index.cjs +204 -125
  95. package/dist/modelrouter/index.cjs.map +1 -1
  96. package/dist/modelrouter/index.d.ts +3 -0
  97. package/dist/modelrouter/index.js +6 -3
  98. package/dist/subagents/anthropic.cjs +268 -52
  99. package/dist/subagents/anthropic.cjs.map +1 -1
  100. package/dist/subagents/anthropic.js +10 -6
  101. package/dist/subagents/vercel.cjs +268 -52
  102. package/dist/subagents/vercel.cjs.map +1 -1
  103. package/dist/subagents/vercel.js +10 -6
  104. package/dist/tools/browser/anthropic.cjs +7 -2
  105. package/dist/tools/browser/anthropic.cjs.map +1 -1
  106. package/dist/tools/browser/anthropic.js +9 -6
  107. package/dist/tools/browser/core.cjs +162 -10
  108. package/dist/tools/browser/core.cjs.map +1 -1
  109. package/dist/tools/browser/core.d.ts +8 -2
  110. package/dist/tools/browser/core.js +8 -5
  111. package/dist/tools/browser/index.cjs +163 -11
  112. package/dist/tools/browser/index.cjs.map +1 -1
  113. package/dist/tools/browser/index.d.ts +2 -0
  114. package/dist/tools/browser/index.js +18 -15
  115. package/dist/tools/browser/index.js.map +1 -1
  116. package/dist/tools/browser/openai.cjs +7 -2
  117. package/dist/tools/browser/openai.cjs.map +1 -1
  118. package/dist/tools/browser/openai.js +9 -6
  119. package/dist/tools/browser/profiles/core.cjs +7 -2
  120. package/dist/tools/browser/profiles/core.cjs.map +1 -1
  121. package/dist/tools/browser/profiles/core.js +3 -3
  122. package/dist/tools/browser/profiles/index.cjs +7 -2
  123. package/dist/tools/browser/profiles/index.cjs.map +1 -1
  124. package/dist/tools/browser/profiles/index.js +3 -3
  125. package/dist/tools/browser/vercel.cjs +7 -2
  126. package/dist/tools/browser/vercel.cjs.map +1 -1
  127. package/dist/tools/browser/vercel.js +9 -6
  128. package/dist/tools/codebase_search/anthropic.cjs +162 -41
  129. package/dist/tools/codebase_search/anthropic.cjs.map +1 -1
  130. package/dist/tools/codebase_search/anthropic.js +7 -4
  131. package/dist/tools/codebase_search/core.cjs +195 -66
  132. package/dist/tools/codebase_search/core.cjs.map +1 -1
  133. package/dist/tools/codebase_search/core.d.ts +18 -7
  134. package/dist/tools/codebase_search/core.js +6 -3
  135. package/dist/tools/codebase_search/index.cjs +162 -41
  136. package/dist/tools/codebase_search/index.cjs.map +1 -1
  137. package/dist/tools/codebase_search/index.d.ts +2 -0
  138. package/dist/tools/codebase_search/index.js +13 -10
  139. package/dist/tools/codebase_search/openai.cjs +162 -41
  140. package/dist/tools/codebase_search/openai.cjs.map +1 -1
  141. package/dist/tools/codebase_search/openai.js +7 -4
  142. package/dist/tools/codebase_search/vercel.cjs +162 -41
  143. package/dist/tools/codebase_search/vercel.cjs.map +1 -1
  144. package/dist/tools/codebase_search/vercel.js +7 -4
  145. package/dist/tools/compact/core.cjs +551 -47
  146. package/dist/tools/compact/core.cjs.map +1 -1
  147. package/dist/tools/compact/core.d.ts +16 -3
  148. package/dist/tools/compact/core.js +7 -1
  149. package/dist/tools/compact/index.cjs +549 -47
  150. package/dist/tools/compact/index.cjs.map +1 -1
  151. package/dist/tools/compact/index.d.ts +2 -0
  152. package/dist/tools/compact/index.js +8 -2
  153. package/dist/tools/fastapply/anthropic.cjs +16 -2
  154. package/dist/tools/fastapply/anthropic.cjs.map +1 -1
  155. package/dist/tools/fastapply/anthropic.js +8 -4
  156. package/dist/tools/fastapply/apply.cjs +7 -2
  157. package/dist/tools/fastapply/apply.cjs.map +1 -1
  158. package/dist/tools/fastapply/apply.js +2 -2
  159. package/dist/tools/fastapply/core.cjs +242 -12
  160. package/dist/tools/fastapply/core.cjs.map +1 -1
  161. package/dist/tools/fastapply/core.d.ts +8 -2
  162. package/dist/tools/fastapply/core.js +7 -3
  163. package/dist/tools/fastapply/index.cjs +16 -2
  164. package/dist/tools/fastapply/index.cjs.map +1 -1
  165. package/dist/tools/fastapply/index.d.ts +2 -0
  166. package/dist/tools/fastapply/index.js +13 -9
  167. package/dist/tools/fastapply/openai.cjs +16 -2
  168. package/dist/tools/fastapply/openai.cjs.map +1 -1
  169. package/dist/tools/fastapply/openai.js +8 -4
  170. package/dist/tools/fastapply/vercel.cjs +16 -2
  171. package/dist/tools/fastapply/vercel.cjs.map +1 -1
  172. package/dist/tools/fastapply/vercel.js +8 -4
  173. package/dist/tools/index.cjs +16 -2
  174. package/dist/tools/index.cjs.map +1 -1
  175. package/dist/tools/index.d.ts +2 -0
  176. package/dist/tools/index.js +13 -9
  177. package/dist/tools/reflex/core.cjs +693 -0
  178. package/dist/tools/reflex/core.cjs.map +1 -0
  179. package/dist/tools/reflex/core.d.ts +53 -0
  180. package/dist/tools/reflex/core.js +16 -0
  181. package/dist/tools/reflex/core.js.map +1 -0
  182. package/dist/tools/reflex/index.cjs +693 -0
  183. package/dist/tools/reflex/index.cjs.map +1 -0
  184. package/dist/tools/reflex/index.d.ts +5 -0
  185. package/dist/tools/reflex/index.js +16 -0
  186. package/dist/tools/reflex/index.js.map +1 -0
  187. package/dist/tools/reflex/types.cjs +19 -0
  188. package/dist/tools/reflex/types.cjs.map +1 -0
  189. package/dist/tools/reflex/types.d.ts +114 -0
  190. package/dist/tools/reflex/types.js +1 -0
  191. package/dist/tools/reflex/types.js.map +1 -0
  192. package/dist/tools/utils/resilience.cjs +7 -2
  193. package/dist/tools/utils/resilience.cjs.map +1 -1
  194. package/dist/tools/utils/resilience.js +2 -2
  195. package/dist/tools/warp_grep/agent/runner.cjs +7 -2
  196. package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
  197. package/dist/tools/warp_grep/agent/runner.js +2 -2
  198. package/dist/tools/warp_grep/anthropic.cjs +268 -52
  199. package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
  200. package/dist/tools/warp_grep/anthropic.d.ts +2 -0
  201. package/dist/tools/warp_grep/anthropic.js +10 -6
  202. package/dist/tools/warp_grep/client.cjs +268 -52
  203. package/dist/tools/warp_grep/client.cjs.map +1 -1
  204. package/dist/tools/warp_grep/client.d.ts +8 -2
  205. package/dist/tools/warp_grep/client.js +9 -5
  206. package/dist/tools/warp_grep/gemini.cjs +268 -52
  207. package/dist/tools/warp_grep/gemini.cjs.map +1 -1
  208. package/dist/tools/warp_grep/gemini.d.ts +2 -0
  209. package/dist/tools/warp_grep/gemini.js +9 -5
  210. package/dist/tools/warp_grep/gemini.js.map +1 -1
  211. package/dist/tools/warp_grep/harness.js +5 -5
  212. package/dist/tools/warp_grep/index.cjs +268 -52
  213. package/dist/tools/warp_grep/index.cjs.map +1 -1
  214. package/dist/tools/warp_grep/index.d.ts +2 -0
  215. package/dist/tools/warp_grep/index.js +12 -8
  216. package/dist/tools/warp_grep/openai.cjs +268 -52
  217. package/dist/tools/warp_grep/openai.cjs.map +1 -1
  218. package/dist/tools/warp_grep/openai.d.ts +2 -0
  219. package/dist/tools/warp_grep/openai.js +10 -6
  220. package/dist/tools/warp_grep/providers/local.js +2 -2
  221. package/dist/tools/warp_grep/vercel.cjs +268 -52
  222. package/dist/tools/warp_grep/vercel.cjs.map +1 -1
  223. package/dist/tools/warp_grep/vercel.d.ts +2 -0
  224. package/dist/tools/warp_grep/vercel.js +10 -6
  225. package/dist/version.cjs +7 -2
  226. package/dist/version.cjs.map +1 -1
  227. package/dist/version.js +1 -1
  228. package/package.json +7 -2
  229. package/dist/chunk-4MTZUTNH.js.map +0 -1
  230. package/dist/chunk-FQJCE2FX.js.map +0 -1
  231. package/dist/chunk-H5WNI6R5.js +0 -102
  232. package/dist/chunk-H5WNI6R5.js.map +0 -1
  233. package/dist/chunk-JLLIVBKY.js.map +0 -1
  234. package/dist/chunk-KCFMXLZ7.js +0 -197
  235. package/dist/chunk-KCFMXLZ7.js.map +0 -1
  236. package/dist/chunk-LE66XCOI.js.map +0 -1
  237. package/dist/chunk-SCVWDNQP.js +0 -84
  238. package/dist/chunk-SCVWDNQP.js.map +0 -1
  239. package/dist/chunk-UK7TI7QY.js.map +0 -1
  240. /package/dist/{chunk-SW527EQT.js.map → chunk-33ZRF6X3.js.map} +0 -0
  241. /package/dist/{chunk-3BCKZKNK.js.map → chunk-3GNXTHHB.js.map} +0 -0
  242. /package/dist/{chunk-IGQYZ2KH.js.map → chunk-3I4LCNWJ.js.map} +0 -0
  243. /package/dist/{chunk-4324ZSCW.js.map → chunk-577P2AXE.js.map} +0 -0
  244. /package/dist/{chunk-MZZMSL26.js.map → chunk-5RTWSAZ6.js.map} +0 -0
  245. /package/dist/{chunk-3XRNC56L.js.map → chunk-7EUJ2AKS.js.map} +0 -0
  246. /package/dist/{chunk-IW4TYYG6.js.map → chunk-AZOSA7VT.js.map} +0 -0
  247. /package/dist/{chunk-ZJQTTOHO.js.map → chunk-C3V5FHZI.js.map} +0 -0
  248. /package/dist/{chunk-LL3EWDKD.js.map → chunk-CEZQSARX.js.map} +0 -0
  249. /package/dist/{chunk-EFCDIESP.js.map → chunk-CV7SLK6R.js.map} +0 -0
  250. /package/dist/{chunk-GLQWEINZ.js.map → chunk-EJ2CQO4V.js.map} +0 -0
  251. /package/dist/{chunk-CMFY26F3.js.map → chunk-GESRH23M.js.map} +0 -0
  252. /package/dist/{chunk-JTUB5ZCT.js.map → chunk-JXJBF6CV.js.map} +0 -0
  253. /package/dist/{chunk-2ALTBYMY.js.map → chunk-MQTMT4OR.js.map} +0 -0
  254. /package/dist/{chunk-C37YAYBK.js.map → chunk-QCFHQPHC.js.map} +0 -0
  255. /package/dist/{chunk-TAS6S42A.js.map → chunk-QE6JHRVD.js.map} +0 -0
  256. /package/dist/{chunk-Y6T4NA75.js.map → chunk-RXCHMNCY.js.map} +0 -0
  257. /package/dist/{chunk-5EUMJI3I.js.map → chunk-TW3XQET2.js.map} +0 -0
  258. /package/dist/{chunk-OPNTDMHH.js.map → chunk-VLZ6PNAD.js.map} +0 -0
  259. /package/dist/{chunk-2OAKX4SZ.js.map → chunk-Z3KRXUNG.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ProfilesClient
3
- } from "./chunk-4324ZSCW.js";
3
+ } from "./chunk-577P2AXE.js";
4
4
  import {
5
5
  buildEmbedCode,
6
6
  buildLiveIframe,
@@ -8,12 +8,18 @@ import {
8
8
  resolvePreset
9
9
  } from "./chunk-YTYCHRQ2.js";
10
10
  import {
11
- fetchWithRetry,
12
- withTimeout
13
- } from "./chunk-JTUB5ZCT.js";
11
+ MorphAPIClient
12
+ } from "./chunk-QE3SPHIM.js";
14
13
  import {
15
14
  logger
16
15
  } from "./chunk-F3NCFNUX.js";
16
+ import {
17
+ fetchWithRetry,
18
+ withTimeout
19
+ } from "./chunk-JXJBF6CV.js";
20
+ import {
21
+ APIResource
22
+ } from "./chunk-LKFZBBTD.js";
17
23
 
18
24
  // tools/browser/core.ts
19
25
  var DEFAULT_CONFIG = {
@@ -22,17 +28,30 @@ var DEFAULT_CONFIG = {
22
28
  // 10 minutes for complex tasks
23
29
  debug: false
24
30
  };
25
- var BrowserClient = class {
31
+ var BrowserClient = class extends APIResource {
26
32
  config;
27
33
  /**
28
34
  * Profile management - create and manage browser profiles for storing login state.
29
35
  */
30
36
  profiles;
31
- constructor(config = {}) {
32
- this.config = {
37
+ constructor(clientOrConfig = {}) {
38
+ const isClient = clientOrConfig instanceof MorphAPIClient;
39
+ super(
40
+ isClient ? clientOrConfig : new MorphAPIClient({
41
+ apiKey: clientOrConfig.apiKey,
42
+ browserURL: clientOrConfig.apiUrl,
43
+ timeout: clientOrConfig.timeout,
44
+ retryConfig: clientOrConfig.retryConfig,
45
+ debug: clientOrConfig.debug
46
+ })
47
+ );
48
+ this.config = isClient ? {
33
49
  ...DEFAULT_CONFIG,
34
- ...config
35
- };
50
+ apiUrl: clientOrConfig.browserURL,
51
+ apiKey: clientOrConfig.resolveApiKey(),
52
+ retryConfig: clientOrConfig.retryConfig,
53
+ debug: clientOrConfig.debug
54
+ } : { ...DEFAULT_CONFIG, ...clientOrConfig };
36
55
  this.profiles = new ProfilesClient(this.config);
37
56
  }
38
57
  /**
@@ -600,4 +619,4 @@ export {
600
619
  getWebp,
601
620
  checkHealth
602
621
  };
603
- //# sourceMappingURL=chunk-FQJCE2FX.js.map
622
+ //# sourceMappingURL=chunk-I4FCFIBU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../tools/browser/core.ts"],"sourcesContent":["/**\n * Core implementation for browser automation tasks\n */\n\nimport { fetchWithRetry, withTimeout } from '../utils/resilience.js';\nimport { logger } from '../../logger.js';\nimport type {\n BrowserConfig,\n BrowserTaskInput,\n BrowserTaskInputWithSchema,\n BrowserTaskResult,\n BrowserTaskWithPromise,\n BrowserTaskWithPromiseAndSchema,\n RecordingStatus,\n RecordingWithMethods,\n ErrorsResponse,\n LiveSessionOptions,\n IframeOptions,\n WebpOptions,\n WebpResponse,\n} from './types.js';\nimport { buildLiveUrl, buildLiveIframe, buildEmbedCode, resolvePreset } from './live.js';\nimport { ProfilesClient } from './profiles/core.js';\nimport { MorphAPIClient } from '../../core/client.js';\nimport { APIResource } from '../../core/resource.js';\n\nconst DEFAULT_CONFIG = {\n apiUrl: process.env.MORPH_ENVIRONMENT === 'DEV' \n ? 'http://localhost:8000'\n : 'https://browser.morphllm.com',\n timeout: 1000000, // 10 minutes for complex tasks\n debug: false,\n};\n\n/**\n * BrowserClient class for easier usage with instance configuration\n *\n * @deprecated Prefer the unified `MorphClient` (`new MorphClient({ apiKey }).browser`).\n * Standalone clients remain only for backwards compatibility and may be removed in a future\n * major version — do not use them in new code.\n */\nexport class BrowserClient extends APIResource {\n private config: BrowserConfig;\n\n /**\n * Profile management - create and manage browser profiles for storing login state.\n */\n public profiles: ProfilesClient;\n\n constructor(clientOrConfig: MorphAPIClient | BrowserConfig = {}) {\n const isClient = clientOrConfig instanceof MorphAPIClient;\n super(\n isClient\n ? clientOrConfig\n : new MorphAPIClient({\n apiKey: clientOrConfig.apiKey,\n browserURL: clientOrConfig.apiUrl,\n timeout: clientOrConfig.timeout,\n retryConfig: clientOrConfig.retryConfig,\n debug: clientOrConfig.debug,\n }),\n );\n // Browser is a distinct service: keep its own wire (raw fetch in the\n // module functions below) but source the host/key/retries from the shared\n // transport so configuration lives in one place.\n this.config = isClient\n ? {\n ...DEFAULT_CONFIG,\n apiUrl: clientOrConfig.browserURL,\n apiKey: clientOrConfig.resolveApiKey(),\n retryConfig: clientOrConfig.retryConfig,\n debug: clientOrConfig.debug,\n }\n : { ...DEFAULT_CONFIG, ...clientOrConfig };\n this.profiles = new ProfilesClient(this.config);\n }\n\n /**\n * Execute a browser automation task\n */\n async execute(input: BrowserTaskInput): Promise<BrowserTaskResult> {\n return executeBrowserTask(input, this.config);\n }\n\n async createTask(input: BrowserTaskInput): Promise<BrowserTaskWithPromise>;\n async createTask<T>(input: BrowserTaskInputWithSchema<T>): Promise<BrowserTaskWithPromiseAndSchema<T>>;\n async createTask<T>(\n input: BrowserTaskInput | BrowserTaskInputWithSchema<T>\n ): Promise<BrowserTaskWithPromise | BrowserTaskWithPromiseAndSchema<T>> {\n const apiUrl = this.config.apiUrl || DEFAULT_CONFIG.apiUrl;\n const debug = this.config.debug || false;\n \n const hasTask = typeof input.task === 'string' && input.task.trim().length > 0;\n const hasDiff = typeof (input as any).diff === 'string' && (input as any).diff.trim().length > 0;\n\n if (!hasTask && !hasDiff) {\n throw new Error('Browser task requires either \"task\" (natural language) or \"diff\" (PR-review planning)');\n }\n\n logger.debug('Browser', 'create_task', { task: (input.task ?? '').slice(0, 100), url: input.url, endpoint: `${apiUrl}/browser-task/async` });\n \n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.config.apiKey) headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n \n // Call ASYNC endpoint for immediate return with live URL\n const response = await fetch(`${apiUrl}/browser-task/async`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n task: input.task,\n diff: input.diff,\n url: input.url,\n max_steps: input.maxSteps ?? 10,\n model: input.model ?? 'morph-computer-use-v0',\n viewport_width: input.viewportWidth ?? 1280,\n viewport_height: input.viewportHeight ?? 720,\n external_id: input.externalId,\n repo_id: input.repoId,\n repo_full_name: input.repoFullName,\n commit_id: input.commitId,\n record_video: input.recordVideo ?? false,\n video_width: input.videoWidth ?? input.viewportWidth ?? 1280,\n video_height: input.videoHeight ?? input.viewportHeight ?? 720,\n allow_resizing: input.allowResizing ?? false,\n structured_output: 'schema' in input ? stringifyStructuredOutput(input.schema) : undefined,\n auth: input.auth,\n profile_id: input.profileId,\n force_query_params: input.forceQueryParams,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n logger.error('Browser', 'create_task_error', { status: response.status, error: errorText });\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n const result = mapTaskResult(await response.json());\n logger.debug('Browser', 'task_created', { recording_id: result.recordingId, task_id: result.taskId, debug_url: !!result.debugUrl });\n \n if ('schema' in input) {\n return wrapTaskResponseWithSchema(result, this.config, input.schema);\n } else {\n return wrapTaskResponse(result, this.config);\n }\n }\n\n /**\n * Execute task with recording and wait for video to be ready\n */\n async executeWithRecording(\n input: BrowserTaskInput & { recordVideo: true }\n ): Promise<BrowserTaskResult & { recording?: RecordingWithMethods }> {\n return executeWithRecording(input, this.config);\n }\n\n /**\n * Get recording status and URLs\n */\n async getRecording(recordingId: string): Promise<RecordingWithMethods> {\n return getRecording(recordingId, this.config);\n }\n\n /**\n * Wait for recording to complete with automatic polling\n */\n async waitForRecording(\n recordingId: string,\n options?: { timeout?: number; pollInterval?: number }\n ): Promise<RecordingWithMethods> {\n return waitForRecording(recordingId, this.config, options);\n }\n\n /**\n * Get errors from recording with screenshots\n */\n async getErrors(recordingId: string): Promise<ErrorsResponse> {\n return getErrors(recordingId, this.config);\n }\n\n /**\n * Get animated WebP preview of recording\n */\n async getWebp(\n recordingId: string,\n options?: WebpOptions\n ): Promise<WebpResponse> {\n return getWebp(recordingId, this.config, options);\n }\n\n /**\n * Check if browser worker service is healthy\n */\n async checkHealth(): Promise<{\n ok: boolean;\n google_configured: boolean;\n database_configured: boolean;\n s3_configured: boolean;\n error?: string;\n }> {\n return checkHealth(this.config);\n }\n}\n\n/**\n * Execute a natural language browser automation task\n * \n * Returns the full task result including rich agent history data (urls, errors, \n * action_history, judgement, etc.). When using this as an agent tool, use the\n * formatResult() functions from the SDK adapters to return a concise summary.\n * \n * @param input - Task parameters\n * @param config - Optional configuration (apiKey, apiUrl to override default)\n * @returns Task result with success status, findings, and comprehensive execution history\n * \n * @example\n * ```typescript\n * const result = await executeBrowserTask(\n * {\n * task: \"Test checkout flow for buying a pineapple\",\n * url: \"https://3000-abc.e2b.dev\",\n * maxSteps: 20,\n * repoId: \"my-project\",\n * commitId: \"uuid-here\"\n * },\n * {\n * apiKey: process.env.MORPH_API_KEY,\n * // apiUrl: 'http://localhost:8001' // Override for local testing\n * }\n * );\n * \n * if (result.success) {\n * console.log('Task completed:', result.result);\n * console.log('URLs visited:', result.urls);\n * console.log('Actions taken:', result.actionNames);\n * console.log('Has errors:', result.hasErrors);\n * console.log('Replay:', result.replayUrl);\n * }\n * ```\n */\nexport async function executeBrowserTask(\n input: BrowserTaskInput,\n config: BrowserConfig = {}\n): Promise<BrowserTaskResult> {\n const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n const timeout = config.timeout || DEFAULT_CONFIG.timeout;\n const debug = config.debug || false;\n\n if (!input.task || input.task.trim().length === 0) {\n return { \n success: false, \n error: 'Task description is required. Example: \"Go to example.com and click the login button\"' \n };\n }\n\n if (input.maxSteps !== undefined && (input.maxSteps < 1 || input.maxSteps > 50)) {\n return { \n success: false, \n error: 'maxSteps must be between 1 and 50. Use more steps for complex multi-page flows.'\n };\n }\n\n logger.debug('Browser', 'execute_start', { task: input.task.slice(0, 100), url: input.url, max_steps: input.maxSteps ?? 10, record_video: input.recordVideo ?? false });\n\n const startTime = Date.now();\n\n try {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (config.apiKey) headers['Authorization'] = `Bearer ${config.apiKey}`;\n\n const fetchPromise = fetchWithRetry(\n `${apiUrl}/browser-task`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify({\n task: input.task,\n url: input.url,\n max_steps: input.maxSteps ?? 10,\n model: input.model ?? 'morph-computer-use-v0',\n viewport_width: input.viewportWidth ?? 1280,\n viewport_height: input.viewportHeight ?? 720,\n external_id: input.externalId,\n repo_id: input.repoId,\n commit_id: input.commitId,\n record_video: input.recordVideo ?? false,\n video_width: input.videoWidth ?? input.viewportWidth ?? 1280,\n video_height: input.videoHeight ?? input.viewportHeight ?? 720,\n allow_resizing: input.allowResizing ?? false,\n structured_output: input.structuredOutput,\n auth: input.auth,\n profile_id: input.profileId,\n force_query_params: input.forceQueryParams,\n }),\n },\n config.retryConfig\n );\n\n const response = await withTimeout(\n fetchPromise,\n timeout,\n `Browser task timed out after ${timeout}ms. Consider increasing timeout or reducing maxSteps.`\n );\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n logger.error('Browser', 'execute_error', { status: response.status, error: errorText });\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n const result: BrowserTaskResult = mapTaskResult(await response.json());\n const elapsed = Date.now() - startTime;\n logger.debug('Browser', 'execute_complete', { success: result.success, latency_ms: elapsed, steps: result.stepsTaken ?? 0, recording_id: result.recordingId });\n\n return result;\n\n } catch (error) {\n if (error instanceof Error) {\n // Handle network errors\n if (error.message.includes('ECONNREFUSED') || error.message.includes('fetch failed')) {\n return {\n success: false,\n error: `Cannot connect to browser worker at ${apiUrl}. Ensure the service is running and accessible. For local dev, set MORPH_ENVIRONMENT=DEV.`,\n };\n }\n\n return {\n success: false,\n error: error.message,\n };\n }\n\n return {\n success: false,\n error: String(error),\n };\n }\n}\n\n/**\n * Get recording status and video URL\n * \n * @param recordingId - Recording UUID from BrowserTaskResult\n * @param config - Configuration with apiKey\n * @returns Recording with convenience methods (.getWebp(), .getErrors())\n * \n * @example\n * ```typescript\n * const recording = await getRecording('uuid-here', { apiKey: 'key' });\n * \n * // Get animated WebP\n * const { webpUrl } = await recording.getWebp({ width: 780 });\n * \n * // Get errors with screenshots\n * const { errors } = await recording.getErrors();\n * ```\n */\nexport async function getRecording(\n recordingId: string,\n config: BrowserConfig = {}\n): Promise<RecordingWithMethods> {\n const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n const debug = config.debug || false;\n\n if (!config.apiKey) {\n throw new Error('API key required for getRecording');\n }\n\n if (debug) console.log(`[Browser] getRecording: ${recordingId}`);\n\n const response = await fetch(`${apiUrl}/recordings/${recordingId}`, {\n method: 'GET',\n headers: { 'Authorization': `Bearer ${config.apiKey}` },\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n if (debug) console.error(`[Browser] getRecording error: ${response.status} - ${errorText}`);\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n const data: RecordingStatus = mapRecordingStatus(await response.json());\n if (debug) console.log(`[Browser] Recording status: ${data.status}`);\n\n // Return recording with convenience methods\n return {\n ...data,\n getWebp: (options?: WebpOptions) => getWebp(recordingId, config, options),\n getErrors: () => getErrors(recordingId, config),\n };\n}\n\n/**\n * Wait for recording to complete with automatic polling\n * \n * @param recordingId - Recording UUID\n * @param config - Configuration with apiKey\n * @param options - Polling options\n * @returns Recording status when completed or errored\n * \n * @example\n * ```typescript\n * const result = await executeBrowserTask({ task: '...', recordVideo: true }, config);\n * if (result.recordingId) {\n * const recording = await waitForRecording(result.recordingId, config, {\n * timeout: 60000, // 1 minute\n * pollInterval: 2000 // Check every 2 seconds\n * });\n * console.log('Video URL:', recording.videoUrl);\n * }\n * ```\n */\nexport async function waitForRecording(\n recordingId: string,\n config: BrowserConfig = {},\n options: { timeout?: number; pollInterval?: number } = {}\n): Promise<RecordingWithMethods> {\n const timeout = options.timeout ?? 60000; // Default 1 minute\n const pollInterval = options.pollInterval ?? 2000; // Default 2 seconds\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeout) {\n const status = await getRecording(recordingId, config);\n \n if (status.status === 'COMPLETED' || status.status === 'ERROR') {\n return status;\n }\n\n // Wait before next poll\n await new Promise(resolve => setTimeout(resolve, pollInterval));\n }\n\n throw new Error(`Recording timeout after ${timeout}ms - status still pending`);\n}\n\n/**\n * Execute task with recording and wait for video to be ready\n * \n * @param input - Task parameters with recordVideo=true\n * @param config - Configuration with apiKey\n * @returns Task result with ready video URL\n * \n * @example\n * ```typescript\n * const result = await executeWithRecording(\n * {\n * task: \"Test checkout flow\",\n * url: \"https://example.com\",\n * recordVideo: true,\n * repoId: \"my-project\"\n * },\n * { apiKey: process.env.MORPH_API_KEY }\n * );\n * \n * console.log('Task result:', result.result);\n * console.log('Video URL:', result.recording?.videoUrl);\n * ```\n */\nexport async function executeWithRecording(\n input: BrowserTaskInput & { recordVideo: true },\n config: BrowserConfig = {}\n): Promise<BrowserTaskResult & { recording?: RecordingWithMethods }> {\n // Execute task with recording\n const taskResult = await executeBrowserTask(input, config);\n\n // If recording was created, wait for it to complete\n if (taskResult.recordingId) {\n try {\n const recording = await waitForRecording(\n taskResult.recordingId,\n config,\n { timeout: 60000, pollInterval: 2000 }\n );\n return {\n ...taskResult,\n recording,\n };\n } catch (error) {\n // Return task result even if recording fails\n // Still attach convenience methods for consistent API\n const errorRecording: RecordingWithMethods = {\n id: taskResult.recordingId,\n status: 'ERROR',\n error: error instanceof Error ? error.message : String(error),\n createdAt: new Date().toISOString(),\n getWebp: (options?: WebpOptions) => getWebp(taskResult.recordingId!, config, options),\n getErrors: () => getErrors(taskResult.recordingId!, config),\n };\n return {\n ...taskResult,\n recording: errorRecording,\n };\n }\n }\n\n return taskResult;\n}\n\n/**\n * Get errors from recording with screenshots\n * \n * Screenshots are captured in real-time (500ms after error occurs) during the browser session.\n * \n * @param recordingId - Recording UUID from BrowserTaskResult\n * @param config - Configuration with apiKey\n * @returns Errors with real-time screenshots\n * \n * @example\n * ```typescript\n * const { errors, totalErrors } = await getErrors('uuid-here', { apiKey: 'key' });\n * \n * console.log(`Found ${totalErrors} errors`);\n * \n * errors.forEach(err => {\n * console.log(`[${err.type}] ${err.message}`);\n * if (err.url) console.log(` URL: ${err.url}`);\n * if (err.screenshotUrl) console.log(` Screenshot: ${err.screenshotUrl}`);\n * \n * // Download screenshot\n * if (err.screenshotUrl) {\n * const response = await fetch(err.screenshotUrl);\n * const screenshot = await response.arrayBuffer();\n * // Save or process screenshot\n * }\n * });\n * ```\n */\nexport async function getErrors(\n recordingId: string,\n config: BrowserConfig = {}\n): Promise<ErrorsResponse> {\n const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n const debug = config.debug || false;\n\n if (!config.apiKey) {\n throw new Error('API key required for getErrors');\n }\n\n if (debug) console.log(`[Browser] getErrors: ${recordingId}`);\n\n const response = await fetch(`${apiUrl}/recordings/${recordingId}/errors`, {\n method: 'GET',\n headers: { 'Authorization': `Bearer ${config.apiKey}` },\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n if (debug) console.error(`[Browser] getErrors error: ${response.status} - ${errorText}`);\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n const errors = mapErrorsResponse(await response.json());\n if (debug) console.log(`[Browser] Found ${errors.totalErrors} errors`);\n\n return errors;\n}\n\n/**\n * Helper to serialize Zod schema for API\n */\nfunction stringifyStructuredOutput(schema: any): string {\n try {\n return JSON.stringify({\n type: 'object',\n description: 'Zod schema definition (Zod v3)',\n zodDef: schema._def,\n });\n } catch (error) {\n console.warn('[Browser] Failed to serialize Zod schema:', error);\n return JSON.stringify({\n type: 'object',\n description: 'Schema serialization failed',\n });\n }\n}\n\n/**\n * Parse and validate structured task output\n */\nfunction parseStructuredTaskOutput<T>(\n result: BrowserTaskResult,\n schema: any\n): BrowserTaskResult & { parsed: T | null } {\n if (!result.output) {\n return { ...result, parsed: null };\n }\n\n try {\n const parsed = JSON.parse(result.output);\n const validated = schema.parse(parsed) as T;\n return { ...result, parsed: validated };\n } catch (error) {\n if (error instanceof SyntaxError) {\n return { ...result, parsed: null };\n }\n throw error;\n }\n}\n\nfunction mapTaskResult(api: any): BrowserTaskResult {\n if (!api || typeof api !== 'object') {\n return api as BrowserTaskResult;\n }\n\n return {\n success: api.success,\n result: api.result,\n error: api.error,\n stepsTaken: api.steps_taken,\n executionTimeMs: api.execution_time_ms,\n urls: api.urls,\n actionNames: api.action_names,\n errors: api.errors,\n modelActions: api.model_actions,\n isDone: api.is_done,\n actionHistory: api.action_history,\n actionResults: api.action_results,\n hasErrors: api.has_errors,\n numberOfSteps: api.number_of_steps,\n judgement: api.judgement,\n isValidated: api.is_validated,\n replayId: api.replay_id,\n replayUrl: api.replay_url,\n recordingId: api.recording_id,\n recordingStatus: api.recording_status,\n taskId: api.task_id,\n status: api.status,\n output: api.output,\n debugUrl: api.debug_url,\n };\n}\n\nfunction mapRecordingStatus(api: any): RecordingStatus {\n return {\n id: api.id,\n status: api.status,\n replayUrl: api.replay_url,\n networkUrl: api.network_url,\n consoleUrl: api.console_url,\n videoUrl: api.video_url,\n result: api.result,\n totalEvents: api.total_events,\n fileSize: api.file_size,\n duration: api.duration,\n error: api.error,\n createdAt: api.created_at,\n };\n}\n\nfunction mapBrowserError(api: any): ErrorsResponse['errors'][number] {\n return {\n type: api.type,\n message: api.message,\n url: api.url,\n timestamp: api.timestamp,\n screenshotUrl: api.screenshot_url,\n capturedAt: api.captured_at,\n status: api.status,\n };\n}\n\nfunction mapErrorsResponse(api: any): ErrorsResponse {\n return {\n recordingId: api.recording_id,\n totalErrors: api.total_errors,\n errors: Array.isArray(api.errors) ? api.errors.map(mapBrowserError) : [],\n };\n}\n\nfunction mapWebpResponse(api: any): WebpResponse {\n return {\n webpUrl: api.webp_url,\n cached: api.cached,\n width: api.width,\n fps: api.fps,\n maxDuration: api.max_duration,\n fileSize: api.file_size,\n maxSizeMb: api.max_size_mb,\n budgetMet: api.budget_met,\n qualityUsed: api.quality_used,\n attempts: api.attempts,\n };\n}\n\n/**\n * Get current task status\n */\nasync function getTaskStatus(\n taskId: string,\n config: BrowserConfig\n): Promise<BrowserTaskResult> {\n const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n const debug = config.debug || false;\n\n if (debug) console.log(`[Browser] getTaskStatus: ${taskId}`);\n\n const headers: Record<string, string> = {};\n if (config.apiKey) headers['Authorization'] = `Bearer ${config.apiKey}`;\n\n const response = await fetch(`${apiUrl}/tasks/${taskId}`, {\n method: 'GET',\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n if (debug) console.error(`[Browser] getTaskStatus error: ${response.status} - ${errorText}`);\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n const result: BrowserTaskResult = mapTaskResult(await response.json());\n if (debug) console.log(`[Browser] Task status: ${result.status}`);\n\n return result;\n}\n\n/**\n * Generate live URL for watching task execution in real-time\n */\nfunction generateLiveUrl(taskId: string, config: BrowserConfig): string {\n const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n const baseUrl = apiUrl.replace('/api', '');\n return `${baseUrl}/tasks/${taskId}/live`;\n}\n\n/**\n * Poll task until completion\n */\nasync function pollTaskUntilComplete(\n taskId: string,\n config: BrowserConfig,\n pollConfig: { interval?: number; timeout?: number } = {}\n): Promise<BrowserTaskResult> {\n const interval = pollConfig.interval ?? 2000; // 2 seconds\n const timeout = pollConfig.timeout ?? 300000; // 5 minutes\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeout) {\n const status = await getTaskStatus(taskId, config);\n \n if (status.status === 'completed' || status.status === 'failed') {\n return status;\n }\n\n await new Promise(resolve => setTimeout(resolve, interval));\n }\n\n throw new Error(`Task polling timeout after ${timeout}ms`);\n}\n\n/**\n * Wrap task response with convenience methods\n */\nfunction wrapTaskResponse(\n result: BrowserTaskResult,\n config: BrowserConfig\n): BrowserTaskWithPromise {\n const debugUrl = result.debugUrl ?? '';\n\n const wrapped: BrowserTaskWithPromise = {\n ...result,\n debugUrl,\n taskId: result.taskId || '',\n liveUrl: result.taskId\n ? generateLiveUrl(result.taskId, config)\n : debugUrl,\n complete: async (pollConfig?: { interval?: number; timeout?: number }) => {\n // If we have a taskId, poll task status endpoint\n if (result.taskId) {\n return pollTaskUntilComplete(result.taskId!, config, pollConfig);\n }\n // If we have a recordingId, poll recording status instead\n if (result.recordingId) {\n const recording = await waitForRecording(\n result.recordingId,\n config,\n pollConfig\n );\n // Return a result-like object (recording doesn't have full task result)\n return {\n ...result,\n recordingStatus: recording.status,\n } as BrowserTaskResult;\n }\n // No way to poll completion\n throw new Error('Cannot poll completion: no taskId or recordingId available');\n },\n // Add Steel live session helpers - either functional or error-throwing\n getLiveUrl: debugUrl\n ? (options?: LiveSessionOptions) => buildLiveUrl(debugUrl, options)\n : () => {\n throw new Error(\n 'Live sessions not available. Your backend must return a debugUrl in the response. Contact support@morphllm.com if you need help.'\n );\n },\n getLiveIframe: debugUrl\n ? (optionsOrPreset?: string | IframeOptions) => {\n const options = resolvePreset(optionsOrPreset);\n return buildLiveIframe(debugUrl, options);\n }\n : () => {\n throw new Error(\n 'Live sessions not available. Your backend must return a debugUrl in the response. Contact support@morphllm.com if you need help.'\n );\n },\n getEmbedCode: debugUrl\n ? () => buildEmbedCode(debugUrl)\n : () => {\n throw new Error(\n 'Live sessions not available. Your backend must return a debugUrl in the response. Contact support@morphllm.com if you need help.'\n );\n },\n };\n\n return wrapped;\n}\n\n/**\n * Wrap task response with schema validation\n */\nfunction wrapTaskResponseWithSchema<T>(\n result: BrowserTaskResult,\n config: BrowserConfig,\n schema: any\n): BrowserTaskWithPromiseAndSchema<T> {\n const debugUrl = result.debugUrl ?? '';\n const parsed = result.output\n ? parseStructuredTaskOutput<T>(result, schema)\n : { ...result, parsed: null };\n\n const wrapped: BrowserTaskWithPromiseAndSchema<T> = {\n ...parsed,\n debugUrl,\n taskId: result.taskId || '',\n liveUrl: result.taskId\n ? generateLiveUrl(result.taskId, config)\n : debugUrl,\n complete: async (pollConfig?: { interval?: number; timeout?: number }) => {\n // If we have a taskId, poll task status endpoint\n if (result.taskId) {\n const finalResult = await pollTaskUntilComplete(result.taskId!, config, pollConfig);\n return parseStructuredTaskOutput<T>(finalResult, schema);\n }\n // If we have a recordingId, poll recording status instead\n if (result.recordingId) {\n const recording = await waitForRecording(\n result.recordingId,\n config,\n pollConfig\n );\n // Return parsed result (recording doesn't have task output)\n return {\n ...parsed,\n recordingStatus: recording.status,\n };\n }\n // No way to poll completion\n throw new Error('Cannot poll completion: no taskId or recordingId available');\n },\n // Add Steel live session helpers - either functional or error-throwing\n getLiveUrl: debugUrl\n ? (options?: LiveSessionOptions) => buildLiveUrl(debugUrl, options)\n : () => {\n throw new Error(\n 'Live sessions not available. Your backend must return a debugUrl in the response. ' +\n 'Contact support@morphllm.com if you need help enabling live sessions. '\n );\n },\n getLiveIframe: debugUrl\n ? (optionsOrPreset?: string | IframeOptions) => {\n const options = resolvePreset(optionsOrPreset);\n return buildLiveIframe(debugUrl, options);\n }\n : () => {\n throw new Error(\n 'Live sessions not available. Your backend must return a debugUrl in the response. ' +\n 'Contact support@morphllm.com if you need help enabling live sessions.'\n );\n },\n getEmbedCode: debugUrl\n ? () => buildEmbedCode(debugUrl)\n : () => {\n throw new Error(\n 'Live sessions not available. Your backend must return a debugUrl in the response. ' +\n 'Contact support@morphllm.com if you need help enabling live sessions.'\n );\n },\n };\n\n return wrapped;\n}\n\n/**\n * Get animated WebP preview of recording\n * \n * Converts the native video recording to an animated WebP. Results are cached in S3.\n * \n * @param recordingId - Recording UUID from BrowserTaskResult\n * @param config - Configuration with apiKey\n * @param options - WebP generation options\n * @returns WebP URL and metadata\n * \n * @example\n * ```typescript\n * const webp = await getWebp('uuid-here', { apiKey: 'key' }, {\n * width: 780,\n * fps: 10,\n * quality: 65,\n * maxDuration: 15\n * });\n * console.log('WebP URL:', webp.webpUrl);\n * console.log('From cache:', webp.cached);\n * ```\n */\nexport async function getWebp(\n recordingId: string,\n config: BrowserConfig = {},\n options: WebpOptions = {}\n): Promise<WebpResponse> {\n const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n const debug = config.debug || false;\n\n if (!config.apiKey) {\n throw new Error('API key required for getWebp');\n }\n\n // Build query params\n const params = new URLSearchParams();\n if (options.maxDuration !== undefined) params.set('max_duration', String(options.maxDuration));\n if (options.fps !== undefined) params.set('fps', String(options.fps));\n if (options.width !== undefined) params.set('width', String(options.width));\n if (options.quality !== undefined) params.set('quality', String(options.quality));\n if (options.maxSizeMb !== undefined) params.set('max_size_mb', String(options.maxSizeMb));\n\n const url = `${apiUrl}/recordings/${recordingId}/webp${params.toString() ? '?' + params.toString() : ''}`;\n \n if (debug) console.log(`[Browser] getWebp: ${url}`);\n\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Authorization': `Bearer ${config.apiKey}` },\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n if (debug) console.error(`[Browser] getWebp error: ${response.status} - ${errorText}`);\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n const result = mapWebpResponse(await response.json());\n if (debug) console.log(`[Browser] WebP ready: ${result.webpUrl} (cached: ${result.cached})`);\n\n return result;\n}\n\n/**\n * Check if browser worker service is healthy\n * \n * @param config - Optional configuration\n * @returns Health status\n */\nexport async function checkHealth(config: BrowserConfig = {}): Promise<{\n ok: boolean;\n google_configured: boolean;\n database_configured: boolean;\n s3_configured: boolean;\n error?: string;\n}> {\n const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n\n try {\n const response = await fetch(`${apiUrl}/health`, {\n method: 'GET',\n headers: config.apiKey\n ? { 'Authorization': `Bearer ${config.apiKey}` }\n : {},\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data = await response.json();\n return {\n ok: true,\n google_configured: data.google_configured ?? false,\n database_configured: data.database_configured ?? false,\n s3_configured: data.s3_configured ?? false,\n };\n } catch (error) {\n return {\n ok: false,\n google_configured: false,\n database_configured: false,\n s3_configured: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  SDK_VERSION
3
- } from "./chunk-JEDEBCZM.js";
3
+ } from "./chunk-73DQQMGR.js";
4
4
 
5
5
  // tools/utils/resilience.ts
6
6
  var DEFAULT_RETRY_CONFIG = {
@@ -91,4 +91,4 @@ export {
91
91
  withTimeout,
92
92
  MorphError
93
93
  };
94
- //# sourceMappingURL=chunk-JTUB5ZCT.js.map
94
+ //# sourceMappingURL=chunk-JXJBF6CV.js.map
@@ -0,0 +1,12 @@
1
+ // core/resource.ts
2
+ var APIResource = class {
3
+ _client;
4
+ constructor(client) {
5
+ this._client = client;
6
+ }
7
+ };
8
+
9
+ export {
10
+ APIResource
11
+ };
12
+ //# sourceMappingURL=chunk-LKFZBBTD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../core/resource.ts"],"sourcesContent":["/**\n * Base class for every API resource (FastApply, Compact, Reflex, …).\n *\n * Mirrors the OpenAI SDK's `APIResource`: a resource holds nothing but a\n * reference to the transport (`MorphAPIClient`) and delegates all HTTP to it.\n * Sub-resources receive the same client by reference, so configuration and the\n * fetch/retry/auth machinery live in exactly one place.\n */\nimport type { MorphAPIClient } from './client.js';\n\nexport abstract class APIResource {\n protected _client: MorphAPIClient;\n\n constructor(client: MorphAPIClient) {\n this._client = client;\n }\n}\n"],"mappings":";AAUO,IAAe,cAAf,MAA2B;AAAA,EACtB;AAAA,EAEV,YAAY,QAAwB;AAClC,SAAK,UAAU;AAAA,EACjB;AACF;","names":[]}
@@ -1,10 +1,10 @@
1
- import {
2
- executeCodebaseSearch
3
- } from "./chunk-H5WNI6R5.js";
4
1
  import {
5
2
  CODEBASE_SEARCH_DESCRIPTION,
6
3
  CODEBASE_SEARCH_SYSTEM_PROMPT
7
4
  } from "./chunk-YQMPVJ2L.js";
5
+ import {
6
+ executeCodebaseSearch
7
+ } from "./chunk-W6AGNJ5O.js";
8
8
 
9
9
  // tools/codebase_search/anthropic.ts
10
10
  function createCodebaseSearchTool(config) {
@@ -80,4 +80,4 @@ function formatResult(result) {
80
80
  export {
81
81
  createCodebaseSearchTool
82
82
  };
83
- //# sourceMappingURL=chunk-2ALTBYMY.js.map
83
+ //# sourceMappingURL=chunk-MQTMT4OR.js.map
@@ -1,66 +1,75 @@
1
+ import {
2
+ ReflexClient
3
+ } from "./chunk-YGNPVOUO.js";
4
+ import {
5
+ createGitHubSearchTool as createGitHubSearchTool2,
6
+ createWarpGrepTool as createWarpGrepTool2
7
+ } from "./chunk-AZOSA7VT.js";
1
8
  import {
2
9
  createGitHubSearchTool,
3
10
  createWarpGrepTool
4
- } from "./chunk-5EUMJI3I.js";
11
+ } from "./chunk-TW3XQET2.js";
5
12
  import {
6
13
  createGitHubSearchTool as createGitHubSearchTool3,
7
14
  createWarpGrepTool as createWarpGrepTool3
8
- } from "./chunk-TAS6S42A.js";
15
+ } from "./chunk-QE6JHRVD.js";
9
16
  import {
10
- createGitHubSearchTool as createGitHubSearchTool2,
11
- createWarpGrepTool as createWarpGrepTool2
12
- } from "./chunk-IW4TYYG6.js";
17
+ createCodebaseSearchTool
18
+ } from "./chunk-33ZRF6X3.js";
13
19
  import {
14
20
  createCodebaseSearchTool as createCodebaseSearchTool3
15
- } from "./chunk-3XRNC56L.js";
21
+ } from "./chunk-7EUJ2AKS.js";
16
22
  import {
17
23
  createCodebaseSearchTool as createCodebaseSearchTool2
18
- } from "./chunk-2ALTBYMY.js";
19
- import {
20
- createCodebaseSearchTool
21
- } from "./chunk-SW527EQT.js";
24
+ } from "./chunk-MQTMT4OR.js";
22
25
  import {
23
26
  CodebaseSearchClient
24
- } from "./chunk-H5WNI6R5.js";
27
+ } from "./chunk-W6AGNJ5O.js";
28
+ import {
29
+ createExploreSubagent as createExploreSubagent2
30
+ } from "./chunk-3I4LCNWJ.js";
31
+ import {
32
+ createEditFileTool as createEditFileTool2
33
+ } from "./chunk-CEZQSARX.js";
25
34
  import {
26
35
  createEditFileTool
27
- } from "./chunk-CMFY26F3.js";
36
+ } from "./chunk-GESRH23M.js";
28
37
  import {
29
38
  createEditFileTool as createEditFileTool3
30
- } from "./chunk-2OAKX4SZ.js";
31
- import {
32
- createEditFileTool as createEditFileTool2
33
- } from "./chunk-LL3EWDKD.js";
39
+ } from "./chunk-Z3KRXUNG.js";
34
40
  import {
35
41
  FastApplyClient
36
- } from "./chunk-4MTZUTNH.js";
42
+ } from "./chunk-S5R4H5HM.js";
37
43
  import {
38
44
  BrowserClient
39
- } from "./chunk-FQJCE2FX.js";
45
+ } from "./chunk-I4FCFIBU.js";
40
46
  import {
41
- createExploreSubagent
42
- } from "./chunk-MZZMSL26.js";
47
+ MorphGit
48
+ } from "./chunk-FN4ADWFQ.js";
43
49
  import {
44
- createExploreSubagent as createExploreSubagent2
45
- } from "./chunk-IGQYZ2KH.js";
50
+ createExploreSubagent
51
+ } from "./chunk-5RTWSAZ6.js";
46
52
  import {
47
53
  WarpGrepClient
48
- } from "./chunk-JLLIVBKY.js";
54
+ } from "./chunk-ACWLQFYS.js";
49
55
  import {
50
56
  AnthropicRouter,
51
57
  GeminiRouter,
52
58
  OpenAIRouter,
53
59
  RawRouter
54
- } from "./chunk-KCFMXLZ7.js";
60
+ } from "./chunk-SM3OQZRS.js";
55
61
  import {
56
62
  CompactClient
57
- } from "./chunk-SCVWDNQP.js";
63
+ } from "./chunk-TS56XYWB.js";
64
+ import {
65
+ MorphAPIClient
66
+ } from "./chunk-QE3SPHIM.js";
58
67
  import {
59
68
  logger
60
69
  } from "./chunk-F3NCFNUX.js";
61
70
  import {
62
- MorphGit
63
- } from "./chunk-LE66XCOI.js";
71
+ APIResource
72
+ } from "./chunk-LKFZBBTD.js";
64
73
 
65
74
  // tools/github/types.ts
66
75
  var GitHubError = class extends Error {
@@ -94,9 +103,7 @@ var PermissionError = class extends GitHubError {
94
103
  // tools/github/core.ts
95
104
  var DEFAULT_BASE_URL = "https://api.morphllm.com";
96
105
  var DEFAULT_TIMEOUT = 3e4;
97
- var GitHubClient = class {
98
- apiKey;
99
- baseUrl;
106
+ var GitHubClient = class extends APIResource {
100
107
  timeout;
101
108
  debug;
102
109
  defaultInstallationId;
@@ -121,13 +128,21 @@ var GitHubClient = class {
121
128
  getInstallUrl() {
122
129
  return "https://github.com/apps/morph-subagents/installations/new";
123
130
  }
124
- constructor(config = {}) {
125
- this.apiKey = config.apiKey || process.env.MORPH_API_KEY || "";
126
- this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
131
+ constructor(clientOrConfig = {}, options = {}) {
132
+ const isClient = clientOrConfig instanceof MorphAPIClient;
133
+ const config = isClient ? {} : clientOrConfig;
134
+ super(
135
+ isClient ? clientOrConfig : new MorphAPIClient({
136
+ apiKey: config.apiKey,
137
+ baseURL: config.baseUrl ?? DEFAULT_BASE_URL,
138
+ timeout: config.timeout ?? DEFAULT_TIMEOUT,
139
+ debug: config.debug
140
+ })
141
+ );
127
142
  this.timeout = config.timeout || DEFAULT_TIMEOUT;
128
143
  this.debug = config.debug || false;
129
- this.defaultInstallationId = config.installationId;
130
- if (!this.apiKey) {
144
+ this.defaultInstallationId = isClient ? options.installationId : config.installationId;
145
+ if (!this._client.resolveApiKey()) {
131
146
  throw new Error("API key required. Set MORPH_API_KEY or pass apiKey in config.");
132
147
  }
133
148
  this.installations = {
@@ -171,59 +186,44 @@ var GitHubClient = class {
171
186
  * Make an authenticated API request
172
187
  */
173
188
  async request(method, path, body) {
174
- const url = `${this.baseUrl}${path}`;
175
189
  if (this.debug) {
176
190
  console.log(`[GitHub SDK] ${method} ${path}`, body || "");
177
191
  }
178
- const controller = new AbortController();
179
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
192
+ let response;
180
193
  try {
181
- const response = await fetch(url, {
182
- method,
183
- headers: {
184
- "Content-Type": "application/json",
185
- Authorization: `Bearer ${this.apiKey}`
186
- },
187
- body: body ? JSON.stringify(body) : void 0,
188
- signal: controller.signal
194
+ response = await this._client.request(method, path, {
195
+ body,
196
+ timeout: this.timeout,
197
+ raw: true
189
198
  });
190
- clearTimeout(timeoutId);
191
- if (!response.ok) {
192
- const errorData = await response.json().catch(() => ({}));
193
- const message = errorData.error || errorData.detail || errorData.message || response.statusText;
194
- if (this.debug) {
195
- console.error(`[GitHub SDK] Error ${response.status}:`, message);
196
- }
197
- if (response.status === 404) {
198
- if (message.includes("installation")) {
199
- throw new NoInstallationError(message);
200
- }
201
- throw new NotFoundError(message);
202
- }
203
- if (response.status === 403) {
204
- throw new PermissionError(message);
205
- }
206
- throw new GitHubError(message, response.status, errorData.code);
199
+ } catch (error) {
200
+ if (error instanceof Error && /timed out/i.test(error.message)) {
201
+ throw new GitHubError("Request timeout", 408, "TIMEOUT");
207
202
  }
208
- const data = await response.json();
203
+ throw new GitHubError(error instanceof Error ? error.message : "Unknown error", 500, "UNKNOWN");
204
+ }
205
+ if (!response.ok) {
206
+ const errorData = await response.json().catch(() => ({}));
207
+ const message = errorData.error || errorData.detail || errorData.message || response.statusText;
209
208
  if (this.debug) {
210
- console.log(`[GitHub SDK] Response:`, JSON.stringify(data).slice(0, 200));
209
+ console.error(`[GitHub SDK] Error ${response.status}:`, message);
211
210
  }
212
- return data;
213
- } catch (error) {
214
- clearTimeout(timeoutId);
215
- if (error instanceof GitHubError) {
216
- throw error;
211
+ if (response.status === 404) {
212
+ if (message.includes("installation")) {
213
+ throw new NoInstallationError(message);
214
+ }
215
+ throw new NotFoundError(message);
217
216
  }
218
- if (error instanceof Error && error.name === "AbortError") {
219
- throw new GitHubError("Request timeout", 408, "TIMEOUT");
217
+ if (response.status === 403) {
218
+ throw new PermissionError(message);
220
219
  }
221
- throw new GitHubError(
222
- error instanceof Error ? error.message : "Unknown error",
223
- 500,
224
- "UNKNOWN"
225
- );
220
+ throw new GitHubError(message, response.status, errorData.code);
221
+ }
222
+ const data = await response.json();
223
+ if (this.debug) {
224
+ console.log(`[GitHub SDK] Response:`, JSON.stringify(data).slice(0, 200));
226
225
  }
226
+ return data;
227
227
  }
228
228
  /**
229
229
  * Get the installation ID to use for a request
@@ -602,7 +602,7 @@ var VercelToolFactory = class {
602
602
  };
603
603
 
604
604
  // client.ts
605
- var MorphClient = class {
605
+ var MorphClient = class extends MorphAPIClient {
606
606
  /** Client configuration */
607
607
  config;
608
608
  /** FastApply tool for editing files with AI-powered merge */
@@ -627,6 +627,8 @@ var MorphClient = class {
627
627
  vercel;
628
628
  /** Compact context with line ranges */
629
629
  compact;
630
+ /** Reflex: train and serve small text classifiers */
631
+ reflex;
630
632
  /**
631
633
  * Create a new Morph SDK client
632
634
  *
@@ -642,78 +644,32 @@ var MorphClient = class {
642
644
  * ```
643
645
  */
644
646
  constructor(config = {}) {
645
- this.config = config;
646
- if (config.debug) {
647
- logger.enable();
648
- }
649
- logger.debug("MorphClient", "initialized", { debug: !!config.debug, timeout: config.timeout });
650
- this.fastApply = new FastApplyClient({
651
- apiKey: config.apiKey,
652
- debug: config.debug,
653
- timeout: config.timeout,
654
- retryConfig: config.retryConfig
655
- });
656
- this.codebaseSearch = new CodebaseSearchClient({
657
- apiKey: config.apiKey,
658
- debug: config.debug,
659
- timeout: config.timeout,
660
- retryConfig: config.retryConfig
661
- });
662
- this.warpGrep = new WarpGrepClient({
663
- morphApiKey: config.apiKey,
664
- debug: config.debug,
665
- timeout: config.timeout,
666
- retryConfig: config.retryConfig
667
- });
668
- this.browser = new BrowserClient({
669
- apiKey: config.apiKey,
670
- debug: config.debug,
671
- timeout: config.timeout,
672
- retryConfig: config.retryConfig
673
- });
674
- this.github = new GitHubClient({
647
+ super({
675
648
  apiKey: config.apiKey,
676
- debug: config.debug,
677
- timeout: config.timeout,
678
- installationId: config.github?.installationId
679
- });
680
- this.git = new MorphGit({
681
- apiKey: config.apiKey,
682
- retryConfig: config.retryConfig
683
- });
684
- this.routers = {
685
- openai: new OpenAIRouter({
686
- apiKey: config.apiKey,
687
- debug: config.debug,
688
- timeout: config.timeout,
689
- retryConfig: config.retryConfig
690
- }),
691
- anthropic: new AnthropicRouter({
692
- apiKey: config.apiKey,
693
- debug: config.debug,
694
- timeout: config.timeout,
695
- retryConfig: config.retryConfig
696
- }),
697
- gemini: new GeminiRouter({
698
- apiKey: config.apiKey,
699
- debug: config.debug,
700
- timeout: config.timeout,
701
- retryConfig: config.retryConfig
702
- }),
703
- raw: new RawRouter({
704
- apiKey: config.apiKey,
705
- debug: config.debug,
706
- timeout: config.timeout,
707
- retryConfig: config.retryConfig
708
- })
709
- };
710
- const compactClient = new CompactClient({
711
- morphApiKey: config.apiKey,
712
649
  timeout: config.timeout,
713
650
  retryConfig: config.retryConfig,
714
651
  debug: config.debug
715
652
  });
653
+ if (!config.apiKey) {
654
+ throw new Error("Morph API key is required. Pass it as { apiKey } when constructing MorphClient.");
655
+ }
656
+ this.config = config;
657
+ logger.debug("MorphClient", "initialized", { debug: !!config.debug, timeout: config.timeout });
658
+ this.fastApply = new FastApplyClient(this);
659
+ this.codebaseSearch = new CodebaseSearchClient(this);
660
+ this.warpGrep = new WarpGrepClient(this);
661
+ this.browser = new BrowserClient(this);
662
+ this.github = new GitHubClient(this, { installationId: config.github?.installationId });
663
+ this.git = new MorphGit(this);
664
+ this.routers = {
665
+ openai: new OpenAIRouter(this),
666
+ anthropic: new AnthropicRouter(this),
667
+ gemini: new GeminiRouter(this),
668
+ raw: new RawRouter(this)
669
+ };
670
+ const compactClient = new CompactClient(this);
716
671
  this.compact = compactClient.compact.bind(compactClient);
672
+ this.reflex = new ReflexClient(this);
717
673
  this.openai = new OpenAIToolFactory(config);
718
674
  this.anthropic = new AnthropicToolFactory(config);
719
675
  this.vercel = new VercelToolFactory(config);
@@ -731,4 +687,4 @@ export {
731
687
  VercelToolFactory,
732
688
  MorphClient
733
689
  };
734
- //# sourceMappingURL=chunk-UK7TI7QY.js.map
690
+ //# sourceMappingURL=chunk-NBKL7VWX.js.map