@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.
- package/dist/{chunk-3XRNC56L.js → chunk-2SNAXTUJ.js} +4 -4
- package/dist/chunk-453ZV2AX.js +120 -0
- package/dist/chunk-453ZV2AX.js.map +1 -0
- package/dist/chunk-53ZJMCWU.js +142 -0
- package/dist/chunk-53ZJMCWU.js.map +1 -0
- package/dist/{chunk-IW4TYYG6.js → chunk-5DA6SZQJ.js} +2 -2
- package/dist/chunk-66OHYI24.js +78 -0
- package/dist/chunk-66OHYI24.js.map +1 -0
- package/dist/chunk-6X6QMRQG.js +158 -0
- package/dist/chunk-6X6QMRQG.js.map +1 -0
- package/dist/{chunk-C37YAYBK.js → chunk-7PVVPLRL.js} +2 -2
- package/dist/{chunk-MZZMSL26.js → chunk-AE7M2I52.js} +2 -2
- package/dist/{chunk-JLLIVBKY.js → chunk-CQF76HJC.js} +30 -6
- package/dist/chunk-CQF76HJC.js.map +1 -0
- package/dist/{chunk-EFCDIESP.js → chunk-ESXCQBMU.js} +2 -2
- package/dist/{chunk-FQJCE2FX.js → chunk-FOIDGIY4.js} +29 -10
- package/dist/chunk-FOIDGIY4.js.map +1 -0
- package/dist/{chunk-JEDEBCZM.js → chunk-GJZXDRH5.js} +8 -3
- package/dist/{chunk-JEDEBCZM.js.map → chunk-GJZXDRH5.js.map} +1 -1
- package/dist/{chunk-2ALTBYMY.js → chunk-IJ33I7P5.js} +4 -4
- package/dist/{chunk-UK7TI7QY.js → chunk-IN2U7AAI.js} +99 -143
- package/dist/chunk-IN2U7AAI.js.map +1 -0
- package/dist/{chunk-LE66XCOI.js → chunk-JWZ5DLAS.js} +27 -10
- package/dist/chunk-JWZ5DLAS.js.map +1 -0
- package/dist/chunk-LKFZBBTD.js +12 -0
- package/dist/chunk-LKFZBBTD.js.map +1 -0
- package/dist/{chunk-TAS6S42A.js → chunk-MO6S2LRD.js} +2 -2
- package/dist/{chunk-2OAKX4SZ.js → chunk-NI7PWQ3B.js} +4 -4
- package/dist/{chunk-GLQWEINZ.js → chunk-QAXXE4AD.js} +2 -2
- package/dist/{chunk-3BCKZKNK.js → chunk-QFE5523Q.js} +2 -2
- package/dist/{chunk-LL3EWDKD.js → chunk-QQXNZIVK.js} +4 -4
- package/dist/{chunk-IGQYZ2KH.js → chunk-QZ3V2BP7.js} +2 -2
- package/dist/chunk-QZR7SJ5N.js +24 -0
- package/dist/chunk-QZR7SJ5N.js.map +1 -0
- package/dist/{chunk-SW527EQT.js → chunk-SJVLAGUL.js} +4 -4
- package/dist/{chunk-CMFY26F3.js → chunk-U4J3BVAQ.js} +4 -4
- package/dist/{chunk-5EUMJI3I.js → chunk-U4MRSZQQ.js} +2 -2
- package/dist/{chunk-ZJQTTOHO.js → chunk-UADW6FYD.js} +2 -2
- package/dist/{chunk-4324ZSCW.js → chunk-VBARKJWL.js} +2 -2
- package/dist/{chunk-OPNTDMHH.js → chunk-VLZ6PNAD.js} +4 -4
- package/dist/chunk-VZ7BOH2K.js +1 -0
- package/dist/chunk-VZ7BOH2K.js.map +1 -0
- package/dist/{chunk-Y6T4NA75.js → chunk-XJDXV5VX.js} +2 -2
- package/dist/{chunk-JTUB5ZCT.js → chunk-XYTYIAMQ.js} +2 -2
- package/dist/{chunk-4MTZUTNH.js → chunk-Z4GJVN52.js} +23 -8
- package/dist/chunk-Z4GJVN52.js.map +1 -0
- package/dist/chunk-ZLSNL6M2.js +97 -0
- package/dist/chunk-ZLSNL6M2.js.map +1 -0
- package/dist/{client-DsAAqupx.d.ts → client-Dh6yzCm4.d.ts} +14 -5
- package/dist/client.cjs +724 -523
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.ts +5 -1
- package/dist/client.js +31 -27
- package/dist/core/client.cjs +540 -0
- package/dist/core/client.cjs.map +1 -0
- package/dist/core/client.d.ts +79 -0
- package/dist/core/client.js +12 -0
- package/dist/core/client.js.map +1 -0
- package/dist/core/error.cjs +309 -0
- package/dist/core/error.cjs.map +1 -0
- package/dist/core/error.d.ts +18 -0
- package/dist/core/error.js +10 -0
- package/dist/core/error.js.map +1 -0
- package/dist/core/index.cjs +552 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +20 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/resource.cjs +36 -0
- package/dist/core/resource.cjs.map +1 -0
- package/dist/core/resource.d.ts +18 -0
- package/dist/core/resource.js +8 -0
- package/dist/core/resource.js.map +1 -0
- package/dist/edge.cjs +236 -173
- package/dist/edge.cjs.map +1 -1
- package/dist/edge.d.ts +2 -0
- package/dist/edge.js +8 -5
- package/dist/git/client.cjs +529 -9
- package/dist/git/client.cjs.map +1 -1
- package/dist/git/client.d.ts +8 -2
- package/dist/git/client.js +7 -1
- package/dist/git/index.cjs +529 -9
- package/dist/git/index.cjs.map +1 -1
- package/dist/git/index.d.ts +2 -0
- package/dist/git/index.js +7 -1
- package/dist/index.cjs +672 -465
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +49 -33
- package/dist/modelrouter/core.cjs +204 -125
- package/dist/modelrouter/core.cjs.map +1 -1
- package/dist/modelrouter/core.d.ts +36 -9
- package/dist/modelrouter/core.js +6 -3
- package/dist/modelrouter/index.cjs +204 -125
- package/dist/modelrouter/index.cjs.map +1 -1
- package/dist/modelrouter/index.d.ts +3 -0
- package/dist/modelrouter/index.js +6 -3
- package/dist/subagents/anthropic.cjs +268 -52
- package/dist/subagents/anthropic.cjs.map +1 -1
- package/dist/subagents/anthropic.js +10 -6
- package/dist/subagents/vercel.cjs +268 -52
- package/dist/subagents/vercel.cjs.map +1 -1
- package/dist/subagents/vercel.js +10 -6
- package/dist/tools/browser/anthropic.cjs +7 -2
- package/dist/tools/browser/anthropic.cjs.map +1 -1
- package/dist/tools/browser/anthropic.js +9 -6
- package/dist/tools/browser/core.cjs +162 -10
- package/dist/tools/browser/core.cjs.map +1 -1
- package/dist/tools/browser/core.d.ts +8 -2
- package/dist/tools/browser/core.js +8 -5
- package/dist/tools/browser/index.cjs +163 -11
- package/dist/tools/browser/index.cjs.map +1 -1
- package/dist/tools/browser/index.d.ts +2 -0
- package/dist/tools/browser/index.js +18 -15
- package/dist/tools/browser/index.js.map +1 -1
- package/dist/tools/browser/openai.cjs +7 -2
- package/dist/tools/browser/openai.cjs.map +1 -1
- package/dist/tools/browser/openai.js +9 -6
- package/dist/tools/browser/profiles/core.cjs +7 -2
- package/dist/tools/browser/profiles/core.cjs.map +1 -1
- package/dist/tools/browser/profiles/core.js +3 -3
- package/dist/tools/browser/profiles/index.cjs +7 -2
- package/dist/tools/browser/profiles/index.cjs.map +1 -1
- package/dist/tools/browser/profiles/index.js +3 -3
- package/dist/tools/browser/vercel.cjs +7 -2
- package/dist/tools/browser/vercel.cjs.map +1 -1
- package/dist/tools/browser/vercel.js +9 -6
- package/dist/tools/codebase_search/anthropic.cjs +162 -41
- package/dist/tools/codebase_search/anthropic.cjs.map +1 -1
- package/dist/tools/codebase_search/anthropic.js +7 -4
- package/dist/tools/codebase_search/core.cjs +195 -66
- package/dist/tools/codebase_search/core.cjs.map +1 -1
- package/dist/tools/codebase_search/core.d.ts +18 -7
- package/dist/tools/codebase_search/core.js +6 -3
- package/dist/tools/codebase_search/index.cjs +162 -41
- package/dist/tools/codebase_search/index.cjs.map +1 -1
- package/dist/tools/codebase_search/index.d.ts +2 -0
- package/dist/tools/codebase_search/index.js +13 -10
- package/dist/tools/codebase_search/openai.cjs +162 -41
- package/dist/tools/codebase_search/openai.cjs.map +1 -1
- package/dist/tools/codebase_search/openai.js +7 -4
- package/dist/tools/codebase_search/vercel.cjs +162 -41
- package/dist/tools/codebase_search/vercel.cjs.map +1 -1
- package/dist/tools/codebase_search/vercel.js +7 -4
- package/dist/tools/compact/core.cjs +551 -47
- package/dist/tools/compact/core.cjs.map +1 -1
- package/dist/tools/compact/core.d.ts +16 -3
- package/dist/tools/compact/core.js +7 -1
- package/dist/tools/compact/index.cjs +549 -47
- package/dist/tools/compact/index.cjs.map +1 -1
- package/dist/tools/compact/index.d.ts +2 -0
- package/dist/tools/compact/index.js +8 -2
- package/dist/tools/fastapply/anthropic.cjs +16 -2
- package/dist/tools/fastapply/anthropic.cjs.map +1 -1
- package/dist/tools/fastapply/anthropic.js +8 -4
- package/dist/tools/fastapply/apply.cjs +7 -2
- package/dist/tools/fastapply/apply.cjs.map +1 -1
- package/dist/tools/fastapply/apply.js +2 -2
- package/dist/tools/fastapply/core.cjs +242 -12
- package/dist/tools/fastapply/core.cjs.map +1 -1
- package/dist/tools/fastapply/core.d.ts +8 -2
- package/dist/tools/fastapply/core.js +7 -3
- package/dist/tools/fastapply/index.cjs +16 -2
- package/dist/tools/fastapply/index.cjs.map +1 -1
- package/dist/tools/fastapply/index.d.ts +2 -0
- package/dist/tools/fastapply/index.js +13 -9
- package/dist/tools/fastapply/openai.cjs +16 -2
- package/dist/tools/fastapply/openai.cjs.map +1 -1
- package/dist/tools/fastapply/openai.js +8 -4
- package/dist/tools/fastapply/vercel.cjs +16 -2
- package/dist/tools/fastapply/vercel.cjs.map +1 -1
- package/dist/tools/fastapply/vercel.js +8 -4
- package/dist/tools/index.cjs +16 -2
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.js +13 -9
- package/dist/tools/reflex/core.cjs +693 -0
- package/dist/tools/reflex/core.cjs.map +1 -0
- package/dist/tools/reflex/core.d.ts +53 -0
- package/dist/tools/reflex/core.js +16 -0
- package/dist/tools/reflex/core.js.map +1 -0
- package/dist/tools/reflex/index.cjs +693 -0
- package/dist/tools/reflex/index.cjs.map +1 -0
- package/dist/tools/reflex/index.d.ts +5 -0
- package/dist/tools/reflex/index.js +16 -0
- package/dist/tools/reflex/index.js.map +1 -0
- package/dist/tools/reflex/types.cjs +19 -0
- package/dist/tools/reflex/types.cjs.map +1 -0
- package/dist/tools/reflex/types.d.ts +113 -0
- package/dist/tools/reflex/types.js +1 -0
- package/dist/tools/reflex/types.js.map +1 -0
- package/dist/tools/utils/resilience.cjs +7 -2
- package/dist/tools/utils/resilience.cjs.map +1 -1
- package/dist/tools/utils/resilience.js +2 -2
- package/dist/tools/warp_grep/agent/runner.cjs +7 -2
- package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/runner.js +2 -2
- package/dist/tools/warp_grep/anthropic.cjs +268 -52
- package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
- package/dist/tools/warp_grep/anthropic.d.ts +2 -0
- package/dist/tools/warp_grep/anthropic.js +10 -6
- package/dist/tools/warp_grep/client.cjs +268 -52
- package/dist/tools/warp_grep/client.cjs.map +1 -1
- package/dist/tools/warp_grep/client.d.ts +8 -2
- package/dist/tools/warp_grep/client.js +9 -5
- package/dist/tools/warp_grep/gemini.cjs +268 -52
- package/dist/tools/warp_grep/gemini.cjs.map +1 -1
- package/dist/tools/warp_grep/gemini.d.ts +2 -0
- package/dist/tools/warp_grep/gemini.js +9 -5
- package/dist/tools/warp_grep/gemini.js.map +1 -1
- package/dist/tools/warp_grep/harness.js +5 -5
- package/dist/tools/warp_grep/index.cjs +268 -52
- package/dist/tools/warp_grep/index.cjs.map +1 -1
- package/dist/tools/warp_grep/index.d.ts +2 -0
- package/dist/tools/warp_grep/index.js +12 -8
- package/dist/tools/warp_grep/openai.cjs +268 -52
- package/dist/tools/warp_grep/openai.cjs.map +1 -1
- package/dist/tools/warp_grep/openai.d.ts +2 -0
- package/dist/tools/warp_grep/openai.js +10 -6
- package/dist/tools/warp_grep/providers/local.js +2 -2
- package/dist/tools/warp_grep/vercel.cjs +268 -52
- package/dist/tools/warp_grep/vercel.cjs.map +1 -1
- package/dist/tools/warp_grep/vercel.d.ts +2 -0
- package/dist/tools/warp_grep/vercel.js +10 -6
- package/dist/version.cjs +7 -2
- package/dist/version.cjs.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +7 -2
- package/dist/chunk-4MTZUTNH.js.map +0 -1
- package/dist/chunk-FQJCE2FX.js.map +0 -1
- package/dist/chunk-H5WNI6R5.js +0 -102
- package/dist/chunk-H5WNI6R5.js.map +0 -1
- package/dist/chunk-JLLIVBKY.js.map +0 -1
- package/dist/chunk-KCFMXLZ7.js +0 -197
- package/dist/chunk-KCFMXLZ7.js.map +0 -1
- package/dist/chunk-LE66XCOI.js.map +0 -1
- package/dist/chunk-SCVWDNQP.js +0 -84
- package/dist/chunk-SCVWDNQP.js.map +0 -1
- package/dist/chunk-UK7TI7QY.js.map +0 -1
- /package/dist/{chunk-3XRNC56L.js.map → chunk-2SNAXTUJ.js.map} +0 -0
- /package/dist/{chunk-IW4TYYG6.js.map → chunk-5DA6SZQJ.js.map} +0 -0
- /package/dist/{chunk-C37YAYBK.js.map → chunk-7PVVPLRL.js.map} +0 -0
- /package/dist/{chunk-MZZMSL26.js.map → chunk-AE7M2I52.js.map} +0 -0
- /package/dist/{chunk-EFCDIESP.js.map → chunk-ESXCQBMU.js.map} +0 -0
- /package/dist/{chunk-2ALTBYMY.js.map → chunk-IJ33I7P5.js.map} +0 -0
- /package/dist/{chunk-TAS6S42A.js.map → chunk-MO6S2LRD.js.map} +0 -0
- /package/dist/{chunk-2OAKX4SZ.js.map → chunk-NI7PWQ3B.js.map} +0 -0
- /package/dist/{chunk-GLQWEINZ.js.map → chunk-QAXXE4AD.js.map} +0 -0
- /package/dist/{chunk-3BCKZKNK.js.map → chunk-QFE5523Q.js.map} +0 -0
- /package/dist/{chunk-LL3EWDKD.js.map → chunk-QQXNZIVK.js.map} +0 -0
- /package/dist/{chunk-IGQYZ2KH.js.map → chunk-QZ3V2BP7.js.map} +0 -0
- /package/dist/{chunk-SW527EQT.js.map → chunk-SJVLAGUL.js.map} +0 -0
- /package/dist/{chunk-CMFY26F3.js.map → chunk-U4J3BVAQ.js.map} +0 -0
- /package/dist/{chunk-5EUMJI3I.js.map → chunk-U4MRSZQQ.js.map} +0 -0
- /package/dist/{chunk-ZJQTTOHO.js.map → chunk-UADW6FYD.js.map} +0 -0
- /package/dist/{chunk-4324ZSCW.js.map → chunk-VBARKJWL.js.map} +0 -0
- /package/dist/{chunk-OPNTDMHH.js.map → chunk-VLZ6PNAD.js.map} +0 -0
- /package/dist/{chunk-Y6T4NA75.js.map → chunk-XJDXV5VX.js.map} +0 -0
- /package/dist/{chunk-JTUB5ZCT.js.map → chunk-XYTYIAMQ.js.map} +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
executeCodebaseSearch
|
|
3
|
-
} from "./chunk-H5WNI6R5.js";
|
|
4
1
|
import {
|
|
5
2
|
CODEBASE_SEARCH_DESCRIPTION
|
|
6
3
|
} from "./chunk-YQMPVJ2L.js";
|
|
4
|
+
import {
|
|
5
|
+
executeCodebaseSearch
|
|
6
|
+
} from "./chunk-ZLSNL6M2.js";
|
|
7
7
|
|
|
8
8
|
// tools/codebase_search/vercel.ts
|
|
9
9
|
import { tool } from "ai";
|
|
@@ -55,4 +55,4 @@ export {
|
|
|
55
55
|
getSystemPrompt,
|
|
56
56
|
vercel_default
|
|
57
57
|
};
|
|
58
|
-
//# sourceMappingURL=chunk-
|
|
58
|
+
//# sourceMappingURL=chunk-2SNAXTUJ.js.map
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {
|
|
2
|
+
logger
|
|
3
|
+
} from "./chunk-F3NCFNUX.js";
|
|
4
|
+
import {
|
|
5
|
+
toMorphError
|
|
6
|
+
} from "./chunk-QZR7SJ5N.js";
|
|
7
|
+
import {
|
|
8
|
+
MorphError,
|
|
9
|
+
fetchWithRetry,
|
|
10
|
+
withTimeout
|
|
11
|
+
} from "./chunk-XYTYIAMQ.js";
|
|
12
|
+
import {
|
|
13
|
+
SDK_VERSION
|
|
14
|
+
} from "./chunk-GJZXDRH5.js";
|
|
15
|
+
|
|
16
|
+
// core/client.ts
|
|
17
|
+
var DEFAULT_BASE_URL = "https://api.morphllm.com";
|
|
18
|
+
var DEFAULT_REPOS_URL = "https://repos.morphllm.com";
|
|
19
|
+
var DEFAULT_BROWSER_URL = "https://browser.morphllm.com";
|
|
20
|
+
var DEFAULT_TIMEOUT = 6e4;
|
|
21
|
+
var env = (name) => typeof process !== "undefined" ? process.env?.[name] : void 0;
|
|
22
|
+
var stripTrailingSlash = (url) => url.replace(/\/+$/, "");
|
|
23
|
+
var MorphAPIClient = class {
|
|
24
|
+
/** Explicit key as provided; resolved against env at request time. */
|
|
25
|
+
apiKey;
|
|
26
|
+
baseURL;
|
|
27
|
+
reposURL;
|
|
28
|
+
browserURL;
|
|
29
|
+
/** Explicit default timeout (ms), if set. The request default is applied lazily so
|
|
30
|
+
* resources can read an undefined value and supply their own fallback. */
|
|
31
|
+
timeout;
|
|
32
|
+
retryConfig;
|
|
33
|
+
debug;
|
|
34
|
+
constructor(options = {}) {
|
|
35
|
+
this.apiKey = options.apiKey;
|
|
36
|
+
this.baseURL = stripTrailingSlash(options.baseURL ?? DEFAULT_BASE_URL);
|
|
37
|
+
this.reposURL = stripTrailingSlash(options.reposURL ?? env("MORPH_SEARCH_URL") ?? DEFAULT_REPOS_URL);
|
|
38
|
+
this.browserURL = stripTrailingSlash(
|
|
39
|
+
options.browserURL ?? (env("MORPH_ENVIRONMENT") === "DEV" ? "http://localhost:8000" : DEFAULT_BROWSER_URL)
|
|
40
|
+
);
|
|
41
|
+
this.timeout = options.timeout;
|
|
42
|
+
this.retryConfig = options.retryConfig;
|
|
43
|
+
this.debug = options.debug ?? false;
|
|
44
|
+
if (this.debug) logger.enable();
|
|
45
|
+
}
|
|
46
|
+
/** The key actually used for requests: explicit, else `MORPH_API_KEY`. */
|
|
47
|
+
resolveApiKey() {
|
|
48
|
+
return this.apiKey ?? env("MORPH_API_KEY");
|
|
49
|
+
}
|
|
50
|
+
/** Headers shared with tools that bring their own HTTP client (FastApply/WarpGrep via the `openai` package). */
|
|
51
|
+
defaultHeaders() {
|
|
52
|
+
return { "X-Morph-SDK-Version": SDK_VERSION };
|
|
53
|
+
}
|
|
54
|
+
buildURL(path, baseURL) {
|
|
55
|
+
if (/^https?:\/\//i.test(path)) return path;
|
|
56
|
+
const base = stripTrailingSlash(baseURL ?? this.baseURL);
|
|
57
|
+
return `${base}${path.startsWith("/") ? "" : "/"}${path}`;
|
|
58
|
+
}
|
|
59
|
+
buildHeaders(apiKey, extra) {
|
|
60
|
+
return {
|
|
61
|
+
"Content-Type": "application/json",
|
|
62
|
+
"X-Morph-SDK-Version": SDK_VERSION,
|
|
63
|
+
Authorization: `Bearer ${apiKey}`,
|
|
64
|
+
...extra
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
applyQuery(url, query) {
|
|
68
|
+
if (!query) return url;
|
|
69
|
+
const params = new URLSearchParams();
|
|
70
|
+
for (const [key, value] of Object.entries(query)) {
|
|
71
|
+
if (value !== void 0 && value !== null) params.set(key, String(value));
|
|
72
|
+
}
|
|
73
|
+
const qs = params.toString();
|
|
74
|
+
return qs ? `${url}${url.includes("?") ? "&" : "?"}${qs}` : url;
|
|
75
|
+
}
|
|
76
|
+
async request(method, path, opts = {}) {
|
|
77
|
+
const apiKey = this.resolveApiKey();
|
|
78
|
+
if (!apiKey) {
|
|
79
|
+
throw new MorphError(
|
|
80
|
+
"Morph API key not found. Set the MORPH_API_KEY environment variable or pass apiKey in config.",
|
|
81
|
+
"missing_api_key",
|
|
82
|
+
401
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
const url = this.applyQuery(this.buildURL(path, opts.baseURL), opts.query);
|
|
86
|
+
const timeout = opts.timeout ?? this.timeout ?? DEFAULT_TIMEOUT;
|
|
87
|
+
const init = {
|
|
88
|
+
method,
|
|
89
|
+
headers: this.buildHeaders(apiKey, opts.headers),
|
|
90
|
+
...opts.body !== void 0 ? { body: JSON.stringify(opts.body) } : {},
|
|
91
|
+
...opts.signal ? { signal: opts.signal } : {}
|
|
92
|
+
};
|
|
93
|
+
logger.debug("MorphAPIClient", "request", { method, url });
|
|
94
|
+
const response = await withTimeout(
|
|
95
|
+
fetchWithRetry(url, init, this.retryConfig ?? {}),
|
|
96
|
+
timeout,
|
|
97
|
+
`Morph request to ${url} timed out after ${timeout}ms`
|
|
98
|
+
);
|
|
99
|
+
if (opts.raw) return response;
|
|
100
|
+
if (!response.ok) throw await toMorphError(response);
|
|
101
|
+
if (opts.stream) return response;
|
|
102
|
+
if (response.status === 204) return void 0;
|
|
103
|
+
const text = await response.text();
|
|
104
|
+
return text ? JSON.parse(text) : void 0;
|
|
105
|
+
}
|
|
106
|
+
get(path, opts) {
|
|
107
|
+
return this.request("GET", path, opts);
|
|
108
|
+
}
|
|
109
|
+
post(path, opts) {
|
|
110
|
+
return this.request("POST", path, opts);
|
|
111
|
+
}
|
|
112
|
+
delete(path, opts) {
|
|
113
|
+
return this.request("DELETE", path, opts);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export {
|
|
118
|
+
MorphAPIClient
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=chunk-453ZV2AX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../core/client.ts"],"sourcesContent":["/**\n * MorphAPIClient — the SDK transport.\n *\n * One place owns authentication, the Morph service hosts, default headers,\n * retries, timeouts, and error mapping. Every resource (FastApply, Compact,\n * Reflex, …) holds a reference to this client and delegates HTTP to it via\n * `get`/`post`/`delete`/`request`, exactly like the OpenAI SDK.\n *\n * This module is intentionally free of tool imports and Node built-ins so it\n * stays edge-safe (it is reachable from `@morphllm/morphsdk/edge` through the\n * Compact and model-router resources).\n */\nimport { fetchWithRetry, withTimeout, MorphError, type RetryConfig } from '../tools/utils/resilience.js';\nimport { logger } from '../logger.js';\nimport { SDK_VERSION } from '../version.js';\nimport { toMorphError } from './error.js';\n\n/** The Morph services the SDK talks to. */\nconst DEFAULT_BASE_URL = 'https://api.morphllm.com';\nconst DEFAULT_REPOS_URL = 'https://repos.morphllm.com';\nconst DEFAULT_BROWSER_URL = 'https://browser.morphllm.com';\nconst DEFAULT_TIMEOUT = 60_000;\n\nconst env = (name: string): string | undefined =>\n typeof process !== 'undefined' ? process.env?.[name] : undefined;\n\nconst stripTrailingSlash = (url: string): string => url.replace(/\\/+$/, '');\n\nexport interface MorphAPIClientOptions {\n /** Morph API key. Resolved against `MORPH_API_KEY` at request time if omitted. */\n apiKey?: string;\n /** Primary API host (default `https://api.morphllm.com`). */\n baseURL?: string;\n /** Code-storage host for codebase search and git (default `https://repos.morphllm.com`). */\n reposURL?: string;\n /** Browser-automation host (default `https://browser.morphllm.com`). */\n browserURL?: string;\n /** Default per-request timeout in ms (default 60s). Resources may override per call. */\n timeout?: number;\n /** Retry policy for transient failures. */\n retryConfig?: RetryConfig;\n /** Enable debug logging. */\n debug?: boolean;\n}\n\n/** Per-request options accepted by `request`/`get`/`post`/`delete`. */\nexport interface RequestOptions {\n /** JSON body; serialized with `JSON.stringify`. */\n body?: unknown;\n /** Query parameters; `undefined`/`null` values are dropped. */\n query?: Record<string, string | number | boolean | undefined | null>;\n /** Extra headers, merged over (and able to override) the defaults. */\n headers?: Record<string, string>;\n /** Override the timeout for this call. */\n timeout?: number;\n /** Hit a different host than the default (e.g. `this._client.reposURL`). */\n baseURL?: string;\n /** Return the raw `Response` of a successful (2xx) request instead of parsed JSON (for streaming). */\n stream?: boolean;\n /**\n * Return the raw `Response` without throwing on non-2xx and without parsing.\n * For resources that map errors into their own taxonomy (e.g. GitHub).\n */\n raw?: boolean;\n /** Caller-supplied abort signal. */\n signal?: AbortSignal;\n}\n\nexport class MorphAPIClient {\n /** Explicit key as provided; resolved against env at request time. */\n apiKey?: string;\n baseURL: string;\n reposURL: string;\n browserURL: string;\n /** Explicit default timeout (ms), if set. The request default is applied lazily so\n * resources can read an undefined value and supply their own fallback. */\n timeout?: number;\n retryConfig?: RetryConfig;\n debug: boolean;\n\n constructor(options: MorphAPIClientOptions = {}) {\n this.apiKey = options.apiKey;\n this.baseURL = stripTrailingSlash(options.baseURL ?? DEFAULT_BASE_URL);\n this.reposURL = stripTrailingSlash(options.reposURL ?? env('MORPH_SEARCH_URL') ?? DEFAULT_REPOS_URL);\n this.browserURL = stripTrailingSlash(\n options.browserURL ?? (env('MORPH_ENVIRONMENT') === 'DEV' ? 'http://localhost:8000' : DEFAULT_BROWSER_URL),\n );\n this.timeout = options.timeout;\n this.retryConfig = options.retryConfig;\n this.debug = options.debug ?? false;\n if (this.debug) logger.enable();\n }\n\n /** The key actually used for requests: explicit, else `MORPH_API_KEY`. */\n resolveApiKey(): string | undefined {\n return this.apiKey ?? env('MORPH_API_KEY');\n }\n\n /** Headers shared with tools that bring their own HTTP client (FastApply/WarpGrep via the `openai` package). */\n defaultHeaders(): Record<string, string> {\n return { 'X-Morph-SDK-Version': SDK_VERSION };\n }\n\n buildURL(path: string, baseURL?: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n const base = stripTrailingSlash(baseURL ?? this.baseURL);\n return `${base}${path.startsWith('/') ? '' : '/'}${path}`;\n }\n\n private buildHeaders(apiKey: string, extra?: Record<string, string>): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n 'X-Morph-SDK-Version': SDK_VERSION,\n Authorization: `Bearer ${apiKey}`,\n ...extra,\n };\n }\n\n private applyQuery(url: string, query?: RequestOptions['query']): string {\n if (!query) return url;\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) params.set(key, String(value));\n }\n const qs = params.toString();\n return qs ? `${url}${url.includes('?') ? '&' : '?'}${qs}` : url;\n }\n\n async request<T>(method: string, path: string, opts: RequestOptions = {}): Promise<T> {\n const apiKey = this.resolveApiKey();\n if (!apiKey) {\n throw new MorphError(\n 'Morph API key not found. Set the MORPH_API_KEY environment variable or pass apiKey in config.',\n 'missing_api_key',\n 401,\n );\n }\n\n const url = this.applyQuery(this.buildURL(path, opts.baseURL), opts.query);\n const timeout = opts.timeout ?? this.timeout ?? DEFAULT_TIMEOUT;\n\n const init: RequestInit = {\n method,\n headers: this.buildHeaders(apiKey, opts.headers),\n ...(opts.body !== undefined ? { body: JSON.stringify(opts.body) } : {}),\n ...(opts.signal ? { signal: opts.signal } : {}),\n };\n\n logger.debug('MorphAPIClient', 'request', { method, url });\n\n const response = await withTimeout(\n fetchWithRetry(url, init, this.retryConfig ?? {}),\n timeout,\n `Morph request to ${url} timed out after ${timeout}ms`,\n );\n\n if (opts.raw) return response as unknown as T;\n if (!response.ok) throw await toMorphError(response);\n if (opts.stream) return response as unknown as T;\n if (response.status === 204) return undefined as T;\n\n const text = await response.text();\n return (text ? JSON.parse(text) : undefined) as T;\n }\n\n get<T>(path: string, opts?: RequestOptions): Promise<T> {\n return this.request<T>('GET', path, opts);\n }\n\n post<T>(path: string, opts?: RequestOptions): Promise<T> {\n return this.request<T>('POST', path, opts);\n }\n\n delete<T>(path: string, opts?: RequestOptions): Promise<T> {\n return this.request<T>('DELETE', path, opts);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,IAAM,mBAAmB;AACzB,IAAM,oBAAoB;AAC1B,IAAM,sBAAsB;AAC5B,IAAM,kBAAkB;AAExB,IAAM,MAAM,CAAC,SACX,OAAO,YAAY,cAAc,QAAQ,MAAM,IAAI,IAAI;AAEzD,IAAM,qBAAqB,CAAC,QAAwB,IAAI,QAAQ,QAAQ,EAAE;AA0CnE,IAAM,iBAAN,MAAqB;AAAA;AAAA,EAE1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,UAAiC,CAAC,GAAG;AAC/C,SAAK,SAAS,QAAQ;AACtB,SAAK,UAAU,mBAAmB,QAAQ,WAAW,gBAAgB;AACrE,SAAK,WAAW,mBAAmB,QAAQ,YAAY,IAAI,kBAAkB,KAAK,iBAAiB;AACnG,SAAK,aAAa;AAAA,MAChB,QAAQ,eAAe,IAAI,mBAAmB,MAAM,QAAQ,0BAA0B;AAAA,IACxF;AACA,SAAK,UAAU,QAAQ;AACvB,SAAK,cAAc,QAAQ;AAC3B,SAAK,QAAQ,QAAQ,SAAS;AAC9B,QAAI,KAAK,MAAO,QAAO,OAAO;AAAA,EAChC;AAAA;AAAA,EAGA,gBAAoC;AAClC,WAAO,KAAK,UAAU,IAAI,eAAe;AAAA,EAC3C;AAAA;AAAA,EAGA,iBAAyC;AACvC,WAAO,EAAE,uBAAuB,YAAY;AAAA,EAC9C;AAAA,EAEA,SAAS,MAAc,SAA0B;AAC/C,QAAI,gBAAgB,KAAK,IAAI,EAAG,QAAO;AACvC,UAAM,OAAO,mBAAmB,WAAW,KAAK,OAAO;AACvD,WAAO,GAAG,IAAI,GAAG,KAAK,WAAW,GAAG,IAAI,KAAK,GAAG,GAAG,IAAI;AAAA,EACzD;AAAA,EAEQ,aAAa,QAAgB,OAAwD;AAC3F,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,uBAAuB;AAAA,MACvB,eAAe,UAAU,MAAM;AAAA,MAC/B,GAAG;AAAA,IACL;AAAA,EACF;AAAA,EAEQ,WAAW,KAAa,OAAyC;AACvE,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,SAAS,IAAI,gBAAgB;AACnC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,UAAI,UAAU,UAAa,UAAU,KAAM,QAAO,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,IAC1E;AACA,UAAM,KAAK,OAAO,SAAS;AAC3B,WAAO,KAAK,GAAG,GAAG,GAAG,IAAI,SAAS,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE,KAAK;AAAA,EAC9D;AAAA,EAEA,MAAM,QAAW,QAAgB,MAAc,OAAuB,CAAC,GAAe;AACpF,UAAM,SAAS,KAAK,cAAc;AAClC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,MAAM,KAAK,WAAW,KAAK,SAAS,MAAM,KAAK,OAAO,GAAG,KAAK,KAAK;AACzE,UAAM,UAAU,KAAK,WAAW,KAAK,WAAW;AAEhD,UAAM,OAAoB;AAAA,MACxB;AAAA,MACA,SAAS,KAAK,aAAa,QAAQ,KAAK,OAAO;AAAA,MAC/C,GAAI,KAAK,SAAS,SAAY,EAAE,MAAM,KAAK,UAAU,KAAK,IAAI,EAAE,IAAI,CAAC;AAAA,MACrE,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,IAC/C;AAEA,WAAO,MAAM,kBAAkB,WAAW,EAAE,QAAQ,IAAI,CAAC;AAEzD,UAAM,WAAW,MAAM;AAAA,MACrB,eAAe,KAAK,MAAM,KAAK,eAAe,CAAC,CAAC;AAAA,MAChD;AAAA,MACA,oBAAoB,GAAG,oBAAoB,OAAO;AAAA,IACpD;AAEA,QAAI,KAAK,IAAK,QAAO;AACrB,QAAI,CAAC,SAAS,GAAI,OAAM,MAAM,aAAa,QAAQ;AACnD,QAAI,KAAK,OAAQ,QAAO;AACxB,QAAI,SAAS,WAAW,IAAK,QAAO;AAEpC,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAQ,OAAO,KAAK,MAAM,IAAI,IAAI;AAAA,EACpC;AAAA,EAEA,IAAO,MAAc,MAAmC;AACtD,WAAO,KAAK,QAAW,OAAO,MAAM,IAAI;AAAA,EAC1C;AAAA,EAEA,KAAQ,MAAc,MAAmC;AACvD,WAAO,KAAK,QAAW,QAAQ,MAAM,IAAI;AAAA,EAC3C;AAAA,EAEA,OAAU,MAAc,MAAmC;AACzD,WAAO,KAAK,QAAW,UAAU,MAAM,IAAI;AAAA,EAC7C;AACF;","names":[]}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MorphAPIClient
|
|
3
|
+
} from "./chunk-453ZV2AX.js";
|
|
4
|
+
import {
|
|
5
|
+
logger
|
|
6
|
+
} from "./chunk-F3NCFNUX.js";
|
|
7
|
+
import {
|
|
8
|
+
MorphError
|
|
9
|
+
} from "./chunk-XYTYIAMQ.js";
|
|
10
|
+
import {
|
|
11
|
+
APIResource
|
|
12
|
+
} from "./chunk-LKFZBBTD.js";
|
|
13
|
+
|
|
14
|
+
// modelrouter/core.ts
|
|
15
|
+
var DEFAULT_API_URL = "https://api.morphllm.com";
|
|
16
|
+
var DEFAULT_TIMEOUT = 5e3;
|
|
17
|
+
function resolveClient(clientOrConfig) {
|
|
18
|
+
if (clientOrConfig instanceof MorphAPIClient) return clientOrConfig;
|
|
19
|
+
return new MorphAPIClient({
|
|
20
|
+
apiKey: clientOrConfig.apiKey,
|
|
21
|
+
baseURL: clientOrConfig.apiUrl ?? DEFAULT_API_URL,
|
|
22
|
+
timeout: clientOrConfig.timeout ?? DEFAULT_TIMEOUT,
|
|
23
|
+
retryConfig: clientOrConfig.retryConfig,
|
|
24
|
+
debug: clientOrConfig.debug
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
var BaseRouter = class extends APIResource {
|
|
28
|
+
provider;
|
|
29
|
+
timeout;
|
|
30
|
+
constructor(provider, clientOrConfig = {}) {
|
|
31
|
+
super(resolveClient(clientOrConfig));
|
|
32
|
+
this.provider = provider;
|
|
33
|
+
const cfg = clientOrConfig instanceof MorphAPIClient ? {} : clientOrConfig;
|
|
34
|
+
this.timeout = cfg.timeout ?? DEFAULT_TIMEOUT;
|
|
35
|
+
}
|
|
36
|
+
/** Throw the historical "API key is required" message when no key is resolvable. */
|
|
37
|
+
requireApiKey() {
|
|
38
|
+
if (!this._client.resolveApiKey()) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
"Morph API key is required. Set MORPH_API_KEY environment variable or pass apiKey in config."
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** POST to the router and surface failures as `Router API error (<status>): ...`. */
|
|
45
|
+
async route(provider, input) {
|
|
46
|
+
try {
|
|
47
|
+
return await this._client.post(`/v1/router/${provider}`, {
|
|
48
|
+
body: { input: input.input, mode: input.mode || "balanced" },
|
|
49
|
+
timeout: this.timeout
|
|
50
|
+
});
|
|
51
|
+
} catch (error) {
|
|
52
|
+
if (error instanceof MorphError) {
|
|
53
|
+
throw new Error(`Router API error (${error.statusCode}): ${error.message}`);
|
|
54
|
+
}
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Select the optimal model for a given input and mode
|
|
60
|
+
*/
|
|
61
|
+
async selectModel(input) {
|
|
62
|
+
this.requireApiKey();
|
|
63
|
+
logger.debug("ModelRouter", "request", { provider: this.provider, mode: input.mode || "balanced" });
|
|
64
|
+
const apiResult = await this.route(this.provider, input);
|
|
65
|
+
logger.debug("ModelRouter", "selected", { provider: this.provider, model: apiResult.model });
|
|
66
|
+
return { model: apiResult.model };
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
var OpenAIRouter = class extends BaseRouter {
|
|
70
|
+
constructor(clientOrConfig = {}) {
|
|
71
|
+
super("openai", clientOrConfig);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Select optimal GPT-5 model
|
|
75
|
+
*
|
|
76
|
+
* @param input - User input and mode
|
|
77
|
+
* @returns Selected model name (gpt-5-mini | gpt-5-low | gpt-5-medium | gpt-5-high)
|
|
78
|
+
*/
|
|
79
|
+
async selectModel(input) {
|
|
80
|
+
return super.selectModel(input);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var AnthropicRouter = class extends BaseRouter {
|
|
84
|
+
constructor(clientOrConfig = {}) {
|
|
85
|
+
super("anthropic", clientOrConfig);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Select optimal Claude model
|
|
89
|
+
*
|
|
90
|
+
* @param input - User input and mode
|
|
91
|
+
* @returns Selected model name (claude-4.5-haiku | claude-4.5-sonnet)
|
|
92
|
+
*/
|
|
93
|
+
async selectModel(input) {
|
|
94
|
+
return super.selectModel(input);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
var GeminiRouter = class extends BaseRouter {
|
|
98
|
+
constructor(clientOrConfig = {}) {
|
|
99
|
+
super("gemini", clientOrConfig);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Select optimal Gemini model
|
|
103
|
+
*
|
|
104
|
+
* @param input - User input and mode
|
|
105
|
+
* @returns Selected model name (gemini-2.5-flash | gemini-2.5-pro)
|
|
106
|
+
*/
|
|
107
|
+
async selectModel(input) {
|
|
108
|
+
return super.selectModel(input);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
var RawRouter = class extends BaseRouter {
|
|
112
|
+
constructor(clientOrConfig = {}) {
|
|
113
|
+
super("raw", clientOrConfig);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get raw difficulty classification
|
|
117
|
+
*
|
|
118
|
+
* @param input - User input and mode
|
|
119
|
+
* @returns Raw difficulty (easy | medium | hard | needs_info)
|
|
120
|
+
*/
|
|
121
|
+
async classify(input) {
|
|
122
|
+
this.requireApiKey();
|
|
123
|
+
logger.debug("RawRouter", "request", { mode: input.mode || "balanced" });
|
|
124
|
+
const apiResult = await this.route("raw", input);
|
|
125
|
+
let difficulty;
|
|
126
|
+
if (apiResult.difficulty === "") {
|
|
127
|
+
difficulty = "medium";
|
|
128
|
+
} else {
|
|
129
|
+
difficulty = apiResult.difficulty || apiResult.model;
|
|
130
|
+
}
|
|
131
|
+
logger.debug("RawRouter", "classified", { difficulty });
|
|
132
|
+
return { difficulty };
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export {
|
|
137
|
+
OpenAIRouter,
|
|
138
|
+
AnthropicRouter,
|
|
139
|
+
GeminiRouter,
|
|
140
|
+
RawRouter
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=chunk-53ZJMCWU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../modelrouter/core.ts"],"sourcesContent":["/**\n * Core implementation for intelligent model routing.\n *\n * Routers are thin resources over the shared `MorphAPIClient` transport: they\n * POST to `/v1/router/<provider>` and map the response. Auth, retries, timeouts,\n * and the SDK-version header all live in the transport.\n */\nimport { MorphAPIClient } from '../core/client.js';\nimport { APIResource } from '../core/resource.js';\nimport { MorphError } from '../tools/utils/resilience.js';\nimport { logger } from '../logger.js';\nimport type {\n RouterConfig,\n RouterInput,\n RouterResult,\n RawRouterResult,\n ComplexityLevel,\n Provider,\n} from './types.js';\n\nconst DEFAULT_API_URL = 'https://api.morphllm.com';\nconst DEFAULT_TIMEOUT = 5000; // 5 seconds (responses typically <500ms)\n\nfunction resolveClient(clientOrConfig: MorphAPIClient | RouterConfig): MorphAPIClient {\n if (clientOrConfig instanceof MorphAPIClient) return clientOrConfig;\n return new MorphAPIClient({\n apiKey: clientOrConfig.apiKey,\n baseURL: clientOrConfig.apiUrl ?? DEFAULT_API_URL,\n timeout: clientOrConfig.timeout ?? DEFAULT_TIMEOUT,\n retryConfig: clientOrConfig.retryConfig,\n debug: clientOrConfig.debug,\n });\n}\n\nabstract class BaseRouter extends APIResource {\n protected provider: Provider;\n protected timeout: number;\n\n constructor(provider: Provider, clientOrConfig: MorphAPIClient | RouterConfig = {}) {\n super(resolveClient(clientOrConfig));\n this.provider = provider;\n const cfg = clientOrConfig instanceof MorphAPIClient ? {} : clientOrConfig;\n this.timeout = cfg.timeout ?? DEFAULT_TIMEOUT;\n }\n\n /** Throw the historical \"API key is required\" message when no key is resolvable. */\n protected requireApiKey(): void {\n if (!this._client.resolveApiKey()) {\n throw new Error(\n 'Morph API key is required. Set MORPH_API_KEY environment variable or pass apiKey in config.',\n );\n }\n }\n\n /** POST to the router and surface failures as `Router API error (<status>): ...`. */\n protected async route<T>(provider: string, input: RouterInput): Promise<T> {\n try {\n return await this._client.post<T>(`/v1/router/${provider}`, {\n body: { input: input.input, mode: input.mode || 'balanced' },\n timeout: this.timeout,\n });\n } catch (error) {\n if (error instanceof MorphError) {\n throw new Error(`Router API error (${error.statusCode}): ${error.message}`);\n }\n throw error;\n }\n }\n\n /**\n * Select the optimal model for a given input and mode\n */\n async selectModel(input: RouterInput): Promise<RouterResult> {\n this.requireApiKey();\n logger.debug('ModelRouter', 'request', { provider: this.provider, mode: input.mode || 'balanced' });\n const apiResult = await this.route<{ model: string; confidence?: number }>(this.provider, input);\n logger.debug('ModelRouter', 'selected', { provider: this.provider, model: apiResult.model });\n return { model: apiResult.model };\n }\n}\n\n/**\n * OpenAI model router for GPT-5 series\n *\n * @deprecated Prefer `MorphClient` (`new MorphClient({ apiKey }).routers.openai`). In edge\n * runtimes where `MorphClient` is unavailable, pass a shared transport:\n * `new OpenAIRouter(new MorphAPIClient({ apiKey }))`. Kept only for backwards compatibility.\n */\nexport class OpenAIRouter extends BaseRouter {\n constructor(clientOrConfig: MorphAPIClient | RouterConfig = {}) {\n super('openai', clientOrConfig);\n }\n\n /**\n * Select optimal GPT-5 model\n *\n * @param input - User input and mode\n * @returns Selected model name (gpt-5-mini | gpt-5-low | gpt-5-medium | gpt-5-high)\n */\n async selectModel(input: RouterInput): Promise<RouterResult> {\n return super.selectModel(input);\n }\n}\n\n/**\n * Anthropic model router for Claude 4.5 series\n *\n * @deprecated Prefer `MorphClient` (`new MorphClient({ apiKey }).routers.anthropic`). In edge\n * runtimes where `MorphClient` is unavailable, pass a shared transport:\n * `new AnthropicRouter(new MorphAPIClient({ apiKey }))`. Kept only for backwards compatibility.\n */\nexport class AnthropicRouter extends BaseRouter {\n constructor(clientOrConfig: MorphAPIClient | RouterConfig = {}) {\n super('anthropic', clientOrConfig);\n }\n\n /**\n * Select optimal Claude model\n *\n * @param input - User input and mode\n * @returns Selected model name (claude-4.5-haiku | claude-4.5-sonnet)\n */\n async selectModel(input: RouterInput): Promise<RouterResult> {\n return super.selectModel(input);\n }\n}\n\n/**\n * Google Gemini model router\n *\n * @deprecated Prefer `MorphClient` (`new MorphClient({ apiKey }).routers.gemini`). In edge\n * runtimes where `MorphClient` is unavailable, pass a shared transport:\n * `new GeminiRouter(new MorphAPIClient({ apiKey }))`. Kept only for backwards compatibility.\n */\nexport class GeminiRouter extends BaseRouter {\n constructor(clientOrConfig: MorphAPIClient | RouterConfig = {}) {\n super('gemini', clientOrConfig);\n }\n\n /**\n * Select optimal Gemini model\n *\n * @param input - User input and mode\n * @returns Selected model name (gemini-2.5-flash | gemini-2.5-pro)\n */\n async selectModel(input: RouterInput): Promise<RouterResult> {\n return super.selectModel(input);\n }\n}\n\n/**\n * Raw difficulty classification router (no provider-specific mapping)\n *\n * @deprecated Prefer `MorphClient` (`new MorphClient({ apiKey }).routers.raw`). In edge\n * runtimes where `MorphClient` is unavailable, pass a shared transport:\n * `new RawRouter(new MorphAPIClient({ apiKey }))`. Kept only for backwards compatibility.\n */\nexport class RawRouter extends BaseRouter {\n constructor(clientOrConfig: MorphAPIClient | RouterConfig = {}) {\n super('raw' as Provider, clientOrConfig);\n }\n\n /**\n * Get raw difficulty classification\n *\n * @param input - User input and mode\n * @returns Raw difficulty (easy | medium | hard | needs_info)\n */\n async classify(input: RouterInput): Promise<RawRouterResult> {\n this.requireApiKey();\n logger.debug('RawRouter', 'request', { mode: input.mode || 'balanced' });\n\n const apiResult = await this.route<{ model?: string; difficulty?: string; confidence?: number }>('raw', input);\n\n // Support both 'model' and 'difficulty' fields for compatibility.\n // Empty string from API means \"medium\" difficulty (API bug workaround).\n let difficulty: ComplexityLevel;\n if (apiResult.difficulty === '') {\n difficulty = 'medium';\n } else {\n difficulty = (apiResult.difficulty || apiResult.model) as ComplexityLevel;\n }\n\n logger.debug('RawRouter', 'classified', { difficulty });\n return { difficulty };\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
executeToolCall,
|
|
15
15
|
formatGitHubReadFileResult,
|
|
16
16
|
formatResult
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-CQF76HJC.js";
|
|
18
18
|
|
|
19
19
|
// tools/warp_grep/anthropic.ts
|
|
20
20
|
var INPUT_SCHEMA = {
|
|
@@ -90,4 +90,4 @@ export {
|
|
|
90
90
|
createGitHubSearchTool,
|
|
91
91
|
createGitHubReadFileTool
|
|
92
92
|
};
|
|
93
|
-
//# sourceMappingURL=chunk-
|
|
93
|
+
//# sourceMappingURL=chunk-5DA6SZQJ.js.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MorphAPIClient
|
|
3
|
+
} from "./chunk-453ZV2AX.js";
|
|
4
|
+
import {
|
|
5
|
+
MorphError
|
|
6
|
+
} from "./chunk-XYTYIAMQ.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-66OHYI24.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":[]}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MorphAPIClient
|
|
3
|
+
} from "./chunk-453ZV2AX.js";
|
|
4
|
+
import {
|
|
5
|
+
MorphError
|
|
6
|
+
} from "./chunk-XYTYIAMQ.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-6X6QMRQG.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?: Record<string, 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":[]}
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
} from "./chunk-F3NCFNUX.js";
|
|
24
24
|
import {
|
|
25
25
|
SDK_VERSION
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-GJZXDRH5.js";
|
|
27
27
|
|
|
28
28
|
// tools/warp_grep/agent/runner.ts
|
|
29
29
|
import OpenAI from "openai";
|
|
@@ -425,4 +425,4 @@ export {
|
|
|
425
425
|
runWarpGrepStreaming,
|
|
426
426
|
runWarpGrep
|
|
427
427
|
};
|
|
428
|
-
//# sourceMappingURL=chunk-
|
|
428
|
+
//# sourceMappingURL=chunk-7PVVPLRL.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
WarpGrepClient,
|
|
3
3
|
formatResult
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CQF76HJC.js";
|
|
5
5
|
import {
|
|
6
6
|
CODEBASE_SEARCH_TOOL,
|
|
7
7
|
SEND_MESSAGE_TOOL,
|
|
@@ -285,4 +285,4 @@ function deduplicateContexts(contexts) {
|
|
|
285
285
|
export {
|
|
286
286
|
createExploreSubagent
|
|
287
287
|
};
|
|
288
|
-
//# sourceMappingURL=chunk-
|
|
288
|
+
//# sourceMappingURL=chunk-AE7M2I52.js.map
|