@runtypelabs/persona 3.13.0 → 3.15.0
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/index.cjs +25 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.global.js +39 -39
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +26 -26
- package/dist/index.js.map +1 -1
- package/dist/theme-editor.cjs +34 -7
- package/dist/theme-editor.d.cts +9 -0
- package/dist/theme-editor.d.ts +9 -0
- package/dist/theme-editor.js +34 -7
- package/package.json +1 -1
- package/src/client.test.ts +64 -0
- package/src/client.ts +37 -8
- package/src/types.ts +9 -0
- package/src/ui.ts +5 -3
package/dist/theme-editor.cjs
CHANGED
|
@@ -4329,7 +4329,7 @@ var AgentWidgetClient = class {
|
|
|
4329
4329
|
}
|
|
4330
4330
|
}
|
|
4331
4331
|
async streamResponse(body, onEvent, assistantMessageId) {
|
|
4332
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb;
|
|
4332
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb, _mb, _nb;
|
|
4333
4333
|
const reader = body.getReader();
|
|
4334
4334
|
const decoder = new TextDecoder();
|
|
4335
4335
|
let buffer = "";
|
|
@@ -5620,11 +5620,34 @@ var AgentWidgetClient = class {
|
|
|
5620
5620
|
streamParsers.delete(id);
|
|
5621
5621
|
rawContentBuffers.delete(id);
|
|
5622
5622
|
seqChunkBuffers.delete(id);
|
|
5623
|
-
} else if (payloadType === "error"
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
})
|
|
5623
|
+
} else if (payloadType === "error" || payloadType === "step_error" || payloadType === "dispatch_error" || payloadType === "flow_error") {
|
|
5624
|
+
let resolvedError = null;
|
|
5625
|
+
if (payload.error instanceof Error) {
|
|
5626
|
+
resolvedError = payload.error;
|
|
5627
|
+
} else if (payloadType === "dispatch_error") {
|
|
5628
|
+
const msg = (_mb = payload.message) != null ? _mb : payload.error;
|
|
5629
|
+
if (msg != null && msg !== "") {
|
|
5630
|
+
resolvedError = new Error(String(msg));
|
|
5631
|
+
}
|
|
5632
|
+
} else if (payloadType === "step_error" || payloadType === "flow_error") {
|
|
5633
|
+
const e = payload.error;
|
|
5634
|
+
if (typeof e === "string" && e !== "") {
|
|
5635
|
+
resolvedError = new Error(e);
|
|
5636
|
+
} else if (e != null && typeof e === "object" && "message" in e) {
|
|
5637
|
+
resolvedError = new Error(String((_nb = e.message) != null ? _nb : e));
|
|
5638
|
+
}
|
|
5639
|
+
} else if (payloadType === "error" && payload.error != null && payload.error !== "") {
|
|
5640
|
+
resolvedError = new Error(String(payload.error));
|
|
5641
|
+
}
|
|
5642
|
+
if (resolvedError) {
|
|
5643
|
+
onEvent({ type: "error", error: resolvedError });
|
|
5644
|
+
const finalMsg = assistantMessage;
|
|
5645
|
+
if (finalMsg && finalMsg.streaming) {
|
|
5646
|
+
finalMsg.streaming = false;
|
|
5647
|
+
emitMessage(finalMsg);
|
|
5648
|
+
}
|
|
5649
|
+
onEvent({ type: "status", status: "idle" });
|
|
5650
|
+
}
|
|
5628
5651
|
}
|
|
5629
5652
|
}
|
|
5630
5653
|
}
|
|
@@ -15973,8 +15996,10 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
|
|
|
15973
15996
|
}
|
|
15974
15997
|
});
|
|
15975
15998
|
}
|
|
15976
|
-
if (eventStreamBuffer) {
|
|
15999
|
+
if (eventStreamBuffer || config.onSSEEvent) {
|
|
15977
16000
|
session.setSSEEventCallback((type, payload) => {
|
|
16001
|
+
var _a2;
|
|
16002
|
+
(_a2 = config.onSSEEvent) == null ? void 0 : _a2.call(config, type, payload);
|
|
15978
16003
|
eventStreamBuffer == null ? void 0 : eventStreamBuffer.push({
|
|
15979
16004
|
id: `evt-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
15980
16005
|
type,
|
|
@@ -16815,6 +16840,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
|
|
|
16815
16840
|
eventStreamStore.open().then(() => eventStreamBuffer == null ? void 0 : eventStreamBuffer.restore()).catch(() => {
|
|
16816
16841
|
});
|
|
16817
16842
|
session.setSSEEventCallback((type, payload) => {
|
|
16843
|
+
var _a3;
|
|
16844
|
+
(_a3 = config.onSSEEvent) == null ? void 0 : _a3.call(config, type, payload);
|
|
16818
16845
|
eventStreamBuffer.push({
|
|
16819
16846
|
id: `evt-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
16820
16847
|
type,
|
package/dist/theme-editor.d.cts
CHANGED
|
@@ -3217,6 +3217,15 @@ type AgentWidgetConfig = {
|
|
|
3217
3217
|
* ```
|
|
3218
3218
|
*/
|
|
3219
3219
|
parseSSEEvent?: AgentWidgetSSEEventParser;
|
|
3220
|
+
/**
|
|
3221
|
+
* Called for every parsed SSE frame (after JSON parse), before native handling.
|
|
3222
|
+
* Use for lightweight side effects (e.g. telemetry). Does not replace native
|
|
3223
|
+
* streaming; pair with {@link parseSSEEvent} only when you need to override text mapping.
|
|
3224
|
+
*
|
|
3225
|
+
* When the event stream inspector is enabled, this runs in the same order as
|
|
3226
|
+
* events are appended to the inspector buffer.
|
|
3227
|
+
*/
|
|
3228
|
+
onSSEEvent?: (eventType: string, payload: unknown) => void;
|
|
3220
3229
|
/**
|
|
3221
3230
|
* Layout configuration for customizing widget appearance and structure.
|
|
3222
3231
|
* Provides control over header, messages, and content slots.
|
package/dist/theme-editor.d.ts
CHANGED
|
@@ -3217,6 +3217,15 @@ type AgentWidgetConfig = {
|
|
|
3217
3217
|
* ```
|
|
3218
3218
|
*/
|
|
3219
3219
|
parseSSEEvent?: AgentWidgetSSEEventParser;
|
|
3220
|
+
/**
|
|
3221
|
+
* Called for every parsed SSE frame (after JSON parse), before native handling.
|
|
3222
|
+
* Use for lightweight side effects (e.g. telemetry). Does not replace native
|
|
3223
|
+
* streaming; pair with {@link parseSSEEvent} only when you need to override text mapping.
|
|
3224
|
+
*
|
|
3225
|
+
* When the event stream inspector is enabled, this runs in the same order as
|
|
3226
|
+
* events are appended to the inspector buffer.
|
|
3227
|
+
*/
|
|
3228
|
+
onSSEEvent?: (eventType: string, payload: unknown) => void;
|
|
3220
3229
|
/**
|
|
3221
3230
|
* Layout configuration for customizing widget appearance and structure.
|
|
3222
3231
|
* Provides control over header, messages, and content slots.
|
package/dist/theme-editor.js
CHANGED
|
@@ -4220,7 +4220,7 @@ var AgentWidgetClient = class {
|
|
|
4220
4220
|
}
|
|
4221
4221
|
}
|
|
4222
4222
|
async streamResponse(body, onEvent, assistantMessageId) {
|
|
4223
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb;
|
|
4223
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb, _mb, _nb;
|
|
4224
4224
|
const reader = body.getReader();
|
|
4225
4225
|
const decoder = new TextDecoder();
|
|
4226
4226
|
let buffer = "";
|
|
@@ -5511,11 +5511,34 @@ var AgentWidgetClient = class {
|
|
|
5511
5511
|
streamParsers.delete(id);
|
|
5512
5512
|
rawContentBuffers.delete(id);
|
|
5513
5513
|
seqChunkBuffers.delete(id);
|
|
5514
|
-
} else if (payloadType === "error"
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
})
|
|
5514
|
+
} else if (payloadType === "error" || payloadType === "step_error" || payloadType === "dispatch_error" || payloadType === "flow_error") {
|
|
5515
|
+
let resolvedError = null;
|
|
5516
|
+
if (payload.error instanceof Error) {
|
|
5517
|
+
resolvedError = payload.error;
|
|
5518
|
+
} else if (payloadType === "dispatch_error") {
|
|
5519
|
+
const msg = (_mb = payload.message) != null ? _mb : payload.error;
|
|
5520
|
+
if (msg != null && msg !== "") {
|
|
5521
|
+
resolvedError = new Error(String(msg));
|
|
5522
|
+
}
|
|
5523
|
+
} else if (payloadType === "step_error" || payloadType === "flow_error") {
|
|
5524
|
+
const e = payload.error;
|
|
5525
|
+
if (typeof e === "string" && e !== "") {
|
|
5526
|
+
resolvedError = new Error(e);
|
|
5527
|
+
} else if (e != null && typeof e === "object" && "message" in e) {
|
|
5528
|
+
resolvedError = new Error(String((_nb = e.message) != null ? _nb : e));
|
|
5529
|
+
}
|
|
5530
|
+
} else if (payloadType === "error" && payload.error != null && payload.error !== "") {
|
|
5531
|
+
resolvedError = new Error(String(payload.error));
|
|
5532
|
+
}
|
|
5533
|
+
if (resolvedError) {
|
|
5534
|
+
onEvent({ type: "error", error: resolvedError });
|
|
5535
|
+
const finalMsg = assistantMessage;
|
|
5536
|
+
if (finalMsg && finalMsg.streaming) {
|
|
5537
|
+
finalMsg.streaming = false;
|
|
5538
|
+
emitMessage(finalMsg);
|
|
5539
|
+
}
|
|
5540
|
+
onEvent({ type: "status", status: "idle" });
|
|
5541
|
+
}
|
|
5519
5542
|
}
|
|
5520
5543
|
}
|
|
5521
5544
|
}
|
|
@@ -15864,8 +15887,10 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
|
|
|
15864
15887
|
}
|
|
15865
15888
|
});
|
|
15866
15889
|
}
|
|
15867
|
-
if (eventStreamBuffer) {
|
|
15890
|
+
if (eventStreamBuffer || config.onSSEEvent) {
|
|
15868
15891
|
session.setSSEEventCallback((type, payload) => {
|
|
15892
|
+
var _a2;
|
|
15893
|
+
(_a2 = config.onSSEEvent) == null ? void 0 : _a2.call(config, type, payload);
|
|
15869
15894
|
eventStreamBuffer == null ? void 0 : eventStreamBuffer.push({
|
|
15870
15895
|
id: `evt-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
15871
15896
|
type,
|
|
@@ -16706,6 +16731,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
|
|
|
16706
16731
|
eventStreamStore.open().then(() => eventStreamBuffer == null ? void 0 : eventStreamBuffer.restore()).catch(() => {
|
|
16707
16732
|
});
|
|
16708
16733
|
session.setSSEEventCallback((type, payload) => {
|
|
16734
|
+
var _a3;
|
|
16735
|
+
(_a3 = config.onSSEEvent) == null ? void 0 : _a3.call(config, type, payload);
|
|
16709
16736
|
eventStreamBuffer.push({
|
|
16710
16737
|
id: `evt-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
16711
16738
|
type,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runtypelabs/persona",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.15.0",
|
|
4
4
|
"description": "Themeable, pluggable streaming agent widget for websites, in plain JS with support for voice input and reasoning / tool output.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
package/src/client.test.ts
CHANGED
|
@@ -1121,6 +1121,70 @@ describe('AgentWidgetClient - Agent Event Streaming', () => {
|
|
|
1121
1121
|
}
|
|
1122
1122
|
});
|
|
1123
1123
|
|
|
1124
|
+
it('should emit error and finalize streaming on step_error', async () => {
|
|
1125
|
+
const events: AgentWidgetEvent[] = [];
|
|
1126
|
+
|
|
1127
|
+
global.fetch = createAgentStreamFetch([
|
|
1128
|
+
'data: {"type":"flow_start","flowId":"f1","flowName":"Test","totalSteps":1}\n\n',
|
|
1129
|
+
'data: {"type":"step_delta","id":"s1","name":"Prompt","executionType":"prompt","text":"partial"}\n\n',
|
|
1130
|
+
sseEvent('step_error', { error: 'step blew up', seq: 3 }),
|
|
1131
|
+
]);
|
|
1132
|
+
|
|
1133
|
+
const client = new AgentWidgetClient({
|
|
1134
|
+
apiUrl: 'http://localhost:8000',
|
|
1135
|
+
agent: { name: 'Test', model: 'openai:gpt-4o-mini', systemPrompt: 'test' },
|
|
1136
|
+
});
|
|
1137
|
+
|
|
1138
|
+
await client.dispatch(
|
|
1139
|
+
{ messages: [{ id: 'usr_1', role: 'user', content: 'Hi', createdAt: new Date().toISOString() }] },
|
|
1140
|
+
(event) => events.push(event)
|
|
1141
|
+
);
|
|
1142
|
+
|
|
1143
|
+
const errorEvents = events.filter(e => e.type === 'error');
|
|
1144
|
+
expect(errorEvents.length).toBe(1);
|
|
1145
|
+
if (errorEvents[0].type === 'error') {
|
|
1146
|
+
expect(errorEvents[0].error.message).toBe('step blew up');
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
const statusIdle = events.filter(e => e.type === 'status' && e.status === 'idle');
|
|
1150
|
+
expect(statusIdle.length).toBeGreaterThanOrEqual(1);
|
|
1151
|
+
|
|
1152
|
+
const messageEvents = events.filter(e => e.type === 'message');
|
|
1153
|
+
const lastAssistant = [...messageEvents]
|
|
1154
|
+
.reverse()
|
|
1155
|
+
.find(e => e.type === 'message' && e.message.role === 'assistant' && !e.message.variant);
|
|
1156
|
+
expect(lastAssistant?.type === 'message' && lastAssistant.message.streaming).toBe(false);
|
|
1157
|
+
});
|
|
1158
|
+
|
|
1159
|
+
it('should emit error and finalize streaming on dispatch_error (message only)', async () => {
|
|
1160
|
+
const events: AgentWidgetEvent[] = [];
|
|
1161
|
+
|
|
1162
|
+
global.fetch = createAgentStreamFetch([
|
|
1163
|
+
'data: {"type":"flow_start","flowId":"f1","flowName":"Test","totalSteps":1}\n\n',
|
|
1164
|
+
'data: {"type":"step_delta","id":"s1","name":"Prompt","executionType":"prompt","text":"x"}\n\n',
|
|
1165
|
+
sseEvent('dispatch_error', { message: 'bad config', seq: 2 }),
|
|
1166
|
+
]);
|
|
1167
|
+
|
|
1168
|
+
const client = new AgentWidgetClient({
|
|
1169
|
+
apiUrl: 'http://localhost:8000',
|
|
1170
|
+
agent: { name: 'Test', model: 'openai:gpt-4o-mini', systemPrompt: 'test' },
|
|
1171
|
+
});
|
|
1172
|
+
|
|
1173
|
+
await client.dispatch(
|
|
1174
|
+
{ messages: [{ id: 'usr_1', role: 'user', content: 'Hi', createdAt: new Date().toISOString() }] },
|
|
1175
|
+
(event) => events.push(event)
|
|
1176
|
+
);
|
|
1177
|
+
|
|
1178
|
+
const errorEvents = events.filter(e => e.type === 'error');
|
|
1179
|
+
expect(errorEvents.length).toBe(1);
|
|
1180
|
+
if (errorEvents[0].type === 'error') {
|
|
1181
|
+
expect(errorEvents[0].error.message).toBe('bad config');
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
const statusIdle = events.filter(e => e.type === 'status' && e.status === 'idle');
|
|
1185
|
+
expect(statusIdle.length).toBeGreaterThanOrEqual(1);
|
|
1186
|
+
});
|
|
1187
|
+
|
|
1124
1188
|
it('should handle agent reflection events', async () => {
|
|
1125
1189
|
const events: AgentWidgetEvent[] = [];
|
|
1126
1190
|
const execId = 'exec_test_7';
|
package/src/client.ts
CHANGED
|
@@ -2592,14 +2592,43 @@ export class AgentWidgetClient {
|
|
|
2592
2592
|
streamParsers.delete(id);
|
|
2593
2593
|
rawContentBuffers.delete(id);
|
|
2594
2594
|
seqChunkBuffers.delete(id);
|
|
2595
|
-
} else if (
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2595
|
+
} else if (
|
|
2596
|
+
payloadType === "error" ||
|
|
2597
|
+
payloadType === "step_error" ||
|
|
2598
|
+
payloadType === "dispatch_error" ||
|
|
2599
|
+
payloadType === "flow_error"
|
|
2600
|
+
) {
|
|
2601
|
+
let resolvedError: Error | null = null;
|
|
2602
|
+
if (payload.error instanceof Error) {
|
|
2603
|
+
resolvedError = payload.error;
|
|
2604
|
+
} else if (payloadType === "dispatch_error") {
|
|
2605
|
+
const msg = payload.message ?? payload.error;
|
|
2606
|
+
if (msg != null && msg !== "") {
|
|
2607
|
+
resolvedError = new Error(String(msg));
|
|
2608
|
+
}
|
|
2609
|
+
} else if (
|
|
2610
|
+
payloadType === "step_error" ||
|
|
2611
|
+
payloadType === "flow_error"
|
|
2612
|
+
) {
|
|
2613
|
+
const e = payload.error;
|
|
2614
|
+
if (typeof e === "string" && e !== "") {
|
|
2615
|
+
resolvedError = new Error(e);
|
|
2616
|
+
} else if (e != null && typeof e === "object" && "message" in e) {
|
|
2617
|
+
resolvedError = new Error(String((e as { message?: unknown }).message ?? e));
|
|
2618
|
+
}
|
|
2619
|
+
} else if (payloadType === "error" && payload.error != null && payload.error !== "") {
|
|
2620
|
+
resolvedError = new Error(String(payload.error));
|
|
2621
|
+
}
|
|
2622
|
+
|
|
2623
|
+
if (resolvedError) {
|
|
2624
|
+
onEvent({ type: "error", error: resolvedError });
|
|
2625
|
+
const finalMsg = assistantMessage as AgentWidgetMessage | null;
|
|
2626
|
+
if (finalMsg && finalMsg.streaming) {
|
|
2627
|
+
finalMsg.streaming = false;
|
|
2628
|
+
emitMessage(finalMsg);
|
|
2629
|
+
}
|
|
2630
|
+
onEvent({ type: "status", status: "idle" });
|
|
2631
|
+
}
|
|
2603
2632
|
}
|
|
2604
2633
|
}
|
|
2605
2634
|
}
|
package/src/types.ts
CHANGED
|
@@ -2901,6 +2901,15 @@ export type AgentWidgetConfig = {
|
|
|
2901
2901
|
* ```
|
|
2902
2902
|
*/
|
|
2903
2903
|
parseSSEEvent?: AgentWidgetSSEEventParser;
|
|
2904
|
+
/**
|
|
2905
|
+
* Called for every parsed SSE frame (after JSON parse), before native handling.
|
|
2906
|
+
* Use for lightweight side effects (e.g. telemetry). Does not replace native
|
|
2907
|
+
* streaming; pair with {@link parseSSEEvent} only when you need to override text mapping.
|
|
2908
|
+
*
|
|
2909
|
+
* When the event stream inspector is enabled, this runs in the same order as
|
|
2910
|
+
* events are appended to the inspector buffer.
|
|
2911
|
+
*/
|
|
2912
|
+
onSSEEvent?: (eventType: string, payload: unknown) => void;
|
|
2904
2913
|
/**
|
|
2905
2914
|
* Layout configuration for customizing widget appearance and structure.
|
|
2906
2915
|
* Provides control over header, messages, and content slots.
|
package/src/ui.ts
CHANGED
|
@@ -3118,9 +3118,10 @@ export const createAgentExperience = (
|
|
|
3118
3118
|
});
|
|
3119
3119
|
}
|
|
3120
3120
|
|
|
3121
|
-
// Wire up event stream buffer to capture SSE events
|
|
3122
|
-
if (eventStreamBuffer) {
|
|
3121
|
+
// Wire up optional SSE tap (host) + event stream buffer to capture SSE events
|
|
3122
|
+
if (eventStreamBuffer || config.onSSEEvent) {
|
|
3123
3123
|
session.setSSEEventCallback((type: string, payload: unknown) => {
|
|
3124
|
+
config.onSSEEvent?.(type, payload);
|
|
3124
3125
|
eventStreamBuffer?.push({
|
|
3125
3126
|
id: `evt-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
3126
3127
|
type,
|
|
@@ -4187,8 +4188,9 @@ export const createAgentExperience = (
|
|
|
4187
4188
|
eventStreamStore = new EventStreamStore(eventStreamDbName);
|
|
4188
4189
|
eventStreamBuffer = new EventStreamBuffer(eventStreamMaxEvents, eventStreamStore);
|
|
4189
4190
|
eventStreamStore.open().then(() => eventStreamBuffer?.restore()).catch(() => {});
|
|
4190
|
-
// Register the SSE event callback
|
|
4191
|
+
// Register the SSE event callback (host tap + buffer)
|
|
4191
4192
|
session.setSSEEventCallback((type: string, payload: unknown) => {
|
|
4193
|
+
config.onSSEEvent?.(type, payload);
|
|
4192
4194
|
eventStreamBuffer!.push({
|
|
4193
4195
|
id: `evt-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
4194
4196
|
type,
|