@runtypelabs/persona 4.21.1 → 4.22.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/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/{types-B_JdVK9o.d.cts → types-9Vxm-PPz.d.cts} +136 -6
- package/dist/animations/{types-B_JdVK9o.d.ts → types-9Vxm-PPz.d.ts} +136 -6
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/animations-extra.d.cts +136 -6
- package/dist/animations-extra.d.ts +136 -6
- package/dist/{approval-ui-RNNBR5R3.js → approval-ui-K7R5Q5OC.js} +1 -1
- package/dist/approval-ui.cjs +2 -2
- package/dist/approval-ui.d.cts +221 -16
- package/dist/approval-ui.d.ts +221 -16
- package/dist/approval-ui.js +2 -2
- package/dist/artifacts-ui-F4N6VMKF.js +7 -0
- package/dist/artifacts-ui.cjs +1 -1
- package/dist/artifacts-ui.d.cts +221 -16
- package/dist/artifacts-ui.d.ts +221 -16
- package/dist/artifacts-ui.js +1 -1
- package/dist/chunk-NQLDCJAP.js +4 -0
- package/dist/codegen.cjs +1 -1
- package/dist/codegen.js +1 -1
- package/dist/context-mentions.d.cts +221 -16
- package/dist/context-mentions.d.ts +221 -16
- package/dist/event-stream-view-GL3ADRY2.js +1 -0
- package/dist/event-stream-view.cjs +1 -1
- package/dist/event-stream-view.d.cts +221 -16
- package/dist/event-stream-view.d.ts +221 -16
- package/dist/event-stream-view.js +1 -1
- package/dist/forms-ui.d.cts +234 -25
- package/dist/forms-ui.d.ts +234 -25
- package/dist/history-view.d.cts +136 -6
- package/dist/history-view.d.ts +136 -6
- package/dist/index.cjs +70 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +302 -32
- package/dist/index.d.ts +302 -32
- package/dist/index.global.js +54 -54
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +69 -69
- package/dist/index.js.map +1 -1
- package/dist/launcher.global.js +2 -2
- package/dist/launcher.global.js.map +1 -1
- package/dist/session-reconnect.d.cts +221 -16
- package/dist/session-reconnect.d.ts +221 -16
- package/dist/smart-dom-reader.d.cts +221 -16
- package/dist/smart-dom-reader.d.ts +221 -16
- package/dist/testing.cjs +3 -3
- package/dist/testing.d.cts +3 -4
- package/dist/testing.d.ts +3 -4
- package/dist/testing.js +3 -3
- package/dist/theme-editor-preview.cjs +73 -73
- package/dist/theme-editor-preview.d.cts +221 -16
- package/dist/theme-editor-preview.d.ts +221 -16
- package/dist/theme-editor-preview.js +51 -51
- package/dist/theme-editor.cjs +4 -4
- package/dist/theme-editor.d.cts +221 -16
- package/dist/theme-editor.d.ts +221 -16
- package/dist/theme-editor.js +2 -2
- package/dist/theme-reference.cjs +1 -1
- package/dist/theme-reference.d.cts +65 -1
- package/dist/theme-reference.d.ts +65 -1
- package/dist/theme-reference.js +1 -1
- package/dist/voice-runtime.d.cts +6 -2
- package/dist/voice-runtime.d.ts +6 -2
- package/dist/webmcp-polyfill.js +1 -4
- package/dist/webmcp-runtime-JI7T4QYF.js +6 -0
- package/dist/webmcp-runtime.cjs +2 -2
- package/dist/webmcp-runtime.d.cts +34 -2
- package/dist/webmcp-runtime.d.ts +34 -2
- package/dist/webmcp-runtime.js +2 -2
- package/package.json +2 -2
- package/src/ask-user-question-tool.ts +1 -1
- package/src/client-history-rest.test.ts +2 -1
- package/src/client-visitor-history.test.ts +20 -4
- package/src/client.composer-options.test.ts +1 -1
- package/src/client.interrupt.test.ts +2 -2
- package/src/client.test.ts +477 -915
- package/src/client.ts +134 -494
- package/src/client.unified-tools.test.ts +76 -0
- package/src/components/artifact-preview.ts +5 -0
- package/src/components/event-stream-badge-theming.test.ts +162 -0
- package/src/components/event-stream-view.test.ts +76 -76
- package/src/components/event-stream-view.ts +55 -20
- package/src/components/tool-bubble.test.ts +12 -0
- package/src/components/tool-bubble.ts +13 -2
- package/src/event-stream-view-bundle.test.ts +2 -2
- package/src/generated/runtype-openapi-contract.ts +137 -1
- package/src/index-core.ts +2 -0
- package/src/internal/runtype-history-provider.test.ts +2 -2
- package/src/runtime/init.registry.test.ts +56 -0
- package/src/runtime/init.ts +17 -0
- package/src/session-history.test.ts +1 -1
- package/src/session.quote.test.ts +1 -1
- package/src/session.resubmit-from.test.ts +1 -1
- package/src/session.test.ts +5 -5
- package/src/session.ts +95 -36
- package/src/suggest-replies-tool.ts +1 -1
- package/src/testing/mock-stream.test.ts +37 -16
- package/src/testing/mock-stream.ts +14 -9
- package/src/types/theme.ts +41 -1
- package/src/types.ts +57 -15
- package/src/ui.ask-user-question-plugin.test.ts +7 -7
- package/src/ui.composer-defer-one.test.ts +6 -34
- package/src/ui.composer-draft-persistence.test.ts +1 -1
- package/src/ui.composer-quote.test.ts +1 -1
- package/src/ui.message-history-actions.test.ts +1 -1
- package/src/ui.reasoning-display.test.ts +136 -2
- package/src/ui.streaming-coalescing.test.ts +10 -13
- package/src/ui.ts +101 -35
- package/src/ui.typing-indicator.test.ts +216 -0
- package/src/ui.voice-custom-provider.test.ts +211 -0
- package/src/utils/__snapshots__/tokens-parity.test.ts.snap +1740 -0
- package/src/utils/event-stream-buffer.test.ts +13 -13
- package/src/utils/event-stream-capture.test.ts +20 -20
- package/src/utils/formatting.ts +22 -0
- package/src/utils/theme.ts +16 -0
- package/src/utils/throughput-tracker.test.ts +100 -142
- package/src/utils/throughput-tracker.ts +18 -132
- package/src/utils/tokens.ts +59 -0
- package/src/utils/voice-support.ts +18 -1
- package/src/voice/voice-turn-tracker.ts +18 -0
- package/src/webmcp-bridge.test.ts +132 -23
- package/src/webmcp-bridge.ts +27 -3
- package/src/webmcp-runtime-entry.ts +71 -11
- package/dist/artifacts-ui-J6AKUGTS.js +0 -7
- package/dist/chunk-HBE7LFNT.js +0 -4
- package/dist/event-stream-view-73NWKWVQ.js +0 -1
- package/dist/webmcp-runtime-P3CHZRHF.js +0 -6
- package/src/utils/__fixtures__/unified-translator.oracle.ts +0 -717
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createElement } from "../utils/dom";
|
|
1
|
+
import { createElement, createNode } from "../utils/dom";
|
|
2
2
|
import { AgentWidgetMessage, AgentWidgetConfig } from "../types";
|
|
3
3
|
import { formatUnknownValue, describeToolTitle, resolveToolHeaderText, computeToolElapsed, parseFormattedTemplate } from "../utils/formatting";
|
|
4
4
|
import { appendCharSpans } from "../utils/tool-loading-animation";
|
|
@@ -73,7 +73,9 @@ const getToolSummaryText = (
|
|
|
73
73
|
const tool = message.toolCall;
|
|
74
74
|
const toolDisplayConfig = config?.features?.toolCallDisplay;
|
|
75
75
|
const collapsedMode = toolDisplayConfig?.collapsedMode ?? "tool-call";
|
|
76
|
-
const previewText =
|
|
76
|
+
const previewText = tool?.success === false
|
|
77
|
+
? tool.error || "Tool failed"
|
|
78
|
+
: getToolPreviewText(message, toolDisplayConfig?.previewMaxLines ?? 3);
|
|
77
79
|
const defaultSummary = tool ? describeToolTitle(tool) : "";
|
|
78
80
|
|
|
79
81
|
if (!tool) {
|
|
@@ -96,6 +98,7 @@ const getToolSummaryText = (
|
|
|
96
98
|
summary = resolveToolHeaderText(tool, toolCallConfig.completeTextTemplate, summary);
|
|
97
99
|
}
|
|
98
100
|
|
|
101
|
+
if (tool.success === false) summary += " · Failed";
|
|
99
102
|
return { summary, previewText, isActive };
|
|
100
103
|
};
|
|
101
104
|
|
|
@@ -388,6 +391,14 @@ export const createToolBubble = (message: AgentWidgetMessage, config?: AgentWidg
|
|
|
388
391
|
content.appendChild(logsBlock);
|
|
389
392
|
}
|
|
390
393
|
|
|
394
|
+
if (tool.success === false) {
|
|
395
|
+
content.appendChild(createNode("div", {
|
|
396
|
+
className: "persona-text-sm persona-whitespace-pre-wrap",
|
|
397
|
+
text: tool.error || "Tool failed",
|
|
398
|
+
attrs: { "data-persona-tool-error": "" },
|
|
399
|
+
}));
|
|
400
|
+
}
|
|
401
|
+
|
|
391
402
|
if (tool.status === "complete" && tool.result !== undefined) {
|
|
392
403
|
const resultBlock = createElement("div", "persona-space-y-1");
|
|
393
404
|
const resultLabel = createElement(
|
|
@@ -23,9 +23,9 @@ const RUNTIME_MARKERS = [
|
|
|
23
23
|
"persona-event-stream-view",
|
|
24
24
|
"persona-event-stream-list",
|
|
25
25
|
// Capture/persistence runtime, moved into this chunk alongside the view:
|
|
26
|
-
// IndexedDB store (createObjectStore) and throughput tracker (
|
|
26
|
+
// IndexedDB store (createObjectStore) and throughput tracker (visibleCharCount).
|
|
27
27
|
"createObjectStore",
|
|
28
|
-
"
|
|
28
|
+
"visibleCharCount",
|
|
29
29
|
];
|
|
30
30
|
|
|
31
31
|
const SUBPATH = "@runtypelabs/persona/event-stream-view";
|
|
@@ -70,6 +70,11 @@ export type RuntypeExecutionStreamEvent = ({
|
|
|
70
70
|
iteration?: number;
|
|
71
71
|
role: "user" | "assistant" | "system";
|
|
72
72
|
seq: number;
|
|
73
|
+
subagent?: {
|
|
74
|
+
agentName?: string;
|
|
75
|
+
parentToolCallId?: string;
|
|
76
|
+
toolName: string;
|
|
77
|
+
};
|
|
73
78
|
turnIndex?: number;
|
|
74
79
|
type: "turn_start";
|
|
75
80
|
}) | ({
|
|
@@ -104,12 +109,61 @@ export type RuntypeExecutionStreamEvent = ({
|
|
|
104
109
|
role: "user" | "assistant" | "system";
|
|
105
110
|
seq: number;
|
|
106
111
|
stopReason?: "end_turn" | "max_tool_calls" | "length" | "content_filter" | "error" | "unknown";
|
|
112
|
+
subagent?: {
|
|
113
|
+
agentName?: string;
|
|
114
|
+
parentToolCallId?: string;
|
|
115
|
+
toolName: string;
|
|
116
|
+
};
|
|
107
117
|
tokens?: {
|
|
108
118
|
input: number;
|
|
109
119
|
output: number;
|
|
110
120
|
};
|
|
111
121
|
type: "turn_complete";
|
|
112
122
|
}) | {
|
|
123
|
+
executionId: string;
|
|
124
|
+
id: string;
|
|
125
|
+
iteration?: number;
|
|
126
|
+
model?: string;
|
|
127
|
+
ordinal: number;
|
|
128
|
+
provider?: string;
|
|
129
|
+
seq: number;
|
|
130
|
+
startedAt?: string;
|
|
131
|
+
stepId?: string;
|
|
132
|
+
subagent?: {
|
|
133
|
+
agentName?: string;
|
|
134
|
+
parentToolCallId?: string;
|
|
135
|
+
toolName: string;
|
|
136
|
+
};
|
|
137
|
+
turnId?: string;
|
|
138
|
+
type: "model_call_start";
|
|
139
|
+
} | {
|
|
140
|
+
completedAt?: string;
|
|
141
|
+
cost?: number;
|
|
142
|
+
durationMs?: number;
|
|
143
|
+
executionId: string;
|
|
144
|
+
finishReason?: string;
|
|
145
|
+
id: string;
|
|
146
|
+
iteration?: number;
|
|
147
|
+
model?: string;
|
|
148
|
+
ordinal: number;
|
|
149
|
+
provider?: string;
|
|
150
|
+
responseModel?: string;
|
|
151
|
+
seq: number;
|
|
152
|
+
subagent?: {
|
|
153
|
+
agentName?: string;
|
|
154
|
+
parentToolCallId?: string;
|
|
155
|
+
toolName: string;
|
|
156
|
+
};
|
|
157
|
+
success?: boolean;
|
|
158
|
+
tokens?: {
|
|
159
|
+
cacheRead?: number;
|
|
160
|
+
cacheWrite?: number;
|
|
161
|
+
input: number;
|
|
162
|
+
output: number;
|
|
163
|
+
};
|
|
164
|
+
turnId?: string;
|
|
165
|
+
type: "model_call_complete";
|
|
166
|
+
} | {
|
|
113
167
|
executionId: string;
|
|
114
168
|
id: string;
|
|
115
169
|
index?: number;
|
|
@@ -118,6 +172,11 @@ export type RuntypeExecutionStreamEvent = ({
|
|
|
118
172
|
seq: number;
|
|
119
173
|
startedAt?: string;
|
|
120
174
|
stepType?: string;
|
|
175
|
+
subagent?: {
|
|
176
|
+
agentName?: string;
|
|
177
|
+
parentToolCallId?: string;
|
|
178
|
+
toolName: string;
|
|
179
|
+
};
|
|
121
180
|
totalSteps?: number;
|
|
122
181
|
type: "step_start";
|
|
123
182
|
} | ({
|
|
@@ -145,6 +204,11 @@ export type RuntypeExecutionStreamEvent = ({
|
|
|
145
204
|
seq: number;
|
|
146
205
|
stepType?: string;
|
|
147
206
|
stopReason?: "end_turn" | "max_tool_calls" | "length" | "content_filter" | "error" | "unknown";
|
|
207
|
+
subagent?: {
|
|
208
|
+
agentName?: string;
|
|
209
|
+
parentToolCallId?: string;
|
|
210
|
+
toolName: string;
|
|
211
|
+
};
|
|
148
212
|
success?: boolean;
|
|
149
213
|
tokensUsed?: number;
|
|
150
214
|
type: "step_complete";
|
|
@@ -167,6 +231,11 @@ export type RuntypeExecutionStreamEvent = ({
|
|
|
167
231
|
role?: "user" | "assistant" | "system";
|
|
168
232
|
seq: number;
|
|
169
233
|
stepId?: string;
|
|
234
|
+
subagent?: {
|
|
235
|
+
agentName?: string;
|
|
236
|
+
parentToolCallId?: string;
|
|
237
|
+
toolName: string;
|
|
238
|
+
};
|
|
170
239
|
turnId?: string;
|
|
171
240
|
type: "text_start";
|
|
172
241
|
}) | {
|
|
@@ -174,11 +243,21 @@ export type RuntypeExecutionStreamEvent = ({
|
|
|
174
243
|
executionId: string;
|
|
175
244
|
id: string;
|
|
176
245
|
seq: number;
|
|
246
|
+
subagent?: {
|
|
247
|
+
agentName?: string;
|
|
248
|
+
parentToolCallId?: string;
|
|
249
|
+
toolName: string;
|
|
250
|
+
};
|
|
177
251
|
type: "text_delta";
|
|
178
252
|
} | {
|
|
179
253
|
executionId: string;
|
|
180
254
|
id: string;
|
|
181
255
|
seq: number;
|
|
256
|
+
subagent?: {
|
|
257
|
+
agentName?: string;
|
|
258
|
+
parentToolCallId?: string;
|
|
259
|
+
toolName: string;
|
|
260
|
+
};
|
|
182
261
|
text?: string;
|
|
183
262
|
type: "text_complete";
|
|
184
263
|
} | ({
|
|
@@ -187,18 +266,33 @@ export type RuntypeExecutionStreamEvent = ({
|
|
|
187
266
|
parentToolCallId?: string;
|
|
188
267
|
scope?: "turn" | "loop";
|
|
189
268
|
seq: number;
|
|
269
|
+
subagent?: {
|
|
270
|
+
agentName?: string;
|
|
271
|
+
parentToolCallId?: string;
|
|
272
|
+
toolName: string;
|
|
273
|
+
};
|
|
190
274
|
type: "reasoning_start";
|
|
191
275
|
}) | {
|
|
192
276
|
delta: string;
|
|
193
277
|
executionId: string;
|
|
194
278
|
id: string;
|
|
195
279
|
seq: number;
|
|
280
|
+
subagent?: {
|
|
281
|
+
agentName?: string;
|
|
282
|
+
parentToolCallId?: string;
|
|
283
|
+
toolName: string;
|
|
284
|
+
};
|
|
196
285
|
type: "reasoning_delta";
|
|
197
286
|
} | ({
|
|
198
287
|
executionId: string;
|
|
199
288
|
id: string;
|
|
200
289
|
scope?: "turn" | "loop";
|
|
201
290
|
seq: number;
|
|
291
|
+
subagent?: {
|
|
292
|
+
agentName?: string;
|
|
293
|
+
parentToolCallId?: string;
|
|
294
|
+
toolName: string;
|
|
295
|
+
};
|
|
202
296
|
text?: string;
|
|
203
297
|
type: "reasoning_complete";
|
|
204
298
|
}) | ({
|
|
@@ -291,6 +385,11 @@ export type RuntypeExecutionStreamEvent = ({
|
|
|
291
385
|
seq: number;
|
|
292
386
|
startedAt?: string;
|
|
293
387
|
stepId?: string;
|
|
388
|
+
subagent?: {
|
|
389
|
+
agentName?: string;
|
|
390
|
+
parentToolCallId?: string;
|
|
391
|
+
toolName: string;
|
|
392
|
+
};
|
|
294
393
|
toolCallId: string;
|
|
295
394
|
toolName: string;
|
|
296
395
|
toolType: string;
|
|
@@ -299,6 +398,11 @@ export type RuntypeExecutionStreamEvent = ({
|
|
|
299
398
|
delta: string;
|
|
300
399
|
executionId: string;
|
|
301
400
|
seq: number;
|
|
401
|
+
subagent?: {
|
|
402
|
+
agentName?: string;
|
|
403
|
+
parentToolCallId?: string;
|
|
404
|
+
toolName: string;
|
|
405
|
+
};
|
|
302
406
|
toolCallId: string;
|
|
303
407
|
type: "tool_input_delta";
|
|
304
408
|
} | {
|
|
@@ -306,6 +410,11 @@ export type RuntypeExecutionStreamEvent = ({
|
|
|
306
410
|
hiddenParameterNames?: Array<string>;
|
|
307
411
|
parameters: Record<string, unknown>;
|
|
308
412
|
seq: number;
|
|
413
|
+
subagent?: {
|
|
414
|
+
agentName?: string;
|
|
415
|
+
parentToolCallId?: string;
|
|
416
|
+
toolName: string;
|
|
417
|
+
};
|
|
309
418
|
toolCallId: string;
|
|
310
419
|
toolName?: string;
|
|
311
420
|
type: "tool_input_complete";
|
|
@@ -323,6 +432,11 @@ export type RuntypeExecutionStreamEvent = ({
|
|
|
323
432
|
result?: unknown;
|
|
324
433
|
seq: number;
|
|
325
434
|
stepId?: string;
|
|
435
|
+
subagent?: {
|
|
436
|
+
agentName?: string;
|
|
437
|
+
parentToolCallId?: string;
|
|
438
|
+
toolName: string;
|
|
439
|
+
};
|
|
326
440
|
success: boolean;
|
|
327
441
|
toolCallId: string;
|
|
328
442
|
toolCost?: number;
|
|
@@ -402,6 +516,19 @@ export type RuntypeExecutionStreamEvent = ({
|
|
|
402
516
|
recoverable?: boolean;
|
|
403
517
|
seq: number;
|
|
404
518
|
type: "error";
|
|
519
|
+
}) | ({
|
|
520
|
+
epoch: number;
|
|
521
|
+
executionId: string;
|
|
522
|
+
kind: "compaction";
|
|
523
|
+
outcome?: "ok" | "failed" | "gap" | "skipped";
|
|
524
|
+
phase: "start" | "complete";
|
|
525
|
+
reason: "threshold" | "overflow" | "manual" | "surface_policy" | "provider_mismatch";
|
|
526
|
+
seq: number;
|
|
527
|
+
strategy: "provider_native" | "summary";
|
|
528
|
+
tier: number;
|
|
529
|
+
tokensAfter?: number;
|
|
530
|
+
tokensBefore?: number;
|
|
531
|
+
type: "context_notice";
|
|
405
532
|
}) | {
|
|
406
533
|
executionId: string;
|
|
407
534
|
seq: number;
|
|
@@ -432,12 +559,14 @@ export type RuntypeStopReasonKind = NonNullable<
|
|
|
432
559
|
>;
|
|
433
560
|
|
|
434
561
|
export type RuntypeClientInitRequest = {
|
|
562
|
+
durableRecovery?: boolean;
|
|
435
563
|
flowId?: string;
|
|
436
564
|
identityProof?: string;
|
|
437
565
|
token: string;
|
|
438
566
|
visitorHistory?: boolean;
|
|
439
567
|
visitorToken?: string;
|
|
440
568
|
} | {
|
|
569
|
+
durableRecovery?: boolean;
|
|
441
570
|
flowId?: string;
|
|
442
571
|
identityProof?: string;
|
|
443
572
|
sessionId: string;
|
|
@@ -446,6 +575,7 @@ export type RuntypeClientInitRequest = {
|
|
|
446
575
|
visitorToken?: string;
|
|
447
576
|
} | {
|
|
448
577
|
conversationId: string;
|
|
578
|
+
durableRecovery?: boolean;
|
|
449
579
|
flowId?: string;
|
|
450
580
|
identityProof?: string;
|
|
451
581
|
token: string;
|
|
@@ -453,6 +583,7 @@ export type RuntypeClientInitRequest = {
|
|
|
453
583
|
visitorToken: string;
|
|
454
584
|
} | {
|
|
455
585
|
conversationId: string;
|
|
586
|
+
durableRecovery?: boolean;
|
|
456
587
|
flowId?: string;
|
|
457
588
|
identityProof: string;
|
|
458
589
|
token: string;
|
|
@@ -471,6 +602,10 @@ export type RuntypeClientInitResponse = {
|
|
|
471
602
|
};
|
|
472
603
|
conversationId: string;
|
|
473
604
|
conversationRevision: string;
|
|
605
|
+
durableRecovery?: {
|
|
606
|
+
enabled: boolean;
|
|
607
|
+
join?: boolean;
|
|
608
|
+
};
|
|
474
609
|
expiresAt: string;
|
|
475
610
|
flow?: {
|
|
476
611
|
description?: string | null;
|
|
@@ -531,13 +666,14 @@ export type RuntypeClientChatRequest = {
|
|
|
531
666
|
}>;
|
|
532
667
|
metadata?: Record<string, unknown>;
|
|
533
668
|
sessionId: string;
|
|
534
|
-
submitMode?: "normal" | "interrupt";
|
|
669
|
+
submitMode?: "normal" | "interrupt" | "join";
|
|
535
670
|
turnId?: string;
|
|
536
671
|
};
|
|
537
672
|
|
|
538
673
|
export type RuntypeClientChatStreamEvent = RuntypeExecutionStreamEvent;
|
|
539
674
|
|
|
540
675
|
export type RuntypeClientResumeRequest = {
|
|
676
|
+
after?: string;
|
|
541
677
|
assistantMessageId?: string;
|
|
542
678
|
clientTools?: Array<{
|
|
543
679
|
description: string;
|
package/src/index-core.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
initAgentWidget as initAgentWidgetFn,
|
|
3
|
+
getAgentWidgetHandles as getAgentWidgetHandlesFn,
|
|
3
4
|
type AgentWidgetInitHandle
|
|
4
5
|
} from "./runtime/init";
|
|
5
6
|
|
|
@@ -326,6 +327,7 @@ export {
|
|
|
326
327
|
} from "./suggest-replies-tool";
|
|
327
328
|
|
|
328
329
|
export { initAgentWidgetFn as initAgentWidget };
|
|
330
|
+
export { getAgentWidgetHandlesFn as getAgentWidgetHandles };
|
|
329
331
|
export {
|
|
330
332
|
createWidgetHostLayout,
|
|
331
333
|
type WidgetHostLayout,
|
|
@@ -128,7 +128,7 @@ describe('createRuntypeHistoryProvider', () => {
|
|
|
128
128
|
fetchMock.mockImplementation((url: string) => {
|
|
129
129
|
if (url.includes('/v1/client/init')) return initOk();
|
|
130
130
|
return respond(200, {
|
|
131
|
-
|
|
131
|
+
...{
|
|
132
132
|
id: 'conv_1',
|
|
133
133
|
title: 'Saved',
|
|
134
134
|
targetId: 'flow_1',
|
|
@@ -182,7 +182,7 @@ describe('createRuntypeHistoryProvider', () => {
|
|
|
182
182
|
fetchMock.mockImplementation((url: string) => {
|
|
183
183
|
if (url.includes('/v1/client/init')) return initOk();
|
|
184
184
|
return respond(200, {
|
|
185
|
-
|
|
185
|
+
id: 'conv_1', title: 'Saved', targetId: null, messageCount: 1,
|
|
186
186
|
// No timestamps: the mapper must synthesize them under the boundary.
|
|
187
187
|
messages: [{ id: 'old1', role: 'user', content: 'older', displayAvailable: true }],
|
|
188
188
|
nextMessageCursor: null,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `getAgentWidgetHandles()` registry: every `initAgentWidget()` mount is
|
|
5
|
+
* listed (oldest first) until its `destroy()`, so companions created after
|
|
6
|
+
* `persona:chat-ready` fired can still adopt a mounted widget.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
10
|
+
|
|
11
|
+
import { getAgentWidgetHandles, initAgentWidget } from "./init";
|
|
12
|
+
|
|
13
|
+
const mountHost = (id: string): HTMLElement => {
|
|
14
|
+
const host = document.createElement("div");
|
|
15
|
+
host.id = id;
|
|
16
|
+
document.body.appendChild(host);
|
|
17
|
+
return host;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const CONFIG = {
|
|
21
|
+
apiUrl: "https://api.example.com/chat",
|
|
22
|
+
launcher: { enabled: false },
|
|
23
|
+
persistState: false,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
describe("getAgentWidgetHandles", () => {
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
// Sweep any instances a failing assertion left behind.
|
|
29
|
+
for (const handle of getAgentWidgetHandles()) handle.destroy();
|
|
30
|
+
document.body.innerHTML = "";
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("lists mounted handles oldest-first and drops them on destroy", () => {
|
|
34
|
+
expect(getAgentWidgetHandles()).toEqual([]);
|
|
35
|
+
|
|
36
|
+
const first = initAgentWidget({ target: mountHost("reg-a"), config: CONFIG });
|
|
37
|
+
const second = initAgentWidget({ target: mountHost("reg-b"), config: CONFIG });
|
|
38
|
+
|
|
39
|
+
expect(getAgentWidgetHandles()).toEqual([first, second]);
|
|
40
|
+
expect(getAgentWidgetHandles().at(-1)).toBe(second);
|
|
41
|
+
|
|
42
|
+
second.destroy();
|
|
43
|
+
expect(getAgentWidgetHandles()).toEqual([first]);
|
|
44
|
+
|
|
45
|
+
first.destroy();
|
|
46
|
+
expect(getAgentWidgetHandles()).toEqual([]);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("returns a copy, not the live registry", () => {
|
|
50
|
+
const handle = initAgentWidget({ target: mountHost("reg-c"), config: CONFIG });
|
|
51
|
+
const snapshot = getAgentWidgetHandles();
|
|
52
|
+
snapshot.length = 0;
|
|
53
|
+
expect(getAgentWidgetHandles()).toEqual([handle]);
|
|
54
|
+
handle.destroy();
|
|
55
|
+
});
|
|
56
|
+
});
|
package/src/runtime/init.ts
CHANGED
|
@@ -46,6 +46,19 @@ const mountStyles = (root: ShadowRoot | HTMLElement, ownerDocument: Document) =>
|
|
|
46
46
|
|
|
47
47
|
export type AgentWidgetInitHandle = AgentWidgetController & { host: HTMLElement };
|
|
48
48
|
|
|
49
|
+
// Live handles for every mounted initAgentWidget() instance, oldest first.
|
|
50
|
+
// `persona:chat-ready` is a one-shot broadcast and `windowKey` is opt-in, so
|
|
51
|
+
// code that runs after a widget mounted previously had no way to reach it.
|
|
52
|
+
// This registry closes that gap: late companions (selection toolbars, host
|
|
53
|
+
// integrations) can adopt the most recent mount via
|
|
54
|
+
// `getAgentWidgetHandles().at(-1)`. Handles deregister on destroy().
|
|
55
|
+
const activeHandles: AgentWidgetInitHandle[] = [];
|
|
56
|
+
|
|
57
|
+
/** Handles of all currently mounted widgets, oldest first. */
|
|
58
|
+
export const getAgentWidgetHandles = (): AgentWidgetInitHandle[] => [
|
|
59
|
+
...activeHandles,
|
|
60
|
+
];
|
|
61
|
+
|
|
49
62
|
export const initAgentWidget = (
|
|
50
63
|
options: AgentWidgetInitOptions
|
|
51
64
|
): AgentWidgetInitHandle => {
|
|
@@ -154,6 +167,8 @@ export const initAgentWidget = (
|
|
|
154
167
|
destroy() {
|
|
155
168
|
destroyCurrentController();
|
|
156
169
|
hostLayout.destroy();
|
|
170
|
+
const index = activeHandles.indexOf(handle);
|
|
171
|
+
if (index !== -1) activeHandles.splice(index, 1);
|
|
157
172
|
if (options.windowKey && typeof window !== "undefined") {
|
|
158
173
|
delete (window as any)[options.windowKey];
|
|
159
174
|
}
|
|
@@ -175,6 +190,8 @@ export const initAgentWidget = (
|
|
|
175
190
|
}
|
|
176
191
|
}) as AgentWidgetInitHandle;
|
|
177
192
|
|
|
193
|
+
activeHandles.push(handle);
|
|
194
|
+
|
|
178
195
|
if (options.windowKey && typeof window !== 'undefined') {
|
|
179
196
|
(window as any)[options.windowKey] = handle;
|
|
180
197
|
}
|
|
@@ -302,7 +302,7 @@ function createRuntypeBackend() {
|
|
|
302
302
|
const end = cursor ? Number(cursor) : conversation.messages.length;
|
|
303
303
|
const start = Math.max(0, end - PAGE_SIZE);
|
|
304
304
|
return respond(200, {
|
|
305
|
-
|
|
305
|
+
...summarize(conversation),
|
|
306
306
|
messages: conversation.messages.slice(start, end),
|
|
307
307
|
nextMessageCursor: start > 0 ? String(start) : null,
|
|
308
308
|
conversationRevision: conversation.revision,
|
|
@@ -12,7 +12,7 @@ const streamResponse = () => {
|
|
|
12
12
|
body: new ReadableStream({
|
|
13
13
|
start(controller) {
|
|
14
14
|
controller.enqueue(
|
|
15
|
-
encoder.encode('data: {"type":"
|
|
15
|
+
encoder.encode('data: {"type":"execution_complete","success":true}\n\n')
|
|
16
16
|
);
|
|
17
17
|
controller.close();
|
|
18
18
|
},
|
|
@@ -13,7 +13,7 @@ const streamResponse = () => {
|
|
|
13
13
|
body: new ReadableStream({
|
|
14
14
|
start(controller) {
|
|
15
15
|
controller.enqueue(
|
|
16
|
-
encoder.encode('data: {"type":"
|
|
16
|
+
encoder.encode('data: {"type":"execution_complete","success":true}\n\n')
|
|
17
17
|
);
|
|
18
18
|
controller.close();
|
|
19
19
|
},
|
package/src/session.test.ts
CHANGED
|
@@ -538,7 +538,7 @@ describe('AgentWidgetSession.resolveAskUserQuestion', () => {
|
|
|
538
538
|
const encoder = new TextEncoder();
|
|
539
539
|
const stream = new ReadableStream({
|
|
540
540
|
start(controller) {
|
|
541
|
-
controller.enqueue(encoder.encode('data: {"type":"
|
|
541
|
+
controller.enqueue(encoder.encode('data: {"type":"execution_complete","success":true}\n\n'));
|
|
542
542
|
controller.close();
|
|
543
543
|
},
|
|
544
544
|
});
|
|
@@ -578,7 +578,7 @@ describe('AgentWidgetSession.resolveAskUserQuestion', () => {
|
|
|
578
578
|
const encoder = new TextEncoder();
|
|
579
579
|
const stream = new ReadableStream({
|
|
580
580
|
start(controller) {
|
|
581
|
-
controller.enqueue(encoder.encode('data: {"type":"
|
|
581
|
+
controller.enqueue(encoder.encode('data: {"type":"execution_complete","success":true}\n\n'));
|
|
582
582
|
controller.close();
|
|
583
583
|
},
|
|
584
584
|
});
|
|
@@ -614,7 +614,7 @@ describe('AgentWidgetSession.resolveAskUserQuestion', () => {
|
|
|
614
614
|
const encoder = new TextEncoder();
|
|
615
615
|
const stream = new ReadableStream({
|
|
616
616
|
start(controller) {
|
|
617
|
-
controller.enqueue(encoder.encode('data: {"type":"
|
|
617
|
+
controller.enqueue(encoder.encode('data: {"type":"execution_complete","success":true}\n\n'));
|
|
618
618
|
controller.close();
|
|
619
619
|
},
|
|
620
620
|
});
|
|
@@ -727,7 +727,7 @@ describe('AgentWidgetSession.resolveAskUserQuestion', () => {
|
|
|
727
727
|
const encoder = new TextEncoder();
|
|
728
728
|
const stream = new ReadableStream({
|
|
729
729
|
start(controller) {
|
|
730
|
-
controller.enqueue(encoder.encode('data: {"type":"
|
|
730
|
+
controller.enqueue(encoder.encode('data: {"type":"execution_complete","success":true}\n\n'));
|
|
731
731
|
controller.close();
|
|
732
732
|
},
|
|
733
733
|
});
|
|
@@ -807,7 +807,7 @@ describe('AgentWidgetSession.resolveApproval', () => {
|
|
|
807
807
|
const encoder = new TextEncoder();
|
|
808
808
|
const stream = new ReadableStream({
|
|
809
809
|
start(controller) {
|
|
810
|
-
controller.enqueue(encoder.encode('data: {"type":"
|
|
810
|
+
controller.enqueue(encoder.encode('data: {"type":"execution_complete","success":true}\n\n'));
|
|
811
811
|
controller.close();
|
|
812
812
|
},
|
|
813
813
|
});
|