@axlsdk/studio 0.16.1 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/{chunk-RE6VPUXA.js → chunk-GADFO7DZ.js} +159 -71
- package/dist/chunk-GADFO7DZ.js.map +1 -0
- package/dist/cli.cjs +173 -126
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +36 -10
- package/dist/cli.js.map +1 -1
- package/dist/client/assets/index-C3yGF34O.js +313 -0
- package/dist/client/assets/index-DNRVA4F2.css +1 -0
- package/dist/client/index.html +2 -2
- package/dist/middleware.cjs +205 -174
- package/dist/middleware.cjs.map +1 -1
- package/dist/middleware.js +37 -67
- package/dist/middleware.js.map +1 -1
- package/dist/server/index.cjs +158 -70
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +13 -0
- package/dist/server/index.d.ts +13 -0
- package/dist/server/index.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-JGQ3MSIG.js +0 -80
- package/dist/chunk-JGQ3MSIG.js.map +0 -1
- package/dist/chunk-RE6VPUXA.js.map +0 -1
- package/dist/client/assets/index-BzQe3w-R.js +0 -313
- package/dist/client/assets/index-C2nTRFWX.css +0 -1
package/dist/middleware.cjs
CHANGED
|
@@ -34,9 +34,9 @@ __export(middleware_exports, {
|
|
|
34
34
|
handleWsMessage: () => handleWsMessage
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(middleware_exports);
|
|
37
|
-
var
|
|
38
|
-
var
|
|
39
|
-
var
|
|
37
|
+
var import_node_path3 = require("path");
|
|
38
|
+
var import_node_fs2 = require("fs");
|
|
39
|
+
var import_node_url2 = require("url");
|
|
40
40
|
var import_node_server = require("@hono/node-server");
|
|
41
41
|
var import_ws = require("ws");
|
|
42
42
|
|
|
@@ -142,8 +142,11 @@ function redactEvalItem(item) {
|
|
|
142
142
|
}
|
|
143
143
|
function redactEvalResult(result, redact) {
|
|
144
144
|
if (!redact) return result;
|
|
145
|
+
const meta = result.metadata;
|
|
146
|
+
const scrubbedMetadata = meta && typeof meta.batchFailure === "string" ? { ...meta, batchFailure: REDACTED } : result.metadata;
|
|
145
147
|
return {
|
|
146
148
|
...result,
|
|
149
|
+
metadata: scrubbedMetadata,
|
|
147
150
|
items: result.items.map(redactEvalItem)
|
|
148
151
|
};
|
|
149
152
|
}
|
|
@@ -938,13 +941,18 @@ function reduceEvalTrends(acc, entry) {
|
|
|
938
941
|
const cost = extractCost(entry.data);
|
|
939
942
|
const model = extractModel(entry.data);
|
|
940
943
|
const duration = extractDuration(entry.data);
|
|
944
|
+
const metadata = entry.data?.metadata;
|
|
945
|
+
const runGroupId = typeof metadata?.runGroupId === "string" ? metadata.runGroupId : void 0;
|
|
946
|
+
const batchAttempted = typeof metadata?.batchAttempted === "number" && Number.isFinite(metadata.batchAttempted) ? metadata.batchAttempted : void 0;
|
|
941
947
|
const run = {
|
|
942
948
|
timestamp: entry.timestamp,
|
|
943
949
|
id: entry.id,
|
|
944
950
|
scores,
|
|
945
951
|
cost,
|
|
946
952
|
...model !== void 0 ? { model } : {},
|
|
947
|
-
...duration !== void 0 ? { duration } : {}
|
|
953
|
+
...duration !== void 0 ? { duration } : {},
|
|
954
|
+
...runGroupId !== void 0 ? { runGroupId } : {},
|
|
955
|
+
...batchAttempted !== void 0 ? { batchAttempted } : {}
|
|
948
956
|
};
|
|
949
957
|
const byEval = { ...acc.byEval };
|
|
950
958
|
const prev = byEval[entry.eval];
|
|
@@ -1627,33 +1635,79 @@ function createEvalRoutes(connMgr, evalLoader) {
|
|
|
1627
1635
|
if (runs > 1) {
|
|
1628
1636
|
const runGroupId = (0, import_node_crypto.randomUUID)();
|
|
1629
1637
|
const results = [];
|
|
1638
|
+
let runFailure;
|
|
1639
|
+
let cancelled = false;
|
|
1630
1640
|
for (let r = 0; r < runs; r++) {
|
|
1631
|
-
if (ac.signal.aborted)
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1641
|
+
if (ac.signal.aborted) {
|
|
1642
|
+
cancelled = true;
|
|
1643
|
+
break;
|
|
1644
|
+
}
|
|
1645
|
+
try {
|
|
1646
|
+
const result = await runtime.runRegisteredEval(name, {
|
|
1647
|
+
metadata: { runGroupId, runIndex: r, batchAttempted: runs },
|
|
1648
|
+
signal: ac.signal,
|
|
1649
|
+
captureTraces,
|
|
1650
|
+
onProgress: (event) => {
|
|
1651
|
+
if (event.type === "run_done") return;
|
|
1652
|
+
connMgr.broadcastWithWildcard(`eval:${evalRunId}`, {
|
|
1653
|
+
...event,
|
|
1654
|
+
run: r + 1,
|
|
1655
|
+
totalRuns: runs
|
|
1656
|
+
});
|
|
1657
|
+
}
|
|
1658
|
+
});
|
|
1659
|
+
results.push(result);
|
|
1660
|
+
connMgr.broadcastWithWildcard(`eval:${evalRunId}`, {
|
|
1661
|
+
type: "run_done",
|
|
1662
|
+
run: r + 1,
|
|
1663
|
+
totalRuns: runs
|
|
1664
|
+
});
|
|
1665
|
+
} catch (err) {
|
|
1666
|
+
const isAbort = ac.signal.aborted || err instanceof Error && err.name === "AbortError";
|
|
1667
|
+
if (isAbort) {
|
|
1668
|
+
cancelled = true;
|
|
1638
1669
|
connMgr.broadcastWithWildcard(`eval:${evalRunId}`, {
|
|
1639
|
-
|
|
1670
|
+
type: "run_cancelled",
|
|
1640
1671
|
run: r + 1,
|
|
1641
1672
|
totalRuns: runs
|
|
1642
1673
|
});
|
|
1674
|
+
break;
|
|
1643
1675
|
}
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1676
|
+
runFailure = err instanceof Error ? err : new Error(String(err));
|
|
1677
|
+
connMgr.broadcastWithWildcard(`eval:${evalRunId}`, {
|
|
1678
|
+
type: "run_failed",
|
|
1679
|
+
run: r + 1,
|
|
1680
|
+
totalRuns: runs,
|
|
1681
|
+
message: redactErrorMessage(runFailure, redactOn)
|
|
1682
|
+
});
|
|
1683
|
+
break;
|
|
1684
|
+
}
|
|
1651
1685
|
}
|
|
1652
1686
|
if (results.length > 0) {
|
|
1687
|
+
const partial = results.length < runs;
|
|
1688
|
+
const failureMsg = runFailure ? redactErrorMessage(runFailure, redactOn) || String(runFailure) || void 0 : void 0;
|
|
1653
1689
|
connMgr.broadcastWithWildcard(`eval:${evalRunId}`, {
|
|
1654
1690
|
type: "done",
|
|
1655
1691
|
evalResultId: results[0].id,
|
|
1656
|
-
runGroupId
|
|
1692
|
+
runGroupId,
|
|
1693
|
+
...partial && {
|
|
1694
|
+
partial: true,
|
|
1695
|
+
batchCompleted: results.length,
|
|
1696
|
+
batchAttempted: runs,
|
|
1697
|
+
// `cancelled` and `batchFailure` are mutually exclusive:
|
|
1698
|
+
// the catch block sets at most one of {cancelled,
|
|
1699
|
+
// runFailure}. The client uses `cancelled` to render a
|
|
1700
|
+
// neutral "Cancelled — X of N runs completed" caption
|
|
1701
|
+
// instead of the amber "Stopped after: <message>"
|
|
1702
|
+
// failure caption.
|
|
1703
|
+
...cancelled ? { cancelled: true } : {},
|
|
1704
|
+
...failureMsg ? { batchFailure: failureMsg } : {}
|
|
1705
|
+
}
|
|
1706
|
+
});
|
|
1707
|
+
} else if (runFailure) {
|
|
1708
|
+
connMgr.broadcastWithWildcard(`eval:${evalRunId}`, {
|
|
1709
|
+
type: "error",
|
|
1710
|
+
message: redactErrorMessage(runFailure, redactOn)
|
|
1657
1711
|
});
|
|
1658
1712
|
} else {
|
|
1659
1713
|
connMgr.broadcastWithWildcard(`eval:${evalRunId}`, {
|
|
@@ -1691,19 +1745,38 @@ function createEvalRoutes(connMgr, evalLoader) {
|
|
|
1691
1745
|
const { aggregateRuns } = await import("@axlsdk/eval");
|
|
1692
1746
|
const runGroupId = (0, import_node_crypto.randomUUID)();
|
|
1693
1747
|
const results = [];
|
|
1748
|
+
let runFailure;
|
|
1694
1749
|
for (let r = 0; r < runs; r++) {
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1750
|
+
try {
|
|
1751
|
+
const result2 = await runtime.runRegisteredEval(name, {
|
|
1752
|
+
metadata: { runGroupId, runIndex: r, batchAttempted: runs },
|
|
1753
|
+
captureTraces
|
|
1754
|
+
});
|
|
1755
|
+
results.push(result2);
|
|
1756
|
+
} catch (err) {
|
|
1757
|
+
runFailure = err instanceof Error ? err : new Error(String(err));
|
|
1758
|
+
break;
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
if (results.length === 0) {
|
|
1762
|
+
throw runFailure ?? new Error("No runs completed");
|
|
1700
1763
|
}
|
|
1701
|
-
const
|
|
1702
|
-
const
|
|
1703
|
-
const
|
|
1764
|
+
const aggregate = aggregateRuns(results);
|
|
1765
|
+
const first = results[0];
|
|
1766
|
+
const partial = results.length < runs;
|
|
1767
|
+
const failureMsg = runFailure ? redactErrorMessage(runFailure, redactOn) || String(runFailure) || void 0 : void 0;
|
|
1704
1768
|
const result = {
|
|
1705
1769
|
...first,
|
|
1706
|
-
_multiRun: {
|
|
1770
|
+
_multiRun: {
|
|
1771
|
+
aggregate,
|
|
1772
|
+
allRuns: results,
|
|
1773
|
+
...partial && {
|
|
1774
|
+
partial: true,
|
|
1775
|
+
batchCompleted: results.length,
|
|
1776
|
+
batchAttempted: runs,
|
|
1777
|
+
...failureMsg ? { batchFailure: failureMsg } : {}
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1707
1780
|
};
|
|
1708
1781
|
return c.json({
|
|
1709
1782
|
ok: true,
|
|
@@ -1875,60 +1948,75 @@ function createEvalRoutes(connMgr, evalLoader) {
|
|
|
1875
1948
|
const runtime = c.get("runtime");
|
|
1876
1949
|
const body = await c.req.json();
|
|
1877
1950
|
const bad = (message) => c.json({ ok: false, error: { code: "BAD_REQUEST", message } }, 400);
|
|
1878
|
-
if (
|
|
1951
|
+
if (body.result === void 0 || body.result === null) {
|
|
1879
1952
|
return bad("result is required");
|
|
1880
1953
|
}
|
|
1881
|
-
const
|
|
1882
|
-
if (
|
|
1883
|
-
return bad("result
|
|
1884
|
-
}
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1954
|
+
const resultsRaw = Array.isArray(body.result) ? body.result : [body.result];
|
|
1955
|
+
if (resultsRaw.length === 0) {
|
|
1956
|
+
return bad("result must be a non-empty array or object");
|
|
1957
|
+
}
|
|
1958
|
+
const validatedResults = [];
|
|
1959
|
+
for (let i = 0; i < resultsRaw.length; i++) {
|
|
1960
|
+
const entry = resultsRaw[i];
|
|
1961
|
+
const prefix = resultsRaw.length > 1 ? `result[${i}]` : "result";
|
|
1962
|
+
if (!entry || typeof entry !== "object") {
|
|
1963
|
+
return bad(`${prefix} must be an object`);
|
|
1964
|
+
}
|
|
1965
|
+
const r = entry;
|
|
1966
|
+
if (!Array.isArray(r.items)) {
|
|
1967
|
+
return bad(`${prefix}.items must be an array`);
|
|
1968
|
+
}
|
|
1969
|
+
if (typeof r.summary !== "object" || r.summary == null) {
|
|
1970
|
+
return bad(`${prefix}.summary must be an object`);
|
|
1971
|
+
}
|
|
1972
|
+
if (typeof r.dataset !== "string" || !r.dataset) {
|
|
1973
|
+
return bad(`${prefix}.dataset must be a non-empty string (required for compare)`);
|
|
1974
|
+
}
|
|
1975
|
+
const summary = r.summary;
|
|
1976
|
+
if (typeof summary.scorers !== "object" || summary.scorers == null) {
|
|
1977
|
+
return bad(`${prefix}.summary.scorers must be an object`);
|
|
1978
|
+
}
|
|
1979
|
+
const summaryScorerNames = Object.keys(summary.scorers);
|
|
1980
|
+
const items = r.items;
|
|
1981
|
+
const summaryScorerSet = new Set(summaryScorerNames);
|
|
1982
|
+
const uncoveredAcrossItems = /* @__PURE__ */ new Set();
|
|
1983
|
+
for (const item of items) {
|
|
1984
|
+
const itemScores = item?.scores;
|
|
1985
|
+
if (itemScores && typeof itemScores === "object") {
|
|
1986
|
+
for (const name of Object.keys(itemScores)) {
|
|
1987
|
+
if (!summaryScorerSet.has(name)) uncoveredAcrossItems.add(name);
|
|
1988
|
+
}
|
|
1904
1989
|
}
|
|
1905
1990
|
}
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1991
|
+
if (uncoveredAcrossItems.size > 0) {
|
|
1992
|
+
return bad(
|
|
1993
|
+
`${prefix} item scores reference scorer(s) not in summary.scorers: ${[...uncoveredAcrossItems].join(", ")}`
|
|
1994
|
+
);
|
|
1995
|
+
}
|
|
1996
|
+
validatedResults.push(r);
|
|
1911
1997
|
}
|
|
1912
1998
|
const trim = (v) => typeof v === "string" && v.trim() !== "" ? v.trim() : void 0;
|
|
1913
|
-
const
|
|
1999
|
+
const firstResult = validatedResults[0];
|
|
2000
|
+
const metadataObj = typeof firstResult.metadata === "object" && firstResult.metadata != null ? firstResult.metadata : {};
|
|
1914
2001
|
const workflowsFromMeta = Array.isArray(metadataObj.workflows) ? metadataObj.workflows : [];
|
|
1915
2002
|
const primaryWorkflow = workflowsFromMeta.find((w) => typeof w === "string");
|
|
1916
|
-
const evalName = trim(body.eval) ?? trim(primaryWorkflow) ??
|
|
1917
|
-
trim(result.workflow) ?? "imported";
|
|
1918
|
-
const id = (0, import_node_crypto.randomUUID)();
|
|
2003
|
+
const evalName = trim(body.eval) ?? trim(primaryWorkflow) ?? trim(firstResult.workflow) ?? "imported";
|
|
1919
2004
|
const timestamp = Date.now();
|
|
1920
|
-
const imported =
|
|
1921
|
-
|
|
1922
|
-
id,
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
timestamp,
|
|
1929
|
-
|
|
1930
|
-
}
|
|
1931
|
-
|
|
2005
|
+
const imported = [];
|
|
2006
|
+
for (const r of validatedResults) {
|
|
2007
|
+
const id = (0, import_node_crypto.randomUUID)();
|
|
2008
|
+
const entry = {
|
|
2009
|
+
...r,
|
|
2010
|
+
id,
|
|
2011
|
+
metadata: typeof r.metadata === "object" && r.metadata != null ? r.metadata : {}
|
|
2012
|
+
};
|
|
2013
|
+
await runtime.saveEvalResult({ id, eval: evalName, timestamp, data: entry });
|
|
2014
|
+
imported.push({ id, eval: evalName, timestamp });
|
|
2015
|
+
}
|
|
2016
|
+
if (imported.length === 1) {
|
|
2017
|
+
return c.json({ ok: true, data: imported[0] });
|
|
2018
|
+
}
|
|
2019
|
+
return c.json({ ok: true, data: { imported } });
|
|
1932
2020
|
});
|
|
1933
2021
|
function closeActiveRuns() {
|
|
1934
2022
|
for (const ac of activeRuns.values()) ac.abort();
|
|
@@ -2245,41 +2333,11 @@ function createServer(options) {
|
|
|
2245
2333
|
}
|
|
2246
2334
|
|
|
2247
2335
|
// src/eval-loader.ts
|
|
2248
|
-
var import_node_path3 = require("path");
|
|
2249
|
-
var import_node_fs3 = require("fs");
|
|
2250
|
-
var import_node_url2 = require("url");
|
|
2251
|
-
|
|
2252
|
-
// src/cli-utils.ts
|
|
2253
2336
|
var import_node_path2 = require("path");
|
|
2254
|
-
var import_node_fs2 = require("fs");
|
|
2255
2337
|
var import_node_url = require("url");
|
|
2256
|
-
|
|
2257
|
-
return /\.[mc]?tsx?$/.test(configPath);
|
|
2258
|
-
}
|
|
2259
|
-
var tsImportFn;
|
|
2260
|
-
async function importModule(filePath, parentURL2) {
|
|
2261
|
-
if (needsTsxLoader(filePath)) {
|
|
2262
|
-
if (tsImportFn === void 0) {
|
|
2263
|
-
try {
|
|
2264
|
-
const mod = await import("tsx/esm/api");
|
|
2265
|
-
tsImportFn = mod.tsImport ?? null;
|
|
2266
|
-
} catch {
|
|
2267
|
-
tsImportFn = null;
|
|
2268
|
-
console.warn(
|
|
2269
|
-
"[axl-studio] Warning: tsx is not installed. TypeScript config files require tsx as a dependency.\n Install it with: npm install -D tsx"
|
|
2270
|
-
);
|
|
2271
|
-
}
|
|
2272
|
-
}
|
|
2273
|
-
if (tsImportFn) {
|
|
2274
|
-
return await tsImportFn((0, import_node_url.pathToFileURL)(filePath).href, parentURL2);
|
|
2275
|
-
}
|
|
2276
|
-
}
|
|
2277
|
-
return await import((0, import_node_url.pathToFileURL)(filePath).href);
|
|
2278
|
-
}
|
|
2279
|
-
|
|
2280
|
-
// src/eval-loader.ts
|
|
2338
|
+
var import_axl6 = require("@axlsdk/axl");
|
|
2281
2339
|
var import_meta = {};
|
|
2282
|
-
var parentURL = import_meta.url ?? (0,
|
|
2340
|
+
var parentURL = import_meta.url ?? (0, import_node_url.pathToFileURL)(typeof __filename !== "undefined" ? __filename : __dirname).href;
|
|
2283
2341
|
function createEvalLoader(config, runtime, cwd) {
|
|
2284
2342
|
let loadPromise;
|
|
2285
2343
|
const { patterns, conditions } = normalizeConfig(config);
|
|
@@ -2296,7 +2354,7 @@ function createEvalLoader(config, runtime, cwd) {
|
|
|
2296
2354
|
}
|
|
2297
2355
|
async function loadEvalFiles(patterns, conditions, cwd, runtime) {
|
|
2298
2356
|
if (conditions.length > 0) {
|
|
2299
|
-
await registerConditions(conditions);
|
|
2357
|
+
await (0, import_axl6.registerConditions)(conditions);
|
|
2300
2358
|
}
|
|
2301
2359
|
const files = resolvePatterns(patterns, cwd);
|
|
2302
2360
|
if (files.length === 0) {
|
|
@@ -2305,11 +2363,30 @@ async function loadEvalFiles(patterns, conditions, cwd, runtime) {
|
|
|
2305
2363
|
}
|
|
2306
2364
|
for (const file of files) {
|
|
2307
2365
|
try {
|
|
2308
|
-
const mod = await importModule(file, parentURL);
|
|
2309
|
-
const evalConfig =
|
|
2366
|
+
const mod = await (0, import_axl6.importModule)(file, parentURL);
|
|
2367
|
+
const evalConfig = (0, import_axl6.pickDefault)(mod);
|
|
2368
|
+
if (!evalConfig || typeof evalConfig !== "object") {
|
|
2369
|
+
console.warn(
|
|
2370
|
+
`[axl-studio] Skipping ${file}: default export is ${evalConfig === null ? "null" : typeof evalConfig}, expected an eval config object.`
|
|
2371
|
+
);
|
|
2372
|
+
continue;
|
|
2373
|
+
}
|
|
2374
|
+
if (Array.isArray(evalConfig.scorers) && evalConfig.scorers.length === 0) {
|
|
2375
|
+
console.warn(
|
|
2376
|
+
`[axl-studio] Skipping ${file}: scorers array is empty \u2014 at least one scorer is required.`
|
|
2377
|
+
);
|
|
2378
|
+
continue;
|
|
2379
|
+
}
|
|
2310
2380
|
if (!evalConfig.workflow || !evalConfig.dataset || !evalConfig.scorers) {
|
|
2381
|
+
const missing = [
|
|
2382
|
+
!evalConfig.workflow && "workflow",
|
|
2383
|
+
!evalConfig.dataset && "dataset",
|
|
2384
|
+
!evalConfig.scorers && "scorers"
|
|
2385
|
+
].filter(Boolean).join(", ");
|
|
2386
|
+
const keys = Object.keys(evalConfig).slice(0, 10);
|
|
2387
|
+
const got = keys.length > 0 ? ` Got: { ${keys.join(", ")} }.` : "";
|
|
2311
2388
|
console.warn(
|
|
2312
|
-
`[axl-studio] Skipping ${file}: not a valid eval config (missing
|
|
2389
|
+
`[axl-studio] Skipping ${file}: not a valid eval config (missing ${missing}).${got}`
|
|
2313
2390
|
);
|
|
2314
2391
|
continue;
|
|
2315
2392
|
}
|
|
@@ -2319,7 +2396,16 @@ async function loadEvalFiles(patterns, conditions, cwd, runtime) {
|
|
|
2319
2396
|
`[axl-studio] Eval name "${name}" from ${file} collides with an already-registered eval \u2014 overwriting`
|
|
2320
2397
|
);
|
|
2321
2398
|
}
|
|
2322
|
-
|
|
2399
|
+
const exported = (0, import_axl6.pickExport)(mod, "executeWorkflow");
|
|
2400
|
+
let customExecute;
|
|
2401
|
+
if (typeof exported === "function") {
|
|
2402
|
+
customExecute = exported;
|
|
2403
|
+
} else if (exported !== void 0) {
|
|
2404
|
+
console.warn(
|
|
2405
|
+
`[axl-studio] ${file} exports executeWorkflow but it is ${typeof exported}, not a function \u2014 ignoring and falling back to runtime.execute()`
|
|
2406
|
+
);
|
|
2407
|
+
}
|
|
2408
|
+
runtime.registerEval(name, evalConfig, customExecute);
|
|
2323
2409
|
} catch (err) {
|
|
2324
2410
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2325
2411
|
console.warn(`[axl-studio] Failed to load eval ${file}: ${msg}`);
|
|
@@ -2337,10 +2423,10 @@ function normalizeConfig(config) {
|
|
|
2337
2423
|
return { patterns: files, conditions: config.conditions ?? [] };
|
|
2338
2424
|
}
|
|
2339
2425
|
function deriveEvalName(filePath, cwd) {
|
|
2340
|
-
const rel = (0,
|
|
2426
|
+
const rel = (0, import_node_path2.relative)(cwd, filePath);
|
|
2341
2427
|
const normalized = rel.replace(/\\/g, "/");
|
|
2342
2428
|
if (normalized.startsWith("../")) {
|
|
2343
|
-
const base = (0,
|
|
2429
|
+
const base = (0, import_node_path2.basename)(filePath);
|
|
2344
2430
|
const stripped = base.replace(/\.eval\.[mc]?[jt]sx?$/, "");
|
|
2345
2431
|
return stripped !== base ? stripped : base.replace(/\.[mc]?[jt]sx?$/, "") || base;
|
|
2346
2432
|
}
|
|
@@ -2353,7 +2439,7 @@ function resolvePatterns(patterns, cwd) {
|
|
|
2353
2439
|
const files = [];
|
|
2354
2440
|
const seen = /* @__PURE__ */ new Set();
|
|
2355
2441
|
for (const pattern of patterns) {
|
|
2356
|
-
const resolved = pattern.includes("*") ? expandGlob(pattern, cwd) : [(0,
|
|
2442
|
+
const resolved = pattern.includes("*") ? (0, import_axl6.expandGlob)(pattern, cwd) : [(0, import_node_path2.resolve)(cwd, pattern)];
|
|
2357
2443
|
for (const file of resolved) {
|
|
2358
2444
|
if (!seen.has(file)) {
|
|
2359
2445
|
seen.add(file);
|
|
@@ -2363,61 +2449,6 @@ function resolvePatterns(patterns, cwd) {
|
|
|
2363
2449
|
}
|
|
2364
2450
|
return files;
|
|
2365
2451
|
}
|
|
2366
|
-
function expandGlob(pattern, cwd) {
|
|
2367
|
-
if (pattern.includes("**/")) {
|
|
2368
|
-
const sepIdx = pattern.indexOf("**/");
|
|
2369
|
-
const baseDir = (0, import_node_path3.resolve)(cwd, pattern.slice(0, sepIdx) || ".");
|
|
2370
|
-
const fileGlob2 = pattern.slice(sepIdx + 3) || "*";
|
|
2371
|
-
return findFiles(baseDir, fileGlob2, true);
|
|
2372
|
-
}
|
|
2373
|
-
const dir = (0, import_node_path3.resolve)(cwd, (0, import_node_path3.dirname)(pattern));
|
|
2374
|
-
const fileGlob = (0, import_node_path3.basename)(pattern);
|
|
2375
|
-
return findFiles(dir, fileGlob, false);
|
|
2376
|
-
}
|
|
2377
|
-
var MAX_DEPTH = 20;
|
|
2378
|
-
function findFiles(dir, fileGlob, recursive, depth = 0) {
|
|
2379
|
-
if (depth > MAX_DEPTH) return [];
|
|
2380
|
-
const matcher = globToRegex(fileGlob);
|
|
2381
|
-
const results = [];
|
|
2382
|
-
try {
|
|
2383
|
-
const entries = (0, import_node_fs3.readdirSync)(dir);
|
|
2384
|
-
for (const entry of entries) {
|
|
2385
|
-
const full = (0, import_node_path3.resolve)(dir, entry);
|
|
2386
|
-
try {
|
|
2387
|
-
const stat = (0, import_node_fs3.statSync)(full);
|
|
2388
|
-
if (stat.isFile() && matcher.test(entry)) {
|
|
2389
|
-
results.push(full);
|
|
2390
|
-
} else if (stat.isDirectory() && recursive) {
|
|
2391
|
-
results.push(...findFiles(full, fileGlob, true, depth + 1));
|
|
2392
|
-
}
|
|
2393
|
-
} catch {
|
|
2394
|
-
}
|
|
2395
|
-
}
|
|
2396
|
-
} catch {
|
|
2397
|
-
}
|
|
2398
|
-
return results;
|
|
2399
|
-
}
|
|
2400
|
-
function globToRegex(glob) {
|
|
2401
|
-
const escaped = glob.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
2402
|
-
return new RegExp(`^${escaped}$`);
|
|
2403
|
-
}
|
|
2404
|
-
async function registerConditions(conditions) {
|
|
2405
|
-
try {
|
|
2406
|
-
const nodeModule = await import("module");
|
|
2407
|
-
const hookCode = [
|
|
2408
|
-
`const extra = ${JSON.stringify(conditions)};`,
|
|
2409
|
-
`export async function resolve(specifier, context, nextResolve) {`,
|
|
2410
|
-
` return nextResolve(specifier, {`,
|
|
2411
|
-
` ...context,`,
|
|
2412
|
-
` conditions: [...new Set([...context.conditions, ...extra])],`,
|
|
2413
|
-
` });`,
|
|
2414
|
-
`}`
|
|
2415
|
-
].join("\n");
|
|
2416
|
-
nodeModule.register(`data:text/javascript,${encodeURIComponent(hookCode)}`);
|
|
2417
|
-
} catch {
|
|
2418
|
-
console.warn("[axl-studio] Warning: import conditions require Node.js 20.6+");
|
|
2419
|
-
}
|
|
2420
|
-
}
|
|
2421
2452
|
|
|
2422
2453
|
// src/middleware.ts
|
|
2423
2454
|
var import_meta2 = {};
|
|
@@ -2432,9 +2463,9 @@ function createStudioMiddleware(options) {
|
|
|
2432
2463
|
const basePath = normalizeBasePath(options.basePath);
|
|
2433
2464
|
const staticRoot = serveClient ? resolveClientDist() : void 0;
|
|
2434
2465
|
if (serveClient && !staticRoot) {
|
|
2435
|
-
const dir = import_meta2.dirname ?? (typeof __dirname !== "undefined" ? __dirname : (0,
|
|
2466
|
+
const dir = import_meta2.dirname ?? (typeof __dirname !== "undefined" ? __dirname : (0, import_node_path3.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url)));
|
|
2436
2467
|
console.warn(
|
|
2437
|
-
`[axl-studio] serveClient is true but no pre-built client found at ${(0,
|
|
2468
|
+
`[axl-studio] serveClient is true but no pre-built client found at ${(0, import_node_path3.resolve)(dir, "client")}. Studio UI will not be available. Set serveClient: false to suppress this warning.`
|
|
2438
2469
|
);
|
|
2439
2470
|
}
|
|
2440
2471
|
const evalLoader = options.evals ? createEvalLoader(options.evals, runtime) : void 0;
|
|
@@ -2607,9 +2638,9 @@ function normalizeBasePath(raw) {
|
|
|
2607
2638
|
return normalized;
|
|
2608
2639
|
}
|
|
2609
2640
|
function resolveClientDist() {
|
|
2610
|
-
const dir = import_meta2.dirname ?? (typeof __dirname !== "undefined" ? __dirname : (0,
|
|
2611
|
-
const candidate = (0,
|
|
2612
|
-
return (0,
|
|
2641
|
+
const dir = import_meta2.dirname ?? (typeof __dirname !== "undefined" ? __dirname : (0, import_node_path3.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url)));
|
|
2642
|
+
const candidate = (0, import_node_path3.resolve)(dir, "client");
|
|
2643
|
+
return (0, import_node_fs2.existsSync)((0, import_node_path3.resolve)(candidate, "index.html")) ? candidate : void 0;
|
|
2613
2644
|
}
|
|
2614
2645
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2615
2646
|
0 && (module.exports = {
|