@axlsdk/studio 0.13.4 → 0.13.6
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 +4 -3
- package/dist/{chunk-NU6255VY.js → chunk-6MWSGTJ4.js} +97 -34
- package/dist/chunk-6MWSGTJ4.js.map +1 -0
- package/dist/cli.cjs +96 -33
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/client/assets/index-CO-ZIHXe.js +191 -0
- package/dist/client/assets/index-DaCmnARn.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 +96 -33
- 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 +96 -33
- 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 +4 -4
- package/dist/chunk-NU6255VY.js.map +0 -1
- package/dist/client/assets/index-6StQoHS_.css +0 -1
- package/dist/client/assets/index-CwdbiyOq.js +0 -150
package/dist/cli.cjs
CHANGED
|
@@ -63,11 +63,18 @@ async function errorHandler(c, next) {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
// src/server/ws/connection-manager.ts
|
|
66
|
+
function isBufferedChannel(channel) {
|
|
67
|
+
return channel.startsWith("execution:");
|
|
68
|
+
}
|
|
69
|
+
var BUFFER_TTL_MS = 3e4;
|
|
70
|
+
var MAX_BUFFER_EVENTS = 500;
|
|
66
71
|
var ConnectionManager = class {
|
|
67
72
|
/** channel -> set of WS connections */
|
|
68
73
|
channels = /* @__PURE__ */ new Map();
|
|
69
74
|
/** ws -> set of subscribed channels (for cleanup) */
|
|
70
75
|
connections = /* @__PURE__ */ new Map();
|
|
76
|
+
/** channel -> replay buffer for execution streams */
|
|
77
|
+
buffers = /* @__PURE__ */ new Map();
|
|
71
78
|
maxConnections = 100;
|
|
72
79
|
/** Register a new WS connection. */
|
|
73
80
|
add(ws) {
|
|
@@ -90,7 +97,7 @@ var ConnectionManager = class {
|
|
|
90
97
|
}
|
|
91
98
|
this.connections.delete(ws);
|
|
92
99
|
}
|
|
93
|
-
/** Subscribe a connection to a channel.
|
|
100
|
+
/** Subscribe a connection to a channel. Replays buffered events for execution channels. */
|
|
94
101
|
subscribe(ws, channel) {
|
|
95
102
|
if (!this.connections.has(ws)) return;
|
|
96
103
|
let subs = this.channels.get(channel);
|
|
@@ -100,6 +107,17 @@ var ConnectionManager = class {
|
|
|
100
107
|
}
|
|
101
108
|
subs.add(ws);
|
|
102
109
|
this.connections.get(ws).add(channel);
|
|
110
|
+
const buffer = this.buffers.get(channel);
|
|
111
|
+
if (buffer) {
|
|
112
|
+
for (const msg of buffer.events) {
|
|
113
|
+
try {
|
|
114
|
+
ws.send(msg);
|
|
115
|
+
} catch {
|
|
116
|
+
this.remove(ws);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
103
121
|
}
|
|
104
122
|
/** Unsubscribe a connection from a channel. */
|
|
105
123
|
unsubscribe(ws, channel) {
|
|
@@ -109,11 +127,30 @@ var ConnectionManager = class {
|
|
|
109
127
|
}
|
|
110
128
|
this.connections.get(ws)?.delete(channel);
|
|
111
129
|
}
|
|
112
|
-
/** Broadcast data to all subscribers of a channel. */
|
|
130
|
+
/** Broadcast data to all subscribers of a channel. Buffers events for execution channels. */
|
|
113
131
|
broadcast(channel, data) {
|
|
132
|
+
const msg = JSON.stringify({ type: "event", channel, data });
|
|
133
|
+
if (isBufferedChannel(channel)) {
|
|
134
|
+
let buffer = this.buffers.get(channel);
|
|
135
|
+
if (!buffer) {
|
|
136
|
+
buffer = { events: [], complete: false };
|
|
137
|
+
this.buffers.set(channel, buffer);
|
|
138
|
+
}
|
|
139
|
+
const event = data;
|
|
140
|
+
const isTerminal = event.type === "done" || event.type === "error";
|
|
141
|
+
if (buffer.events.length < MAX_BUFFER_EVENTS || isTerminal) {
|
|
142
|
+
buffer.events.push(msg);
|
|
143
|
+
}
|
|
144
|
+
if (isTerminal) {
|
|
145
|
+
buffer.complete = true;
|
|
146
|
+
if (buffer.timer) clearTimeout(buffer.timer);
|
|
147
|
+
buffer.timer = setTimeout(() => {
|
|
148
|
+
this.buffers.delete(channel);
|
|
149
|
+
}, BUFFER_TTL_MS);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
114
152
|
const subs = this.channels.get(channel);
|
|
115
153
|
if (!subs || subs.size === 0) return;
|
|
116
|
-
const msg = JSON.stringify({ type: "event", channel, data });
|
|
117
154
|
for (const ws of [...subs]) {
|
|
118
155
|
try {
|
|
119
156
|
ws.send(msg);
|
|
@@ -140,13 +177,17 @@ var ConnectionManager = class {
|
|
|
140
177
|
}
|
|
141
178
|
}
|
|
142
179
|
}
|
|
143
|
-
/** Close all connections
|
|
180
|
+
/** Close all connections, clear all state and buffers. Used during shutdown. */
|
|
144
181
|
closeAll() {
|
|
145
182
|
for (const ws of this.connections.keys()) {
|
|
146
183
|
ws.close?.();
|
|
147
184
|
}
|
|
185
|
+
for (const buffer of this.buffers.values()) {
|
|
186
|
+
if (buffer.timer) clearTimeout(buffer.timer);
|
|
187
|
+
}
|
|
148
188
|
this.connections.clear();
|
|
149
189
|
this.channels.clear();
|
|
190
|
+
this.buffers.clear();
|
|
150
191
|
}
|
|
151
192
|
/** Get the number of active connections. */
|
|
152
193
|
get connectionCount() {
|
|
@@ -351,15 +392,8 @@ function createWorkflowRoutes(connMgr) {
|
|
|
351
392
|
const stream = runtime.stream(name, body.input ?? {}, { metadata: body.metadata });
|
|
352
393
|
const executionId = `stream-${Date.now()}`;
|
|
353
394
|
(async () => {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
connMgr.broadcastWithWildcard(`execution:${executionId}`, event);
|
|
357
|
-
}
|
|
358
|
-
} catch (err) {
|
|
359
|
-
connMgr.broadcastWithWildcard(`execution:${executionId}`, {
|
|
360
|
-
type: "error",
|
|
361
|
-
message: err instanceof Error ? err.message : "Stream error"
|
|
362
|
-
});
|
|
395
|
+
for await (const event of stream) {
|
|
396
|
+
connMgr.broadcastWithWildcard(`execution:${executionId}`, event);
|
|
363
397
|
}
|
|
364
398
|
})();
|
|
365
399
|
return c.json({ ok: true, data: { executionId, streaming: true } });
|
|
@@ -440,15 +474,8 @@ function createSessionRoutes(connMgr) {
|
|
|
440
474
|
const stream = await session.stream(body.workflow, body.message);
|
|
441
475
|
const executionId = `session-${id}-${Date.now()}`;
|
|
442
476
|
(async () => {
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
connMgr.broadcastWithWildcard(`execution:${executionId}`, event);
|
|
446
|
-
}
|
|
447
|
-
} catch (err) {
|
|
448
|
-
connMgr.broadcastWithWildcard(`execution:${executionId}`, {
|
|
449
|
-
type: "error",
|
|
450
|
-
message: err instanceof Error ? err.message : "Stream error"
|
|
451
|
-
});
|
|
477
|
+
for await (const event of stream) {
|
|
478
|
+
connMgr.broadcastWithWildcard(`execution:${executionId}`, event);
|
|
452
479
|
}
|
|
453
480
|
})();
|
|
454
481
|
return c.json({ ok: true, data: { executionId, streaming: true } });
|
|
@@ -759,26 +786,57 @@ function createPlaygroundRoutes(connMgr) {
|
|
|
759
786
|
app7.post("/playground/chat", async (c) => {
|
|
760
787
|
const runtime = c.get("runtime");
|
|
761
788
|
const body = await c.req.json();
|
|
762
|
-
|
|
763
|
-
|
|
789
|
+
if (!body.message || typeof body.message !== "string" || !body.message.trim()) {
|
|
790
|
+
return c.json(
|
|
791
|
+
{
|
|
792
|
+
ok: false,
|
|
793
|
+
error: {
|
|
794
|
+
code: "INVALID_INPUT",
|
|
795
|
+
message: "message is required and must be a non-empty string"
|
|
796
|
+
}
|
|
797
|
+
},
|
|
798
|
+
400
|
|
799
|
+
);
|
|
800
|
+
}
|
|
801
|
+
const agents = runtime.getAgents();
|
|
802
|
+
const agent = body.agent ? agents.find((a) => a._name === body.agent) : agents[0];
|
|
803
|
+
if (!agent) {
|
|
764
804
|
return c.json(
|
|
765
|
-
{
|
|
805
|
+
{
|
|
806
|
+
ok: false,
|
|
807
|
+
error: { code: "NO_AGENT", message: `Agent "${body.agent ?? ""}" not found` }
|
|
808
|
+
},
|
|
766
809
|
400
|
|
767
810
|
);
|
|
768
811
|
}
|
|
769
812
|
const sessionId = body.sessionId ?? `playground-${Date.now()}`;
|
|
770
|
-
const session = runtime.session(sessionId);
|
|
771
|
-
const stream = await session.stream(workflowName, body.message);
|
|
772
813
|
const executionId = `playground-${sessionId}-${Date.now()}`;
|
|
814
|
+
const store = runtime.getStateStore();
|
|
815
|
+
const history = await store.getSession(sessionId);
|
|
816
|
+
history.push({ role: "user", content: body.message });
|
|
817
|
+
const ctx = runtime.createContext({
|
|
818
|
+
sessionHistory: history,
|
|
819
|
+
onToken: (token) => {
|
|
820
|
+
connMgr.broadcastWithWildcard(`execution:${executionId}`, {
|
|
821
|
+
type: "token",
|
|
822
|
+
data: token
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
});
|
|
773
826
|
(async () => {
|
|
774
827
|
try {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
}
|
|
828
|
+
const result = await ctx.ask(agent, body.message);
|
|
829
|
+
const resultText = typeof result === "string" ? result : JSON.stringify(result);
|
|
830
|
+
history.push({ role: "assistant", content: resultText });
|
|
831
|
+
await store.saveSession(sessionId, history);
|
|
832
|
+
connMgr.broadcastWithWildcard(`execution:${executionId}`, {
|
|
833
|
+
type: "done",
|
|
834
|
+
data: resultText
|
|
835
|
+
});
|
|
778
836
|
} catch (err) {
|
|
779
837
|
connMgr.broadcastWithWildcard(`execution:${executionId}`, {
|
|
780
838
|
type: "error",
|
|
781
|
-
message: err instanceof Error ? err.message :
|
|
839
|
+
message: err instanceof Error ? err.message : String(err)
|
|
782
840
|
});
|
|
783
841
|
}
|
|
784
842
|
})();
|
|
@@ -890,19 +948,24 @@ function createServer(options) {
|
|
|
890
948
|
app7.use("/*", async (c, next) => {
|
|
891
949
|
const reqPath = c.req.path;
|
|
892
950
|
const resolved = basePath && reqPath.startsWith(basePath) ? reqPath.slice(basePath.length) || "/" : reqPath;
|
|
893
|
-
if (resolved === "/" || resolved === "/index.html") {
|
|
951
|
+
if (resolved === "/" || resolved === "/index.html" || resolved === "/ws") {
|
|
894
952
|
return next();
|
|
895
953
|
}
|
|
896
954
|
return staticHandler(c, next);
|
|
897
955
|
});
|
|
898
956
|
if (spaHtml) {
|
|
899
|
-
app7.get("*", (c) =>
|
|
957
|
+
app7.get("*", async (c, next) => {
|
|
958
|
+
const resolved = basePath && c.req.path.startsWith(basePath) ? c.req.path.slice(basePath.length) || "/" : c.req.path;
|
|
959
|
+
if (resolved === "/ws") return next();
|
|
960
|
+
return c.html(spaHtml);
|
|
961
|
+
});
|
|
900
962
|
}
|
|
901
963
|
}
|
|
902
964
|
return {
|
|
903
965
|
app: app7,
|
|
904
966
|
connMgr,
|
|
905
967
|
costAggregator,
|
|
968
|
+
/** Create WS handlers. Call before registering static/SPA routes are reached. */
|
|
906
969
|
createWsHandlers: () => createWsHandlers(connMgr),
|
|
907
970
|
traceListener
|
|
908
971
|
};
|