@axlsdk/studio 0.13.5 → 0.13.7
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 +6 -4
- package/dist/{chunk-NU6255VY.js → chunk-YWRYXT7U.js} +171 -36
- package/dist/chunk-YWRYXT7U.js.map +1 -0
- package/dist/cli.cjs +170 -35
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/client/assets/index-C_uwupnn.js +221 -0
- package/dist/client/assets/index-DVcH6P9w.css +1 -0
- package/dist/client/index.html +2 -2
- package/dist/{connection-manager-DbOgO_gK.d.cts → connection-manager-B7AWpsCD.d.cts} +9 -3
- package/dist/{connection-manager-DbOgO_gK.d.ts → connection-manager-B7AWpsCD.d.ts} +9 -3
- package/dist/middleware.cjs +170 -35
- package/dist/middleware.cjs.map +1 -1
- package/dist/middleware.d.cts +1 -1
- package/dist/middleware.d.ts +1 -1
- package/dist/middleware.js +1 -1
- package/dist/server/index.cjs +180 -35
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +3 -2
- package/dist/server/index.d.ts +3 -2
- package/dist/server/index.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-NU6255VY.js.map +0 -1
- package/dist/client/assets/index-DG2zy3iH.js +0 -150
- package/dist/client/assets/index-WUBHc-Rd.css +0 -1
package/dist/server/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/server/index.ts
|
|
@@ -58,11 +68,18 @@ async function errorHandler(c, next) {
|
|
|
58
68
|
}
|
|
59
69
|
|
|
60
70
|
// src/server/ws/connection-manager.ts
|
|
71
|
+
function isBufferedChannel(channel) {
|
|
72
|
+
return channel.startsWith("execution:");
|
|
73
|
+
}
|
|
74
|
+
var BUFFER_TTL_MS = 3e4;
|
|
75
|
+
var MAX_BUFFER_EVENTS = 500;
|
|
61
76
|
var ConnectionManager = class {
|
|
62
77
|
/** channel -> set of WS connections */
|
|
63
78
|
channels = /* @__PURE__ */ new Map();
|
|
64
79
|
/** ws -> set of subscribed channels (for cleanup) */
|
|
65
80
|
connections = /* @__PURE__ */ new Map();
|
|
81
|
+
/** channel -> replay buffer for execution streams */
|
|
82
|
+
buffers = /* @__PURE__ */ new Map();
|
|
66
83
|
maxConnections = 100;
|
|
67
84
|
/** Register a new WS connection. */
|
|
68
85
|
add(ws) {
|
|
@@ -85,7 +102,7 @@ var ConnectionManager = class {
|
|
|
85
102
|
}
|
|
86
103
|
this.connections.delete(ws);
|
|
87
104
|
}
|
|
88
|
-
/** Subscribe a connection to a channel.
|
|
105
|
+
/** Subscribe a connection to a channel. Replays buffered events for execution channels. */
|
|
89
106
|
subscribe(ws, channel) {
|
|
90
107
|
if (!this.connections.has(ws)) return;
|
|
91
108
|
let subs = this.channels.get(channel);
|
|
@@ -95,6 +112,17 @@ var ConnectionManager = class {
|
|
|
95
112
|
}
|
|
96
113
|
subs.add(ws);
|
|
97
114
|
this.connections.get(ws).add(channel);
|
|
115
|
+
const buffer = this.buffers.get(channel);
|
|
116
|
+
if (buffer) {
|
|
117
|
+
for (const msg of buffer.events) {
|
|
118
|
+
try {
|
|
119
|
+
ws.send(msg);
|
|
120
|
+
} catch {
|
|
121
|
+
this.remove(ws);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
98
126
|
}
|
|
99
127
|
/** Unsubscribe a connection from a channel. */
|
|
100
128
|
unsubscribe(ws, channel) {
|
|
@@ -104,11 +132,30 @@ var ConnectionManager = class {
|
|
|
104
132
|
}
|
|
105
133
|
this.connections.get(ws)?.delete(channel);
|
|
106
134
|
}
|
|
107
|
-
/** Broadcast data to all subscribers of a channel. */
|
|
135
|
+
/** Broadcast data to all subscribers of a channel. Buffers events for execution channels. */
|
|
108
136
|
broadcast(channel, data) {
|
|
137
|
+
const msg = JSON.stringify({ type: "event", channel, data });
|
|
138
|
+
if (isBufferedChannel(channel)) {
|
|
139
|
+
let buffer = this.buffers.get(channel);
|
|
140
|
+
if (!buffer) {
|
|
141
|
+
buffer = { events: [], complete: false };
|
|
142
|
+
this.buffers.set(channel, buffer);
|
|
143
|
+
}
|
|
144
|
+
const event = data;
|
|
145
|
+
const isTerminal = event.type === "done" || event.type === "error";
|
|
146
|
+
if (buffer.events.length < MAX_BUFFER_EVENTS || isTerminal) {
|
|
147
|
+
buffer.events.push(msg);
|
|
148
|
+
}
|
|
149
|
+
if (isTerminal) {
|
|
150
|
+
buffer.complete = true;
|
|
151
|
+
if (buffer.timer) clearTimeout(buffer.timer);
|
|
152
|
+
buffer.timer = setTimeout(() => {
|
|
153
|
+
this.buffers.delete(channel);
|
|
154
|
+
}, BUFFER_TTL_MS);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
109
157
|
const subs = this.channels.get(channel);
|
|
110
158
|
if (!subs || subs.size === 0) return;
|
|
111
|
-
const msg = JSON.stringify({ type: "event", channel, data });
|
|
112
159
|
for (const ws of [...subs]) {
|
|
113
160
|
try {
|
|
114
161
|
ws.send(msg);
|
|
@@ -135,13 +182,17 @@ var ConnectionManager = class {
|
|
|
135
182
|
}
|
|
136
183
|
}
|
|
137
184
|
}
|
|
138
|
-
/** Close all connections
|
|
185
|
+
/** Close all connections, clear all state and buffers. Used during shutdown. */
|
|
139
186
|
closeAll() {
|
|
140
187
|
for (const ws of this.connections.keys()) {
|
|
141
188
|
ws.close?.();
|
|
142
189
|
}
|
|
190
|
+
for (const buffer of this.buffers.values()) {
|
|
191
|
+
if (buffer.timer) clearTimeout(buffer.timer);
|
|
192
|
+
}
|
|
143
193
|
this.connections.clear();
|
|
144
194
|
this.channels.clear();
|
|
195
|
+
this.buffers.clear();
|
|
145
196
|
}
|
|
146
197
|
/** Get the number of active connections. */
|
|
147
198
|
get connectionCount() {
|
|
@@ -346,15 +397,8 @@ function createWorkflowRoutes(connMgr) {
|
|
|
346
397
|
const stream = runtime.stream(name, body.input ?? {}, { metadata: body.metadata });
|
|
347
398
|
const executionId = `stream-${Date.now()}`;
|
|
348
399
|
(async () => {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
connMgr.broadcastWithWildcard(`execution:${executionId}`, event);
|
|
352
|
-
}
|
|
353
|
-
} catch (err) {
|
|
354
|
-
connMgr.broadcastWithWildcard(`execution:${executionId}`, {
|
|
355
|
-
type: "error",
|
|
356
|
-
message: err instanceof Error ? err.message : "Stream error"
|
|
357
|
-
});
|
|
400
|
+
for await (const event of stream) {
|
|
401
|
+
connMgr.broadcastWithWildcard(`execution:${executionId}`, event);
|
|
358
402
|
}
|
|
359
403
|
})();
|
|
360
404
|
return c.json({ ok: true, data: { executionId, streaming: true } });
|
|
@@ -435,15 +479,8 @@ function createSessionRoutes(connMgr) {
|
|
|
435
479
|
const stream = await session.stream(body.workflow, body.message);
|
|
436
480
|
const executionId = `session-${id}-${Date.now()}`;
|
|
437
481
|
(async () => {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
connMgr.broadcastWithWildcard(`execution:${executionId}`, event);
|
|
441
|
-
}
|
|
442
|
-
} catch (err) {
|
|
443
|
-
connMgr.broadcastWithWildcard(`execution:${executionId}`, {
|
|
444
|
-
type: "error",
|
|
445
|
-
message: err instanceof Error ? err.message : "Stream error"
|
|
446
|
-
});
|
|
482
|
+
for await (const event of stream) {
|
|
483
|
+
connMgr.broadcastWithWildcard(`execution:${executionId}`, event);
|
|
447
484
|
}
|
|
448
485
|
})();
|
|
449
486
|
return c.json({ ok: true, data: { executionId, streaming: true } });
|
|
@@ -725,8 +762,80 @@ function createEvalRoutes(evalLoader) {
|
|
|
725
762
|
404
|
|
726
763
|
);
|
|
727
764
|
}
|
|
765
|
+
let runs = 1;
|
|
766
|
+
try {
|
|
767
|
+
const body = await c.req.json().catch(() => ({}));
|
|
768
|
+
if (typeof body.runs === "number" && Number.isFinite(body.runs) && body.runs > 1) {
|
|
769
|
+
runs = Math.min(Math.floor(body.runs), 25);
|
|
770
|
+
}
|
|
771
|
+
} catch {
|
|
772
|
+
}
|
|
728
773
|
try {
|
|
729
|
-
|
|
774
|
+
if (runs > 1) {
|
|
775
|
+
const { randomUUID } = await import("crypto");
|
|
776
|
+
const { aggregateRuns } = await import("@axlsdk/eval");
|
|
777
|
+
const runGroupId = randomUUID();
|
|
778
|
+
const results = [];
|
|
779
|
+
for (let r = 0; r < runs; r++) {
|
|
780
|
+
const result2 = await runtime.runRegisteredEval(name, {
|
|
781
|
+
metadata: { runGroupId, runIndex: r }
|
|
782
|
+
});
|
|
783
|
+
results.push(result2);
|
|
784
|
+
}
|
|
785
|
+
const typedResults = results;
|
|
786
|
+
const aggregate = aggregateRuns(typedResults);
|
|
787
|
+
const first = typedResults[0];
|
|
788
|
+
const result = { ...first, _multiRun: { aggregate, allRuns: typedResults } };
|
|
789
|
+
return c.json({ ok: true, data: result });
|
|
790
|
+
} else {
|
|
791
|
+
const result = await runtime.runRegisteredEval(name);
|
|
792
|
+
return c.json({ ok: true, data: result });
|
|
793
|
+
}
|
|
794
|
+
} catch (err) {
|
|
795
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
796
|
+
return c.json({ ok: false, error: { code: "EVAL_ERROR", message } }, 400);
|
|
797
|
+
}
|
|
798
|
+
});
|
|
799
|
+
app7.post("/evals/:name/rescore", async (c) => {
|
|
800
|
+
if (evalLoader) await evalLoader();
|
|
801
|
+
const runtime = c.get("runtime");
|
|
802
|
+
const name = c.req.param("name");
|
|
803
|
+
const body = await c.req.json();
|
|
804
|
+
if (!body.resultId || typeof body.resultId !== "string") {
|
|
805
|
+
return c.json(
|
|
806
|
+
{ ok: false, error: { code: "BAD_REQUEST", message: "resultId is required" } },
|
|
807
|
+
400
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
const entry = runtime.getRegisteredEval(name);
|
|
811
|
+
if (!entry) {
|
|
812
|
+
return c.json(
|
|
813
|
+
{ ok: false, error: { code: "NOT_FOUND", message: `Eval "${name}" not found` } },
|
|
814
|
+
404
|
|
815
|
+
);
|
|
816
|
+
}
|
|
817
|
+
const history = await runtime.getEvalHistory();
|
|
818
|
+
const historyEntry = history.find((h) => h.id === body.resultId);
|
|
819
|
+
if (!historyEntry) {
|
|
820
|
+
return c.json(
|
|
821
|
+
{ ok: false, error: { code: "NOT_FOUND", message: `Result "${body.resultId}" not found` } },
|
|
822
|
+
404
|
|
823
|
+
);
|
|
824
|
+
}
|
|
825
|
+
try {
|
|
826
|
+
const { rescore } = await import("@axlsdk/eval");
|
|
827
|
+
const config = entry.config;
|
|
828
|
+
const result = await rescore(
|
|
829
|
+
historyEntry.data,
|
|
830
|
+
config.scorers,
|
|
831
|
+
runtime
|
|
832
|
+
);
|
|
833
|
+
await runtime.saveEvalResult({
|
|
834
|
+
id: result.id,
|
|
835
|
+
eval: name,
|
|
836
|
+
timestamp: Date.now(),
|
|
837
|
+
data: result
|
|
838
|
+
});
|
|
730
839
|
return c.json({ ok: true, data: result });
|
|
731
840
|
} catch (err) {
|
|
732
841
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -737,7 +846,7 @@ function createEvalRoutes(evalLoader) {
|
|
|
737
846
|
const runtime = c.get("runtime");
|
|
738
847
|
const body = await c.req.json();
|
|
739
848
|
try {
|
|
740
|
-
const result = await runtime.evalCompare(body.baseline, body.candidate);
|
|
849
|
+
const result = await runtime.evalCompare(body.baseline, body.candidate, body.options);
|
|
741
850
|
return c.json({ ok: true, data: result });
|
|
742
851
|
} catch (err) {
|
|
743
852
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -754,26 +863,57 @@ function createPlaygroundRoutes(connMgr) {
|
|
|
754
863
|
app7.post("/playground/chat", async (c) => {
|
|
755
864
|
const runtime = c.get("runtime");
|
|
756
865
|
const body = await c.req.json();
|
|
757
|
-
|
|
758
|
-
|
|
866
|
+
if (!body.message || typeof body.message !== "string" || !body.message.trim()) {
|
|
867
|
+
return c.json(
|
|
868
|
+
{
|
|
869
|
+
ok: false,
|
|
870
|
+
error: {
|
|
871
|
+
code: "INVALID_INPUT",
|
|
872
|
+
message: "message is required and must be a non-empty string"
|
|
873
|
+
}
|
|
874
|
+
},
|
|
875
|
+
400
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
const agents = runtime.getAgents();
|
|
879
|
+
const agent = body.agent ? agents.find((a) => a._name === body.agent) : agents[0];
|
|
880
|
+
if (!agent) {
|
|
759
881
|
return c.json(
|
|
760
|
-
{
|
|
882
|
+
{
|
|
883
|
+
ok: false,
|
|
884
|
+
error: { code: "NO_AGENT", message: `Agent "${body.agent ?? ""}" not found` }
|
|
885
|
+
},
|
|
761
886
|
400
|
|
762
887
|
);
|
|
763
888
|
}
|
|
764
889
|
const sessionId = body.sessionId ?? `playground-${Date.now()}`;
|
|
765
|
-
const session = runtime.session(sessionId);
|
|
766
|
-
const stream = await session.stream(workflowName, body.message);
|
|
767
890
|
const executionId = `playground-${sessionId}-${Date.now()}`;
|
|
891
|
+
const store = runtime.getStateStore();
|
|
892
|
+
const history = await store.getSession(sessionId);
|
|
893
|
+
history.push({ role: "user", content: body.message });
|
|
894
|
+
const ctx = runtime.createContext({
|
|
895
|
+
sessionHistory: history,
|
|
896
|
+
onToken: (token) => {
|
|
897
|
+
connMgr.broadcastWithWildcard(`execution:${executionId}`, {
|
|
898
|
+
type: "token",
|
|
899
|
+
data: token
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
});
|
|
768
903
|
(async () => {
|
|
769
904
|
try {
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
}
|
|
905
|
+
const result = await ctx.ask(agent, body.message);
|
|
906
|
+
const resultText = typeof result === "string" ? result : JSON.stringify(result);
|
|
907
|
+
history.push({ role: "assistant", content: resultText });
|
|
908
|
+
await store.saveSession(sessionId, history);
|
|
909
|
+
connMgr.broadcastWithWildcard(`execution:${executionId}`, {
|
|
910
|
+
type: "done",
|
|
911
|
+
data: resultText
|
|
912
|
+
});
|
|
773
913
|
} catch (err) {
|
|
774
914
|
connMgr.broadcastWithWildcard(`execution:${executionId}`, {
|
|
775
915
|
type: "error",
|
|
776
|
-
message: err instanceof Error ? err.message :
|
|
916
|
+
message: err instanceof Error ? err.message : String(err)
|
|
777
917
|
});
|
|
778
918
|
}
|
|
779
919
|
})();
|
|
@@ -885,19 +1025,24 @@ function createServer(options) {
|
|
|
885
1025
|
app7.use("/*", async (c, next) => {
|
|
886
1026
|
const reqPath = c.req.path;
|
|
887
1027
|
const resolved = basePath && reqPath.startsWith(basePath) ? reqPath.slice(basePath.length) || "/" : reqPath;
|
|
888
|
-
if (resolved === "/" || resolved === "/index.html") {
|
|
1028
|
+
if (resolved === "/" || resolved === "/index.html" || resolved === "/ws") {
|
|
889
1029
|
return next();
|
|
890
1030
|
}
|
|
891
1031
|
return staticHandler(c, next);
|
|
892
1032
|
});
|
|
893
1033
|
if (spaHtml) {
|
|
894
|
-
app7.get("*", (c) =>
|
|
1034
|
+
app7.get("*", async (c, next) => {
|
|
1035
|
+
const resolved = basePath && c.req.path.startsWith(basePath) ? c.req.path.slice(basePath.length) || "/" : c.req.path;
|
|
1036
|
+
if (resolved === "/ws") return next();
|
|
1037
|
+
return c.html(spaHtml);
|
|
1038
|
+
});
|
|
895
1039
|
}
|
|
896
1040
|
}
|
|
897
1041
|
return {
|
|
898
1042
|
app: app7,
|
|
899
1043
|
connMgr,
|
|
900
1044
|
costAggregator,
|
|
1045
|
+
/** Create WS handlers. Call before registering static/SPA routes are reached. */
|
|
901
1046
|
createWsHandlers: () => createWsHandlers(connMgr),
|
|
902
1047
|
traceListener
|
|
903
1048
|
};
|