@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
@@ -0,0 +1,78 @@
1
+ import {
2
+ MorphAPIClient
3
+ } from "./chunk-QE3SPHIM.js";
4
+ import {
5
+ MorphError
6
+ } from "./chunk-JXJBF6CV.js";
7
+ import {
8
+ APIResource
9
+ } from "./chunk-LKFZBBTD.js";
10
+
11
+ // tools/compact/core.ts
12
+ var DEFAULT_API_URL = "https://api.morphllm.com";
13
+ var DEFAULT_TIMEOUT = 12e4;
14
+ function resolveClient(clientOrConfig) {
15
+ if (clientOrConfig instanceof MorphAPIClient) return clientOrConfig;
16
+ return new MorphAPIClient({
17
+ apiKey: clientOrConfig.morphApiKey,
18
+ baseURL: clientOrConfig.morphApiUrl ?? DEFAULT_API_URL,
19
+ timeout: clientOrConfig.timeout ?? DEFAULT_TIMEOUT,
20
+ retryConfig: clientOrConfig.retryConfig,
21
+ debug: clientOrConfig.debug
22
+ });
23
+ }
24
+ var CompactClient = class extends APIResource {
25
+ /** Resolved URL/timeout, exposed for backwards-compatible introspection. */
26
+ config;
27
+ constructor(clientOrConfig = {}) {
28
+ super(resolveClient(clientOrConfig));
29
+ const cfg = clientOrConfig instanceof MorphAPIClient ? {} : clientOrConfig;
30
+ this.config = {
31
+ morphApiUrl: this._client.baseURL,
32
+ timeout: cfg.timeout ?? DEFAULT_TIMEOUT,
33
+ debug: cfg.debug ?? false
34
+ };
35
+ }
36
+ /**
37
+ * Compact messages or text via /v1/compact.
38
+ * Returns per-message `compacted_line_ranges` showing which lines were removed.
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const client = new CompactClient({ morphApiKey: 'sk-...' });
43
+ * const result = await client.compact({
44
+ * input: codeFile,
45
+ * query: "authentication",
46
+ * compressionRatio: 0.5,
47
+ * });
48
+ * console.log(result.output);
49
+ * ```
50
+ */
51
+ async compact(input) {
52
+ const body = {
53
+ compression_ratio: input.compressionRatio ?? 0.5,
54
+ preserve_recent: input.preserveRecent ?? 2,
55
+ model: input.model ?? "morph-compactor",
56
+ include_line_ranges: input.includeLineRanges ?? true,
57
+ include_markers: input.includeMarkers ?? true
58
+ };
59
+ if (input.query !== void 0) body.query = input.query;
60
+ if (input.messages) body.messages = input.messages;
61
+ else if (typeof input.input === "string") body.input = input.input;
62
+ else if (Array.isArray(input.input)) body.messages = input.input;
63
+ else throw new Error("Either 'input' or 'messages' must be provided");
64
+ try {
65
+ return await this._client.post("/v1/compact", { body, timeout: this.config.timeout });
66
+ } catch (err) {
67
+ if (err instanceof MorphError) {
68
+ throw new Error(`Compact API error ${err.statusCode}: ${err.message}`);
69
+ }
70
+ throw err;
71
+ }
72
+ }
73
+ };
74
+
75
+ export {
76
+ CompactClient
77
+ };
78
+ //# sourceMappingURL=chunk-TS56XYWB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../tools/compact/core.ts"],"sourcesContent":["/**\n * CompactClient — calls the Morph /v1/compact endpoint.\n *\n * Returns per-message compacted_line_ranges showing which lines were removed.\n * HTTP goes through the shared `MorphAPIClient` transport.\n */\nimport { MorphAPIClient } from '../../core/client.js';\nimport { APIResource } from '../../core/resource.js';\nimport { MorphError } from '../utils/resilience.js';\nimport type { CompactConfig, CompactInput, CompactResult } from './types.js';\n\nconst DEFAULT_API_URL = 'https://api.morphllm.com';\nconst DEFAULT_TIMEOUT = 120000;\n\nfunction resolveClient(clientOrConfig: MorphAPIClient | CompactConfig): MorphAPIClient {\n if (clientOrConfig instanceof MorphAPIClient) return clientOrConfig;\n return new MorphAPIClient({\n apiKey: clientOrConfig.morphApiKey,\n baseURL: clientOrConfig.morphApiUrl ?? DEFAULT_API_URL,\n timeout: clientOrConfig.timeout ?? DEFAULT_TIMEOUT,\n retryConfig: clientOrConfig.retryConfig,\n debug: clientOrConfig.debug,\n });\n}\n\n/**\n * @deprecated Prefer the unified `MorphClient` (`new MorphClient({ apiKey }).compact`).\n * In edge runtimes where `MorphClient` is unavailable, pass a shared transport:\n * `new CompactClient(new MorphAPIClient({ apiKey }))`. Kept only for backwards compatibility.\n */\nexport class CompactClient extends APIResource {\n /** Resolved URL/timeout, exposed for backwards-compatible introspection. */\n readonly config: { morphApiUrl: string; timeout: number; debug: boolean };\n\n constructor(clientOrConfig: MorphAPIClient | CompactConfig = {}) {\n super(resolveClient(clientOrConfig));\n const cfg = clientOrConfig instanceof MorphAPIClient ? {} : clientOrConfig;\n this.config = {\n morphApiUrl: this._client.baseURL,\n timeout: cfg.timeout ?? DEFAULT_TIMEOUT,\n debug: cfg.debug ?? false,\n };\n }\n\n /**\n * Compact messages or text via /v1/compact.\n * Returns per-message `compacted_line_ranges` showing which lines were removed.\n *\n * @example\n * ```typescript\n * const client = new CompactClient({ morphApiKey: 'sk-...' });\n * const result = await client.compact({\n * input: codeFile,\n * query: \"authentication\",\n * compressionRatio: 0.5,\n * });\n * console.log(result.output);\n * ```\n */\n async compact(input: CompactInput): Promise<CompactResult> {\n // Build request body with snake_case keys\n const body: Record<string, unknown> = {\n compression_ratio: input.compressionRatio ?? 0.5,\n preserve_recent: input.preserveRecent ?? 2,\n model: input.model ?? 'morph-compactor',\n include_line_ranges: input.includeLineRanges ?? true,\n include_markers: input.includeMarkers ?? true,\n };\n\n if (input.query !== undefined) body.query = input.query;\n\n // Normalize input: string → { input }, array → { messages }, messages field → { messages }\n if (input.messages) body.messages = input.messages;\n else if (typeof input.input === 'string') body.input = input.input;\n else if (Array.isArray(input.input)) body.messages = input.input;\n else throw new Error(\"Either 'input' or 'messages' must be provided\");\n\n try {\n return await this._client.post<CompactResult>('/v1/compact', { body, timeout: this.config.timeout });\n } catch (err) {\n // Preserve the historical `Compact API error <status>: ...` message shape.\n if (err instanceof MorphError) {\n throw new Error(`Compact API error ${err.statusCode}: ${err.message}`);\n }\n throw err;\n }\n }\n}\n"],"mappings":";;;;;;;;;;;AAWA,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AAExB,SAAS,cAAc,gBAAgE;AACrF,MAAI,0BAA0B,eAAgB,QAAO;AACrD,SAAO,IAAI,eAAe;AAAA,IACxB,QAAQ,eAAe;AAAA,IACvB,SAAS,eAAe,eAAe;AAAA,IACvC,SAAS,eAAe,WAAW;AAAA,IACnC,aAAa,eAAe;AAAA,IAC5B,OAAO,eAAe;AAAA,EACxB,CAAC;AACH;AAOO,IAAM,gBAAN,cAA4B,YAAY;AAAA;AAAA,EAEpC;AAAA,EAET,YAAY,iBAAiD,CAAC,GAAG;AAC/D,UAAM,cAAc,cAAc,CAAC;AACnC,UAAM,MAAM,0BAA0B,iBAAiB,CAAC,IAAI;AAC5D,SAAK,SAAS;AAAA,MACZ,aAAa,KAAK,QAAQ;AAAA,MAC1B,SAAS,IAAI,WAAW;AAAA,MACxB,OAAO,IAAI,SAAS;AAAA,IACtB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,QAAQ,OAA6C;AAEzD,UAAM,OAAgC;AAAA,MACpC,mBAAmB,MAAM,oBAAoB;AAAA,MAC7C,iBAAiB,MAAM,kBAAkB;AAAA,MACzC,OAAO,MAAM,SAAS;AAAA,MACtB,qBAAqB,MAAM,qBAAqB;AAAA,MAChD,iBAAiB,MAAM,kBAAkB;AAAA,IAC3C;AAEA,QAAI,MAAM,UAAU,OAAW,MAAK,QAAQ,MAAM;AAGlD,QAAI,MAAM,SAAU,MAAK,WAAW,MAAM;AAAA,aACjC,OAAO,MAAM,UAAU,SAAU,MAAK,QAAQ,MAAM;AAAA,aACpD,MAAM,QAAQ,MAAM,KAAK,EAAG,MAAK,WAAW,MAAM;AAAA,QACtD,OAAM,IAAI,MAAM,+CAA+C;AAEpE,QAAI;AACF,aAAO,MAAM,KAAK,QAAQ,KAAoB,eAAe,EAAE,MAAM,SAAS,KAAK,OAAO,QAAQ,CAAC;AAAA,IACrG,SAAS,KAAK;AAEZ,UAAI,eAAe,YAAY;AAC7B,cAAM,IAAI,MAAM,qBAAqB,IAAI,UAAU,KAAK,IAAI,OAAO,EAAE;AAAA,MACvE;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;","names":[]}
@@ -14,7 +14,7 @@ import {
14
14
  executeToolCall,
15
15
  formatGitHubReadFileResult,
16
16
  formatResult
17
- } from "./chunk-JLLIVBKY.js";
17
+ } from "./chunk-ACWLQFYS.js";
18
18
 
19
19
  // tools/warp_grep/openai.ts
20
20
  var TOOL_PARAMETERS = {
@@ -104,4 +104,4 @@ export {
104
104
  createGitHubReadFileTool,
105
105
  openai_default
106
106
  };
107
- //# sourceMappingURL=chunk-5EUMJI3I.js.map
107
+ //# sourceMappingURL=chunk-TW3XQET2.js.map
@@ -1,6 +1,3 @@
1
- import {
2
- readAllLines
3
- } from "./chunk-G2RSY56Q.js";
4
1
  import {
5
2
  fixPathRepetition,
6
3
  isSymlink,
@@ -11,6 +8,9 @@ import {
11
8
  import {
12
9
  runRipgrep
13
10
  } from "./chunk-TPP2UGQP.js";
11
+ import {
12
+ readAllLines
13
+ } from "./chunk-G2RSY56Q.js";
14
14
  import {
15
15
  AGENT_CONFIG,
16
16
  DEFAULT_EXCLUDES
@@ -341,4 +341,4 @@ Details: ${res.stderr}` : ""}`
341
341
  export {
342
342
  LocalRipgrepProvider
343
343
  };
344
- //# sourceMappingURL=chunk-OPNTDMHH.js.map
344
+ //# sourceMappingURL=chunk-VLZ6PNAD.js.map
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=chunk-VZ7BOH2K.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,97 @@
1
+ import {
2
+ MorphAPIClient
3
+ } from "./chunk-QE3SPHIM.js";
4
+ import {
5
+ logger
6
+ } from "./chunk-F3NCFNUX.js";
7
+ import {
8
+ MorphError
9
+ } from "./chunk-JXJBF6CV.js";
10
+ import {
11
+ APIResource
12
+ } from "./chunk-LKFZBBTD.js";
13
+
14
+ // tools/codebase_search/core.ts
15
+ var DEFAULT_TIMEOUT = 3e4;
16
+ var emptyStats = { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: 0 };
17
+ async function runSearch(client, input, repoId, timeout, baseURL) {
18
+ const startTime = Date.now();
19
+ logger.debug("CodebaseSearch", "request", { query: input.query.slice(0, 100), repo_id: repoId });
20
+ try {
21
+ const data = await client.post(
22
+ "/v1/codebase_search",
23
+ {
24
+ baseURL: baseURL ?? client.reposURL,
25
+ timeout,
26
+ body: {
27
+ query: input.query,
28
+ repoId,
29
+ targetDirectories: input.target_directories || [],
30
+ limit: input.limit || 10,
31
+ candidateLimit: 50
32
+ }
33
+ }
34
+ );
35
+ const elapsed = Date.now() - startTime;
36
+ logger.debug("CodebaseSearch", "response", { results_count: data.results?.length || 0, latency_ms: elapsed });
37
+ return {
38
+ success: true,
39
+ results: data.results || [],
40
+ stats: data.stats || { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: elapsed }
41
+ };
42
+ } catch (error) {
43
+ const message = error instanceof MorphError && error.statusCode ? `Search failed (${error.statusCode}): ${error.message}` : error instanceof Error ? error.message : "Unknown error";
44
+ logger.error("CodebaseSearch", "error", { error: message, latency_ms: Date.now() - startTime });
45
+ return { success: false, results: [], stats: { ...emptyStats }, error: message };
46
+ }
47
+ }
48
+ var CodebaseSearchClient = class extends APIResource {
49
+ timeout;
50
+ constructor(clientOrConfig = {}) {
51
+ super(
52
+ clientOrConfig instanceof MorphAPIClient ? clientOrConfig : new MorphAPIClient({
53
+ apiKey: clientOrConfig.apiKey,
54
+ timeout: clientOrConfig.timeout ?? DEFAULT_TIMEOUT,
55
+ retryConfig: clientOrConfig.retryConfig,
56
+ debug: clientOrConfig.debug
57
+ })
58
+ );
59
+ this.timeout = (clientOrConfig instanceof MorphAPIClient ? void 0 : clientOrConfig.timeout) ?? DEFAULT_TIMEOUT;
60
+ }
61
+ /**
62
+ * Execute a semantic code search
63
+ *
64
+ * @param input - Search parameters including query, repoId, and target directories
65
+ * @param overrides - Optional config overrides for this operation
66
+ * @returns Search results with ranked code matches
67
+ */
68
+ async search(input, overrides) {
69
+ return runSearch(
70
+ this._client,
71
+ { query: input.query, target_directories: input.target_directories, explanation: input.explanation, limit: input.limit },
72
+ input.repoId,
73
+ overrides?.timeout ?? this.timeout,
74
+ overrides?.searchUrl
75
+ );
76
+ }
77
+ };
78
+ async function executeCodebaseSearch(input, config) {
79
+ const apiKey = config.apiKey || process.env.MORPH_API_KEY;
80
+ if (!apiKey) {
81
+ throw new Error("MORPH_API_KEY not found. Set environment variable or pass in config");
82
+ }
83
+ const client = new MorphAPIClient({
84
+ apiKey,
85
+ reposURL: config.searchUrl,
86
+ timeout: config.timeout ?? DEFAULT_TIMEOUT,
87
+ retryConfig: config.retryConfig,
88
+ debug: config.debug
89
+ });
90
+ return runSearch(client, input, config.repoId, config.timeout ?? DEFAULT_TIMEOUT, config.searchUrl);
91
+ }
92
+
93
+ export {
94
+ CodebaseSearchClient,
95
+ executeCodebaseSearch
96
+ };
97
+ //# sourceMappingURL=chunk-W6AGNJ5O.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../tools/codebase_search/core.ts"],"sourcesContent":["/**\n * Core implementation for codebase search.\n * Calls the Morph rerank service for two-stage semantic search over the\n * code-storage host, through the shared `MorphAPIClient` transport.\n */\nimport { MorphAPIClient } from '../../core/client.js';\nimport { APIResource } from '../../core/resource.js';\nimport { MorphError } from '../utils/resilience.js';\nimport { logger } from '../../logger.js';\nimport type { CodebaseSearchConfig, CodebaseSearchInput, CodebaseSearchResult } from './types.js';\n\nconst DEFAULT_TIMEOUT = 30000;\n\nconst emptyStats = { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: 0 };\n\n/**\n * Run a search against `/v1/codebase_search` on the repos host. HTTP failures\n * are returned in-band as `{ success: false, error }` (never thrown), matching\n * the long-standing contract callers rely on.\n */\nasync function runSearch(\n client: MorphAPIClient,\n input: CodebaseSearchInput,\n repoId: string,\n timeout: number,\n baseURL?: string,\n): Promise<CodebaseSearchResult> {\n const startTime = Date.now();\n logger.debug('CodebaseSearch', 'request', { query: input.query.slice(0, 100), repo_id: repoId });\n\n try {\n const data = await client.post<{ results?: unknown[]; stats?: CodebaseSearchResult['stats'] }>(\n '/v1/codebase_search',\n {\n baseURL: baseURL ?? client.reposURL,\n timeout,\n body: {\n query: input.query,\n repoId,\n targetDirectories: input.target_directories || [],\n limit: input.limit || 10,\n candidateLimit: 50,\n },\n },\n );\n\n const elapsed = Date.now() - startTime;\n logger.debug('CodebaseSearch', 'response', { results_count: data.results?.length || 0, latency_ms: elapsed });\n return {\n success: true,\n results: (data.results as CodebaseSearchResult['results']) || [],\n stats: data.stats || { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: elapsed },\n };\n } catch (error) {\n const message =\n error instanceof MorphError && error.statusCode\n ? `Search failed (${error.statusCode}): ${error.message}`\n : error instanceof Error\n ? error.message\n : 'Unknown error';\n logger.error('CodebaseSearch', 'error', { error: message, latency_ms: Date.now() - startTime });\n return { success: false, results: [], stats: { ...emptyStats }, error: message };\n }\n}\n\n/**\n * CodebaseSearch client for programmatic semantic search\n *\n * @deprecated Prefer the unified `MorphClient` (`new MorphClient({ apiKey }).codebaseSearch`).\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 CodebaseSearchClient extends APIResource {\n private readonly timeout: number;\n\n constructor(\n clientOrConfig: MorphAPIClient | { apiKey?: string; debug?: boolean; timeout?: number; retryConfig?: any } = {},\n ) {\n super(\n clientOrConfig instanceof MorphAPIClient\n ? clientOrConfig\n : new MorphAPIClient({\n apiKey: clientOrConfig.apiKey,\n timeout: clientOrConfig.timeout ?? DEFAULT_TIMEOUT,\n retryConfig: clientOrConfig.retryConfig,\n debug: clientOrConfig.debug,\n }),\n );\n this.timeout = (clientOrConfig instanceof MorphAPIClient ? undefined : clientOrConfig.timeout) ?? DEFAULT_TIMEOUT;\n }\n\n /**\n * Execute a semantic code search\n *\n * @param input - Search parameters including query, repoId, and target directories\n * @param overrides - Optional config overrides for this operation\n * @returns Search results with ranked code matches\n */\n async search(\n input: { query: string; repoId: string; target_directories?: string[]; explanation?: string; limit?: number },\n overrides?: { searchUrl?: string; timeout?: number },\n ): Promise<CodebaseSearchResult> {\n return runSearch(\n this._client,\n { query: input.query, target_directories: input.target_directories, explanation: input.explanation, limit: input.limit },\n input.repoId,\n overrides?.timeout ?? this.timeout,\n overrides?.searchUrl,\n );\n }\n}\n\n/**\n * Execute semantic code search (standalone — builds its own transport).\n * Throws on a missing API key; returns `{ success: false, error }` on HTTP failure.\n */\nexport async function executeCodebaseSearch(\n input: CodebaseSearchInput,\n config: CodebaseSearchConfig,\n): Promise<CodebaseSearchResult> {\n const apiKey = config.apiKey || process.env.MORPH_API_KEY;\n if (!apiKey) {\n throw new Error('MORPH_API_KEY not found. Set environment variable or pass in config');\n }\n\n const client = new MorphAPIClient({\n apiKey,\n reposURL: config.searchUrl,\n timeout: config.timeout ?? DEFAULT_TIMEOUT,\n retryConfig: config.retryConfig,\n debug: config.debug,\n });\n\n return runSearch(client, input, config.repoId, config.timeout ?? DEFAULT_TIMEOUT, config.searchUrl);\n}\n"],"mappings":";;;;;;;;;;;;;;AAWA,IAAM,kBAAkB;AAExB,IAAM,aAAa,EAAE,cAAc,GAAG,qBAAqB,GAAG,cAAc,EAAE;AAO9E,eAAe,UACb,QACA,OACA,QACA,SACA,SAC+B;AAC/B,QAAM,YAAY,KAAK,IAAI;AAC3B,SAAO,MAAM,kBAAkB,WAAW,EAAE,OAAO,MAAM,MAAM,MAAM,GAAG,GAAG,GAAG,SAAS,OAAO,CAAC;AAE/F,MAAI;AACF,UAAM,OAAO,MAAM,OAAO;AAAA,MACxB;AAAA,MACA;AAAA,QACE,SAAS,WAAW,OAAO;AAAA,QAC3B;AAAA,QACA,MAAM;AAAA,UACJ,OAAO,MAAM;AAAA,UACb;AAAA,UACA,mBAAmB,MAAM,sBAAsB,CAAC;AAAA,UAChD,OAAO,MAAM,SAAS;AAAA,UACtB,gBAAgB;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,WAAO,MAAM,kBAAkB,YAAY,EAAE,eAAe,KAAK,SAAS,UAAU,GAAG,YAAY,QAAQ,CAAC;AAC5G,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAU,KAAK,WAA+C,CAAC;AAAA,MAC/D,OAAO,KAAK,SAAS,EAAE,cAAc,GAAG,qBAAqB,GAAG,cAAc,QAAQ;AAAA,IACxF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,UACJ,iBAAiB,cAAc,MAAM,aACjC,kBAAkB,MAAM,UAAU,MAAM,MAAM,OAAO,KACrD,iBAAiB,QACf,MAAM,UACN;AACR,WAAO,MAAM,kBAAkB,SAAS,EAAE,OAAO,SAAS,YAAY,KAAK,IAAI,IAAI,UAAU,CAAC;AAC9F,WAAO,EAAE,SAAS,OAAO,SAAS,CAAC,GAAG,OAAO,EAAE,GAAG,WAAW,GAAG,OAAO,QAAQ;AAAA,EACjF;AACF;AASO,IAAM,uBAAN,cAAmC,YAAY;AAAA,EACnC;AAAA,EAEjB,YACE,iBAA6G,CAAC,GAC9G;AACA;AAAA,MACE,0BAA0B,iBACtB,iBACA,IAAI,eAAe;AAAA,QACjB,QAAQ,eAAe;AAAA,QACvB,SAAS,eAAe,WAAW;AAAA,QACnC,aAAa,eAAe;AAAA,QAC5B,OAAO,eAAe;AAAA,MACxB,CAAC;AAAA,IACP;AACA,SAAK,WAAW,0BAA0B,iBAAiB,SAAY,eAAe,YAAY;AAAA,EACpG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,OACA,WAC+B;AAC/B,WAAO;AAAA,MACL,KAAK;AAAA,MACL,EAAE,OAAO,MAAM,OAAO,oBAAoB,MAAM,oBAAoB,aAAa,MAAM,aAAa,OAAO,MAAM,MAAM;AAAA,MACvH,MAAM;AAAA,MACN,WAAW,WAAW,KAAK;AAAA,MAC3B,WAAW;AAAA,IACb;AAAA,EACF;AACF;AAMA,eAAsB,sBACpB,OACA,QAC+B;AAC/B,QAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAC5C,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,qEAAqE;AAAA,EACvF;AAEA,QAAM,SAAS,IAAI,eAAe;AAAA,IAChC;AAAA,IACA,UAAU,OAAO;AAAA,IACjB,SAAS,OAAO,WAAW;AAAA,IAC3B,aAAa,OAAO;AAAA,IACpB,OAAO,OAAO;AAAA,EAChB,CAAC;AAED,SAAO,UAAU,QAAQ,OAAO,OAAO,QAAQ,OAAO,WAAW,iBAAiB,OAAO,SAAS;AACpG;","names":[]}
@@ -0,0 +1,158 @@
1
+ import {
2
+ MorphAPIClient
3
+ } from "./chunk-QE3SPHIM.js";
4
+ import {
5
+ MorphError
6
+ } from "./chunk-JXJBF6CV.js";
7
+ import {
8
+ APIResource
9
+ } from "./chunk-LKFZBBTD.js";
10
+
11
+ // tools/reflex/core.ts
12
+ var BASE_MODEL = "morph-reflex-v1";
13
+ function resolveClient(clientOrConfig) {
14
+ if (clientOrConfig instanceof MorphAPIClient) return clientOrConfig;
15
+ return new MorphAPIClient({
16
+ apiKey: clientOrConfig.apiKey,
17
+ baseURL: clientOrConfig.baseUrl,
18
+ timeout: clientOrConfig.timeout,
19
+ retryConfig: clientOrConfig.retryConfig,
20
+ debug: clientOrConfig.debug
21
+ });
22
+ }
23
+ var ReflexClient = class extends APIResource {
24
+ /** Train, retrieve, and manage classifier jobs. */
25
+ jobs;
26
+ constructor(clientOrConfig = {}) {
27
+ super(resolveClient(clientOrConfig));
28
+ this.jobs = new ReflexJobsResource(this._client);
29
+ }
30
+ /** Classify text against a trained model. The model must be `succeeded`. */
31
+ async predict(input) {
32
+ const raw = await this._client.post("/v1/reflex/predict", {
33
+ body: { model: input.model, text: input.text }
34
+ });
35
+ return {
36
+ model: raw.model,
37
+ label: raw.label,
38
+ confidence: raw.confidence,
39
+ allScores: raw.all_scores ?? [],
40
+ inferenceTimeMs: raw.inference_time_ms
41
+ };
42
+ }
43
+ };
44
+ var ReflexJobsResource = class extends APIResource {
45
+ /** Start a training job from labeled data, a description, or unlabeled text. */
46
+ async create(input) {
47
+ return toReflexJob(await this._client.post("/v1/fine_tuning/jobs", { body: createBody(input) }));
48
+ }
49
+ /** Fetch a job by id. */
50
+ async retrieve(id) {
51
+ return toReflexJob(await this._client.get(`/v1/fine_tuning/jobs/${encodeURIComponent(id)}`));
52
+ }
53
+ /** List the caller's jobs, newest first. */
54
+ async list(input = {}) {
55
+ const raw = await this._client.get("/v1/fine_tuning/jobs", {
56
+ query: { limit: input.limit, after: input.after }
57
+ });
58
+ return { data: (raw.data ?? []).map(toReflexJob), hasMore: Boolean(raw.has_more) };
59
+ }
60
+ /** Stop a queued or running job. */
61
+ async cancel(id) {
62
+ return toReflexJob(await this._client.post(`/v1/fine_tuning/jobs/${encodeURIComponent(id)}/cancel`));
63
+ }
64
+ /** Delete a job and its trained model. */
65
+ async delete(id) {
66
+ const raw = await this._client.delete(
67
+ `/v1/fine_tuning/jobs/${encodeURIComponent(id)}`
68
+ );
69
+ return { id: raw.id, deleted: Boolean(raw.deleted) };
70
+ }
71
+ /** The training loss curve as events, plus a terminal event. */
72
+ async events(id) {
73
+ const raw = await this._client.get(
74
+ `/v1/fine_tuning/jobs/${encodeURIComponent(id)}/events`
75
+ );
76
+ return (raw.data ?? []).map(toReflexEvent);
77
+ }
78
+ /**
79
+ * Poll until the job reaches a terminal status and return it on success.
80
+ * Throws a `MorphError` if it fails, is cancelled, or exceeds `timeoutMs`.
81
+ */
82
+ async waitForReady(id, opts = {}) {
83
+ const pollMs = opts.pollMs ?? 3e3;
84
+ const deadline = Date.now() + (opts.timeoutMs ?? 15 * 6e4);
85
+ for (; ; ) {
86
+ const job = await this.retrieve(id);
87
+ if (job.status === "succeeded") return job;
88
+ if (job.status === "failed" || job.status === "cancelled") {
89
+ throw new MorphError(job.error?.message ?? `Reflex job ${job.status}`, `reflex_job_${job.status}`);
90
+ }
91
+ if (Date.now() >= deadline) {
92
+ throw new MorphError(`Reflex job ${id} did not finish in time`, "reflex_timeout");
93
+ }
94
+ await sleep(pollMs);
95
+ }
96
+ }
97
+ };
98
+ function createBody(input) {
99
+ const base = { model: BASE_MODEL };
100
+ if (input.suffix) base.suffix = input.suffix;
101
+ if ("trainingData" in input) {
102
+ if (input.labels) base.labels = input.labels;
103
+ return { ...base, training_data: input.trainingData };
104
+ }
105
+ if ("generate" in input) {
106
+ return {
107
+ ...base,
108
+ labels: input.labels,
109
+ generate: {
110
+ description: input.generate.description,
111
+ ...input.generate.examplesPerLabel != null ? { examples_per_label: input.generate.examplesPerLabel } : {}
112
+ }
113
+ };
114
+ }
115
+ return {
116
+ ...base,
117
+ labels: input.labels,
118
+ label_data: {
119
+ texts: input.labelData.texts,
120
+ ...input.labelData.description ? { description: input.labelData.description } : {}
121
+ }
122
+ };
123
+ }
124
+ function toReflexJob(raw) {
125
+ return {
126
+ id: raw.id,
127
+ object: "fine_tuning.job",
128
+ model: raw.model,
129
+ createdAt: raw.created_at,
130
+ finishedAt: raw.finished_at ?? null,
131
+ fineTunedModel: raw.fine_tuned_model ?? null,
132
+ status: raw.status,
133
+ labels: raw.labels ?? [],
134
+ trainedExamples: raw.trained_examples ?? 0,
135
+ result: raw.result ? { accuracy: raw.result.accuracy ?? null, f1Score: raw.result.f1_score ?? null } : null,
136
+ error: raw.error ? { message: raw.error.message } : null,
137
+ suffix: raw.suffix ?? null
138
+ };
139
+ }
140
+ function toReflexEvent(raw) {
141
+ return {
142
+ id: raw.id,
143
+ createdAt: raw.created_at,
144
+ level: raw.level,
145
+ message: raw.message,
146
+ type: raw.type,
147
+ data: { epoch: raw.data?.epoch ?? 0, step: raw.data?.step ?? 0, trainLoss: raw.data?.train_loss ?? 0 }
148
+ };
149
+ }
150
+ function sleep(ms) {
151
+ return new Promise((resolve) => setTimeout(resolve, ms));
152
+ }
153
+
154
+ export {
155
+ ReflexClient,
156
+ ReflexJobsResource
157
+ };
158
+ //# sourceMappingURL=chunk-YGNPVOUO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../tools/reflex/core.ts"],"sourcesContent":["/**\n * Reflex: train and serve small text classifiers.\n *\n * const morph = new MorphClient({ apiKey });\n * const job = await morph.reflex.jobs.create({ trainingData: rows, suffix: 'support' });\n * const ready = await morph.reflex.jobs.waitForReady(job.id);\n * const out = await morph.reflex.predict({ model: ready.fineTunedModel!, text: 'refund please' });\n *\n * Mirrors the OpenAI fine-tuning shape (`reflex.jobs.create/retrieve/list/cancel/delete`)\n * plus `reflex.predict`. All HTTP goes through the shared `MorphAPIClient` transport.\n */\nimport { MorphAPIClient } from '../../core/client.js';\nimport { APIResource } from '../../core/resource.js';\nimport { MorphError } from '../utils/resilience.js';\nimport type {\n CreateReflexJobInput,\n DeletedReflexJob,\n ListReflexJobsInput,\n ReflexConfig,\n ReflexEvent,\n ReflexJob,\n ReflexJobList,\n ReflexPredictInput,\n ReflexPredictResult,\n} from './types.js';\n\nconst BASE_MODEL = 'morph-reflex-v1';\n\n/** Build a transport from either a shared client or a standalone `ReflexConfig`. */\nfunction resolveClient(clientOrConfig: MorphAPIClient | ReflexConfig): MorphAPIClient {\n if (clientOrConfig instanceof MorphAPIClient) return clientOrConfig;\n return new MorphAPIClient({\n apiKey: clientOrConfig.apiKey,\n baseURL: clientOrConfig.baseUrl,\n timeout: clientOrConfig.timeout,\n retryConfig: clientOrConfig.retryConfig,\n debug: clientOrConfig.debug,\n });\n}\n\n/**\n * @deprecated Prefer the unified `MorphClient` (`new MorphClient({ apiKey }).reflex`).\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 ReflexClient extends APIResource {\n /** Train, retrieve, and manage classifier jobs. */\n public readonly jobs: ReflexJobsResource;\n\n constructor(clientOrConfig: MorphAPIClient | ReflexConfig = {}) {\n super(resolveClient(clientOrConfig));\n this.jobs = new ReflexJobsResource(this._client);\n }\n\n /** Classify text against a trained model. The model must be `succeeded`. */\n async predict(input: ReflexPredictInput): Promise<ReflexPredictResult> {\n const raw = await this._client.post<RawPredict>('/v1/reflex/predict', {\n body: { model: input.model, text: input.text },\n });\n return {\n model: raw.model,\n label: raw.label,\n confidence: raw.confidence,\n allScores: raw.all_scores ?? [],\n inferenceTimeMs: raw.inference_time_ms,\n };\n }\n}\n\nexport class ReflexJobsResource extends APIResource {\n /** Start a training job from labeled data, a description, or unlabeled text. */\n async create(input: CreateReflexJobInput): Promise<ReflexJob> {\n return toReflexJob(await this._client.post<RawJob>('/v1/fine_tuning/jobs', { body: createBody(input) }));\n }\n\n /** Fetch a job by id. */\n async retrieve(id: string): Promise<ReflexJob> {\n return toReflexJob(await this._client.get<RawJob>(`/v1/fine_tuning/jobs/${encodeURIComponent(id)}`));\n }\n\n /** List the caller's jobs, newest first. */\n async list(input: ListReflexJobsInput = {}): Promise<ReflexJobList> {\n const raw = await this._client.get<RawJobList>('/v1/fine_tuning/jobs', {\n query: { limit: input.limit, after: input.after },\n });\n return { data: (raw.data ?? []).map(toReflexJob), hasMore: Boolean(raw.has_more) };\n }\n\n /** Stop a queued or running job. */\n async cancel(id: string): Promise<ReflexJob> {\n return toReflexJob(await this._client.post<RawJob>(`/v1/fine_tuning/jobs/${encodeURIComponent(id)}/cancel`));\n }\n\n /** Delete a job and its trained model. */\n async delete(id: string): Promise<DeletedReflexJob> {\n const raw = await this._client.delete<{ id: string; deleted?: boolean }>(\n `/v1/fine_tuning/jobs/${encodeURIComponent(id)}`,\n );\n return { id: raw.id, deleted: Boolean(raw.deleted) };\n }\n\n /** The training loss curve as events, plus a terminal event. */\n async events(id: string): Promise<ReflexEvent[]> {\n const raw = await this._client.get<{ data?: RawEvent[] }>(\n `/v1/fine_tuning/jobs/${encodeURIComponent(id)}/events`,\n );\n return (raw.data ?? []).map(toReflexEvent);\n }\n\n /**\n * Poll until the job reaches a terminal status and return it on success.\n * Throws a `MorphError` if it fails, is cancelled, or exceeds `timeoutMs`.\n */\n async waitForReady(id: string, opts: { pollMs?: number; timeoutMs?: number } = {}): Promise<ReflexJob> {\n const pollMs = opts.pollMs ?? 3_000;\n const deadline = Date.now() + (opts.timeoutMs ?? 15 * 60_000);\n\n for (;;) {\n const job = await this.retrieve(id);\n if (job.status === 'succeeded') return job;\n if (job.status === 'failed' || job.status === 'cancelled') {\n throw new MorphError(job.error?.message ?? `Reflex job ${job.status}`, `reflex_job_${job.status}`);\n }\n if (Date.now() >= deadline) {\n throw new MorphError(`Reflex job ${id} did not finish in time`, 'reflex_timeout');\n }\n await sleep(pollMs);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Mapping (camelCase <-> snake_case) and helpers\n// ---------------------------------------------------------------------------\n\ninterface RawJob {\n id: string;\n model: string;\n created_at: number;\n finished_at: number | null;\n fine_tuned_model: string | null;\n status: ReflexJob['status'];\n labels?: string[];\n trained_examples?: number;\n result?: { accuracy: number | null; f1_score: number | null } | null;\n error?: { message: string } | null;\n suffix?: string | null;\n}\ninterface RawJobList {\n data?: RawJob[];\n has_more?: boolean;\n}\ninterface RawPredict {\n model: string;\n label: string;\n confidence: number;\n all_scores?: number[];\n inference_time_ms: number;\n}\ninterface RawEvent {\n id: string;\n created_at: number;\n level: ReflexEvent['level'];\n message: string;\n type: ReflexEvent['type'];\n data?: { epoch?: number; step?: number; train_loss?: number };\n}\n\nfunction createBody(input: CreateReflexJobInput): Record<string, unknown> {\n const base: Record<string, unknown> = { model: BASE_MODEL };\n if (input.suffix) base.suffix = input.suffix;\n\n if ('trainingData' in input) {\n if (input.labels) base.labels = input.labels;\n return { ...base, training_data: input.trainingData };\n }\n if ('generate' in input) {\n return {\n ...base,\n labels: input.labels,\n generate: {\n description: input.generate.description,\n ...(input.generate.examplesPerLabel != null ? { examples_per_label: input.generate.examplesPerLabel } : {}),\n },\n };\n }\n return {\n ...base,\n labels: input.labels,\n label_data: {\n texts: input.labelData.texts,\n ...(input.labelData.description ? { description: input.labelData.description } : {}),\n },\n };\n}\n\nfunction toReflexJob(raw: RawJob): ReflexJob {\n return {\n id: raw.id,\n object: 'fine_tuning.job',\n model: raw.model,\n createdAt: raw.created_at,\n finishedAt: raw.finished_at ?? null,\n fineTunedModel: raw.fine_tuned_model ?? null,\n status: raw.status,\n labels: raw.labels ?? [],\n trainedExamples: raw.trained_examples ?? 0,\n result: raw.result ? { accuracy: raw.result.accuracy ?? null, f1Score: raw.result.f1_score ?? null } : null,\n error: raw.error ? { message: raw.error.message } : null,\n suffix: raw.suffix ?? null,\n };\n}\n\nfunction toReflexEvent(raw: RawEvent): ReflexEvent {\n return {\n id: raw.id,\n createdAt: raw.created_at,\n level: raw.level,\n message: raw.message,\n type: raw.type,\n data: { epoch: raw.data?.epoch ?? 0, step: raw.data?.step ?? 0, trainLoss: raw.data?.train_loss ?? 0 },\n };\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n"],"mappings":"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","names":[]}
@@ -1,10 +1,10 @@
1
+ import {
2
+ executeEditFile
3
+ } from "./chunk-S5R4H5HM.js";
1
4
  import {
2
5
  EDIT_FILE_SYSTEM_PROMPT,
3
6
  EDIT_FILE_TOOL_DESCRIPTION
4
7
  } from "./chunk-63WE2C5R.js";
5
- import {
6
- executeEditFile
7
- } from "./chunk-4MTZUTNH.js";
8
8
  import {
9
9
  __export
10
10
  } from "./chunk-PZ5AY32C.js";
@@ -86,4 +86,4 @@ export {
86
86
  vercel_default,
87
87
  vercel_exports
88
88
  };
89
- //# sourceMappingURL=chunk-2OAKX4SZ.js.map
89
+ //# sourceMappingURL=chunk-Z3KRXUNG.js.map
@@ -0,0 +1,24 @@
1
+ import {
2
+ MorphError
3
+ } from "./chunk-JXJBF6CV.js";
4
+
5
+ // core/error.ts
6
+ async function toMorphError(response) {
7
+ let message = `Morph API request failed (${response.status})`;
8
+ let code = "api_error";
9
+ try {
10
+ const body = await response.json();
11
+ message = body.error?.message ?? body.message ?? message;
12
+ code = body.error?.code ?? body.error?.type ?? code;
13
+ } catch {
14
+ }
15
+ if (response.status === 401) code = "authentication_error";
16
+ if (response.status === 429) code = "rate_limit_exceeded";
17
+ const retryable = response.status === 429 || response.status === 503;
18
+ return new MorphError(message, code, response.status, retryable);
19
+ }
20
+
21
+ export {
22
+ toMorphError
23
+ };
24
+ //# sourceMappingURL=chunk-ZFOR3LI4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../core/error.ts"],"sourcesContent":["/**\n * Single error mapper for the SDK transport.\n *\n * Consolidates the per-tool error handling that used to live in every client\n * (compact, reflex, github, …) into one place, preserving the actionable\n * 401/429 messaging. Reuses the existing `MorphError` type so callers that\n * `instanceof MorphError` keep working.\n */\nimport { MorphError } from '../tools/utils/resilience.js';\n\ninterface ApiErrorBody {\n error?: { message?: string; code?: string; type?: string };\n message?: string;\n}\n\n/**\n * Turn a non-OK `Response` into a `MorphError`, extracting the API's error\n * message when present and marking 429/503 as retryable.\n */\nexport async function toMorphError(response: Response): Promise<MorphError> {\n let message = `Morph API request failed (${response.status})`;\n let code = 'api_error';\n\n try {\n const body = (await response.json()) as ApiErrorBody;\n message = body.error?.message ?? body.message ?? message;\n code = body.error?.code ?? body.error?.type ?? code;\n } catch {\n // Non-JSON body — keep the status-based default message.\n }\n\n if (response.status === 401) code = 'authentication_error';\n if (response.status === 429) code = 'rate_limit_exceeded';\n\n const retryable = response.status === 429 || response.status === 503;\n return new MorphError(message, code, response.status, retryable);\n}\n"],"mappings":";;;;;AAmBA,eAAsB,aAAa,UAAyC;AAC1E,MAAI,UAAU,6BAA6B,SAAS,MAAM;AAC1D,MAAI,OAAO;AAEX,MAAI;AACF,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,cAAU,KAAK,OAAO,WAAW,KAAK,WAAW;AACjD,WAAO,KAAK,OAAO,QAAQ,KAAK,OAAO,QAAQ;AAAA,EACjD,QAAQ;AAAA,EAER;AAEA,MAAI,SAAS,WAAW,IAAK,QAAO;AACpC,MAAI,SAAS,WAAW,IAAK,QAAO;AAEpC,QAAM,YAAY,SAAS,WAAW,OAAO,SAAS,WAAW;AACjE,SAAO,IAAI,WAAW,SAAS,MAAM,SAAS,QAAQ,SAAS;AACjE;","names":[]}
@@ -1,10 +1,13 @@
1
1
  import { RetryConfig } from './tools/utils/resilience.js';
2
+ import { MorphAPIClient } from './core/client.js';
2
3
  import { FastApplyClient } from './tools/fastapply/core.js';
3
4
  import { CodebaseSearchClient } from './tools/codebase_search/core.js';
4
5
  import { BrowserClient } from './tools/browser/core.js';
5
6
  import { WarpGrepClient } from './tools/warp_grep/client.js';
7
+ import { APIResource } from './core/resource.js';
6
8
  import { MorphGit } from './git/client.js';
7
9
  import { CompactClient } from './tools/compact/core.js';
10
+ import { ReflexClient } from './tools/reflex/core.js';
8
11
  import { OpenAIRouter, AnthropicRouter, GeminiRouter, RawRouter } from './modelrouter/core.js';
9
12
  import { EditFileConfig, EditFileInput, EditFileResult, EditChanges } from './tools/fastapply/types.js';
10
13
  import { CodebaseSearchConfig, CodebaseSearchInput, CodebaseSearchResult } from './tools/codebase_search/types.js';
@@ -515,10 +518,12 @@ declare class PermissionError extends GitHubError {
515
518
  * number: 42
516
519
  * });
517
520
  * ```
521
+ *
522
+ * @deprecated Prefer the unified `MorphClient` (`new MorphClient({ apiKey }).github`).
523
+ * Standalone clients remain only for backwards compatibility and may be removed in a future
524
+ * major version — do not use them in new code.
518
525
  */
519
- declare class GitHubClient {
520
- private apiKey;
521
- private baseUrl;
526
+ declare class GitHubClient extends APIResource {
522
527
  private timeout;
523
528
  private debug;
524
529
  private defaultInstallationId?;
@@ -580,7 +585,9 @@ declare class GitHubClient {
580
585
  * Users visit this URL once to install the Morph GitHub App on their account/org.
581
586
  */
582
587
  getInstallUrl(): string;
583
- constructor(config?: GitHubClientConfig);
588
+ constructor(clientOrConfig?: MorphAPIClient | GitHubClientConfig, options?: {
589
+ installationId?: string;
590
+ });
584
591
  /**
585
592
  * Make an authenticated API request
586
593
  */
@@ -961,7 +968,7 @@ interface MorphClientConfig {
961
968
  * - routers: Intelligent model selection (OpenAI, Anthropic, Gemini)
962
969
  * - openai/anthropic/vercel: Tool factories for agent frameworks
963
970
  */
964
- declare class MorphClient {
971
+ declare class MorphClient extends MorphAPIClient {
965
972
  /** Client configuration */
966
973
  config: MorphClientConfig;
967
974
  /** FastApply tool for editing files with AI-powered merge */
@@ -991,6 +998,8 @@ declare class MorphClient {
991
998
  vercel: VercelToolFactory;
992
999
  /** Compact context with line ranges */
993
1000
  compact: CompactClient['compact'];
1001
+ /** Reflex: train and serve small text classifiers */
1002
+ reflex: ReflexClient;
994
1003
  /**
995
1004
  * Create a new Morph SDK client
996
1005
  *