@standardagents/builder 0.8.5 → 0.9.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/dist/built-in-routes.js +1 -1
- package/dist/built-in-routes.js.map +1 -1
- package/dist/client/assets/img/agent-builder-logo-dark.svg +16 -0
- package/dist/client/assets/img/agent-builder-logo-light.svg +16 -0
- package/dist/client/assets/img/favicon.svg +11 -0
- package/dist/client/assets/index.css +1 -1
- package/dist/client/assets/{json.worker-C21G4-GD.js → json.worker-B3O9ZXir.js} +1 -6
- package/dist/client/index.html +1 -0
- package/dist/client/index.js +19 -19
- package/dist/client/monaco.js +13 -465
- package/dist/client/vue.js +1 -143
- package/dist/index.d.ts +15 -24
- package/dist/index.js +84 -113
- package/dist/index.js.map +1 -1
- package/dist/plugin.js +5 -2
- package/dist/plugin.js.map +1 -1
- package/dist/rou3.js +1 -1
- package/dist/rou3.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -77,8 +77,9 @@ declare global {
|
|
|
77
77
|
*/
|
|
78
78
|
type BeforeClose = () => Promise<void> | void;
|
|
79
79
|
/**
|
|
80
|
-
* Manages
|
|
81
|
-
*
|
|
80
|
+
* Manages HTTP streaming of content chunks.
|
|
81
|
+
* WebSocket telemetry is handled separately by DurableThread.
|
|
82
|
+
* Inspired by bod.coach MultiplexedStream pattern.
|
|
82
83
|
*/
|
|
83
84
|
declare class StreamManager {
|
|
84
85
|
/**
|
|
@@ -89,10 +90,6 @@ declare class StreamManager {
|
|
|
89
90
|
* HTTP ReadableStream for content chunks
|
|
90
91
|
*/
|
|
91
92
|
httpStream: ReadableStream<Uint8Array>;
|
|
92
|
-
/**
|
|
93
|
-
* WebSocket connections for telemetry
|
|
94
|
-
*/
|
|
95
|
-
private wsConnections;
|
|
96
93
|
/**
|
|
97
94
|
* Active channels
|
|
98
95
|
*/
|
|
@@ -126,24 +123,6 @@ declare class StreamManager {
|
|
|
126
123
|
* Send content chunk to HTTP stream
|
|
127
124
|
*/
|
|
128
125
|
sendContent(chunk: string): void;
|
|
129
|
-
/**
|
|
130
|
-
* Send telemetry event to all WebSocket connections
|
|
131
|
-
*/
|
|
132
|
-
sendTelemetry(event: TelemetryEvent): void;
|
|
133
|
-
/**
|
|
134
|
-
* Emit a custom event to all WebSocket connections
|
|
135
|
-
*
|
|
136
|
-
* This sends a custom event message that can be received by frontend
|
|
137
|
-
* clients using the onThreadEvent hook.
|
|
138
|
-
*
|
|
139
|
-
* @param type - The event type name
|
|
140
|
-
* @param data - The event payload (any serializable data)
|
|
141
|
-
*/
|
|
142
|
-
emitEvent(type: string, data: unknown): void;
|
|
143
|
-
/**
|
|
144
|
-
* Add a WebSocket connection for telemetry
|
|
145
|
-
*/
|
|
146
|
-
addWebSocket(ws: WebSocket): void;
|
|
147
126
|
/**
|
|
148
127
|
* Add a before close hook
|
|
149
128
|
*/
|
|
@@ -473,6 +452,8 @@ interface FlowState {
|
|
|
473
452
|
emitLog?: (log: unknown) => void;
|
|
474
453
|
emitMessage?: (message: unknown) => void;
|
|
475
454
|
emitMessageChunk?: (messageId: string, chunk: string, depth?: number) => void;
|
|
455
|
+
emitTelemetry?: (event: TelemetryEvent) => void;
|
|
456
|
+
emitEvent?: (type: string, data: unknown) => void;
|
|
476
457
|
rootState: FlowState;
|
|
477
458
|
rootMessageId?: string | null;
|
|
478
459
|
parentLogId?: string | null;
|
|
@@ -1085,6 +1066,16 @@ declare class DurableThread<Env extends ThreadEnv = ThreadEnv> extends DurableOb
|
|
|
1085
1066
|
* Does NOT update database - only broadcasts to connected clients
|
|
1086
1067
|
*/
|
|
1087
1068
|
private broadcastMessageChunk;
|
|
1069
|
+
/**
|
|
1070
|
+
* Broadcast a telemetry event to all connected message WebSocket clients
|
|
1071
|
+
* Used for execution status updates (turn_started, tool_started, etc.)
|
|
1072
|
+
*/
|
|
1073
|
+
private broadcastTelemetry;
|
|
1074
|
+
/**
|
|
1075
|
+
* Broadcast a custom event to all connected message WebSocket clients
|
|
1076
|
+
* Used by tools via emitThreadEvent() to send user-defined events
|
|
1077
|
+
*/
|
|
1078
|
+
private broadcastEvent;
|
|
1088
1079
|
/**
|
|
1089
1080
|
* WebSocket Hibernation API handler for incoming messages
|
|
1090
1081
|
* Called when a message is received on a hibernated WebSocket
|
package/dist/index.js
CHANGED
|
@@ -39,10 +39,6 @@ var init_StreamManager = __esm({
|
|
|
39
39
|
* HTTP ReadableStream for content chunks
|
|
40
40
|
*/
|
|
41
41
|
httpStream;
|
|
42
|
-
/**
|
|
43
|
-
* WebSocket connections for telemetry
|
|
44
|
-
*/
|
|
45
|
-
wsConnections;
|
|
46
42
|
/**
|
|
47
43
|
* Active channels
|
|
48
44
|
*/
|
|
@@ -74,7 +70,6 @@ var init_StreamManager = __esm({
|
|
|
74
70
|
closed = false;
|
|
75
71
|
constructor(beforeClose = []) {
|
|
76
72
|
this.encoder = new TextEncoder();
|
|
77
|
-
this.wsConnections = /* @__PURE__ */ new Set();
|
|
78
73
|
this.httpStream = new ReadableStream({
|
|
79
74
|
start: (controller) => {
|
|
80
75
|
this.httpController = controller;
|
|
@@ -99,73 +94,6 @@ var init_StreamManager = __esm({
|
|
|
99
94
|
console.error("Error sending content chunk:", error);
|
|
100
95
|
}
|
|
101
96
|
}
|
|
102
|
-
/**
|
|
103
|
-
* Send telemetry event to all WebSocket connections
|
|
104
|
-
*/
|
|
105
|
-
sendTelemetry(event) {
|
|
106
|
-
if (this.closed) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const message = JSON.stringify(event);
|
|
110
|
-
for (const ws of this.wsConnections) {
|
|
111
|
-
if (ws.readyState !== WebSocket.OPEN) {
|
|
112
|
-
this.wsConnections.delete(ws);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
for (const ws of this.wsConnections) {
|
|
116
|
-
try {
|
|
117
|
-
ws.send(message);
|
|
118
|
-
} catch (error) {
|
|
119
|
-
console.error("Error sending telemetry:", error);
|
|
120
|
-
this.wsConnections.delete(ws);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Emit a custom event to all WebSocket connections
|
|
126
|
-
*
|
|
127
|
-
* This sends a custom event message that can be received by frontend
|
|
128
|
-
* clients using the onThreadEvent hook.
|
|
129
|
-
*
|
|
130
|
-
* @param type - The event type name
|
|
131
|
-
* @param data - The event payload (any serializable data)
|
|
132
|
-
*/
|
|
133
|
-
emitEvent(type, data) {
|
|
134
|
-
if (this.closed) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
const message = JSON.stringify({
|
|
138
|
-
type: "event",
|
|
139
|
-
eventType: type,
|
|
140
|
-
data,
|
|
141
|
-
timestamp: Date.now()
|
|
142
|
-
});
|
|
143
|
-
for (const ws of this.wsConnections) {
|
|
144
|
-
if (ws.readyState !== WebSocket.OPEN) {
|
|
145
|
-
this.wsConnections.delete(ws);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
for (const ws of this.wsConnections) {
|
|
149
|
-
try {
|
|
150
|
-
ws.send(message);
|
|
151
|
-
} catch (error) {
|
|
152
|
-
console.error("Error emitting event:", error);
|
|
153
|
-
this.wsConnections.delete(ws);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Add a WebSocket connection for telemetry
|
|
159
|
-
*/
|
|
160
|
-
addWebSocket(ws) {
|
|
161
|
-
this.wsConnections.add(ws);
|
|
162
|
-
ws.addEventListener("close", () => {
|
|
163
|
-
this.wsConnections.delete(ws);
|
|
164
|
-
});
|
|
165
|
-
ws.addEventListener("error", () => {
|
|
166
|
-
this.wsConnections.delete(ws);
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
97
|
/**
|
|
170
98
|
* Add a before close hook
|
|
171
99
|
*/
|
|
@@ -224,16 +152,6 @@ var init_StreamManager = __esm({
|
|
|
224
152
|
console.error("Error closing HTTP stream:", error);
|
|
225
153
|
}
|
|
226
154
|
}
|
|
227
|
-
for (const ws of this.wsConnections) {
|
|
228
|
-
try {
|
|
229
|
-
if (ws.readyState === WebSocket.OPEN) {
|
|
230
|
-
ws.close();
|
|
231
|
-
}
|
|
232
|
-
} catch (error) {
|
|
233
|
-
console.error("Error closing WebSocket:", error);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
this.wsConnections.clear();
|
|
237
155
|
this.resolver();
|
|
238
156
|
} catch (error) {
|
|
239
157
|
console.error("Error during stream close:", error);
|
|
@@ -891,7 +809,7 @@ var init_LLMRequest = __esm({
|
|
|
891
809
|
} catch (primaryError) {
|
|
892
810
|
console.error(`Primary model ${context.model} failed:`, primaryError);
|
|
893
811
|
lastFailedLogId = primaryError?._lastLogId;
|
|
894
|
-
state.
|
|
812
|
+
state.emitTelemetry?.({
|
|
895
813
|
type: "fallback_triggered",
|
|
896
814
|
from: context.model,
|
|
897
815
|
to: "fetching_fallbacks",
|
|
@@ -901,7 +819,7 @@ var init_LLMRequest = __esm({
|
|
|
901
819
|
const fallbacks = await this.getFallbacks(context.model, state);
|
|
902
820
|
for (const fallback of fallbacks) {
|
|
903
821
|
try {
|
|
904
|
-
state.
|
|
822
|
+
state.emitTelemetry?.({
|
|
905
823
|
type: "fallback_triggered",
|
|
906
824
|
from: context.model,
|
|
907
825
|
to: fallback.fallback_model_id,
|
|
@@ -947,7 +865,7 @@ var init_LLMRequest = __esm({
|
|
|
947
865
|
attempts++;
|
|
948
866
|
try {
|
|
949
867
|
logId = await this.logRequest(state, modelId, context, previousLogId);
|
|
950
|
-
state.
|
|
868
|
+
state.emitTelemetry?.({
|
|
951
869
|
type: "llm_request",
|
|
952
870
|
model: modelId,
|
|
953
871
|
attempt: attempts,
|
|
@@ -955,7 +873,7 @@ var init_LLMRequest = __esm({
|
|
|
955
873
|
});
|
|
956
874
|
const response = await this.callModel(modelId, context, state, logId);
|
|
957
875
|
await this.logSuccess(response, state, modelId, startTime, context, logId);
|
|
958
|
-
state.
|
|
876
|
+
state.emitTelemetry?.({
|
|
959
877
|
type: "llm_response",
|
|
960
878
|
tokens: response.usage.total_tokens,
|
|
961
879
|
latency: Date.now() - startTime,
|
|
@@ -1433,7 +1351,7 @@ var init_ToolExecutor = __esm({
|
|
|
1433
1351
|
const call = state.sequence.queue.shift();
|
|
1434
1352
|
const toolMessageId = crypto.randomUUID();
|
|
1435
1353
|
try {
|
|
1436
|
-
state.
|
|
1354
|
+
state.emitTelemetry?.({
|
|
1437
1355
|
type: "tool_started",
|
|
1438
1356
|
tool: call.function.name,
|
|
1439
1357
|
timestamp: Date.now()
|
|
@@ -1445,7 +1363,7 @@ var init_ToolExecutor = __esm({
|
|
|
1445
1363
|
error: validationError
|
|
1446
1364
|
};
|
|
1447
1365
|
await this.storeToolResult(call, result2, state, toolMessageId);
|
|
1448
|
-
state.
|
|
1366
|
+
state.emitTelemetry?.({
|
|
1449
1367
|
type: "tool_completed",
|
|
1450
1368
|
tool: call.function.name,
|
|
1451
1369
|
status: "error",
|
|
@@ -1468,7 +1386,7 @@ var init_ToolExecutor = __esm({
|
|
|
1468
1386
|
continue;
|
|
1469
1387
|
}
|
|
1470
1388
|
await this.storeToolResult(call, hookResult, state, toolMessageId);
|
|
1471
|
-
state.
|
|
1389
|
+
state.emitTelemetry?.({
|
|
1472
1390
|
type: "tool_completed",
|
|
1473
1391
|
tool: call.function.name,
|
|
1474
1392
|
status: hookResult.status,
|
|
@@ -1488,7 +1406,7 @@ var init_ToolExecutor = __esm({
|
|
|
1488
1406
|
continue;
|
|
1489
1407
|
}
|
|
1490
1408
|
await this.storeToolResult(call, hookResult, state, toolMessageId);
|
|
1491
|
-
state.
|
|
1409
|
+
state.emitTelemetry?.({
|
|
1492
1410
|
type: "tool_completed",
|
|
1493
1411
|
tool: call.function.name,
|
|
1494
1412
|
status: "error",
|
|
@@ -1729,7 +1647,7 @@ var init_ToolExecutor = __esm({
|
|
|
1729
1647
|
const propertyValue = args[initUserMessageProperty];
|
|
1730
1648
|
userMessageContent = typeof propertyValue === "string" ? propertyValue : JSON.stringify(propertyValue);
|
|
1731
1649
|
}
|
|
1732
|
-
const extraMessages = state.extraMessages || [];
|
|
1650
|
+
const extraMessages = [...state.extraMessages || []];
|
|
1733
1651
|
if (userMessageContent) {
|
|
1734
1652
|
extraMessages.push({
|
|
1735
1653
|
id: crypto.randomUUID(),
|
|
@@ -2358,7 +2276,7 @@ var init_FlowEngine = __esm({
|
|
|
2358
2276
|
status: interruptionMessage.status
|
|
2359
2277
|
});
|
|
2360
2278
|
}
|
|
2361
|
-
state.
|
|
2279
|
+
state.emitTelemetry?.({
|
|
2362
2280
|
type: "stopped_by_user",
|
|
2363
2281
|
timestamp: Date.now()
|
|
2364
2282
|
});
|
|
@@ -2389,7 +2307,7 @@ var init_FlowEngine = __esm({
|
|
|
2389
2307
|
|
|
2390
2308
|
[ERROR] ${errorMessage}
|
|
2391
2309
|
`);
|
|
2392
|
-
state.
|
|
2310
|
+
state.emitTelemetry?.({
|
|
2393
2311
|
type: "stopped",
|
|
2394
2312
|
reason: `Error: ${errorMessage}`,
|
|
2395
2313
|
side: state.currentSide,
|
|
@@ -2408,7 +2326,7 @@ var init_FlowEngine = __esm({
|
|
|
2408
2326
|
"max_turns_reached",
|
|
2409
2327
|
`Thread ${threadId}`
|
|
2410
2328
|
);
|
|
2411
|
-
state.
|
|
2329
|
+
state.emitTelemetry?.({
|
|
2412
2330
|
type: "stopped",
|
|
2413
2331
|
reason: "Maximum turns reached",
|
|
2414
2332
|
side: state.currentSide,
|
|
@@ -2524,6 +2442,8 @@ var init_FlowEngine = __esm({
|
|
|
2524
2442
|
emitLog: stateInput.emitLog,
|
|
2525
2443
|
emitMessage: stateInput.emitMessage,
|
|
2526
2444
|
emitMessageChunk: stateInput.emitMessageChunk,
|
|
2445
|
+
emitTelemetry: stateInput.emitTelemetry,
|
|
2446
|
+
emitEvent: stateInput.emitEvent,
|
|
2527
2447
|
rootMessageId: stateInput.rootMessageId,
|
|
2528
2448
|
parentLogId: stateInput.parentLogId,
|
|
2529
2449
|
currentLogId: stateInput.currentLogId,
|
|
@@ -2557,7 +2477,7 @@ var init_FlowEngine = __esm({
|
|
|
2557
2477
|
if (maxTurns !== null && currentSideTurnCount >= maxTurns) {
|
|
2558
2478
|
state.stopped = true;
|
|
2559
2479
|
state.stoppedBy = state.currentSide;
|
|
2560
|
-
state.
|
|
2480
|
+
state.emitTelemetry?.({
|
|
2561
2481
|
type: "stopped",
|
|
2562
2482
|
reason: `Side ${state.currentSide} reached max turns (${maxTurns})`,
|
|
2563
2483
|
side: state.currentSide,
|
|
@@ -2570,7 +2490,7 @@ var init_FlowEngine = __esm({
|
|
|
2570
2490
|
if (completedExchanges >= state.agentConfig.max_session_turns) {
|
|
2571
2491
|
state.stopped = true;
|
|
2572
2492
|
state.stoppedBy = state.currentSide;
|
|
2573
|
-
state.
|
|
2493
|
+
state.emitTelemetry?.({
|
|
2574
2494
|
type: "stopped",
|
|
2575
2495
|
reason: `Reached max session turns (${state.agentConfig.max_session_turns} exchanges)`,
|
|
2576
2496
|
side: state.currentSide,
|
|
@@ -2584,7 +2504,7 @@ var init_FlowEngine = __esm({
|
|
|
2584
2504
|
} else {
|
|
2585
2505
|
state.sideBTurnCount++;
|
|
2586
2506
|
}
|
|
2587
|
-
state.
|
|
2507
|
+
state.emitTelemetry?.({
|
|
2588
2508
|
type: "turn_started",
|
|
2589
2509
|
turn: state.turnCount,
|
|
2590
2510
|
side: state.currentSide,
|
|
@@ -2642,7 +2562,7 @@ var init_FlowEngine = __esm({
|
|
|
2642
2562
|
if (state.agentConfig.type === "ai_human" && forcedSide === "b") {
|
|
2643
2563
|
state.stopped = true;
|
|
2644
2564
|
state.stoppedBy = "a";
|
|
2645
|
-
state.
|
|
2565
|
+
state.emitTelemetry?.({
|
|
2646
2566
|
type: "stopped",
|
|
2647
2567
|
reason: "Forced turn to human (side_b)",
|
|
2648
2568
|
side: state.currentSide,
|
|
@@ -2669,7 +2589,7 @@ var init_FlowEngine = __esm({
|
|
|
2669
2589
|
if (state.agentConfig.type === "dual_ai" && !state.stopped) {
|
|
2670
2590
|
this.switchSides(state);
|
|
2671
2591
|
}
|
|
2672
|
-
state.
|
|
2592
|
+
state.emitTelemetry?.({
|
|
2673
2593
|
type: "turn_completed",
|
|
2674
2594
|
turn: state.turnCount,
|
|
2675
2595
|
stopped: state.stopped,
|
|
@@ -2726,7 +2646,7 @@ var init_FlowEngine = __esm({
|
|
|
2726
2646
|
state.currentSide = "a";
|
|
2727
2647
|
state.prompt = state.prompts.sideA;
|
|
2728
2648
|
state.pendingHandoff = void 0;
|
|
2729
|
-
state.
|
|
2649
|
+
state.emitTelemetry?.({
|
|
2730
2650
|
type: "agent_handoff",
|
|
2731
2651
|
new_agent_id: newAgentName,
|
|
2732
2652
|
new_agent_title: state.agentConfig.title,
|
|
@@ -3626,7 +3546,7 @@ var init_FlowEngine = __esm({
|
|
|
3626
3546
|
if (endConversationTool && response.tool_calls?.some((call) => call.function.name === endConversationTool)) {
|
|
3627
3547
|
state.stopped = true;
|
|
3628
3548
|
state.stoppedBy = state.currentSide;
|
|
3629
|
-
state.
|
|
3549
|
+
state.emitTelemetry?.({
|
|
3630
3550
|
type: "stopped",
|
|
3631
3551
|
reason: `End conversation tool called: ${endConversationTool}`,
|
|
3632
3552
|
side: state.currentSide,
|
|
@@ -3640,7 +3560,7 @@ var init_FlowEngine = __esm({
|
|
|
3640
3560
|
if (stopOnResponse && response.content && !response.tool_calls) {
|
|
3641
3561
|
state.stopped = true;
|
|
3642
3562
|
state.stoppedBy = state.currentSide;
|
|
3643
|
-
state.
|
|
3563
|
+
state.emitTelemetry?.({
|
|
3644
3564
|
type: "stopped",
|
|
3645
3565
|
reason: "Returns content (no tool calls)",
|
|
3646
3566
|
side: state.currentSide,
|
|
@@ -3650,7 +3570,7 @@ var init_FlowEngine = __esm({
|
|
|
3650
3570
|
if (stopTool && response.tool_calls?.some((call) => call.function.name === stopTool)) {
|
|
3651
3571
|
state.stopped = true;
|
|
3652
3572
|
state.stoppedBy = state.currentSide;
|
|
3653
|
-
state.
|
|
3573
|
+
state.emitTelemetry?.({
|
|
3654
3574
|
type: "stopped",
|
|
3655
3575
|
reason: `Stop tool called: ${stopTool}`,
|
|
3656
3576
|
side: state.currentSide,
|
|
@@ -5933,9 +5853,12 @@ function agentbuilder(options = {}) {
|
|
|
5933
5853
|
optimizeDeps: {
|
|
5934
5854
|
// Pre-bundle these deps to prevent reload during startup
|
|
5935
5855
|
include: ["openai", "zod"],
|
|
5936
|
-
// Exclude
|
|
5856
|
+
// Exclude workspace packages from pre-bundling to prevent "new version of pre-bundle" errors
|
|
5857
|
+
// during first startup when node_modules/.vite cache is empty
|
|
5937
5858
|
exclude: [
|
|
5938
|
-
"@standardagents/builder/mcp"
|
|
5859
|
+
"@standardagents/builder/mcp",
|
|
5860
|
+
"@standardagents/builder/runtime",
|
|
5861
|
+
"@standardagents/builder/built-in-routes"
|
|
5939
5862
|
]
|
|
5940
5863
|
},
|
|
5941
5864
|
ssr: {
|
|
@@ -8815,6 +8738,55 @@ var DurableThread = class extends DurableObject {
|
|
|
8815
8738
|
}
|
|
8816
8739
|
}
|
|
8817
8740
|
}
|
|
8741
|
+
/**
|
|
8742
|
+
* Broadcast a telemetry event to all connected message WebSocket clients
|
|
8743
|
+
* Used for execution status updates (turn_started, tool_started, etc.)
|
|
8744
|
+
*/
|
|
8745
|
+
broadcastTelemetry(event) {
|
|
8746
|
+
const payload = JSON.stringify(event);
|
|
8747
|
+
for (const ws of Array.from(this.messageSockets)) {
|
|
8748
|
+
try {
|
|
8749
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
8750
|
+
ws.send(payload);
|
|
8751
|
+
} else {
|
|
8752
|
+
this.messageSockets.delete(ws);
|
|
8753
|
+
}
|
|
8754
|
+
} catch (err) {
|
|
8755
|
+
console.error(
|
|
8756
|
+
"[DurableThread] Failed to send telemetry to WebSocket:",
|
|
8757
|
+
err
|
|
8758
|
+
);
|
|
8759
|
+
this.messageSockets.delete(ws);
|
|
8760
|
+
}
|
|
8761
|
+
}
|
|
8762
|
+
}
|
|
8763
|
+
/**
|
|
8764
|
+
* Broadcast a custom event to all connected message WebSocket clients
|
|
8765
|
+
* Used by tools via emitThreadEvent() to send user-defined events
|
|
8766
|
+
*/
|
|
8767
|
+
broadcastEvent(type, data) {
|
|
8768
|
+
const payload = JSON.stringify({
|
|
8769
|
+
type: "event",
|
|
8770
|
+
eventType: type,
|
|
8771
|
+
data,
|
|
8772
|
+
timestamp: Date.now()
|
|
8773
|
+
});
|
|
8774
|
+
for (const ws of Array.from(this.messageSockets)) {
|
|
8775
|
+
try {
|
|
8776
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
8777
|
+
ws.send(payload);
|
|
8778
|
+
} else {
|
|
8779
|
+
this.messageSockets.delete(ws);
|
|
8780
|
+
}
|
|
8781
|
+
} catch (err) {
|
|
8782
|
+
console.error(
|
|
8783
|
+
"[DurableThread] Failed to send event to WebSocket:",
|
|
8784
|
+
err
|
|
8785
|
+
);
|
|
8786
|
+
this.messageSockets.delete(ws);
|
|
8787
|
+
}
|
|
8788
|
+
}
|
|
8789
|
+
}
|
|
8818
8790
|
/**
|
|
8819
8791
|
* WebSocket Hibernation API handler for incoming messages
|
|
8820
8792
|
* Called when a message is received on a hibernated WebSocket
|
|
@@ -8963,6 +8935,8 @@ var DurableThread = class extends DurableObject {
|
|
|
8963
8935
|
emitLog: (log) => this.broadcastLog(log),
|
|
8964
8936
|
emitMessage: (message) => this.broadcastMessage(message),
|
|
8965
8937
|
emitMessageChunk: (messageId, chunk, depth) => this.broadcastMessageChunk(messageId, chunk, depth),
|
|
8938
|
+
emitTelemetry: (event) => this.broadcastTelemetry(event),
|
|
8939
|
+
emitEvent: (type, data2) => this.broadcastEvent(type, data2),
|
|
8966
8940
|
rootMessageId,
|
|
8967
8941
|
abortController: this.currentAbortController
|
|
8968
8942
|
});
|
|
@@ -9054,11 +9028,6 @@ var DurableThread = class extends DurableObject {
|
|
|
9054
9028
|
});
|
|
9055
9029
|
const nextSide = role === "assistant" ? "b" : "a";
|
|
9056
9030
|
const stream = new StreamManager();
|
|
9057
|
-
for (const ws of this.messageSockets) {
|
|
9058
|
-
if (ws.readyState === WebSocket.OPEN) {
|
|
9059
|
-
stream.addWebSocket(ws);
|
|
9060
|
-
}
|
|
9061
|
-
}
|
|
9062
9031
|
await FlowEngine2.execute({
|
|
9063
9032
|
agentConfig: agent,
|
|
9064
9033
|
storage: this.ctx.storage,
|
|
@@ -9075,6 +9044,8 @@ var DurableThread = class extends DurableObject {
|
|
|
9075
9044
|
emitLog: (log) => this.broadcastLog(log),
|
|
9076
9045
|
emitMessage: (message2) => this.broadcastMessage(message2),
|
|
9077
9046
|
emitMessageChunk: (messageId2, chunk, depth) => this.broadcastMessageChunk(messageId2, chunk, depth),
|
|
9047
|
+
emitTelemetry: (event) => this.broadcastTelemetry(event),
|
|
9048
|
+
emitEvent: (type, data) => this.broadcastEvent(type, data),
|
|
9078
9049
|
abortController: this.currentAbortController
|
|
9079
9050
|
});
|
|
9080
9051
|
} finally {
|
|
@@ -10355,11 +10326,11 @@ async function reloadHistory(state) {
|
|
|
10355
10326
|
return state.messageHistory;
|
|
10356
10327
|
}
|
|
10357
10328
|
function emitThreadEvent(flow, type, data) {
|
|
10358
|
-
if (!flow.
|
|
10359
|
-
console.warn("Cannot emit event:
|
|
10329
|
+
if (!flow.emitEvent) {
|
|
10330
|
+
console.warn("Cannot emit event: emitEvent callback is not available");
|
|
10360
10331
|
return;
|
|
10361
10332
|
}
|
|
10362
|
-
flow.
|
|
10333
|
+
flow.emitEvent(type, data);
|
|
10363
10334
|
}
|
|
10364
10335
|
function forceTurn(flow, side) {
|
|
10365
10336
|
if (flow.sequence.isHandling) {
|