@morphllm/morphsdk 0.2.171 → 0.2.172

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-3XRNC56L.js → chunk-2SNAXTUJ.js} +4 -4
  2. package/dist/chunk-453ZV2AX.js +120 -0
  3. package/dist/chunk-453ZV2AX.js.map +1 -0
  4. package/dist/chunk-53ZJMCWU.js +142 -0
  5. package/dist/chunk-53ZJMCWU.js.map +1 -0
  6. package/dist/{chunk-IW4TYYG6.js → chunk-5DA6SZQJ.js} +2 -2
  7. package/dist/chunk-66OHYI24.js +78 -0
  8. package/dist/chunk-66OHYI24.js.map +1 -0
  9. package/dist/chunk-6X6QMRQG.js +158 -0
  10. package/dist/chunk-6X6QMRQG.js.map +1 -0
  11. package/dist/{chunk-C37YAYBK.js → chunk-7PVVPLRL.js} +2 -2
  12. package/dist/{chunk-MZZMSL26.js → chunk-AE7M2I52.js} +2 -2
  13. package/dist/{chunk-JLLIVBKY.js → chunk-CQF76HJC.js} +30 -6
  14. package/dist/chunk-CQF76HJC.js.map +1 -0
  15. package/dist/{chunk-EFCDIESP.js → chunk-ESXCQBMU.js} +2 -2
  16. package/dist/{chunk-FQJCE2FX.js → chunk-FOIDGIY4.js} +29 -10
  17. package/dist/chunk-FOIDGIY4.js.map +1 -0
  18. package/dist/{chunk-JEDEBCZM.js → chunk-GJZXDRH5.js} +8 -3
  19. package/dist/{chunk-JEDEBCZM.js.map → chunk-GJZXDRH5.js.map} +1 -1
  20. package/dist/{chunk-2ALTBYMY.js → chunk-IJ33I7P5.js} +4 -4
  21. package/dist/{chunk-UK7TI7QY.js → chunk-IN2U7AAI.js} +99 -143
  22. package/dist/chunk-IN2U7AAI.js.map +1 -0
  23. package/dist/{chunk-LE66XCOI.js → chunk-JWZ5DLAS.js} +27 -10
  24. package/dist/chunk-JWZ5DLAS.js.map +1 -0
  25. package/dist/chunk-LKFZBBTD.js +12 -0
  26. package/dist/chunk-LKFZBBTD.js.map +1 -0
  27. package/dist/{chunk-TAS6S42A.js → chunk-MO6S2LRD.js} +2 -2
  28. package/dist/{chunk-2OAKX4SZ.js → chunk-NI7PWQ3B.js} +4 -4
  29. package/dist/{chunk-GLQWEINZ.js → chunk-QAXXE4AD.js} +2 -2
  30. package/dist/{chunk-3BCKZKNK.js → chunk-QFE5523Q.js} +2 -2
  31. package/dist/{chunk-LL3EWDKD.js → chunk-QQXNZIVK.js} +4 -4
  32. package/dist/{chunk-IGQYZ2KH.js → chunk-QZ3V2BP7.js} +2 -2
  33. package/dist/chunk-QZR7SJ5N.js +24 -0
  34. package/dist/chunk-QZR7SJ5N.js.map +1 -0
  35. package/dist/{chunk-SW527EQT.js → chunk-SJVLAGUL.js} +4 -4
  36. package/dist/{chunk-CMFY26F3.js → chunk-U4J3BVAQ.js} +4 -4
  37. package/dist/{chunk-5EUMJI3I.js → chunk-U4MRSZQQ.js} +2 -2
  38. package/dist/{chunk-ZJQTTOHO.js → chunk-UADW6FYD.js} +2 -2
  39. package/dist/{chunk-4324ZSCW.js → chunk-VBARKJWL.js} +2 -2
  40. package/dist/{chunk-OPNTDMHH.js → chunk-VLZ6PNAD.js} +4 -4
  41. package/dist/chunk-VZ7BOH2K.js +1 -0
  42. package/dist/chunk-VZ7BOH2K.js.map +1 -0
  43. package/dist/{chunk-Y6T4NA75.js → chunk-XJDXV5VX.js} +2 -2
  44. package/dist/{chunk-JTUB5ZCT.js → chunk-XYTYIAMQ.js} +2 -2
  45. package/dist/{chunk-4MTZUTNH.js → chunk-Z4GJVN52.js} +23 -8
  46. package/dist/chunk-Z4GJVN52.js.map +1 -0
  47. package/dist/chunk-ZLSNL6M2.js +97 -0
  48. package/dist/chunk-ZLSNL6M2.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 +113 -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-3XRNC56L.js.map → chunk-2SNAXTUJ.js.map} +0 -0
  241. /package/dist/{chunk-IW4TYYG6.js.map → chunk-5DA6SZQJ.js.map} +0 -0
  242. /package/dist/{chunk-C37YAYBK.js.map → chunk-7PVVPLRL.js.map} +0 -0
  243. /package/dist/{chunk-MZZMSL26.js.map → chunk-AE7M2I52.js.map} +0 -0
  244. /package/dist/{chunk-EFCDIESP.js.map → chunk-ESXCQBMU.js.map} +0 -0
  245. /package/dist/{chunk-2ALTBYMY.js.map → chunk-IJ33I7P5.js.map} +0 -0
  246. /package/dist/{chunk-TAS6S42A.js.map → chunk-MO6S2LRD.js.map} +0 -0
  247. /package/dist/{chunk-2OAKX4SZ.js.map → chunk-NI7PWQ3B.js.map} +0 -0
  248. /package/dist/{chunk-GLQWEINZ.js.map → chunk-QAXXE4AD.js.map} +0 -0
  249. /package/dist/{chunk-3BCKZKNK.js.map → chunk-QFE5523Q.js.map} +0 -0
  250. /package/dist/{chunk-LL3EWDKD.js.map → chunk-QQXNZIVK.js.map} +0 -0
  251. /package/dist/{chunk-IGQYZ2KH.js.map → chunk-QZ3V2BP7.js.map} +0 -0
  252. /package/dist/{chunk-SW527EQT.js.map → chunk-SJVLAGUL.js.map} +0 -0
  253. /package/dist/{chunk-CMFY26F3.js.map → chunk-U4J3BVAQ.js.map} +0 -0
  254. /package/dist/{chunk-5EUMJI3I.js.map → chunk-U4MRSZQQ.js.map} +0 -0
  255. /package/dist/{chunk-ZJQTTOHO.js.map → chunk-UADW6FYD.js.map} +0 -0
  256. /package/dist/{chunk-4324ZSCW.js.map → chunk-VBARKJWL.js.map} +0 -0
  257. /package/dist/{chunk-OPNTDMHH.js.map → chunk-VLZ6PNAD.js.map} +0 -0
  258. /package/dist/{chunk-Y6T4NA75.js.map → chunk-XJDXV5VX.js.map} +0 -0
  259. /package/dist/{chunk-JTUB5ZCT.js.map → chunk-XYTYIAMQ.js.map} +0 -0
package/dist/client.cjs CHANGED
@@ -30,66 +30,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
- // logger.ts
34
- var MorphLogger, logger;
35
- var init_logger = __esm({
36
- "logger.ts"() {
37
- "use strict";
38
- MorphLogger = class {
39
- enabled;
40
- fileStream;
41
- /** Resolves once the file stream is initialized (or immediately if no file logging). */
42
- ready;
43
- constructor() {
44
- this.enabled = typeof process !== "undefined" && (process.env.MORPH_DEBUG === "1" || !!process.env.MORPH_LOG_FILE);
45
- this.fileStream = null;
46
- const f = typeof process !== "undefined" ? process.env.MORPH_LOG_FILE : void 0;
47
- if (f) {
48
- this.ready = import("fs").then((fs5) => {
49
- this.fileStream = fs5.createWriteStream(f, { flags: "a" });
50
- }).catch(() => {
51
- });
52
- } else {
53
- this.ready = Promise.resolve();
54
- }
55
- }
56
- debug(component, msg, data) {
57
- this._log("debug", component, msg, data);
58
- }
59
- info(component, msg, data) {
60
- this._log("info", component, msg, data);
61
- }
62
- warn(component, msg, data) {
63
- this._log("warn", component, msg, data);
64
- }
65
- error(component, msg, data) {
66
- this._log("error", component, msg, data);
67
- }
68
- enable() {
69
- this.enabled = true;
70
- }
71
- get isEnabled() {
72
- return this.enabled;
73
- }
74
- _log(level, component, msg, data) {
75
- if (level !== "error" && !this.enabled) return;
76
- const ts = (/* @__PURE__ */ new Date()).toISOString();
77
- const prefix = `[${ts}] [${level.toUpperCase()}] [${component}]`;
78
- console.error(data ? `${prefix} ${msg} ${JSON.stringify(data)}` : `${prefix} ${msg}`);
79
- this.fileStream?.write(JSON.stringify({ ts, level, component, msg, ...data && { data } }) + "\n");
80
- }
81
- };
82
- logger = new MorphLogger();
83
- }
84
- });
85
-
86
33
  // package.json
87
34
  var package_default;
88
35
  var init_package = __esm({
89
36
  "package.json"() {
90
37
  package_default = {
91
38
  name: "@morphllm/morphsdk",
92
- version: "0.2.171",
39
+ version: "0.2.172",
93
40
  description: "TypeScript SDK and CLI for Morph Fast Apply integration",
94
41
  type: "module",
95
42
  main: "./dist/index.cjs",
@@ -226,6 +173,11 @@ var init_package = __esm({
226
173
  import: "./dist/tools/compact/index.js",
227
174
  require: "./dist/tools/compact/index.cjs"
228
175
  },
176
+ "./tools/reflex": {
177
+ types: "./dist/tools/reflex/index.d.ts",
178
+ import: "./dist/tools/reflex/index.js",
179
+ require: "./dist/tools/reflex/index.cjs"
180
+ },
229
181
  "./subagents": {
230
182
  types: "./dist/subagents/index.d.ts",
231
183
  import: "./dist/subagents/index.js",
@@ -251,7 +203,7 @@ var init_package = __esm({
251
203
  "!dist/**/*.test.*"
252
204
  ],
253
205
  scripts: {
254
- build: "tsup version.ts index.ts edge.ts client.ts tools/index.ts tools/fastapply/index.ts tools/fastapply/core.ts tools/fastapply/apply.ts tools/fastapply/types.ts tools/fastapply/prompts.ts tools/fastapply/anthropic.ts tools/fastapply/openai.ts tools/fastapply/vercel.ts tools/codebase_search/index.ts tools/codebase_search/core.ts tools/codebase_search/types.ts tools/codebase_search/prompts.ts tools/codebase_search/anthropic.ts tools/codebase_search/openai.ts tools/codebase_search/vercel.ts tools/warp_grep/index.ts tools/warp_grep/client.ts tools/warp_grep/openai.ts tools/warp_grep/anthropic.ts tools/warp_grep/vercel.ts tools/warp_grep/gemini.ts tools/warp_grep/harness.ts tools/warp_grep/agent/config.ts tools/warp_grep/agent/parser.ts tools/warp_grep/agent/runner.ts tools/warp_grep/agent/types.ts tools/warp_grep/agent/formatter.ts tools/warp_grep/providers/types.ts tools/warp_grep/providers/local.ts tools/warp_grep/providers/remote.ts tools/warp_grep/providers/code_storage_http.ts tools/warp_grep/tools/grep.ts tools/warp_grep/tools/analyse.ts tools/warp_grep/tools/read.ts tools/warp_grep/tools/finish.ts tools/warp_grep/utils/paths.ts tools/warp_grep/utils/github.ts tools/warp_grep/utils/ripgrep.ts tools/warp_grep/utils/format.ts tools/warp_grep/utils/files.ts git/index.ts git/client.ts git/config.ts git/types.ts tools/browser/index.ts tools/browser/core.ts tools/browser/types.ts tools/browser/prompts.ts tools/browser/anthropic.ts tools/browser/openai.ts tools/browser/vercel.ts tools/browser/live.ts tools/browser/errors.ts tools/browser/profiles/index.ts tools/browser/profiles/core.ts tools/browser/profiles/types.ts modelrouter/index.ts modelrouter/core.ts modelrouter/types.ts tools/compact/index.ts tools/compact/core.ts tools/compact/types.ts tools/utils/resilience.ts subagents/index.ts subagents/types.ts subagents/prompts.ts subagents/vercel.ts subagents/anthropic.ts --format esm,cjs --sourcemap --clean --dts --dts-resolve",
206
+ build: "tsup version.ts index.ts edge.ts client.ts core/index.ts core/client.ts core/resource.ts core/error.ts tools/index.ts tools/fastapply/index.ts tools/fastapply/core.ts tools/fastapply/apply.ts tools/fastapply/types.ts tools/fastapply/prompts.ts tools/fastapply/anthropic.ts tools/fastapply/openai.ts tools/fastapply/vercel.ts tools/codebase_search/index.ts tools/codebase_search/core.ts tools/codebase_search/types.ts tools/codebase_search/prompts.ts tools/codebase_search/anthropic.ts tools/codebase_search/openai.ts tools/codebase_search/vercel.ts tools/warp_grep/index.ts tools/warp_grep/client.ts tools/warp_grep/openai.ts tools/warp_grep/anthropic.ts tools/warp_grep/vercel.ts tools/warp_grep/gemini.ts tools/warp_grep/harness.ts tools/warp_grep/agent/config.ts tools/warp_grep/agent/parser.ts tools/warp_grep/agent/runner.ts tools/warp_grep/agent/types.ts tools/warp_grep/agent/formatter.ts tools/warp_grep/providers/types.ts tools/warp_grep/providers/local.ts tools/warp_grep/providers/remote.ts tools/warp_grep/providers/code_storage_http.ts tools/warp_grep/tools/grep.ts tools/warp_grep/tools/analyse.ts tools/warp_grep/tools/read.ts tools/warp_grep/tools/finish.ts tools/warp_grep/utils/paths.ts tools/warp_grep/utils/github.ts tools/warp_grep/utils/ripgrep.ts tools/warp_grep/utils/format.ts tools/warp_grep/utils/files.ts git/index.ts git/client.ts git/config.ts git/types.ts tools/browser/index.ts tools/browser/core.ts tools/browser/types.ts tools/browser/prompts.ts tools/browser/anthropic.ts tools/browser/openai.ts tools/browser/vercel.ts tools/browser/live.ts tools/browser/errors.ts tools/browser/profiles/index.ts tools/browser/profiles/core.ts tools/browser/profiles/types.ts modelrouter/index.ts modelrouter/core.ts modelrouter/types.ts tools/compact/index.ts tools/compact/core.ts tools/compact/types.ts tools/reflex/index.ts tools/reflex/core.ts tools/reflex/types.ts tools/utils/resilience.ts subagents/index.ts subagents/types.ts subagents/prompts.ts subagents/vercel.ts subagents/anthropic.ts --format esm,cjs --sourcemap --clean --dts --dts-resolve",
255
207
  prepare: "npm run build",
256
208
  typecheck: "tsc --noEmit",
257
209
  lint: "eslint .",
@@ -342,6 +294,59 @@ var init_version = __esm({
342
294
  }
343
295
  });
344
296
 
297
+ // logger.ts
298
+ var MorphLogger, logger;
299
+ var init_logger = __esm({
300
+ "logger.ts"() {
301
+ "use strict";
302
+ MorphLogger = class {
303
+ enabled;
304
+ fileStream;
305
+ /** Resolves once the file stream is initialized (or immediately if no file logging). */
306
+ ready;
307
+ constructor() {
308
+ this.enabled = typeof process !== "undefined" && (process.env.MORPH_DEBUG === "1" || !!process.env.MORPH_LOG_FILE);
309
+ this.fileStream = null;
310
+ const f = typeof process !== "undefined" ? process.env.MORPH_LOG_FILE : void 0;
311
+ if (f) {
312
+ this.ready = import("fs").then((fs5) => {
313
+ this.fileStream = fs5.createWriteStream(f, { flags: "a" });
314
+ }).catch(() => {
315
+ });
316
+ } else {
317
+ this.ready = Promise.resolve();
318
+ }
319
+ }
320
+ debug(component, msg, data) {
321
+ this._log("debug", component, msg, data);
322
+ }
323
+ info(component, msg, data) {
324
+ this._log("info", component, msg, data);
325
+ }
326
+ warn(component, msg, data) {
327
+ this._log("warn", component, msg, data);
328
+ }
329
+ error(component, msg, data) {
330
+ this._log("error", component, msg, data);
331
+ }
332
+ enable() {
333
+ this.enabled = true;
334
+ }
335
+ get isEnabled() {
336
+ return this.enabled;
337
+ }
338
+ _log(level, component, msg, data) {
339
+ if (level !== "error" && !this.enabled) return;
340
+ const ts = (/* @__PURE__ */ new Date()).toISOString();
341
+ const prefix = `[${ts}] [${level.toUpperCase()}] [${component}]`;
342
+ console.error(data ? `${prefix} ${msg} ${JSON.stringify(data)}` : `${prefix} ${msg}`);
343
+ this.fileStream?.write(JSON.stringify({ ts, level, component, msg, ...data && { data } }) + "\n");
344
+ }
345
+ };
346
+ logger = new MorphLogger();
347
+ }
348
+ });
349
+
345
350
  // tools/fastapply/apply.ts
346
351
  var apply_exports = {};
347
352
  __export(apply_exports, {
@@ -384,7 +389,7 @@ async function callMorphAPI(originalCode, codeEdit, instructions, filepath, conf
384
389
  const apiUrl = config.morphApiUrl || DEFAULT_API_URL;
385
390
  const useLarge = config.large ?? (typeof process !== "undefined" ? process.env?.MORPH_LARGE_APPLY !== "false" : true);
386
391
  const model = useLarge ? "morph-v3-large" : "morph-v3-fast";
387
- const timeout = config.timeout || DEFAULT_TIMEOUT;
392
+ const timeout = config.timeout || DEFAULT_TIMEOUT2;
388
393
  const debug = config.debug || false;
389
394
  if (!apiKey) {
390
395
  throw new Error(
@@ -478,7 +483,7 @@ async function applyEdit(input, config = {}) {
478
483
  };
479
484
  }
480
485
  }
481
- var import_diff, import_openai, DEFAULT_API_URL, DEFAULT_TIMEOUT;
486
+ var import_diff, import_openai, DEFAULT_API_URL, DEFAULT_TIMEOUT2;
482
487
  var init_apply = __esm({
483
488
  "tools/fastapply/apply.ts"() {
484
489
  "use strict";
@@ -487,7 +492,7 @@ var init_apply = __esm({
487
492
  init_version();
488
493
  init_logger();
489
494
  DEFAULT_API_URL = "https://api.morphllm.com";
490
- DEFAULT_TIMEOUT = 9e4;
495
+ DEFAULT_TIMEOUT2 = 9e4;
491
496
  }
492
497
  });
493
498
 
@@ -1084,11 +1089,229 @@ __export(client_exports, {
1084
1089
  MorphClient: () => MorphClient
1085
1090
  });
1086
1091
  module.exports = __toCommonJS(client_exports);
1092
+
1093
+ // tools/utils/resilience.ts
1094
+ init_version();
1095
+ var DEFAULT_RETRY_CONFIG = {
1096
+ maxRetries: 3,
1097
+ initialDelay: 1e3,
1098
+ maxDelay: 3e4,
1099
+ backoffMultiplier: 2,
1100
+ retryableErrors: ["ECONNREFUSED", "ETIMEDOUT", "ENOTFOUND"]
1101
+ };
1102
+ async function fetchWithRetry(url, options, retryConfig = {}) {
1103
+ const {
1104
+ maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,
1105
+ initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,
1106
+ maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,
1107
+ backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,
1108
+ retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,
1109
+ onRetry
1110
+ } = retryConfig;
1111
+ let lastError = null;
1112
+ let delay = initialDelay;
1113
+ options = { ...options, headers: { "X-Morph-SDK-Version": SDK_VERSION, ...options.headers } };
1114
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
1115
+ try {
1116
+ const response = await fetch(url, options);
1117
+ if (response.status === 429 || response.status === 503) {
1118
+ if (attempt < maxRetries) {
1119
+ const retryAfter = response.headers.get("Retry-After");
1120
+ const waitTime = retryAfter ? parseInt(retryAfter) * 1e3 : Math.min(delay, maxDelay);
1121
+ const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);
1122
+ if (onRetry) {
1123
+ onRetry(attempt + 1, error);
1124
+ }
1125
+ await sleep(waitTime);
1126
+ delay *= backoffMultiplier;
1127
+ continue;
1128
+ }
1129
+ }
1130
+ return response;
1131
+ } catch (error) {
1132
+ lastError = error;
1133
+ const isRetryable = retryableErrors.some(
1134
+ (errType) => lastError?.message?.includes(errType)
1135
+ );
1136
+ if (!isRetryable || attempt === maxRetries) {
1137
+ throw lastError;
1138
+ }
1139
+ const waitTime = Math.min(delay, maxDelay);
1140
+ if (onRetry) {
1141
+ onRetry(attempt + 1, lastError);
1142
+ }
1143
+ await sleep(waitTime);
1144
+ delay *= backoffMultiplier;
1145
+ }
1146
+ }
1147
+ throw lastError || new Error("Max retries exceeded");
1148
+ }
1149
+ async function withTimeout(promise, timeoutMs, errorMessage) {
1150
+ let timeoutId;
1151
+ const timeoutPromise = new Promise((_, reject) => {
1152
+ timeoutId = setTimeout(() => {
1153
+ reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));
1154
+ }, timeoutMs);
1155
+ });
1156
+ try {
1157
+ const result = await Promise.race([promise, timeoutPromise]);
1158
+ clearTimeout(timeoutId);
1159
+ return result;
1160
+ } catch (error) {
1161
+ clearTimeout(timeoutId);
1162
+ throw error;
1163
+ }
1164
+ }
1165
+ function sleep(ms) {
1166
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
1167
+ }
1168
+ var MorphError = class extends Error {
1169
+ constructor(message, code, statusCode, retryable = false) {
1170
+ super(message);
1171
+ this.code = code;
1172
+ this.statusCode = statusCode;
1173
+ this.retryable = retryable;
1174
+ this.name = "MorphError";
1175
+ }
1176
+ };
1177
+
1178
+ // core/client.ts
1179
+ init_logger();
1180
+ init_version();
1181
+
1182
+ // core/error.ts
1183
+ async function toMorphError(response) {
1184
+ let message = `Morph API request failed (${response.status})`;
1185
+ let code = "api_error";
1186
+ try {
1187
+ const body = await response.json();
1188
+ message = body.error?.message ?? body.message ?? message;
1189
+ code = body.error?.code ?? body.error?.type ?? code;
1190
+ } catch {
1191
+ }
1192
+ if (response.status === 401) code = "authentication_error";
1193
+ if (response.status === 429) code = "rate_limit_exceeded";
1194
+ const retryable = response.status === 429 || response.status === 503;
1195
+ return new MorphError(message, code, response.status, retryable);
1196
+ }
1197
+
1198
+ // core/client.ts
1199
+ var DEFAULT_BASE_URL = "https://api.morphllm.com";
1200
+ var DEFAULT_REPOS_URL = "https://repos.morphllm.com";
1201
+ var DEFAULT_BROWSER_URL = "https://browser.morphllm.com";
1202
+ var DEFAULT_TIMEOUT = 6e4;
1203
+ var env = (name) => typeof process !== "undefined" ? process.env?.[name] : void 0;
1204
+ var stripTrailingSlash = (url) => url.replace(/\/+$/, "");
1205
+ var MorphAPIClient = class {
1206
+ /** Explicit key as provided; resolved against env at request time. */
1207
+ apiKey;
1208
+ baseURL;
1209
+ reposURL;
1210
+ browserURL;
1211
+ /** Explicit default timeout (ms), if set. The request default is applied lazily so
1212
+ * resources can read an undefined value and supply their own fallback. */
1213
+ timeout;
1214
+ retryConfig;
1215
+ debug;
1216
+ constructor(options = {}) {
1217
+ this.apiKey = options.apiKey;
1218
+ this.baseURL = stripTrailingSlash(options.baseURL ?? DEFAULT_BASE_URL);
1219
+ this.reposURL = stripTrailingSlash(options.reposURL ?? env("MORPH_SEARCH_URL") ?? DEFAULT_REPOS_URL);
1220
+ this.browserURL = stripTrailingSlash(
1221
+ options.browserURL ?? (env("MORPH_ENVIRONMENT") === "DEV" ? "http://localhost:8000" : DEFAULT_BROWSER_URL)
1222
+ );
1223
+ this.timeout = options.timeout;
1224
+ this.retryConfig = options.retryConfig;
1225
+ this.debug = options.debug ?? false;
1226
+ if (this.debug) logger.enable();
1227
+ }
1228
+ /** The key actually used for requests: explicit, else `MORPH_API_KEY`. */
1229
+ resolveApiKey() {
1230
+ return this.apiKey ?? env("MORPH_API_KEY");
1231
+ }
1232
+ /** Headers shared with tools that bring their own HTTP client (FastApply/WarpGrep via the `openai` package). */
1233
+ defaultHeaders() {
1234
+ return { "X-Morph-SDK-Version": SDK_VERSION };
1235
+ }
1236
+ buildURL(path6, baseURL) {
1237
+ if (/^https?:\/\//i.test(path6)) return path6;
1238
+ const base = stripTrailingSlash(baseURL ?? this.baseURL);
1239
+ return `${base}${path6.startsWith("/") ? "" : "/"}${path6}`;
1240
+ }
1241
+ buildHeaders(apiKey, extra) {
1242
+ return {
1243
+ "Content-Type": "application/json",
1244
+ "X-Morph-SDK-Version": SDK_VERSION,
1245
+ Authorization: `Bearer ${apiKey}`,
1246
+ ...extra
1247
+ };
1248
+ }
1249
+ applyQuery(url, query) {
1250
+ if (!query) return url;
1251
+ const params = new URLSearchParams();
1252
+ for (const [key, value] of Object.entries(query)) {
1253
+ if (value !== void 0 && value !== null) params.set(key, String(value));
1254
+ }
1255
+ const qs = params.toString();
1256
+ return qs ? `${url}${url.includes("?") ? "&" : "?"}${qs}` : url;
1257
+ }
1258
+ async request(method, path6, opts = {}) {
1259
+ const apiKey = this.resolveApiKey();
1260
+ if (!apiKey) {
1261
+ throw new MorphError(
1262
+ "Morph API key not found. Set the MORPH_API_KEY environment variable or pass apiKey in config.",
1263
+ "missing_api_key",
1264
+ 401
1265
+ );
1266
+ }
1267
+ const url = this.applyQuery(this.buildURL(path6, opts.baseURL), opts.query);
1268
+ const timeout = opts.timeout ?? this.timeout ?? DEFAULT_TIMEOUT;
1269
+ const init = {
1270
+ method,
1271
+ headers: this.buildHeaders(apiKey, opts.headers),
1272
+ ...opts.body !== void 0 ? { body: JSON.stringify(opts.body) } : {},
1273
+ ...opts.signal ? { signal: opts.signal } : {}
1274
+ };
1275
+ logger.debug("MorphAPIClient", "request", { method, url });
1276
+ const response = await withTimeout(
1277
+ fetchWithRetry(url, init, this.retryConfig ?? {}),
1278
+ timeout,
1279
+ `Morph request to ${url} timed out after ${timeout}ms`
1280
+ );
1281
+ if (opts.raw) return response;
1282
+ if (!response.ok) throw await toMorphError(response);
1283
+ if (opts.stream) return response;
1284
+ if (response.status === 204) return void 0;
1285
+ const text = await response.text();
1286
+ return text ? JSON.parse(text) : void 0;
1287
+ }
1288
+ get(path6, opts) {
1289
+ return this.request("GET", path6, opts);
1290
+ }
1291
+ post(path6, opts) {
1292
+ return this.request("POST", path6, opts);
1293
+ }
1294
+ delete(path6, opts) {
1295
+ return this.request("DELETE", path6, opts);
1296
+ }
1297
+ };
1298
+
1299
+ // client.ts
1087
1300
  init_logger();
1088
1301
 
1089
1302
  // tools/fastapply/core.ts
1090
1303
  var import_path = require("path");
1091
1304
  init_logger();
1305
+
1306
+ // core/resource.ts
1307
+ var APIResource = class {
1308
+ _client;
1309
+ constructor(client) {
1310
+ this._client = client;
1311
+ }
1312
+ };
1313
+
1314
+ // tools/fastapply/core.ts
1092
1315
  init_apply();
1093
1316
  var DEFAULT_CONFIG = {
1094
1317
  morphApiUrl: "https://api.morphllm.com",
@@ -1098,15 +1321,24 @@ var DEFAULT_CONFIG = {
1098
1321
  timeout: 9e4,
1099
1322
  debug: false
1100
1323
  };
1101
- var FastApplyClient = class {
1324
+ var FastApplyClient = class extends APIResource {
1102
1325
  config;
1103
- constructor(config = {}) {
1326
+ constructor(clientOrConfig = {}) {
1327
+ const isClient = clientOrConfig instanceof MorphAPIClient;
1328
+ super(
1329
+ isClient ? clientOrConfig : new MorphAPIClient({
1330
+ apiKey: clientOrConfig.apiKey,
1331
+ timeout: clientOrConfig.timeout ?? DEFAULT_CONFIG.timeout,
1332
+ retryConfig: clientOrConfig.retryConfig,
1333
+ debug: clientOrConfig.debug
1334
+ })
1335
+ );
1104
1336
  this.config = {
1105
- morphApiKey: config.apiKey,
1106
- morphApiUrl: DEFAULT_CONFIG.morphApiUrl,
1107
- debug: config.debug,
1108
- timeout: config.timeout || DEFAULT_CONFIG.timeout,
1109
- retryConfig: config.retryConfig,
1337
+ morphApiKey: this._client.resolveApiKey(),
1338
+ morphApiUrl: this._client.baseURL,
1339
+ debug: this._client.debug,
1340
+ timeout: (isClient ? void 0 : clientOrConfig.timeout) ?? DEFAULT_CONFIG.timeout,
1341
+ retryConfig: this._client.retryConfig,
1110
1342
  generateUdiff: DEFAULT_CONFIG.generateUdiff,
1111
1343
  autoWrite: DEFAULT_CONFIG.autoWrite
1112
1344
  };
@@ -1205,155 +1437,29 @@ async function executeEditFile(input, config = {}) {
1205
1437
  };
1206
1438
  }
1207
1439
  }
1208
-
1209
- // tools/utils/resilience.ts
1210
- init_version();
1211
- var DEFAULT_RETRY_CONFIG = {
1212
- maxRetries: 3,
1213
- initialDelay: 1e3,
1214
- maxDelay: 3e4,
1215
- backoffMultiplier: 2,
1216
- retryableErrors: ["ECONNREFUSED", "ETIMEDOUT", "ENOTFOUND"]
1217
- };
1218
- async function fetchWithRetry(url, options, retryConfig = {}) {
1219
- const {
1220
- maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,
1221
- initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,
1222
- maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,
1223
- backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,
1224
- retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,
1225
- onRetry
1226
- } = retryConfig;
1227
- let lastError = null;
1228
- let delay = initialDelay;
1229
- options = { ...options, headers: { "X-Morph-SDK-Version": SDK_VERSION, ...options.headers } };
1230
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
1231
- try {
1232
- const response = await fetch(url, options);
1233
- if (response.status === 429 || response.status === 503) {
1234
- if (attempt < maxRetries) {
1235
- const retryAfter = response.headers.get("Retry-After");
1236
- const waitTime = retryAfter ? parseInt(retryAfter) * 1e3 : Math.min(delay, maxDelay);
1237
- const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);
1238
- if (onRetry) {
1239
- onRetry(attempt + 1, error);
1240
- }
1241
- await sleep(waitTime);
1242
- delay *= backoffMultiplier;
1243
- continue;
1244
- }
1245
- }
1246
- return response;
1247
- } catch (error) {
1248
- lastError = error;
1249
- const isRetryable = retryableErrors.some(
1250
- (errType) => lastError?.message?.includes(errType)
1251
- );
1252
- if (!isRetryable || attempt === maxRetries) {
1253
- throw lastError;
1254
- }
1255
- const waitTime = Math.min(delay, maxDelay);
1256
- if (onRetry) {
1257
- onRetry(attempt + 1, lastError);
1258
- }
1259
- await sleep(waitTime);
1260
- delay *= backoffMultiplier;
1261
- }
1262
- }
1263
- throw lastError || new Error("Max retries exceeded");
1264
- }
1265
- async function withTimeout(promise, timeoutMs, errorMessage) {
1266
- let timeoutId;
1267
- const timeoutPromise = new Promise((_, reject) => {
1268
- timeoutId = setTimeout(() => {
1269
- reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));
1270
- }, timeoutMs);
1271
- });
1272
- try {
1273
- const result = await Promise.race([promise, timeoutPromise]);
1274
- clearTimeout(timeoutId);
1275
- return result;
1276
- } catch (error) {
1277
- clearTimeout(timeoutId);
1278
- throw error;
1279
- }
1280
- }
1281
- function sleep(ms) {
1282
- return new Promise((resolve2) => setTimeout(resolve2, ms));
1283
- }
1284
-
1285
- // tools/codebase_search/core.ts
1286
- init_logger();
1287
- var CodebaseSearchClient = class {
1288
- config;
1289
- constructor(config = {}) {
1290
- this.config = {
1291
- apiKey: config.apiKey,
1292
- searchUrl: process.env.MORPH_SEARCH_URL || "https://repos.morphllm.com",
1293
- debug: config.debug,
1294
- timeout: config.timeout || 3e4,
1295
- retryConfig: config.retryConfig
1296
- };
1297
- }
1298
- /**
1299
- * Execute a semantic code search
1300
- *
1301
- * @param input - Search parameters including query, repoId, and target directories
1302
- * @param overrides - Optional config overrides for this operation
1303
- * @returns Search results with ranked code matches
1304
- */
1305
- async search(input, overrides) {
1306
- return executeCodebaseSearch(
1307
- {
1308
- query: input.query,
1309
- target_directories: input.target_directories,
1310
- explanation: input.explanation,
1311
- limit: input.limit
1312
- },
1313
- { ...this.config, repoId: input.repoId, ...overrides }
1314
- );
1315
- }
1316
- };
1317
- async function executeCodebaseSearch(input, config) {
1318
- const apiKey = config.apiKey || process.env.MORPH_API_KEY;
1319
- if (!apiKey) {
1320
- throw new Error("MORPH_API_KEY not found. Set environment variable or pass in config");
1321
- }
1322
- const searchUrl = config.searchUrl || process.env.MORPH_SEARCH_URL || "https://repos.morphllm.com";
1323
- const timeout = config.timeout || 3e4;
1324
- logger.debug("CodebaseSearch", "request", { query: input.query.slice(0, 100), repo_id: config.repoId, url: `${searchUrl}/v1/codebase_search` });
1440
+
1441
+ // tools/codebase_search/core.ts
1442
+ init_logger();
1443
+ var DEFAULT_TIMEOUT3 = 3e4;
1444
+ var emptyStats = { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: 0 };
1445
+ async function runSearch(client, input, repoId, timeout, baseURL) {
1325
1446
  const startTime = Date.now();
1447
+ logger.debug("CodebaseSearch", "request", { query: input.query.slice(0, 100), repo_id: repoId });
1326
1448
  try {
1327
- const fetchPromise = fetchWithRetry(
1328
- `${searchUrl}/v1/codebase_search`,
1449
+ const data = await client.post(
1450
+ "/v1/codebase_search",
1329
1451
  {
1330
- method: "POST",
1331
- headers: {
1332
- "Content-Type": "application/json",
1333
- "Authorization": `Bearer ${apiKey}`
1334
- },
1335
- body: JSON.stringify({
1452
+ baseURL: baseURL ?? client.reposURL,
1453
+ timeout,
1454
+ body: {
1336
1455
  query: input.query,
1337
- repoId: config.repoId,
1456
+ repoId,
1338
1457
  targetDirectories: input.target_directories || [],
1339
1458
  limit: input.limit || 10,
1340
1459
  candidateLimit: 50
1341
- })
1342
- },
1343
- config.retryConfig
1460
+ }
1461
+ }
1344
1462
  );
1345
- const response = await withTimeout(fetchPromise, timeout, `Codebase search timed out after ${timeout}ms`);
1346
- if (!response.ok) {
1347
- const errorText = await response.text();
1348
- logger.error("CodebaseSearch", "response_error", { status: response.status, error: errorText, latency_ms: Date.now() - startTime });
1349
- return {
1350
- success: false,
1351
- results: [],
1352
- stats: { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: 0 },
1353
- error: `Search failed (${response.status}): ${errorText}`
1354
- };
1355
- }
1356
- const data = await response.json();
1357
1463
  const elapsed = Date.now() - startTime;
1358
1464
  logger.debug("CodebaseSearch", "response", { results_count: data.results?.length || 0, latency_ms: elapsed });
1359
1465
  return {
@@ -1362,14 +1468,54 @@ async function executeCodebaseSearch(input, config) {
1362
1468
  stats: data.stats || { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: elapsed }
1363
1469
  };
1364
1470
  } catch (error) {
1365
- logger.error("CodebaseSearch", "exception", { error: error instanceof Error ? error.message : String(error), latency_ms: Date.now() - startTime });
1366
- return {
1367
- success: false,
1368
- results: [],
1369
- stats: { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: 0 },
1370
- error: error instanceof Error ? error.message : "Unknown error"
1371
- };
1471
+ const message = error instanceof MorphError && error.statusCode ? `Search failed (${error.statusCode}): ${error.message}` : error instanceof Error ? error.message : "Unknown error";
1472
+ logger.error("CodebaseSearch", "error", { error: message, latency_ms: Date.now() - startTime });
1473
+ return { success: false, results: [], stats: { ...emptyStats }, error: message };
1474
+ }
1475
+ }
1476
+ var CodebaseSearchClient = class extends APIResource {
1477
+ timeout;
1478
+ constructor(clientOrConfig = {}) {
1479
+ super(
1480
+ clientOrConfig instanceof MorphAPIClient ? clientOrConfig : new MorphAPIClient({
1481
+ apiKey: clientOrConfig.apiKey,
1482
+ timeout: clientOrConfig.timeout ?? DEFAULT_TIMEOUT3,
1483
+ retryConfig: clientOrConfig.retryConfig,
1484
+ debug: clientOrConfig.debug
1485
+ })
1486
+ );
1487
+ this.timeout = (clientOrConfig instanceof MorphAPIClient ? void 0 : clientOrConfig.timeout) ?? DEFAULT_TIMEOUT3;
1488
+ }
1489
+ /**
1490
+ * Execute a semantic code search
1491
+ *
1492
+ * @param input - Search parameters including query, repoId, and target directories
1493
+ * @param overrides - Optional config overrides for this operation
1494
+ * @returns Search results with ranked code matches
1495
+ */
1496
+ async search(input, overrides) {
1497
+ return runSearch(
1498
+ this._client,
1499
+ { query: input.query, target_directories: input.target_directories, explanation: input.explanation, limit: input.limit },
1500
+ input.repoId,
1501
+ overrides?.timeout ?? this.timeout,
1502
+ overrides?.searchUrl
1503
+ );
1504
+ }
1505
+ };
1506
+ async function executeCodebaseSearch(input, config) {
1507
+ const apiKey = config.apiKey || process.env.MORPH_API_KEY;
1508
+ if (!apiKey) {
1509
+ throw new Error("MORPH_API_KEY not found. Set environment variable or pass in config");
1372
1510
  }
1511
+ const client = new MorphAPIClient({
1512
+ apiKey,
1513
+ reposURL: config.searchUrl,
1514
+ timeout: config.timeout ?? DEFAULT_TIMEOUT3,
1515
+ retryConfig: config.retryConfig,
1516
+ debug: config.debug
1517
+ });
1518
+ return runSearch(client, input, config.repoId, config.timeout ?? DEFAULT_TIMEOUT3, config.searchUrl);
1373
1519
  }
1374
1520
 
1375
1521
  // tools/browser/core.ts
@@ -1474,7 +1620,7 @@ function resolvePreset(optionsOrPreset) {
1474
1620
  }
1475
1621
 
1476
1622
  // tools/browser/errors.ts
1477
- var MorphError = class extends Error {
1623
+ var MorphError2 = class extends Error {
1478
1624
  /** Error code for programmatic handling */
1479
1625
  code;
1480
1626
  /** Original cause of the error, if any */
@@ -1500,7 +1646,7 @@ var MorphError = class extends Error {
1500
1646
  };
1501
1647
  }
1502
1648
  };
1503
- var MorphValidationError = class extends MorphError {
1649
+ var MorphValidationError = class extends MorphError2 {
1504
1650
  /** The field that failed validation */
1505
1651
  field;
1506
1652
  constructor(message, field) {
@@ -1515,7 +1661,7 @@ var MorphValidationError = class extends MorphError {
1515
1661
  };
1516
1662
  }
1517
1663
  };
1518
- var MorphAPIError = class extends MorphError {
1664
+ var MorphAPIError = class extends MorphError2 {
1519
1665
  /** HTTP status code */
1520
1666
  statusCode;
1521
1667
  /** Request ID for debugging (if available) */
@@ -2044,17 +2190,30 @@ var DEFAULT_CONFIG2 = {
2044
2190
  // 10 minutes for complex tasks
2045
2191
  debug: false
2046
2192
  };
2047
- var BrowserClient = class {
2193
+ var BrowserClient = class extends APIResource {
2048
2194
  config;
2049
2195
  /**
2050
2196
  * Profile management - create and manage browser profiles for storing login state.
2051
2197
  */
2052
2198
  profiles;
2053
- constructor(config = {}) {
2054
- this.config = {
2199
+ constructor(clientOrConfig = {}) {
2200
+ const isClient = clientOrConfig instanceof MorphAPIClient;
2201
+ super(
2202
+ isClient ? clientOrConfig : new MorphAPIClient({
2203
+ apiKey: clientOrConfig.apiKey,
2204
+ browserURL: clientOrConfig.apiUrl,
2205
+ timeout: clientOrConfig.timeout,
2206
+ retryConfig: clientOrConfig.retryConfig,
2207
+ debug: clientOrConfig.debug
2208
+ })
2209
+ );
2210
+ this.config = isClient ? {
2055
2211
  ...DEFAULT_CONFIG2,
2056
- ...config
2057
- };
2212
+ apiUrl: clientOrConfig.browserURL,
2213
+ apiKey: clientOrConfig.resolveApiKey(),
2214
+ retryConfig: clientOrConfig.retryConfig,
2215
+ debug: clientOrConfig.debug
2216
+ } : { ...DEFAULT_CONFIG2, ...clientOrConfig };
2058
2217
  this.profiles = new ProfilesClient(this.config);
2059
2218
  }
2060
2219
  /**
@@ -3576,14 +3735,27 @@ function parseGitHubUrl(input) {
3576
3735
 
3577
3736
  // tools/compact/core.ts
3578
3737
  var DEFAULT_API_URL4 = "https://api.morphllm.com";
3579
- var DEFAULT_TIMEOUT2 = 12e4;
3580
- var CompactClient = class {
3738
+ var DEFAULT_TIMEOUT4 = 12e4;
3739
+ function resolveClient(clientOrConfig) {
3740
+ if (clientOrConfig instanceof MorphAPIClient) return clientOrConfig;
3741
+ return new MorphAPIClient({
3742
+ apiKey: clientOrConfig.morphApiKey,
3743
+ baseURL: clientOrConfig.morphApiUrl ?? DEFAULT_API_URL4,
3744
+ timeout: clientOrConfig.timeout ?? DEFAULT_TIMEOUT4,
3745
+ retryConfig: clientOrConfig.retryConfig,
3746
+ debug: clientOrConfig.debug
3747
+ });
3748
+ }
3749
+ var CompactClient = class extends APIResource {
3750
+ /** Resolved URL/timeout, exposed for backwards-compatible introspection. */
3581
3751
  config;
3582
- constructor(config = {}) {
3752
+ constructor(clientOrConfig = {}) {
3753
+ super(resolveClient(clientOrConfig));
3754
+ const cfg = clientOrConfig instanceof MorphAPIClient ? {} : clientOrConfig;
3583
3755
  this.config = {
3584
- ...config,
3585
- morphApiUrl: config.morphApiUrl ?? DEFAULT_API_URL4,
3586
- timeout: config.timeout ?? DEFAULT_TIMEOUT2
3756
+ morphApiUrl: this._client.baseURL,
3757
+ timeout: cfg.timeout ?? DEFAULT_TIMEOUT4,
3758
+ debug: cfg.debug ?? false
3587
3759
  };
3588
3760
  }
3589
3761
  /**
@@ -3602,17 +3774,6 @@ var CompactClient = class {
3602
3774
  * ```
3603
3775
  */
3604
3776
  async compact(input) {
3605
- const apiKey = this.config.morphApiKey || (typeof process !== "undefined" ? process.env?.MORPH_API_KEY : void 0);
3606
- const debug = this.config.debug || false;
3607
- if (!apiKey) {
3608
- throw new Error(
3609
- "Morph API key not found. Set MORPH_API_KEY environment variable or pass morphApiKey in config."
3610
- );
3611
- }
3612
- const url = `${this.config.morphApiUrl}/v1/compact`;
3613
- if (debug) {
3614
- console.log(`[Compact] Calling ${url}`);
3615
- }
3616
3777
  const body = {
3617
3778
  compression_ratio: input.compressionRatio ?? 0.5,
3618
3779
  preserve_recent: input.preserveRecent ?? 2,
@@ -3620,37 +3781,19 @@ var CompactClient = class {
3620
3781
  include_line_ranges: input.includeLineRanges ?? true,
3621
3782
  include_markers: input.includeMarkers ?? true
3622
3783
  };
3623
- if (input.query !== void 0) {
3624
- body.query = input.query;
3625
- }
3626
- if (input.messages) {
3627
- body.messages = input.messages;
3628
- } else if (typeof input.input === "string") {
3629
- body.input = input.input;
3630
- } else if (Array.isArray(input.input)) {
3631
- body.messages = input.input;
3632
- } else {
3633
- throw new Error("Either 'input' or 'messages' must be provided");
3634
- }
3635
- const startTime = Date.now();
3636
- const response = await fetch(url, {
3637
- method: "POST",
3638
- headers: {
3639
- "Authorization": `Bearer ${apiKey}`,
3640
- "Content-Type": "application/json"
3641
- },
3642
- body: JSON.stringify(body),
3643
- signal: AbortSignal.timeout(this.config.timeout)
3644
- });
3645
- if (!response.ok) {
3646
- const text = await response.text();
3647
- throw new Error(`Compact API error ${response.status}: ${text}`);
3648
- }
3649
- const data = await response.json();
3650
- if (debug) {
3651
- console.log(`[Compact] compact() done in ${Date.now() - startTime}ms`);
3784
+ if (input.query !== void 0) body.query = input.query;
3785
+ if (input.messages) body.messages = input.messages;
3786
+ else if (typeof input.input === "string") body.input = input.input;
3787
+ else if (Array.isArray(input.input)) body.messages = input.input;
3788
+ else throw new Error("Either 'input' or 'messages' must be provided");
3789
+ try {
3790
+ return await this._client.post("/v1/compact", { body, timeout: this.config.timeout });
3791
+ } catch (err) {
3792
+ if (err instanceof MorphError) {
3793
+ throw new Error(`Compact API error ${err.statusCode}: ${err.message}`);
3794
+ }
3795
+ throw err;
3652
3796
  }
3653
- return data;
3654
3797
  }
3655
3798
  };
3656
3799
 
@@ -3706,10 +3849,28 @@ async function getLocalProvider(repoRoot, excludes, allowNames) {
3706
3849
  const opts = allowNames?.length ? { allowNames } : void 0;
3707
3850
  return new LocalRipgrepProvider2(repoRoot, excludes, opts);
3708
3851
  }
3709
- var WarpGrepClient = class {
3852
+ var WarpGrepClient = class extends APIResource {
3710
3853
  config;
3711
- constructor(config = {}) {
3712
- this.config = { ...config };
3854
+ constructor(clientOrConfig = {}) {
3855
+ const isClient = clientOrConfig instanceof MorphAPIClient;
3856
+ super(
3857
+ isClient ? clientOrConfig : new MorphAPIClient({
3858
+ apiKey: clientOrConfig.morphApiKey,
3859
+ baseURL: clientOrConfig.morphApiUrl,
3860
+ timeout: clientOrConfig.timeout,
3861
+ retryConfig: clientOrConfig.retryConfig,
3862
+ debug: clientOrConfig.debug
3863
+ })
3864
+ );
3865
+ const cfg = isClient ? {} : clientOrConfig;
3866
+ this.config = {
3867
+ ...cfg,
3868
+ morphApiKey: this._client.resolveApiKey(),
3869
+ morphApiUrl: this._client.baseURL,
3870
+ timeout: this._client.timeout,
3871
+ retryConfig: this._client.retryConfig,
3872
+ debug: this._client.debug
3873
+ };
3713
3874
  }
3714
3875
  execute(input) {
3715
3876
  const toolConfig = {
@@ -3983,11 +4144,9 @@ var PermissionError = class extends GitHubError {
3983
4144
  };
3984
4145
 
3985
4146
  // tools/github/core.ts
3986
- var DEFAULT_BASE_URL = "https://api.morphllm.com";
3987
- var DEFAULT_TIMEOUT3 = 3e4;
3988
- var GitHubClient = class {
3989
- apiKey;
3990
- baseUrl;
4147
+ var DEFAULT_BASE_URL2 = "https://api.morphllm.com";
4148
+ var DEFAULT_TIMEOUT5 = 3e4;
4149
+ var GitHubClient = class extends APIResource {
3991
4150
  timeout;
3992
4151
  debug;
3993
4152
  defaultInstallationId;
@@ -4012,13 +4171,21 @@ var GitHubClient = class {
4012
4171
  getInstallUrl() {
4013
4172
  return "https://github.com/apps/morph-subagents/installations/new";
4014
4173
  }
4015
- constructor(config = {}) {
4016
- this.apiKey = config.apiKey || process.env.MORPH_API_KEY || "";
4017
- this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
4018
- this.timeout = config.timeout || DEFAULT_TIMEOUT3;
4174
+ constructor(clientOrConfig = {}, options = {}) {
4175
+ const isClient = clientOrConfig instanceof MorphAPIClient;
4176
+ const config = isClient ? {} : clientOrConfig;
4177
+ super(
4178
+ isClient ? clientOrConfig : new MorphAPIClient({
4179
+ apiKey: config.apiKey,
4180
+ baseURL: config.baseUrl ?? DEFAULT_BASE_URL2,
4181
+ timeout: config.timeout ?? DEFAULT_TIMEOUT5,
4182
+ debug: config.debug
4183
+ })
4184
+ );
4185
+ this.timeout = config.timeout || DEFAULT_TIMEOUT5;
4019
4186
  this.debug = config.debug || false;
4020
- this.defaultInstallationId = config.installationId;
4021
- if (!this.apiKey) {
4187
+ this.defaultInstallationId = isClient ? options.installationId : config.installationId;
4188
+ if (!this._client.resolveApiKey()) {
4022
4189
  throw new Error("API key required. Set MORPH_API_KEY or pass apiKey in config.");
4023
4190
  }
4024
4191
  this.installations = {
@@ -4062,59 +4229,44 @@ var GitHubClient = class {
4062
4229
  * Make an authenticated API request
4063
4230
  */
4064
4231
  async request(method, path6, body) {
4065
- const url = `${this.baseUrl}${path6}`;
4066
4232
  if (this.debug) {
4067
4233
  console.log(`[GitHub SDK] ${method} ${path6}`, body || "");
4068
4234
  }
4069
- const controller = new AbortController();
4070
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
4235
+ let response;
4071
4236
  try {
4072
- const response = await fetch(url, {
4073
- method,
4074
- headers: {
4075
- "Content-Type": "application/json",
4076
- Authorization: `Bearer ${this.apiKey}`
4077
- },
4078
- body: body ? JSON.stringify(body) : void 0,
4079
- signal: controller.signal
4237
+ response = await this._client.request(method, path6, {
4238
+ body,
4239
+ timeout: this.timeout,
4240
+ raw: true
4080
4241
  });
4081
- clearTimeout(timeoutId);
4082
- if (!response.ok) {
4083
- const errorData = await response.json().catch(() => ({}));
4084
- const message = errorData.error || errorData.detail || errorData.message || response.statusText;
4085
- if (this.debug) {
4086
- console.error(`[GitHub SDK] Error ${response.status}:`, message);
4087
- }
4088
- if (response.status === 404) {
4089
- if (message.includes("installation")) {
4090
- throw new NoInstallationError(message);
4091
- }
4092
- throw new NotFoundError(message);
4093
- }
4094
- if (response.status === 403) {
4095
- throw new PermissionError(message);
4096
- }
4097
- throw new GitHubError(message, response.status, errorData.code);
4242
+ } catch (error) {
4243
+ if (error instanceof Error && /timed out/i.test(error.message)) {
4244
+ throw new GitHubError("Request timeout", 408, "TIMEOUT");
4098
4245
  }
4099
- const data = await response.json();
4246
+ throw new GitHubError(error instanceof Error ? error.message : "Unknown error", 500, "UNKNOWN");
4247
+ }
4248
+ if (!response.ok) {
4249
+ const errorData = await response.json().catch(() => ({}));
4250
+ const message = errorData.error || errorData.detail || errorData.message || response.statusText;
4100
4251
  if (this.debug) {
4101
- console.log(`[GitHub SDK] Response:`, JSON.stringify(data).slice(0, 200));
4252
+ console.error(`[GitHub SDK] Error ${response.status}:`, message);
4102
4253
  }
4103
- return data;
4104
- } catch (error) {
4105
- clearTimeout(timeoutId);
4106
- if (error instanceof GitHubError) {
4107
- throw error;
4254
+ if (response.status === 404) {
4255
+ if (message.includes("installation")) {
4256
+ throw new NoInstallationError(message);
4257
+ }
4258
+ throw new NotFoundError(message);
4108
4259
  }
4109
- if (error instanceof Error && error.name === "AbortError") {
4110
- throw new GitHubError("Request timeout", 408, "TIMEOUT");
4260
+ if (response.status === 403) {
4261
+ throw new PermissionError(message);
4111
4262
  }
4112
- throw new GitHubError(
4113
- error instanceof Error ? error.message : "Unknown error",
4114
- 500,
4115
- "UNKNOWN"
4116
- );
4263
+ throw new GitHubError(message, response.status, errorData.code);
4117
4264
  }
4265
+ const data = await response.json();
4266
+ if (this.debug) {
4267
+ console.log(`[GitHub SDK] Response:`, JSON.stringify(data).slice(0, 200));
4268
+ }
4269
+ return data;
4118
4270
  }
4119
4271
  /**
4120
4272
  * Get the installation ID to use for a request
@@ -4308,18 +4460,28 @@ var import_isomorphic_git = __toESM(require("isomorphic-git"), 1);
4308
4460
  var import_node = __toESM(require("isomorphic-git/http/node"), 1);
4309
4461
  var import_fs2 = __toESM(require("fs"), 1);
4310
4462
  var DEFAULT_PROXY_URL = "https://repos.morphllm.com";
4311
- var MorphGit = class {
4463
+ var MorphGit = class extends APIResource {
4312
4464
  apiKey;
4313
4465
  proxyUrl;
4314
- constructor(config) {
4315
- if (!config.apiKey) {
4316
- throw new Error("API key is required. Get one at https://morphllm.com/dashboard");
4317
- }
4318
- if (!config.apiKey.startsWith("sk-") && !config.apiKey.startsWith("morph-")) {
4319
- throw new Error("Invalid API key format. Expected: sk-... or morph-...");
4466
+ constructor(clientOrConfig) {
4467
+ const isClient = clientOrConfig instanceof MorphAPIClient;
4468
+ if (!isClient) {
4469
+ if (!clientOrConfig.apiKey) {
4470
+ throw new Error("API key is required. Get one at https://morphllm.com/dashboard");
4471
+ }
4472
+ if (!clientOrConfig.apiKey.startsWith("sk-") && !clientOrConfig.apiKey.startsWith("morph-")) {
4473
+ throw new Error("Invalid API key format. Expected: sk-... or morph-...");
4474
+ }
4320
4475
  }
4321
- this.apiKey = config.apiKey;
4322
- this.proxyUrl = config.proxyUrl || DEFAULT_PROXY_URL;
4476
+ super(
4477
+ isClient ? clientOrConfig : new MorphAPIClient({
4478
+ apiKey: clientOrConfig.apiKey,
4479
+ reposURL: clientOrConfig.proxyUrl,
4480
+ retryConfig: clientOrConfig.retryConfig
4481
+ })
4482
+ );
4483
+ this.apiKey = this._client.resolveApiKey() ?? "";
4484
+ this.proxyUrl = isClient ? this._client.reposURL : clientOrConfig.proxyUrl || DEFAULT_PROXY_URL;
4323
4485
  }
4324
4486
  /**
4325
4487
  * Get auth callback for isomorphic-git operations
@@ -4847,87 +5009,212 @@ var MorphGit = class {
4847
5009
  var import_isomorphic_git2 = __toESM(require("isomorphic-git"), 1);
4848
5010
  var import_node2 = __toESM(require("isomorphic-git/http/node"), 1);
4849
5011
 
5012
+ // tools/reflex/core.ts
5013
+ var BASE_MODEL = "morph-reflex-v1";
5014
+ function resolveClient2(clientOrConfig) {
5015
+ if (clientOrConfig instanceof MorphAPIClient) return clientOrConfig;
5016
+ return new MorphAPIClient({
5017
+ apiKey: clientOrConfig.apiKey,
5018
+ baseURL: clientOrConfig.baseUrl,
5019
+ timeout: clientOrConfig.timeout,
5020
+ retryConfig: clientOrConfig.retryConfig,
5021
+ debug: clientOrConfig.debug
5022
+ });
5023
+ }
5024
+ var ReflexClient = class extends APIResource {
5025
+ /** Train, retrieve, and manage classifier jobs. */
5026
+ jobs;
5027
+ constructor(clientOrConfig = {}) {
5028
+ super(resolveClient2(clientOrConfig));
5029
+ this.jobs = new ReflexJobsResource(this._client);
5030
+ }
5031
+ /** Classify text against a trained model. The model must be `succeeded`. */
5032
+ async predict(input) {
5033
+ const raw = await this._client.post("/v1/reflex/predict", {
5034
+ body: { model: input.model, text: input.text }
5035
+ });
5036
+ return {
5037
+ model: raw.model,
5038
+ label: raw.label,
5039
+ confidence: raw.confidence,
5040
+ allScores: raw.all_scores ?? {},
5041
+ inferenceTimeMs: raw.inference_time_ms
5042
+ };
5043
+ }
5044
+ };
5045
+ var ReflexJobsResource = class extends APIResource {
5046
+ /** Start a training job from labeled data, a description, or unlabeled text. */
5047
+ async create(input) {
5048
+ return toReflexJob(await this._client.post("/v1/fine_tuning/jobs", { body: createBody(input) }));
5049
+ }
5050
+ /** Fetch a job by id. */
5051
+ async retrieve(id) {
5052
+ return toReflexJob(await this._client.get(`/v1/fine_tuning/jobs/${encodeURIComponent(id)}`));
5053
+ }
5054
+ /** List the caller's jobs, newest first. */
5055
+ async list(input = {}) {
5056
+ const raw = await this._client.get("/v1/fine_tuning/jobs", {
5057
+ query: { limit: input.limit, after: input.after }
5058
+ });
5059
+ return { data: (raw.data ?? []).map(toReflexJob), hasMore: Boolean(raw.has_more) };
5060
+ }
5061
+ /** Stop a queued or running job. */
5062
+ async cancel(id) {
5063
+ return toReflexJob(await this._client.post(`/v1/fine_tuning/jobs/${encodeURIComponent(id)}/cancel`));
5064
+ }
5065
+ /** Delete a job and its trained model. */
5066
+ async delete(id) {
5067
+ const raw = await this._client.delete(
5068
+ `/v1/fine_tuning/jobs/${encodeURIComponent(id)}`
5069
+ );
5070
+ return { id: raw.id, deleted: Boolean(raw.deleted) };
5071
+ }
5072
+ /** The training loss curve as events, plus a terminal event. */
5073
+ async events(id) {
5074
+ const raw = await this._client.get(
5075
+ `/v1/fine_tuning/jobs/${encodeURIComponent(id)}/events`
5076
+ );
5077
+ return (raw.data ?? []).map(toReflexEvent);
5078
+ }
5079
+ /**
5080
+ * Poll until the job reaches a terminal status and return it on success.
5081
+ * Throws a `MorphError` if it fails, is cancelled, or exceeds `timeoutMs`.
5082
+ */
5083
+ async waitForReady(id, opts = {}) {
5084
+ const pollMs = opts.pollMs ?? 3e3;
5085
+ const deadline = Date.now() + (opts.timeoutMs ?? 15 * 6e4);
5086
+ for (; ; ) {
5087
+ const job = await this.retrieve(id);
5088
+ if (job.status === "succeeded") return job;
5089
+ if (job.status === "failed" || job.status === "cancelled") {
5090
+ throw new MorphError(job.error?.message ?? `Reflex job ${job.status}`, `reflex_job_${job.status}`);
5091
+ }
5092
+ if (Date.now() >= deadline) {
5093
+ throw new MorphError(`Reflex job ${id} did not finish in time`, "reflex_timeout");
5094
+ }
5095
+ await sleep2(pollMs);
5096
+ }
5097
+ }
5098
+ };
5099
+ function createBody(input) {
5100
+ const base = { model: BASE_MODEL };
5101
+ if (input.suffix) base.suffix = input.suffix;
5102
+ if ("trainingData" in input) {
5103
+ if (input.labels) base.labels = input.labels;
5104
+ return { ...base, training_data: input.trainingData };
5105
+ }
5106
+ if ("generate" in input) {
5107
+ return {
5108
+ ...base,
5109
+ labels: input.labels,
5110
+ generate: {
5111
+ description: input.generate.description,
5112
+ ...input.generate.examplesPerLabel != null ? { examples_per_label: input.generate.examplesPerLabel } : {}
5113
+ }
5114
+ };
5115
+ }
5116
+ return {
5117
+ ...base,
5118
+ labels: input.labels,
5119
+ label_data: {
5120
+ texts: input.labelData.texts,
5121
+ ...input.labelData.description ? { description: input.labelData.description } : {}
5122
+ }
5123
+ };
5124
+ }
5125
+ function toReflexJob(raw) {
5126
+ return {
5127
+ id: raw.id,
5128
+ object: "fine_tuning.job",
5129
+ model: raw.model,
5130
+ createdAt: raw.created_at,
5131
+ finishedAt: raw.finished_at ?? null,
5132
+ fineTunedModel: raw.fine_tuned_model ?? null,
5133
+ status: raw.status,
5134
+ labels: raw.labels ?? [],
5135
+ trainedExamples: raw.trained_examples ?? 0,
5136
+ result: raw.result ? { accuracy: raw.result.accuracy ?? null, f1Score: raw.result.f1_score ?? null } : null,
5137
+ error: raw.error ? { message: raw.error.message } : null,
5138
+ suffix: raw.suffix ?? null
5139
+ };
5140
+ }
5141
+ function toReflexEvent(raw) {
5142
+ return {
5143
+ id: raw.id,
5144
+ createdAt: raw.created_at,
5145
+ level: raw.level,
5146
+ message: raw.message,
5147
+ type: raw.type,
5148
+ data: { epoch: raw.data?.epoch ?? 0, step: raw.data?.step ?? 0, trainLoss: raw.data?.train_loss ?? 0 }
5149
+ };
5150
+ }
5151
+ function sleep2(ms) {
5152
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
5153
+ }
5154
+
4850
5155
  // modelrouter/core.ts
4851
5156
  init_logger();
4852
- var DEFAULT_CONFIG3 = {
4853
- apiUrl: "https://api.morphllm.com",
4854
- timeout: 5e3,
4855
- // 5 seconds (responses typically <500ms)
4856
- debug: false
4857
- };
4858
- var BaseRouter = class {
4859
- config;
5157
+ var DEFAULT_API_URL5 = "https://api.morphllm.com";
5158
+ var DEFAULT_TIMEOUT6 = 5e3;
5159
+ function resolveClient3(clientOrConfig) {
5160
+ if (clientOrConfig instanceof MorphAPIClient) return clientOrConfig;
5161
+ return new MorphAPIClient({
5162
+ apiKey: clientOrConfig.apiKey,
5163
+ baseURL: clientOrConfig.apiUrl ?? DEFAULT_API_URL5,
5164
+ timeout: clientOrConfig.timeout ?? DEFAULT_TIMEOUT6,
5165
+ retryConfig: clientOrConfig.retryConfig,
5166
+ debug: clientOrConfig.debug
5167
+ });
5168
+ }
5169
+ var BaseRouter = class extends APIResource {
4860
5170
  provider;
4861
- constructor(provider, config = {}) {
5171
+ timeout;
5172
+ constructor(provider, clientOrConfig = {}) {
5173
+ super(resolveClient3(clientOrConfig));
4862
5174
  this.provider = provider;
4863
- this.config = {
4864
- apiKey: config.apiKey,
4865
- apiUrl: config.apiUrl || DEFAULT_CONFIG3.apiUrl,
4866
- timeout: config.timeout || DEFAULT_CONFIG3.timeout,
4867
- debug: config.debug || DEFAULT_CONFIG3.debug,
4868
- retryConfig: config.retryConfig
4869
- };
5175
+ const cfg = clientOrConfig instanceof MorphAPIClient ? {} : clientOrConfig;
5176
+ this.timeout = cfg.timeout ?? DEFAULT_TIMEOUT6;
4870
5177
  }
4871
- /**
4872
- * Select the optimal model for a given input and mode
4873
- */
4874
- async selectModel(input) {
4875
- const mode = input.mode || "balanced";
4876
- const apiKey = this.config.apiKey || (typeof process !== "undefined" ? process.env?.MORPH_API_KEY : void 0);
4877
- if (!apiKey) {
5178
+ /** Throw the historical "API key is required" message when no key is resolvable. */
5179
+ requireApiKey() {
5180
+ if (!this._client.resolveApiKey()) {
4878
5181
  throw new Error(
4879
5182
  "Morph API key is required. Set MORPH_API_KEY environment variable or pass apiKey in config."
4880
5183
  );
4881
5184
  }
4882
- const url = `${this.config.apiUrl}/v1/router/${this.provider}`;
4883
- const payload = {
4884
- input: input.input,
4885
- mode
4886
- };
4887
- logger.debug("ModelRouter", "request", { provider: this.provider, mode, input_len: input.input.length, url });
5185
+ }
5186
+ /** POST to the router and surface failures as `Router API error (<status>): ...`. */
5187
+ async route(provider, input) {
4888
5188
  try {
4889
- const fetchPromise = fetchWithRetry(
4890
- url,
4891
- {
4892
- method: "POST",
4893
- headers: {
4894
- "Content-Type": "application/json",
4895
- Authorization: `Bearer ${apiKey}`
4896
- },
4897
- body: JSON.stringify(payload)
4898
- },
4899
- this.config.retryConfig
4900
- );
4901
- const response = await withTimeout(
4902
- fetchPromise,
4903
- this.config.timeout,
4904
- `Router API request timed out after ${this.config.timeout}ms`
4905
- );
4906
- if (!response.ok) {
4907
- const errorText = await response.text();
4908
- throw new Error(
4909
- `Router API error (${response.status}): ${errorText || response.statusText}`
4910
- );
4911
- }
4912
- const apiResult = await response.json();
4913
- const result = {
4914
- model: apiResult.model
4915
- };
4916
- logger.debug("ModelRouter", "selected", { provider: this.provider, model: apiResult.model, confidence: apiResult.confidence });
4917
- return result;
5189
+ return await this._client.post(`/v1/router/${provider}`, {
5190
+ body: { input: input.input, mode: input.mode || "balanced" },
5191
+ timeout: this.timeout
5192
+ });
4918
5193
  } catch (error) {
4919
- logger.error("ModelRouter", "error", { provider: this.provider, error: error instanceof Error ? error.message : String(error) });
5194
+ if (error instanceof MorphError) {
5195
+ throw new Error(`Router API error (${error.statusCode}): ${error.message}`);
5196
+ }
4920
5197
  throw error;
4921
5198
  }
4922
5199
  }
5200
+ /**
5201
+ * Select the optimal model for a given input and mode
5202
+ */
5203
+ async selectModel(input) {
5204
+ this.requireApiKey();
5205
+ logger.debug("ModelRouter", "request", { provider: this.provider, mode: input.mode || "balanced" });
5206
+ const apiResult = await this.route(this.provider, input);
5207
+ logger.debug("ModelRouter", "selected", { provider: this.provider, model: apiResult.model });
5208
+ return { model: apiResult.model };
5209
+ }
4923
5210
  };
4924
5211
  var OpenAIRouter = class extends BaseRouter {
4925
- constructor(config = {}) {
4926
- super("openai", config);
5212
+ constructor(clientOrConfig = {}) {
5213
+ super("openai", clientOrConfig);
4927
5214
  }
4928
5215
  /**
4929
5216
  * Select optimal GPT-5 model
4930
- *
5217
+ *
4931
5218
  * @param input - User input and mode
4932
5219
  * @returns Selected model name (gpt-5-mini | gpt-5-low | gpt-5-medium | gpt-5-high)
4933
5220
  */
@@ -4936,12 +5223,12 @@ var OpenAIRouter = class extends BaseRouter {
4936
5223
  }
4937
5224
  };
4938
5225
  var AnthropicRouter = class extends BaseRouter {
4939
- constructor(config = {}) {
4940
- super("anthropic", config);
5226
+ constructor(clientOrConfig = {}) {
5227
+ super("anthropic", clientOrConfig);
4941
5228
  }
4942
5229
  /**
4943
5230
  * Select optimal Claude model
4944
- *
5231
+ *
4945
5232
  * @param input - User input and mode
4946
5233
  * @returns Selected model name (claude-4.5-haiku | claude-4.5-sonnet)
4947
5234
  */
@@ -4950,12 +5237,12 @@ var AnthropicRouter = class extends BaseRouter {
4950
5237
  }
4951
5238
  };
4952
5239
  var GeminiRouter = class extends BaseRouter {
4953
- constructor(config = {}) {
4954
- super("gemini", config);
5240
+ constructor(clientOrConfig = {}) {
5241
+ super("gemini", clientOrConfig);
4955
5242
  }
4956
5243
  /**
4957
5244
  * Select optimal Gemini model
4958
- *
5245
+ *
4959
5246
  * @param input - User input and mode
4960
5247
  * @returns Selected model name (gemini-2.5-flash | gemini-2.5-pro)
4961
5248
  */
@@ -4964,69 +5251,27 @@ var GeminiRouter = class extends BaseRouter {
4964
5251
  }
4965
5252
  };
4966
5253
  var RawRouter = class extends BaseRouter {
4967
- constructor(config = {}) {
4968
- super("raw", config);
5254
+ constructor(clientOrConfig = {}) {
5255
+ super("raw", clientOrConfig);
4969
5256
  }
4970
5257
  /**
4971
5258
  * Get raw difficulty classification
4972
- *
5259
+ *
4973
5260
  * @param input - User input and mode
4974
5261
  * @returns Raw difficulty (easy | medium | hard | needs_info)
4975
5262
  */
4976
5263
  async classify(input) {
4977
- const mode = input.mode || "balanced";
4978
- const apiKey = this.config.apiKey || (typeof process !== "undefined" ? process.env?.MORPH_API_KEY : void 0);
4979
- if (!apiKey) {
4980
- throw new Error(
4981
- "Morph API key is required. Set MORPH_API_KEY environment variable or pass apiKey in config."
4982
- );
4983
- }
4984
- const url = `${this.config.apiUrl}/v1/router/raw`;
4985
- const payload = {
4986
- input: input.input,
4987
- mode
4988
- };
4989
- logger.debug("RawRouter", "request", { mode, input_len: input.input.length, url });
4990
- try {
4991
- const fetchPromise = fetchWithRetry(
4992
- url,
4993
- {
4994
- method: "POST",
4995
- headers: {
4996
- "Content-Type": "application/json",
4997
- Authorization: `Bearer ${apiKey}`
4998
- },
4999
- body: JSON.stringify(payload)
5000
- },
5001
- this.config.retryConfig
5002
- );
5003
- const response = await withTimeout(
5004
- fetchPromise,
5005
- this.config.timeout,
5006
- `Router API request timed out after ${this.config.timeout}ms`
5007
- );
5008
- if (!response.ok) {
5009
- const errorText = await response.text();
5010
- throw new Error(
5011
- `Router API error (${response.status}): ${errorText || response.statusText}`
5012
- );
5013
- }
5014
- const apiResult = await response.json();
5015
- let difficulty;
5016
- if (apiResult.difficulty === "") {
5017
- difficulty = "medium";
5018
- } else {
5019
- difficulty = apiResult.difficulty || apiResult.model;
5020
- }
5021
- const result = {
5022
- difficulty
5023
- };
5024
- logger.debug("RawRouter", "classified", { difficulty });
5025
- return result;
5026
- } catch (error) {
5027
- logger.error("RawRouter", "error", { error: error instanceof Error ? error.message : String(error) });
5028
- throw error;
5264
+ this.requireApiKey();
5265
+ logger.debug("RawRouter", "request", { mode: input.mode || "balanced" });
5266
+ const apiResult = await this.route("raw", input);
5267
+ let difficulty;
5268
+ if (apiResult.difficulty === "") {
5269
+ difficulty = "medium";
5270
+ } else {
5271
+ difficulty = apiResult.difficulty || apiResult.model;
5029
5272
  }
5273
+ logger.debug("RawRouter", "classified", { difficulty });
5274
+ return { difficulty };
5030
5275
  }
5031
5276
  };
5032
5277
 
@@ -6409,7 +6654,7 @@ var VercelToolFactory = class {
6409
6654
  };
6410
6655
 
6411
6656
  // client.ts
6412
- var MorphClient = class {
6657
+ var MorphClient = class extends MorphAPIClient {
6413
6658
  /** Client configuration */
6414
6659
  config;
6415
6660
  /** FastApply tool for editing files with AI-powered merge */
@@ -6434,6 +6679,8 @@ var MorphClient = class {
6434
6679
  vercel;
6435
6680
  /** Compact context with line ranges */
6436
6681
  compact;
6682
+ /** Reflex: train and serve small text classifiers */
6683
+ reflex;
6437
6684
  /**
6438
6685
  * Create a new Morph SDK client
6439
6686
  *
@@ -6449,78 +6696,32 @@ var MorphClient = class {
6449
6696
  * ```
6450
6697
  */
6451
6698
  constructor(config = {}) {
6452
- this.config = config;
6453
- if (config.debug) {
6454
- logger.enable();
6455
- }
6456
- logger.debug("MorphClient", "initialized", { debug: !!config.debug, timeout: config.timeout });
6457
- this.fastApply = new FastApplyClient({
6458
- apiKey: config.apiKey,
6459
- debug: config.debug,
6460
- timeout: config.timeout,
6461
- retryConfig: config.retryConfig
6462
- });
6463
- this.codebaseSearch = new CodebaseSearchClient({
6464
- apiKey: config.apiKey,
6465
- debug: config.debug,
6466
- timeout: config.timeout,
6467
- retryConfig: config.retryConfig
6468
- });
6469
- this.warpGrep = new WarpGrepClient({
6470
- morphApiKey: config.apiKey,
6471
- debug: config.debug,
6472
- timeout: config.timeout,
6473
- retryConfig: config.retryConfig
6474
- });
6475
- this.browser = new BrowserClient({
6476
- apiKey: config.apiKey,
6477
- debug: config.debug,
6478
- timeout: config.timeout,
6479
- retryConfig: config.retryConfig
6480
- });
6481
- this.github = new GitHubClient({
6482
- apiKey: config.apiKey,
6483
- debug: config.debug,
6484
- timeout: config.timeout,
6485
- installationId: config.github?.installationId
6486
- });
6487
- this.git = new MorphGit({
6699
+ super({
6488
6700
  apiKey: config.apiKey,
6489
- retryConfig: config.retryConfig
6490
- });
6491
- this.routers = {
6492
- openai: new OpenAIRouter({
6493
- apiKey: config.apiKey,
6494
- debug: config.debug,
6495
- timeout: config.timeout,
6496
- retryConfig: config.retryConfig
6497
- }),
6498
- anthropic: new AnthropicRouter({
6499
- apiKey: config.apiKey,
6500
- debug: config.debug,
6501
- timeout: config.timeout,
6502
- retryConfig: config.retryConfig
6503
- }),
6504
- gemini: new GeminiRouter({
6505
- apiKey: config.apiKey,
6506
- debug: config.debug,
6507
- timeout: config.timeout,
6508
- retryConfig: config.retryConfig
6509
- }),
6510
- raw: new RawRouter({
6511
- apiKey: config.apiKey,
6512
- debug: config.debug,
6513
- timeout: config.timeout,
6514
- retryConfig: config.retryConfig
6515
- })
6516
- };
6517
- const compactClient = new CompactClient({
6518
- morphApiKey: config.apiKey,
6519
6701
  timeout: config.timeout,
6520
6702
  retryConfig: config.retryConfig,
6521
6703
  debug: config.debug
6522
6704
  });
6705
+ if (!config.apiKey) {
6706
+ throw new Error("Morph API key is required. Pass it as { apiKey } when constructing MorphClient.");
6707
+ }
6708
+ this.config = config;
6709
+ logger.debug("MorphClient", "initialized", { debug: !!config.debug, timeout: config.timeout });
6710
+ this.fastApply = new FastApplyClient(this);
6711
+ this.codebaseSearch = new CodebaseSearchClient(this);
6712
+ this.warpGrep = new WarpGrepClient(this);
6713
+ this.browser = new BrowserClient(this);
6714
+ this.github = new GitHubClient(this, { installationId: config.github?.installationId });
6715
+ this.git = new MorphGit(this);
6716
+ this.routers = {
6717
+ openai: new OpenAIRouter(this),
6718
+ anthropic: new AnthropicRouter(this),
6719
+ gemini: new GeminiRouter(this),
6720
+ raw: new RawRouter(this)
6721
+ };
6722
+ const compactClient = new CompactClient(this);
6523
6723
  this.compact = compactClient.compact.bind(compactClient);
6724
+ this.reflex = new ReflexClient(this);
6524
6725
  this.openai = new OpenAIToolFactory(config);
6525
6726
  this.anthropic = new AnthropicToolFactory(config);
6526
6727
  this.vercel = new VercelToolFactory(config);