@webskill/chatbot 0.0.2 → 0.1.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/README.md +26 -6
- package/dist/chatbot.css +9 -3
- package/dist/index.d.ts +288 -161
- package/dist/index.js +910 -1313
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -6,10 +6,10 @@ import { t as yaml } from "./yaml-C888tCbJ.js";
|
|
|
6
6
|
import { t as json } from "./json-BOcU6nei.js";
|
|
7
7
|
import { t as typescript } from "./typescript-DAau_Qyl.js";
|
|
8
8
|
import { t as jsx$1 } from "./jsx-D2Jv0wvt.js";
|
|
9
|
-
import { AnthropicClient, FsArtifactStore, FsMemoryStore, FsRunSnapshotStore, FsRunTraceStore, FsSessionStore, FullDisclosureRouter, GoogleGenAiClient, OpenAiCompatibleClient, SkillDiscovery, WebSkillError, WebSkillRuntime, messageOf, summarizeToolCalls } from "@webskill/sdk";
|
|
9
|
+
import { AnthropicClient, FsArtifactStore, FsMemoryStore, FsRunSnapshotStore, FsRunTraceStore, FsSessionStore, FullDisclosureRouter, GoogleGenAiClient, OpenAiCompatibleClient, SkillDiscovery, WebSkillError, WebSkillRuntime, isUnsupportedRunSnapshot, messageOf, summarizeToolCalls, textParts } from "@webskill/sdk";
|
|
10
10
|
import { BrowserWorkerScriptExecutor } from "@webskill/sdk/browser";
|
|
11
|
-
import { JsonRenderSpecSurface, NativeSpecSurface, OpenUiSpecSurface, ReactBridgeState, UiSurfaceList, UiSurfaceSnapshotList } from "@webskill/sdk/ui-react";
|
|
12
|
-
import { A2UI_SPEC_FORM_PATH,
|
|
11
|
+
import { JsonRenderSpecSurface, NativeSpecSurface, OpenUiSpecSurface, ReactBridgeState, SpecInteractionChannel, UiSurfaceList, UiSurfaceSnapshotList, probeJsonRenderAvailability } from "@webskill/sdk/ui-react";
|
|
12
|
+
import { A2UI_SPEC_FORM_PATH, createUiCatalogToolSource, fromA2uiSpecAction, fromA2uiSurfaceAction, interactionToFormModel, interactionToUiSpec, loadOpenUiPeers, loadWebSkillLitCatalog, renderMiniChart, shapeInteractionValue, toA2uiSpecMessages, toA2uiSurfaceAction, toVercelToolInvocation, uiCatalog } from "@webskill/sdk/ui";
|
|
13
13
|
import * as React$1 from "react";
|
|
14
14
|
import React, { Children, Component, Fragment, createContext, createElement, forwardRef, isValidElement, memo, useCallback, useContext, useDeferredValue, useEffect, useEffectEvent, useId, useInsertionEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
15
15
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -183,6 +183,70 @@ const createLucideIcon = (iconName, iconNode) => {
|
|
|
183
183
|
return Component;
|
|
184
184
|
};
|
|
185
185
|
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/archive-restore.mjs
|
|
188
|
+
/**
|
|
189
|
+
* @license lucide-react v1.27.0 - ISC
|
|
190
|
+
*
|
|
191
|
+
* This source code is licensed under the ISC license.
|
|
192
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
193
|
+
*/
|
|
194
|
+
const __iconNode$33 = [
|
|
195
|
+
["rect", {
|
|
196
|
+
width: "20",
|
|
197
|
+
height: "5",
|
|
198
|
+
x: "2",
|
|
199
|
+
y: "3",
|
|
200
|
+
rx: "1",
|
|
201
|
+
key: "1wp1u1"
|
|
202
|
+
}],
|
|
203
|
+
["path", {
|
|
204
|
+
d: "M4 8v11a2 2 0 0 0 2 2h2",
|
|
205
|
+
key: "tvwodi"
|
|
206
|
+
}],
|
|
207
|
+
["path", {
|
|
208
|
+
d: "M20 8v11a2 2 0 0 1-2 2h-2",
|
|
209
|
+
key: "1gkqxj"
|
|
210
|
+
}],
|
|
211
|
+
["path", {
|
|
212
|
+
d: "m9 15 3-3 3 3",
|
|
213
|
+
key: "1pd0qc"
|
|
214
|
+
}],
|
|
215
|
+
["path", {
|
|
216
|
+
d: "M12 12v9",
|
|
217
|
+
key: "192myk"
|
|
218
|
+
}]
|
|
219
|
+
];
|
|
220
|
+
const ArchiveRestore = createLucideIcon("archive-restore", __iconNode$33);
|
|
221
|
+
|
|
222
|
+
//#endregion
|
|
223
|
+
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/archive.mjs
|
|
224
|
+
/**
|
|
225
|
+
* @license lucide-react v1.27.0 - ISC
|
|
226
|
+
*
|
|
227
|
+
* This source code is licensed under the ISC license.
|
|
228
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
229
|
+
*/
|
|
230
|
+
const __iconNode$32 = [
|
|
231
|
+
["rect", {
|
|
232
|
+
width: "20",
|
|
233
|
+
height: "5",
|
|
234
|
+
x: "2",
|
|
235
|
+
y: "3",
|
|
236
|
+
rx: "1",
|
|
237
|
+
key: "1wp1u1"
|
|
238
|
+
}],
|
|
239
|
+
["path", {
|
|
240
|
+
d: "M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8",
|
|
241
|
+
key: "1s80jp"
|
|
242
|
+
}],
|
|
243
|
+
["path", {
|
|
244
|
+
d: "M10 12h4",
|
|
245
|
+
key: "a56b0p"
|
|
246
|
+
}]
|
|
247
|
+
];
|
|
248
|
+
const Archive = createLucideIcon("archive", __iconNode$32);
|
|
249
|
+
|
|
186
250
|
//#endregion
|
|
187
251
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/arrow-up.mjs
|
|
188
252
|
/**
|
|
@@ -191,14 +255,14 @@ const createLucideIcon = (iconName, iconNode) => {
|
|
|
191
255
|
* This source code is licensed under the ISC license.
|
|
192
256
|
* See the LICENSE file in the root directory of this source tree.
|
|
193
257
|
*/
|
|
194
|
-
const __iconNode$
|
|
258
|
+
const __iconNode$31 = [["path", {
|
|
195
259
|
d: "m5 12 7-7 7 7",
|
|
196
260
|
key: "hav0vg"
|
|
197
261
|
}], ["path", {
|
|
198
262
|
d: "M12 19V5",
|
|
199
263
|
key: "x0mq9r"
|
|
200
264
|
}]];
|
|
201
|
-
const ArrowUp = createLucideIcon("arrow-up", __iconNode$
|
|
265
|
+
const ArrowUp = createLucideIcon("arrow-up", __iconNode$31);
|
|
202
266
|
|
|
203
267
|
//#endregion
|
|
204
268
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/check.mjs
|
|
@@ -208,11 +272,11 @@ const ArrowUp = createLucideIcon("arrow-up", __iconNode$30);
|
|
|
208
272
|
* This source code is licensed under the ISC license.
|
|
209
273
|
* See the LICENSE file in the root directory of this source tree.
|
|
210
274
|
*/
|
|
211
|
-
const __iconNode$
|
|
275
|
+
const __iconNode$30 = [["path", {
|
|
212
276
|
d: "M20 6 9 17l-5-5",
|
|
213
277
|
key: "1gmf2c"
|
|
214
278
|
}]];
|
|
215
|
-
const Check = createLucideIcon("check", __iconNode$
|
|
279
|
+
const Check = createLucideIcon("check", __iconNode$30);
|
|
216
280
|
|
|
217
281
|
//#endregion
|
|
218
282
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/chevron-down.mjs
|
|
@@ -222,11 +286,11 @@ const Check = createLucideIcon("check", __iconNode$29);
|
|
|
222
286
|
* This source code is licensed under the ISC license.
|
|
223
287
|
* See the LICENSE file in the root directory of this source tree.
|
|
224
288
|
*/
|
|
225
|
-
const __iconNode$
|
|
289
|
+
const __iconNode$29 = [["path", {
|
|
226
290
|
d: "m6 9 6 6 6-6",
|
|
227
291
|
key: "qrunsl"
|
|
228
292
|
}]];
|
|
229
|
-
const ChevronDown = createLucideIcon("chevron-down", __iconNode$
|
|
293
|
+
const ChevronDown = createLucideIcon("chevron-down", __iconNode$29);
|
|
230
294
|
|
|
231
295
|
//#endregion
|
|
232
296
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/circle-check.mjs
|
|
@@ -236,7 +300,7 @@ const ChevronDown = createLucideIcon("chevron-down", __iconNode$28);
|
|
|
236
300
|
* This source code is licensed under the ISC license.
|
|
237
301
|
* See the LICENSE file in the root directory of this source tree.
|
|
238
302
|
*/
|
|
239
|
-
const __iconNode$
|
|
303
|
+
const __iconNode$28 = [["circle", {
|
|
240
304
|
cx: "12",
|
|
241
305
|
cy: "12",
|
|
242
306
|
r: "10",
|
|
@@ -245,7 +309,7 @@ const __iconNode$27 = [["circle", {
|
|
|
245
309
|
d: "m9 12 2 2 4-4",
|
|
246
310
|
key: "dzmm74"
|
|
247
311
|
}]];
|
|
248
|
-
const CircleCheck = createLucideIcon("circle-check", __iconNode$
|
|
312
|
+
const CircleCheck = createLucideIcon("circle-check", __iconNode$28);
|
|
249
313
|
|
|
250
314
|
//#endregion
|
|
251
315
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/circle-question-mark.mjs
|
|
@@ -255,7 +319,7 @@ const CircleCheck = createLucideIcon("circle-check", __iconNode$27);
|
|
|
255
319
|
* This source code is licensed under the ISC license.
|
|
256
320
|
* See the LICENSE file in the root directory of this source tree.
|
|
257
321
|
*/
|
|
258
|
-
const __iconNode$
|
|
322
|
+
const __iconNode$27 = [
|
|
259
323
|
["circle", {
|
|
260
324
|
cx: "12",
|
|
261
325
|
cy: "12",
|
|
@@ -271,7 +335,7 @@ const __iconNode$26 = [
|
|
|
271
335
|
key: "p32p05"
|
|
272
336
|
}]
|
|
273
337
|
];
|
|
274
|
-
const CircleQuestionMark = createLucideIcon("circle-question-mark", __iconNode$
|
|
338
|
+
const CircleQuestionMark = createLucideIcon("circle-question-mark", __iconNode$27);
|
|
275
339
|
|
|
276
340
|
//#endregion
|
|
277
341
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/circle-x.mjs
|
|
@@ -281,7 +345,7 @@ const CircleQuestionMark = createLucideIcon("circle-question-mark", __iconNode$2
|
|
|
281
345
|
* This source code is licensed under the ISC license.
|
|
282
346
|
* See the LICENSE file in the root directory of this source tree.
|
|
283
347
|
*/
|
|
284
|
-
const __iconNode$
|
|
348
|
+
const __iconNode$26 = [
|
|
285
349
|
["circle", {
|
|
286
350
|
cx: "12",
|
|
287
351
|
cy: "12",
|
|
@@ -297,7 +361,7 @@ const __iconNode$25 = [
|
|
|
297
361
|
key: "z0biqf"
|
|
298
362
|
}]
|
|
299
363
|
];
|
|
300
|
-
const CircleX = createLucideIcon("circle-x", __iconNode$
|
|
364
|
+
const CircleX = createLucideIcon("circle-x", __iconNode$26);
|
|
301
365
|
|
|
302
366
|
//#endregion
|
|
303
367
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/clipboard-list.mjs
|
|
@@ -307,7 +371,7 @@ const CircleX = createLucideIcon("circle-x", __iconNode$25);
|
|
|
307
371
|
* This source code is licensed under the ISC license.
|
|
308
372
|
* See the LICENSE file in the root directory of this source tree.
|
|
309
373
|
*/
|
|
310
|
-
const __iconNode$
|
|
374
|
+
const __iconNode$25 = [
|
|
311
375
|
["rect", {
|
|
312
376
|
width: "8",
|
|
313
377
|
height: "4",
|
|
@@ -338,7 +402,7 @@ const __iconNode$24 = [
|
|
|
338
402
|
key: "18s6g9"
|
|
339
403
|
}]
|
|
340
404
|
];
|
|
341
|
-
const ClipboardList = createLucideIcon("clipboard-list", __iconNode$
|
|
405
|
+
const ClipboardList = createLucideIcon("clipboard-list", __iconNode$25);
|
|
342
406
|
|
|
343
407
|
//#endregion
|
|
344
408
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/copy.mjs
|
|
@@ -348,7 +412,7 @@ const ClipboardList = createLucideIcon("clipboard-list", __iconNode$24);
|
|
|
348
412
|
* This source code is licensed under the ISC license.
|
|
349
413
|
* See the LICENSE file in the root directory of this source tree.
|
|
350
414
|
*/
|
|
351
|
-
const __iconNode$
|
|
415
|
+
const __iconNode$24 = [["rect", {
|
|
352
416
|
width: "14",
|
|
353
417
|
height: "14",
|
|
354
418
|
x: "8",
|
|
@@ -360,7 +424,7 @@ const __iconNode$23 = [["rect", {
|
|
|
360
424
|
d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",
|
|
361
425
|
key: "zix9uf"
|
|
362
426
|
}]];
|
|
363
|
-
const Copy = createLucideIcon("copy", __iconNode$
|
|
427
|
+
const Copy = createLucideIcon("copy", __iconNode$24);
|
|
364
428
|
|
|
365
429
|
//#endregion
|
|
366
430
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/download.mjs
|
|
@@ -370,7 +434,7 @@ const Copy = createLucideIcon("copy", __iconNode$23);
|
|
|
370
434
|
* This source code is licensed under the ISC license.
|
|
371
435
|
* See the LICENSE file in the root directory of this source tree.
|
|
372
436
|
*/
|
|
373
|
-
const __iconNode$
|
|
437
|
+
const __iconNode$23 = [
|
|
374
438
|
["path", {
|
|
375
439
|
d: "M12 15V3",
|
|
376
440
|
key: "m9g1x1"
|
|
@@ -384,7 +448,7 @@ const __iconNode$22 = [
|
|
|
384
448
|
key: "brsn70"
|
|
385
449
|
}]
|
|
386
450
|
];
|
|
387
|
-
const Download = createLucideIcon("download", __iconNode$
|
|
451
|
+
const Download = createLucideIcon("download", __iconNode$23);
|
|
388
452
|
|
|
389
453
|
//#endregion
|
|
390
454
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/external-link.mjs
|
|
@@ -394,7 +458,7 @@ const Download = createLucideIcon("download", __iconNode$22);
|
|
|
394
458
|
* This source code is licensed under the ISC license.
|
|
395
459
|
* See the LICENSE file in the root directory of this source tree.
|
|
396
460
|
*/
|
|
397
|
-
const __iconNode$
|
|
461
|
+
const __iconNode$22 = [
|
|
398
462
|
["path", {
|
|
399
463
|
d: "M15 3h6v6",
|
|
400
464
|
key: "1q9fwt"
|
|
@@ -408,7 +472,7 @@ const __iconNode$21 = [
|
|
|
408
472
|
key: "a6xqqp"
|
|
409
473
|
}]
|
|
410
474
|
];
|
|
411
|
-
const ExternalLink = createLucideIcon("external-link", __iconNode$
|
|
475
|
+
const ExternalLink = createLucideIcon("external-link", __iconNode$22);
|
|
412
476
|
|
|
413
477
|
//#endregion
|
|
414
478
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/file.mjs
|
|
@@ -418,14 +482,14 @@ const ExternalLink = createLucideIcon("external-link", __iconNode$21);
|
|
|
418
482
|
* This source code is licensed under the ISC license.
|
|
419
483
|
* See the LICENSE file in the root directory of this source tree.
|
|
420
484
|
*/
|
|
421
|
-
const __iconNode$
|
|
485
|
+
const __iconNode$21 = [["path", {
|
|
422
486
|
d: "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",
|
|
423
487
|
key: "1oefj6"
|
|
424
488
|
}], ["path", {
|
|
425
489
|
d: "M14 2v5a1 1 0 0 0 1 1h5",
|
|
426
490
|
key: "wfsgrz"
|
|
427
491
|
}]];
|
|
428
|
-
const File = createLucideIcon("file", __iconNode$
|
|
492
|
+
const File = createLucideIcon("file", __iconNode$21);
|
|
429
493
|
|
|
430
494
|
//#endregion
|
|
431
495
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/list-checks.mjs
|
|
@@ -435,7 +499,7 @@ const File = createLucideIcon("file", __iconNode$20);
|
|
|
435
499
|
* This source code is licensed under the ISC license.
|
|
436
500
|
* See the LICENSE file in the root directory of this source tree.
|
|
437
501
|
*/
|
|
438
|
-
const __iconNode$
|
|
502
|
+
const __iconNode$20 = [
|
|
439
503
|
["path", {
|
|
440
504
|
d: "M13 5h8",
|
|
441
505
|
key: "a7qcls"
|
|
@@ -457,7 +521,7 @@ const __iconNode$19 = [
|
|
|
457
521
|
key: "1obspn"
|
|
458
522
|
}]
|
|
459
523
|
];
|
|
460
|
-
const ListChecks = createLucideIcon("list-checks", __iconNode$
|
|
524
|
+
const ListChecks = createLucideIcon("list-checks", __iconNode$20);
|
|
461
525
|
|
|
462
526
|
//#endregion
|
|
463
527
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/loader-circle.mjs
|
|
@@ -467,11 +531,11 @@ const ListChecks = createLucideIcon("list-checks", __iconNode$19);
|
|
|
467
531
|
* This source code is licensed under the ISC license.
|
|
468
532
|
* See the LICENSE file in the root directory of this source tree.
|
|
469
533
|
*/
|
|
470
|
-
const __iconNode$
|
|
534
|
+
const __iconNode$19 = [["path", {
|
|
471
535
|
d: "M21 12a9 9 0 1 1-6.219-8.56",
|
|
472
536
|
key: "13zald"
|
|
473
537
|
}]];
|
|
474
|
-
const LoaderCircle = createLucideIcon("loader-circle", __iconNode$
|
|
538
|
+
const LoaderCircle = createLucideIcon("loader-circle", __iconNode$19);
|
|
475
539
|
|
|
476
540
|
//#endregion
|
|
477
541
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/menu.mjs
|
|
@@ -481,7 +545,7 @@ const LoaderCircle = createLucideIcon("loader-circle", __iconNode$18);
|
|
|
481
545
|
* This source code is licensed under the ISC license.
|
|
482
546
|
* See the LICENSE file in the root directory of this source tree.
|
|
483
547
|
*/
|
|
484
|
-
const __iconNode$
|
|
548
|
+
const __iconNode$18 = [
|
|
485
549
|
["path", {
|
|
486
550
|
d: "M4 5h16",
|
|
487
551
|
key: "1tepv9"
|
|
@@ -495,7 +559,7 @@ const __iconNode$17 = [
|
|
|
495
559
|
key: "1djgab"
|
|
496
560
|
}]
|
|
497
561
|
];
|
|
498
|
-
const Menu = createLucideIcon("menu", __iconNode$
|
|
562
|
+
const Menu = createLucideIcon("menu", __iconNode$18);
|
|
499
563
|
|
|
500
564
|
//#endregion
|
|
501
565
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/message-circle-question-mark.mjs
|
|
@@ -505,7 +569,7 @@ const Menu = createLucideIcon("menu", __iconNode$17);
|
|
|
505
569
|
* This source code is licensed under the ISC license.
|
|
506
570
|
* See the LICENSE file in the root directory of this source tree.
|
|
507
571
|
*/
|
|
508
|
-
const __iconNode$
|
|
572
|
+
const __iconNode$17 = [
|
|
509
573
|
["path", {
|
|
510
574
|
d: "M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719",
|
|
511
575
|
key: "1sd12s"
|
|
@@ -519,7 +583,7 @@ const __iconNode$16 = [
|
|
|
519
583
|
key: "p32p05"
|
|
520
584
|
}]
|
|
521
585
|
];
|
|
522
|
-
const MessageCircleQuestionMark = createLucideIcon("message-circle-question-mark", __iconNode$
|
|
586
|
+
const MessageCircleQuestionMark = createLucideIcon("message-circle-question-mark", __iconNode$17);
|
|
523
587
|
|
|
524
588
|
//#endregion
|
|
525
589
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/panel-right-open.mjs
|
|
@@ -529,7 +593,7 @@ const MessageCircleQuestionMark = createLucideIcon("message-circle-question-mark
|
|
|
529
593
|
* This source code is licensed under the ISC license.
|
|
530
594
|
* See the LICENSE file in the root directory of this source tree.
|
|
531
595
|
*/
|
|
532
|
-
const __iconNode$
|
|
596
|
+
const __iconNode$16 = [
|
|
533
597
|
["rect", {
|
|
534
598
|
width: "18",
|
|
535
599
|
height: "18",
|
|
@@ -547,7 +611,7 @@ const __iconNode$15 = [
|
|
|
547
611
|
key: "1pgupc"
|
|
548
612
|
}]
|
|
549
613
|
];
|
|
550
|
-
const PanelRightOpen = createLucideIcon("panel-right-open", __iconNode$
|
|
614
|
+
const PanelRightOpen = createLucideIcon("panel-right-open", __iconNode$16);
|
|
551
615
|
|
|
552
616
|
//#endregion
|
|
553
617
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/paperclip.mjs
|
|
@@ -557,11 +621,28 @@ const PanelRightOpen = createLucideIcon("panel-right-open", __iconNode$15);
|
|
|
557
621
|
* This source code is licensed under the ISC license.
|
|
558
622
|
* See the LICENSE file in the root directory of this source tree.
|
|
559
623
|
*/
|
|
560
|
-
const __iconNode$
|
|
624
|
+
const __iconNode$15 = [["path", {
|
|
561
625
|
d: "m16 6-8.414 8.586a2 2 0 0 0 2.829 2.829l8.414-8.586a4 4 0 1 0-5.657-5.657l-8.379 8.551a6 6 0 1 0 8.485 8.485l8.379-8.551",
|
|
562
626
|
key: "1miecu"
|
|
563
627
|
}]];
|
|
564
|
-
const Paperclip = createLucideIcon("paperclip", __iconNode$
|
|
628
|
+
const Paperclip = createLucideIcon("paperclip", __iconNode$15);
|
|
629
|
+
|
|
630
|
+
//#endregion
|
|
631
|
+
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/pencil.mjs
|
|
632
|
+
/**
|
|
633
|
+
* @license lucide-react v1.27.0 - ISC
|
|
634
|
+
*
|
|
635
|
+
* This source code is licensed under the ISC license.
|
|
636
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
637
|
+
*/
|
|
638
|
+
const __iconNode$14 = [["path", {
|
|
639
|
+
d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",
|
|
640
|
+
key: "1a8usu"
|
|
641
|
+
}], ["path", {
|
|
642
|
+
d: "m15 5 4 4",
|
|
643
|
+
key: "1mk7zo"
|
|
644
|
+
}]];
|
|
645
|
+
const Pencil = createLucideIcon("pencil", __iconNode$14);
|
|
565
646
|
|
|
566
647
|
//#endregion
|
|
567
648
|
//#region ../../node_modules/.pnpm/lucide-react@1.27.0_react@19.2.8/node_modules/lucide-react/dist/esm/icons/play.mjs
|
|
@@ -913,8 +994,8 @@ function Label({ className = "", ...props }) {
|
|
|
913
994
|
|
|
914
995
|
//#endregion
|
|
915
996
|
//#region ../../node_modules/.pnpm/@radix-ui+react-compose-refs@1.1.5_@types+react@19.2.17_react@19.2.8/node_modules/@radix-ui/react-compose-refs/dist/index.mjs
|
|
916
|
-
var __defProp$
|
|
917
|
-
var __name$
|
|
997
|
+
var __defProp$21 = Object.defineProperty;
|
|
998
|
+
var __name$21 = (target, value) => __defProp$21(target, "name", {
|
|
918
999
|
value,
|
|
919
1000
|
configurable: true
|
|
920
1001
|
});
|
|
@@ -922,7 +1003,7 @@ function setRef$2(ref, value) {
|
|
|
922
1003
|
if (typeof ref === "function") return ref(value);
|
|
923
1004
|
else if (ref !== null && ref !== void 0) ref.current = value;
|
|
924
1005
|
}
|
|
925
|
-
__name$
|
|
1006
|
+
__name$21(setRef$2, "setRef");
|
|
926
1007
|
function composeRefs$1(...refs) {
|
|
927
1008
|
return (node) => {
|
|
928
1009
|
let hasCleanup = false;
|
|
@@ -940,16 +1021,16 @@ function composeRefs$1(...refs) {
|
|
|
940
1021
|
};
|
|
941
1022
|
};
|
|
942
1023
|
}
|
|
943
|
-
__name$
|
|
1024
|
+
__name$21(composeRefs$1, "composeRefs");
|
|
944
1025
|
function useComposedRefs$1(...refs) {
|
|
945
1026
|
return React$1.useCallback(composeRefs$1(...refs), refs);
|
|
946
1027
|
}
|
|
947
|
-
__name$
|
|
1028
|
+
__name$21(useComposedRefs$1, "useComposedRefs");
|
|
948
1029
|
|
|
949
1030
|
//#endregion
|
|
950
1031
|
//#region ../../node_modules/.pnpm/@radix-ui+react-context@1.2.2_@types+react@19.2.17_react@19.2.8/node_modules/@radix-ui/react-context/dist/index.mjs
|
|
951
|
-
var __defProp$
|
|
952
|
-
var __name$
|
|
1032
|
+
var __defProp$20 = Object.defineProperty;
|
|
1033
|
+
var __name$20 = (target, value) => __defProp$20(target, "name", {
|
|
953
1034
|
value,
|
|
954
1035
|
configurable: true
|
|
955
1036
|
});
|
|
@@ -957,7 +1038,7 @@ var __name$21 = (target, value) => __defProp$21(target, "name", {
|
|
|
957
1038
|
function createContext2(rootComponentName, defaultContext) {
|
|
958
1039
|
const Context = React$1.createContext(defaultContext);
|
|
959
1040
|
Context.displayName = rootComponentName + "Context";
|
|
960
|
-
const Provider = /* @__PURE__ */ __name$
|
|
1041
|
+
const Provider = /* @__PURE__ */ __name$20((props) => {
|
|
961
1042
|
const { children, ...context } = props;
|
|
962
1043
|
const value = React$1.useMemo(() => context, Object.values(context));
|
|
963
1044
|
return /* @__PURE__ */ jsx(Context.Provider, {
|
|
@@ -974,10 +1055,10 @@ function createContext2(rootComponentName, defaultContext) {
|
|
|
974
1055
|
if (optional) return void 0;
|
|
975
1056
|
throw new Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``);
|
|
976
1057
|
}
|
|
977
|
-
__name$
|
|
1058
|
+
__name$20(useContext2, "useContext");
|
|
978
1059
|
return [Provider, useContext2];
|
|
979
1060
|
}
|
|
980
|
-
__name$
|
|
1061
|
+
__name$20(createContext2, "createContext");
|
|
981
1062
|
// @__NO_SIDE_EFFECTS__
|
|
982
1063
|
function createContextScope(scopeName, createContextScopeDeps = []) {
|
|
983
1064
|
let defaultContexts = [];
|
|
@@ -986,7 +1067,7 @@ function createContextScope(scopeName, createContextScopeDeps = []) {
|
|
|
986
1067
|
BaseContext.displayName = rootComponentName + "Context";
|
|
987
1068
|
const index = defaultContexts.length;
|
|
988
1069
|
defaultContexts = [...defaultContexts, defaultContext];
|
|
989
|
-
const Provider = /* @__PURE__ */ __name$
|
|
1070
|
+
const Provider = /* @__PURE__ */ __name$20((props) => {
|
|
990
1071
|
const { scope, children, ...context } = props;
|
|
991
1072
|
const Context = scope?.[scopeName]?.[index] || BaseContext;
|
|
992
1073
|
const value = React$1.useMemo(() => context, Object.values(context));
|
|
@@ -1005,15 +1086,15 @@ function createContextScope(scopeName, createContextScopeDeps = []) {
|
|
|
1005
1086
|
if (optional) return void 0;
|
|
1006
1087
|
throw new Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``);
|
|
1007
1088
|
}
|
|
1008
|
-
__name$
|
|
1089
|
+
__name$20(useContext2, "useContext");
|
|
1009
1090
|
return [Provider, useContext2];
|
|
1010
1091
|
}
|
|
1011
|
-
__name$
|
|
1012
|
-
const createScope = /* @__PURE__ */ __name$
|
|
1092
|
+
__name$20(createContext3, "createContext");
|
|
1093
|
+
const createScope = /* @__PURE__ */ __name$20(() => {
|
|
1013
1094
|
const scopeContexts = defaultContexts.map((defaultContext) => {
|
|
1014
1095
|
return React$1.createContext(defaultContext);
|
|
1015
1096
|
});
|
|
1016
|
-
return /* @__PURE__ */ __name$
|
|
1097
|
+
return /* @__PURE__ */ __name$20(function useScope(scope) {
|
|
1017
1098
|
const contexts = scope?.[scopeName] || scopeContexts;
|
|
1018
1099
|
return React$1.useMemo(() => ({ [`__scope${scopeName}`]: {
|
|
1019
1100
|
...scope,
|
|
@@ -1024,16 +1105,16 @@ function createContextScope(scopeName, createContextScopeDeps = []) {
|
|
|
1024
1105
|
createScope.scopeName = scopeName;
|
|
1025
1106
|
return [createContext3, composeContextScopes(createScope, ...createContextScopeDeps)];
|
|
1026
1107
|
}
|
|
1027
|
-
__name$
|
|
1108
|
+
__name$20(createContextScope, "createContextScope");
|
|
1028
1109
|
function composeContextScopes(...scopes) {
|
|
1029
1110
|
const baseScope = scopes[0];
|
|
1030
1111
|
if (scopes.length === 1) return baseScope;
|
|
1031
|
-
const createScope = /* @__PURE__ */ __name$
|
|
1112
|
+
const createScope = /* @__PURE__ */ __name$20(() => {
|
|
1032
1113
|
const scopeHooks = scopes.map((createScope2) => ({
|
|
1033
1114
|
useScope: createScope2(),
|
|
1034
1115
|
scopeName: createScope2.scopeName
|
|
1035
1116
|
}));
|
|
1036
|
-
return /* @__PURE__ */ __name$
|
|
1117
|
+
return /* @__PURE__ */ __name$20(function useComposedScopes(overrideScopes) {
|
|
1037
1118
|
const nextScopes = scopeHooks.reduce((nextScopes2, { useScope, scopeName }) => {
|
|
1038
1119
|
const currentScope = useScope(overrideScopes)[`__scope${scopeName}`];
|
|
1039
1120
|
return {
|
|
@@ -1047,33 +1128,33 @@ function composeContextScopes(...scopes) {
|
|
|
1047
1128
|
createScope.scopeName = baseScope.scopeName;
|
|
1048
1129
|
return createScope;
|
|
1049
1130
|
}
|
|
1050
|
-
__name$
|
|
1131
|
+
__name$20(composeContextScopes, "composeContextScopes");
|
|
1051
1132
|
|
|
1052
1133
|
//#endregion
|
|
1053
1134
|
//#region ../../node_modules/.pnpm/@radix-ui+primitive@1.1.7/node_modules/@radix-ui/primitive/dist/index.mjs
|
|
1054
|
-
var __defProp$
|
|
1055
|
-
var __name$
|
|
1135
|
+
var __defProp$19 = Object.defineProperty;
|
|
1136
|
+
var __name$19 = (target, value) => __defProp$19(target, "name", {
|
|
1056
1137
|
value,
|
|
1057
1138
|
configurable: true
|
|
1058
1139
|
});
|
|
1059
1140
|
var canUseDOM = !!(typeof window !== "undefined" && window.document && window.document.createElement);
|
|
1060
1141
|
function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
|
|
1061
|
-
return /* @__PURE__ */ __name$
|
|
1142
|
+
return /* @__PURE__ */ __name$19(function handleEvent(event) {
|
|
1062
1143
|
originalEventHandler?.(event);
|
|
1063
1144
|
if (checkForDefaultPrevented === false || !event || !event.defaultPrevented) return ourEventHandler?.(event);
|
|
1064
1145
|
}, "handleEvent");
|
|
1065
1146
|
}
|
|
1066
|
-
__name$
|
|
1147
|
+
__name$19(composeEventHandlers, "composeEventHandlers");
|
|
1067
1148
|
function getOwnerWindow(element) {
|
|
1068
1149
|
if (!canUseDOM) throw new Error("Cannot access window outside of the DOM");
|
|
1069
1150
|
return element?.ownerDocument?.defaultView ?? window;
|
|
1070
1151
|
}
|
|
1071
|
-
__name$
|
|
1152
|
+
__name$19(getOwnerWindow, "getOwnerWindow");
|
|
1072
1153
|
function getOwnerDocument(element) {
|
|
1073
1154
|
if (!canUseDOM) throw new Error("Cannot access document outside of the DOM");
|
|
1074
1155
|
return element?.ownerDocument ?? document;
|
|
1075
1156
|
}
|
|
1076
|
-
__name$
|
|
1157
|
+
__name$19(getOwnerDocument, "getOwnerDocument");
|
|
1077
1158
|
function getActiveElement(node, activeDescendant = false) {
|
|
1078
1159
|
const { activeElement } = getOwnerDocument(node);
|
|
1079
1160
|
if (!activeElement?.nodeName) return null;
|
|
@@ -1087,11 +1168,11 @@ function getActiveElement(node, activeDescendant = false) {
|
|
|
1087
1168
|
}
|
|
1088
1169
|
return activeElement;
|
|
1089
1170
|
}
|
|
1090
|
-
__name$
|
|
1171
|
+
__name$19(getActiveElement, "getActiveElement");
|
|
1091
1172
|
function isFrame(element) {
|
|
1092
1173
|
return element.tagName === "IFRAME";
|
|
1093
1174
|
}
|
|
1094
|
-
__name$
|
|
1175
|
+
__name$19(isFrame, "isFrame");
|
|
1095
1176
|
|
|
1096
1177
|
//#endregion
|
|
1097
1178
|
//#region ../../node_modules/.pnpm/@radix-ui+react-use-layout-effect@1.1.4_@types+react@19.2.17_react@19.2.8/node_modules/@radix-ui/react-use-layout-effect/dist/index.mjs
|
|
@@ -1099,8 +1180,8 @@ var useLayoutEffect2 = globalThis?.document ? React$1.useLayoutEffect : () => {}
|
|
|
1099
1180
|
|
|
1100
1181
|
//#endregion
|
|
1101
1182
|
//#region ../../node_modules/.pnpm/@radix-ui+react-use-effect-event@0.0.5_@types+react@19.2.17_react@19.2.8/node_modules/@radix-ui/react-use-effect-event/dist/index.mjs
|
|
1102
|
-
var __defProp$
|
|
1103
|
-
var __name$
|
|
1183
|
+
var __defProp$18 = Object.defineProperty;
|
|
1184
|
+
var __name$18 = (target, value) => __defProp$18(target, "name", {
|
|
1104
1185
|
value,
|
|
1105
1186
|
configurable: true
|
|
1106
1187
|
});
|
|
@@ -1119,17 +1200,17 @@ function useEffectEvent$1(callback) {
|
|
|
1119
1200
|
});
|
|
1120
1201
|
return React$1.useMemo(() => ((...args) => ref.current?.(...args)), []);
|
|
1121
1202
|
}
|
|
1122
|
-
__name$
|
|
1203
|
+
__name$18(useEffectEvent$1, "useEffectEvent");
|
|
1123
1204
|
|
|
1124
1205
|
//#endregion
|
|
1125
1206
|
//#region ../../node_modules/.pnpm/@radix-ui+react-use-controllable-state@1.2.6_@types+react@19.2.17_react@19.2.8/node_modules/@radix-ui/react-use-controllable-state/dist/index.mjs
|
|
1126
|
-
var __defProp$
|
|
1127
|
-
var __name$
|
|
1207
|
+
var __defProp$17 = Object.defineProperty;
|
|
1208
|
+
var __name$17 = (target, value) => __defProp$17(target, "name", {
|
|
1128
1209
|
value,
|
|
1129
1210
|
configurable: true
|
|
1130
1211
|
});
|
|
1131
1212
|
var useInsertionEffect$1 = React$1[" useInsertionEffect ".trim().toString()] || useLayoutEffect2;
|
|
1132
|
-
function useControllableState({ prop, defaultProp, onChange = /* @__PURE__ */ __name$
|
|
1213
|
+
function useControllableState({ prop, defaultProp, onChange = /* @__PURE__ */ __name$17(() => {}, "onChange"), caller }) {
|
|
1133
1214
|
const [uncontrolledProp, setUncontrolledProp, onChangeRef] = useUncontrolledState({
|
|
1134
1215
|
defaultProp,
|
|
1135
1216
|
onChange
|
|
@@ -1146,7 +1227,7 @@ function useControllableState({ prop, defaultProp, onChange = /* @__PURE__ */ __
|
|
|
1146
1227
|
}
|
|
1147
1228
|
return [value, React$1.useCallback((nextValue) => {
|
|
1148
1229
|
if (isControlled) {
|
|
1149
|
-
const value2 = isFunction$
|
|
1230
|
+
const value2 = isFunction$1(nextValue) ? nextValue(prop) : nextValue;
|
|
1150
1231
|
if (value2 !== prop) onChangeRef.current?.(value2);
|
|
1151
1232
|
} else setUncontrolledProp(nextValue);
|
|
1152
1233
|
}, [
|
|
@@ -1156,7 +1237,7 @@ function useControllableState({ prop, defaultProp, onChange = /* @__PURE__ */ __
|
|
|
1156
1237
|
onChangeRef
|
|
1157
1238
|
])];
|
|
1158
1239
|
}
|
|
1159
|
-
__name$
|
|
1240
|
+
__name$17(useControllableState, "useControllableState");
|
|
1160
1241
|
function useUncontrolledState({ defaultProp, onChange }) {
|
|
1161
1242
|
const [value, setValue] = React$1.useState(defaultProp);
|
|
1162
1243
|
const prevValueRef = React$1.useRef(value);
|
|
@@ -1176,11 +1257,11 @@ function useUncontrolledState({ defaultProp, onChange }) {
|
|
|
1176
1257
|
onChangeRef
|
|
1177
1258
|
];
|
|
1178
1259
|
}
|
|
1179
|
-
__name$
|
|
1180
|
-
function isFunction$
|
|
1260
|
+
__name$17(useUncontrolledState, "useUncontrolledState");
|
|
1261
|
+
function isFunction$1(value) {
|
|
1181
1262
|
return typeof value === "function";
|
|
1182
1263
|
}
|
|
1183
|
-
__name$
|
|
1264
|
+
__name$17(isFunction$1, "isFunction");
|
|
1184
1265
|
var SYNC_STATE = Symbol("RADIX:SYNC_STATE");
|
|
1185
1266
|
function useControllableStateReducer(reducer, userArgs, initialArg, init) {
|
|
1186
1267
|
const { prop: controlledState, defaultProp, onChange: onChangeProp, caller } = userArgs;
|
|
@@ -1239,12 +1320,12 @@ function useControllableStateReducer(reducer, userArgs, initialArg, init) {
|
|
|
1239
1320
|
]);
|
|
1240
1321
|
return [state, dispatch];
|
|
1241
1322
|
}
|
|
1242
|
-
__name$
|
|
1323
|
+
__name$17(useControllableStateReducer, "useControllableStateReducer");
|
|
1243
1324
|
|
|
1244
1325
|
//#endregion
|
|
1245
1326
|
//#region ../../node_modules/.pnpm/@radix-ui+react-use-size@1.1.4_@types+react@19.2.17_react@19.2.8/node_modules/@radix-ui/react-use-size/dist/index.mjs
|
|
1246
|
-
var __defProp$
|
|
1247
|
-
var __name$
|
|
1327
|
+
var __defProp$16 = Object.defineProperty;
|
|
1328
|
+
var __name$16 = (target, value) => __defProp$16(target, "name", {
|
|
1248
1329
|
value,
|
|
1249
1330
|
configurable: true
|
|
1250
1331
|
});
|
|
@@ -1282,12 +1363,12 @@ function useSize(element) {
|
|
|
1282
1363
|
}, [element]);
|
|
1283
1364
|
return size;
|
|
1284
1365
|
}
|
|
1285
|
-
__name$
|
|
1366
|
+
__name$16(useSize, "useSize");
|
|
1286
1367
|
|
|
1287
1368
|
//#endregion
|
|
1288
1369
|
//#region ../../node_modules/.pnpm/@radix-ui+react-presence@1.1.10_@types+react-dom@19.2.3_@types+react@19.2.17__@types+re_138587ba593102bdcf335a5673d92068/node_modules/@radix-ui/react-presence/dist/index.mjs
|
|
1289
|
-
var __defProp$
|
|
1290
|
-
var __name$
|
|
1370
|
+
var __defProp$15 = Object.defineProperty;
|
|
1371
|
+
var __name$15 = (target, value) => __defProp$15(target, "name", {
|
|
1291
1372
|
value,
|
|
1292
1373
|
configurable: true
|
|
1293
1374
|
});
|
|
@@ -1296,8 +1377,8 @@ function useStateMachine(initialState, machine) {
|
|
|
1296
1377
|
return machine[state][event] ?? state;
|
|
1297
1378
|
}, initialState);
|
|
1298
1379
|
}
|
|
1299
|
-
__name$
|
|
1300
|
-
var Presence = /* @__PURE__ */ __name$
|
|
1380
|
+
__name$15(useStateMachine, "useStateMachine");
|
|
1381
|
+
var Presence = /* @__PURE__ */ __name$15((props) => {
|
|
1301
1382
|
const { present, children } = props;
|
|
1302
1383
|
const presence = usePresence$1(present);
|
|
1303
1384
|
const child = typeof children === "function" ? children({ present: presence.isPresent }) : React$1.Children.only(children);
|
|
@@ -1346,7 +1427,7 @@ function usePresence$1(present) {
|
|
|
1346
1427
|
if (node) {
|
|
1347
1428
|
let timeoutId;
|
|
1348
1429
|
const ownerWindow = node.ownerDocument.defaultView ?? window;
|
|
1349
|
-
const handleAnimationEnd = /* @__PURE__ */ __name$
|
|
1430
|
+
const handleAnimationEnd = /* @__PURE__ */ __name$15((event) => {
|
|
1350
1431
|
const isCurrentAnimation = getAnimationName(stylesRef.current).includes(CSS.escape(event.animationName));
|
|
1351
1432
|
if (event.target === node && isCurrentAnimation) {
|
|
1352
1433
|
send("ANIMATION_END");
|
|
@@ -1359,7 +1440,7 @@ function usePresence$1(present) {
|
|
|
1359
1440
|
}
|
|
1360
1441
|
}
|
|
1361
1442
|
}, "handleAnimationEnd");
|
|
1362
|
-
const handleAnimationStart = /* @__PURE__ */ __name$
|
|
1443
|
+
const handleAnimationStart = /* @__PURE__ */ __name$15((event) => {
|
|
1363
1444
|
if (event.target === node) prevAnimationNameRef.current = getAnimationName(stylesRef.current);
|
|
1364
1445
|
}, "handleAnimationStart");
|
|
1365
1446
|
node.addEventListener("animationstart", handleAnimationStart);
|
|
@@ -1385,12 +1466,12 @@ function usePresence$1(present) {
|
|
|
1385
1466
|
}, [])
|
|
1386
1467
|
};
|
|
1387
1468
|
}
|
|
1388
|
-
__name$
|
|
1469
|
+
__name$15(usePresence$1, "usePresence");
|
|
1389
1470
|
function setRef$1(ref, value) {
|
|
1390
1471
|
if (typeof ref === "function") return ref(value);
|
|
1391
1472
|
else if (ref !== null && ref !== void 0) ref.current = value;
|
|
1392
1473
|
}
|
|
1393
|
-
__name$
|
|
1474
|
+
__name$15(setRef$1, "setRef");
|
|
1394
1475
|
function useStableComposedRefs(...refs) {
|
|
1395
1476
|
const refsRef = React$1.useRef(refs);
|
|
1396
1477
|
refsRef.current = refs;
|
|
@@ -1411,11 +1492,11 @@ function useStableComposedRefs(...refs) {
|
|
|
1411
1492
|
};
|
|
1412
1493
|
}, []);
|
|
1413
1494
|
}
|
|
1414
|
-
__name$
|
|
1495
|
+
__name$15(useStableComposedRefs, "useStableComposedRefs");
|
|
1415
1496
|
function getAnimationName(styles) {
|
|
1416
1497
|
return styles?.animationName || "none";
|
|
1417
1498
|
}
|
|
1418
|
-
__name$
|
|
1499
|
+
__name$15(getAnimationName, "getAnimationName");
|
|
1419
1500
|
function getElementRef$1(element) {
|
|
1420
1501
|
let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get;
|
|
1421
1502
|
let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
|
|
@@ -1425,12 +1506,12 @@ function getElementRef$1(element) {
|
|
|
1425
1506
|
if (mayWarn) return element.props.ref;
|
|
1426
1507
|
return element.props.ref || element.ref;
|
|
1427
1508
|
}
|
|
1428
|
-
__name$
|
|
1509
|
+
__name$15(getElementRef$1, "getElementRef");
|
|
1429
1510
|
|
|
1430
1511
|
//#endregion
|
|
1431
1512
|
//#region ../../node_modules/.pnpm/@radix-ui+react-slot@1.3.3_@types+react@19.2.17_react@19.2.8/node_modules/@radix-ui/react-slot/dist/index.mjs
|
|
1432
|
-
var __defProp$
|
|
1433
|
-
var __name$
|
|
1513
|
+
var __defProp$14 = Object.defineProperty;
|
|
1514
|
+
var __name$14 = (target, value) => __defProp$14(target, "name", {
|
|
1434
1515
|
value,
|
|
1435
1516
|
configurable: true
|
|
1436
1517
|
});
|
|
@@ -1467,17 +1548,17 @@ function createSlot(ownerName) {
|
|
|
1467
1548
|
Slot2.displayName = `${ownerName}.Slot`;
|
|
1468
1549
|
return Slot2;
|
|
1469
1550
|
}
|
|
1470
|
-
__name$
|
|
1551
|
+
__name$14(createSlot, "createSlot");
|
|
1471
1552
|
var SLOTTABLE_IDENTIFIER = Symbol.for("radix.slottable");
|
|
1472
1553
|
// @__NO_SIDE_EFFECTS__
|
|
1473
1554
|
function createSlottable(ownerName) {
|
|
1474
|
-
const Slottable2 = /* @__PURE__ */ __name$
|
|
1555
|
+
const Slottable2 = /* @__PURE__ */ __name$14((props) => "child" in props ? props.children(props.child) : props.children, "Slottable");
|
|
1475
1556
|
Slottable2.displayName = `${ownerName}.Slottable`;
|
|
1476
1557
|
Slottable2.__radixId = SLOTTABLE_IDENTIFIER;
|
|
1477
1558
|
return Slottable2;
|
|
1478
1559
|
}
|
|
1479
|
-
__name$
|
|
1480
|
-
var getSlottableElementFromSlottable = /* @__PURE__ */ __name$
|
|
1560
|
+
__name$14(createSlottable, "createSlottable");
|
|
1561
|
+
var getSlottableElementFromSlottable = /* @__PURE__ */ __name$14((slottable, child) => {
|
|
1481
1562
|
if ("child" in slottable.props) {
|
|
1482
1563
|
const child2 = slottable.props.child;
|
|
1483
1564
|
if (!React$1.isValidElement(child2)) return null;
|
|
@@ -1508,7 +1589,7 @@ function mergeProps(slotProps, childProps) {
|
|
|
1508
1589
|
...overrideProps
|
|
1509
1590
|
};
|
|
1510
1591
|
}
|
|
1511
|
-
__name$
|
|
1592
|
+
__name$14(mergeProps, "mergeProps");
|
|
1512
1593
|
function getElementRef(element) {
|
|
1513
1594
|
let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get;
|
|
1514
1595
|
let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
|
|
@@ -1518,32 +1599,32 @@ function getElementRef(element) {
|
|
|
1518
1599
|
if (mayWarn) return element.props.ref;
|
|
1519
1600
|
return element.props.ref || element.ref;
|
|
1520
1601
|
}
|
|
1521
|
-
__name$
|
|
1602
|
+
__name$14(getElementRef, "getElementRef");
|
|
1522
1603
|
function isSlottable(child) {
|
|
1523
1604
|
return React$1.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;
|
|
1524
1605
|
}
|
|
1525
|
-
__name$
|
|
1606
|
+
__name$14(isSlottable, "isSlottable");
|
|
1526
1607
|
var REACT_LAZY_TYPE = Symbol.for("react.lazy");
|
|
1527
1608
|
function isLazyComponent(element) {
|
|
1528
1609
|
return element != null && typeof element === "object" && "$$typeof" in element && element.$$typeof === REACT_LAZY_TYPE && "_payload" in element && isPromiseLike(element._payload);
|
|
1529
1610
|
}
|
|
1530
|
-
__name$
|
|
1611
|
+
__name$14(isLazyComponent, "isLazyComponent");
|
|
1531
1612
|
function isPromiseLike(value) {
|
|
1532
1613
|
return typeof value === "object" && value !== null && "then" in value;
|
|
1533
1614
|
}
|
|
1534
|
-
__name$
|
|
1535
|
-
var createSlotError = /* @__PURE__ */ __name$
|
|
1615
|
+
__name$14(isPromiseLike, "isPromiseLike");
|
|
1616
|
+
var createSlotError = /* @__PURE__ */ __name$14((ownerName) => {
|
|
1536
1617
|
return `${ownerName} failed to slot onto its children. Expected a single React element child or \`Slottable\`.`;
|
|
1537
1618
|
}, "createSlotError");
|
|
1538
|
-
var createSlottableError = /* @__PURE__ */ __name$
|
|
1619
|
+
var createSlottableError = /* @__PURE__ */ __name$14((ownerName) => {
|
|
1539
1620
|
return `${ownerName} failed to slot onto its \`Slottable\`. Expected \`Slottable\` to receive a single React element child.`;
|
|
1540
1621
|
}, "createSlottableError");
|
|
1541
1622
|
var use = React$1[" use ".trim().toString()];
|
|
1542
1623
|
|
|
1543
1624
|
//#endregion
|
|
1544
1625
|
//#region ../../node_modules/.pnpm/@radix-ui+react-primitive@2.1.10_@types+react-dom@19.2.3_@types+react@19.2.17__@types+r_be17283a23f513d7b972453cc36e2a96/node_modules/@radix-ui/react-primitive/dist/index.mjs
|
|
1545
|
-
var __defProp$
|
|
1546
|
-
var __name$
|
|
1626
|
+
var __defProp$13 = Object.defineProperty;
|
|
1627
|
+
var __name$13 = (target, value) => __defProp$13(target, "name", {
|
|
1547
1628
|
value,
|
|
1548
1629
|
configurable: true
|
|
1549
1630
|
});
|
|
@@ -1585,230 +1666,7 @@ var Primitive = [
|
|
|
1585
1666
|
function dispatchDiscreteCustomEvent(target, event) {
|
|
1586
1667
|
if (target) ReactDOM.flushSync(() => target.dispatchEvent(event));
|
|
1587
1668
|
}
|
|
1588
|
-
__name$
|
|
1589
|
-
|
|
1590
|
-
//#endregion
|
|
1591
|
-
//#region ../../node_modules/.pnpm/@radix-ui+react-checkbox@1.3.11_@types+react-dom@19.2.3_@types+react@19.2.17__@types+re_f6e0f4835f2e28dbd2e5cb3844d005eb/node_modules/@radix-ui/react-checkbox/dist/index.mjs
|
|
1592
|
-
var __defProp$13 = Object.defineProperty;
|
|
1593
|
-
var __name$13 = (target, value) => __defProp$13(target, "name", {
|
|
1594
|
-
value,
|
|
1595
|
-
configurable: true
|
|
1596
|
-
});
|
|
1597
|
-
var CHECKBOX_NAME = "Checkbox";
|
|
1598
|
-
var [createCheckboxContext, createCheckboxScope] = createContextScope(CHECKBOX_NAME);
|
|
1599
|
-
var [CheckboxProviderImpl, useCheckboxContext] = createCheckboxContext(CHECKBOX_NAME);
|
|
1600
|
-
function CheckboxProvider(props) {
|
|
1601
|
-
const { __scopeCheckbox, checked: checkedProp, children, defaultChecked, disabled, form, name, onCheckedChange, required, value = "on", internal_do_not_use_render } = props;
|
|
1602
|
-
const [checked, setChecked] = useControllableState({
|
|
1603
|
-
prop: checkedProp,
|
|
1604
|
-
defaultProp: defaultChecked ?? false,
|
|
1605
|
-
onChange: onCheckedChange,
|
|
1606
|
-
caller: CHECKBOX_NAME
|
|
1607
|
-
});
|
|
1608
|
-
const [control, setControl] = React$1.useState(null);
|
|
1609
|
-
const [bubbleInput, setBubbleInput] = React$1.useState(null);
|
|
1610
|
-
const hasConsumerStoppedPropagationRef = React$1.useRef(false);
|
|
1611
|
-
const [userInteractionCount, onUserInteraction] = React$1.useReducer((count) => count + 1, 0);
|
|
1612
|
-
const isFormControl = control ? !!form || !!control.closest("form") : true;
|
|
1613
|
-
const context = {
|
|
1614
|
-
checked,
|
|
1615
|
-
disabled,
|
|
1616
|
-
setChecked,
|
|
1617
|
-
control,
|
|
1618
|
-
setControl,
|
|
1619
|
-
name,
|
|
1620
|
-
form,
|
|
1621
|
-
value,
|
|
1622
|
-
hasConsumerStoppedPropagationRef,
|
|
1623
|
-
userInteractionCount,
|
|
1624
|
-
onUserInteraction,
|
|
1625
|
-
required,
|
|
1626
|
-
defaultChecked: isIndeterminate(defaultChecked) ? false : defaultChecked,
|
|
1627
|
-
isFormControl,
|
|
1628
|
-
bubbleInput,
|
|
1629
|
-
setBubbleInput
|
|
1630
|
-
};
|
|
1631
|
-
return /* @__PURE__ */ jsx(CheckboxProviderImpl, {
|
|
1632
|
-
scope: __scopeCheckbox,
|
|
1633
|
-
...context,
|
|
1634
|
-
children: isFunction$1(internal_do_not_use_render) ? internal_do_not_use_render(context) : children
|
|
1635
|
-
});
|
|
1636
|
-
}
|
|
1637
|
-
__name$13(CheckboxProvider, "CheckboxProvider");
|
|
1638
|
-
var TRIGGER_NAME$3 = "CheckboxTrigger";
|
|
1639
|
-
var CheckboxTrigger = /* @__PURE__ */ React$1.forwardRef(/* @__PURE__ */ __name$13(function CheckboxTrigger2({ __scopeCheckbox, onKeyDown, onClick, ...checkboxProps }, forwardedRef) {
|
|
1640
|
-
const { control, value, disabled, checked, required, setControl, setChecked, hasConsumerStoppedPropagationRef, onUserInteraction, isFormControl, bubbleInput } = useCheckboxContext(TRIGGER_NAME$3, __scopeCheckbox);
|
|
1641
|
-
const composedRefs = useComposedRefs$1(forwardedRef, setControl);
|
|
1642
|
-
const initialCheckedStateRef = React$1.useRef(checked);
|
|
1643
|
-
React$1.useEffect(() => {
|
|
1644
|
-
const form = control?.form;
|
|
1645
|
-
if (form) {
|
|
1646
|
-
const reset = /* @__PURE__ */ __name$13(() => setChecked(initialCheckedStateRef.current), "reset");
|
|
1647
|
-
form.addEventListener("reset", reset);
|
|
1648
|
-
return () => form.removeEventListener("reset", reset);
|
|
1649
|
-
}
|
|
1650
|
-
}, [control, setChecked]);
|
|
1651
|
-
return /* @__PURE__ */ jsx(Primitive.button, {
|
|
1652
|
-
type: "button",
|
|
1653
|
-
role: "checkbox",
|
|
1654
|
-
"aria-checked": isIndeterminate(checked) ? "mixed" : checked,
|
|
1655
|
-
"aria-required": required,
|
|
1656
|
-
"data-state": getState$3(checked),
|
|
1657
|
-
"data-disabled": disabled ? "" : void 0,
|
|
1658
|
-
disabled,
|
|
1659
|
-
value,
|
|
1660
|
-
...checkboxProps,
|
|
1661
|
-
ref: composedRefs,
|
|
1662
|
-
onKeyDown: composeEventHandlers(onKeyDown, (event) => {
|
|
1663
|
-
if (event.key === "Enter") event.preventDefault();
|
|
1664
|
-
}),
|
|
1665
|
-
onClick: composeEventHandlers(onClick, (event) => {
|
|
1666
|
-
onUserInteraction();
|
|
1667
|
-
setChecked((prevChecked) => isIndeterminate(prevChecked) ? true : !prevChecked);
|
|
1668
|
-
if (bubbleInput && isFormControl) {
|
|
1669
|
-
hasConsumerStoppedPropagationRef.current = event.isPropagationStopped();
|
|
1670
|
-
if (!hasConsumerStoppedPropagationRef.current) event.stopPropagation();
|
|
1671
|
-
}
|
|
1672
|
-
})
|
|
1673
|
-
});
|
|
1674
|
-
}, "CheckboxTrigger"));
|
|
1675
|
-
var Checkbox$1 = /* @__PURE__ */ React$1.forwardRef(/* @__PURE__ */ __name$13(function Checkbox2(props, forwardedRef) {
|
|
1676
|
-
const { __scopeCheckbox, name, checked, defaultChecked, required, disabled, value, onCheckedChange, form, ...checkboxProps } = props;
|
|
1677
|
-
return /* @__PURE__ */ jsx(CheckboxProvider, {
|
|
1678
|
-
__scopeCheckbox,
|
|
1679
|
-
checked,
|
|
1680
|
-
defaultChecked,
|
|
1681
|
-
disabled,
|
|
1682
|
-
required,
|
|
1683
|
-
onCheckedChange,
|
|
1684
|
-
name,
|
|
1685
|
-
form,
|
|
1686
|
-
value,
|
|
1687
|
-
internal_do_not_use_render: ({ isFormControl }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(CheckboxTrigger, {
|
|
1688
|
-
...checkboxProps,
|
|
1689
|
-
ref: forwardedRef,
|
|
1690
|
-
__scopeCheckbox
|
|
1691
|
-
}), isFormControl && /* @__PURE__ */ jsx(CheckboxBubbleInput, { __scopeCheckbox })] })
|
|
1692
|
-
});
|
|
1693
|
-
}, "Checkbox"));
|
|
1694
|
-
var INDICATOR_NAME = "CheckboxIndicator";
|
|
1695
|
-
var CheckboxIndicator = /* @__PURE__ */ React$1.forwardRef(/* @__PURE__ */ __name$13(function CheckboxIndicator2(props, forwardedRef) {
|
|
1696
|
-
const { __scopeCheckbox, forceMount, ...indicatorProps } = props;
|
|
1697
|
-
const context = useCheckboxContext(INDICATOR_NAME, __scopeCheckbox);
|
|
1698
|
-
return /* @__PURE__ */ jsx(Presence, {
|
|
1699
|
-
present: forceMount || isIndeterminate(context.checked) || context.checked === true,
|
|
1700
|
-
children: /* @__PURE__ */ jsx(Primitive.span, {
|
|
1701
|
-
"data-state": getState$3(context.checked),
|
|
1702
|
-
"data-disabled": context.disabled ? "" : void 0,
|
|
1703
|
-
...indicatorProps,
|
|
1704
|
-
ref: forwardedRef,
|
|
1705
|
-
style: {
|
|
1706
|
-
pointerEvents: "none",
|
|
1707
|
-
...props.style
|
|
1708
|
-
}
|
|
1709
|
-
})
|
|
1710
|
-
});
|
|
1711
|
-
}, "CheckboxIndicator"));
|
|
1712
|
-
var BUBBLE_INPUT_NAME$1 = "CheckboxBubbleInput";
|
|
1713
|
-
var CheckboxBubbleInput = /* @__PURE__ */ React$1.forwardRef(/* @__PURE__ */ __name$13(function CheckboxBubbleInput2({ __scopeCheckbox, onClick, ...props }, forwardedRef) {
|
|
1714
|
-
const { control, hasConsumerStoppedPropagationRef, userInteractionCount, checked, defaultChecked, required, disabled, name, value, form, bubbleInput, setBubbleInput } = useCheckboxContext(BUBBLE_INPUT_NAME$1, __scopeCheckbox);
|
|
1715
|
-
const composedRefs = useComposedRefs$1(forwardedRef, setBubbleInput);
|
|
1716
|
-
const controlSize = useSize(control);
|
|
1717
|
-
const shouldStopClickPropagationRef = React$1.useRef(false);
|
|
1718
|
-
const prevCheckedRef = React$1.useRef(checked);
|
|
1719
|
-
const prevUserInteractionCountRef = React$1.useRef(userInteractionCount);
|
|
1720
|
-
React$1.useEffect(() => {
|
|
1721
|
-
const input = bubbleInput;
|
|
1722
|
-
if (!input) return;
|
|
1723
|
-
const inputProto = window.HTMLInputElement.prototype;
|
|
1724
|
-
const setChecked = Object.getOwnPropertyDescriptor(inputProto, "checked").set;
|
|
1725
|
-
const isUserInteraction = userInteractionCount !== prevUserInteractionCountRef.current;
|
|
1726
|
-
prevUserInteractionCountRef.current = userInteractionCount;
|
|
1727
|
-
const checkedChanged = prevCheckedRef.current !== checked;
|
|
1728
|
-
prevCheckedRef.current = checked;
|
|
1729
|
-
const bubbles = !(isUserInteraction && hasConsumerStoppedPropagationRef.current);
|
|
1730
|
-
if (checkedChanged && setChecked) {
|
|
1731
|
-
shouldStopClickPropagationRef.current = !isUserInteraction;
|
|
1732
|
-
const event = new Event("click", { bubbles });
|
|
1733
|
-
input.indeterminate = isIndeterminate(checked);
|
|
1734
|
-
setChecked.call(input, isIndeterminate(checked) ? false : checked);
|
|
1735
|
-
input.dispatchEvent(event);
|
|
1736
|
-
shouldStopClickPropagationRef.current = false;
|
|
1737
|
-
}
|
|
1738
|
-
}, [
|
|
1739
|
-
bubbleInput,
|
|
1740
|
-
checked,
|
|
1741
|
-
hasConsumerStoppedPropagationRef,
|
|
1742
|
-
userInteractionCount
|
|
1743
|
-
]);
|
|
1744
|
-
const defaultCheckedRef = React$1.useRef(isIndeterminate(checked) ? false : checked);
|
|
1745
|
-
return /* @__PURE__ */ jsx(Primitive.input, {
|
|
1746
|
-
type: "checkbox",
|
|
1747
|
-
"aria-hidden": true,
|
|
1748
|
-
defaultChecked: defaultChecked ?? defaultCheckedRef.current,
|
|
1749
|
-
required,
|
|
1750
|
-
disabled,
|
|
1751
|
-
name,
|
|
1752
|
-
value,
|
|
1753
|
-
form,
|
|
1754
|
-
...props,
|
|
1755
|
-
tabIndex: -1,
|
|
1756
|
-
ref: composedRefs,
|
|
1757
|
-
onClick: composeEventHandlers(onClick, (event) => {
|
|
1758
|
-
if (shouldStopClickPropagationRef.current) event.stopPropagation();
|
|
1759
|
-
}),
|
|
1760
|
-
style: {
|
|
1761
|
-
...props.style,
|
|
1762
|
-
...controlSize,
|
|
1763
|
-
position: "absolute",
|
|
1764
|
-
pointerEvents: "none",
|
|
1765
|
-
opacity: 0,
|
|
1766
|
-
margin: 0,
|
|
1767
|
-
transform: "translateX(-100%)"
|
|
1768
|
-
}
|
|
1769
|
-
});
|
|
1770
|
-
}, "CheckboxBubbleInput"));
|
|
1771
|
-
function isFunction$1(value) {
|
|
1772
|
-
return typeof value === "function";
|
|
1773
|
-
}
|
|
1774
|
-
__name$13(isFunction$1, "isFunction");
|
|
1775
|
-
function isIndeterminate(checked) {
|
|
1776
|
-
return checked === "indeterminate";
|
|
1777
|
-
}
|
|
1778
|
-
__name$13(isIndeterminate, "isIndeterminate");
|
|
1779
|
-
function getState$3(checked) {
|
|
1780
|
-
return isIndeterminate(checked) ? "indeterminate" : checked ? "checked" : "unchecked";
|
|
1781
|
-
}
|
|
1782
|
-
__name$13(getState$3, "getState");
|
|
1783
|
-
|
|
1784
|
-
//#endregion
|
|
1785
|
-
//#region ../ui-kit/src/components/Checkbox.tsx
|
|
1786
|
-
/** Source-owned shadcn-style checkbox backed by Radix for keyboard semantics. */
|
|
1787
|
-
function Checkbox({ className = "", invalid = false, "aria-invalid": ariaInvalid, ...props }) {
|
|
1788
|
-
return /* @__PURE__ */ jsx(Checkbox$1, {
|
|
1789
|
-
"aria-invalid": invalid ? true : ariaInvalid,
|
|
1790
|
-
className: `inline-flex size-4 shrink-0 items-center justify-center rounded-sm border bg-surface shadow-xs outline-none transition-colors disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground ${invalid ? "border-destructive focus-visible:ring-destructive/20" : "border-input focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/20"} ${className}`,
|
|
1791
|
-
...props,
|
|
1792
|
-
children: /* @__PURE__ */ jsx(CheckboxIndicator, {
|
|
1793
|
-
className: "flex items-center justify-center",
|
|
1794
|
-
children: /* @__PURE__ */ jsx(Check, {
|
|
1795
|
-
className: "size-3",
|
|
1796
|
-
"aria-hidden": true
|
|
1797
|
-
})
|
|
1798
|
-
})
|
|
1799
|
-
});
|
|
1800
|
-
}
|
|
1801
|
-
|
|
1802
|
-
//#endregion
|
|
1803
|
-
//#region ../ui-kit/src/components/Textarea.tsx
|
|
1804
|
-
/** Source-owned textarea with the same form-control states as Input. */
|
|
1805
|
-
function Textarea({ className = "", invalid = false, "aria-invalid": ariaInvalid, ...props }) {
|
|
1806
|
-
return /* @__PURE__ */ jsx("textarea", {
|
|
1807
|
-
"aria-invalid": invalid ? true : ariaInvalid,
|
|
1808
|
-
className: `min-h-20 w-full resize-y rounded-md border bg-surface px-3 py-2 text-sm text-ink shadow-xs outline-none transition-colors placeholder:text-muted disabled:cursor-not-allowed disabled:opacity-50 ${invalid ? "border-destructive focus-visible:ring-destructive/20" : "border-input focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/20"} ${className}`,
|
|
1809
|
-
...props
|
|
1810
|
-
});
|
|
1811
|
-
}
|
|
1669
|
+
__name$13(dispatchDiscreteCustomEvent, "dispatchDiscreteCustomEvent");
|
|
1812
1670
|
|
|
1813
1671
|
//#endregion
|
|
1814
1672
|
//#region ../../node_modules/.pnpm/@radix-ui+react-switch@1.3.7_@types+react-dom@19.2.3_@types+react@19.2.17__@types+react_e96baf15833549650471eefa4ffd78d0/node_modules/@radix-ui/react-switch/dist/index.mjs
|
|
@@ -40690,6 +40548,10 @@ function defaultRuntimeConfig() {
|
|
|
40690
40548
|
approvalScope: "once-per-run"
|
|
40691
40549
|
},
|
|
40692
40550
|
router: { strategy: "progressive" },
|
|
40551
|
+
hooks: {
|
|
40552
|
+
timeoutMs: 5e3,
|
|
40553
|
+
failOnHookError: false
|
|
40554
|
+
},
|
|
40693
40555
|
streaming: true,
|
|
40694
40556
|
renderResult: true,
|
|
40695
40557
|
sandbox: {
|
|
@@ -40699,6 +40561,10 @@ function defaultRuntimeConfig() {
|
|
|
40699
40561
|
readReference: true,
|
|
40700
40562
|
writeArtifact: true,
|
|
40701
40563
|
confirm: true
|
|
40564
|
+
},
|
|
40565
|
+
remoteUrl: {
|
|
40566
|
+
allowHttp: false,
|
|
40567
|
+
allowPrivateHosts: false
|
|
40702
40568
|
}
|
|
40703
40569
|
},
|
|
40704
40570
|
llm: {
|
|
@@ -40719,6 +40585,7 @@ function mergeRuntimeConfigDefaults(partial) {
|
|
|
40719
40585
|
loop: sub("loop", d.loop),
|
|
40720
40586
|
interaction: sub("interaction", d.interaction),
|
|
40721
40587
|
router: sub("router", d.router),
|
|
40588
|
+
hooks: sub("hooks", d.hooks),
|
|
40722
40589
|
streaming: typeof p["streaming"] === "boolean" ? p["streaming"] : d.streaming,
|
|
40723
40590
|
renderResult: typeof p["renderResult"] === "boolean" ? p["renderResult"] : d.renderResult,
|
|
40724
40591
|
sandbox: {
|
|
@@ -40726,6 +40593,10 @@ function mergeRuntimeConfigDefaults(partial) {
|
|
|
40726
40593
|
capabilities: {
|
|
40727
40594
|
...d.sandbox.capabilities,
|
|
40728
40595
|
...p["sandbox"]?.["capabilities"] ?? {}
|
|
40596
|
+
},
|
|
40597
|
+
remoteUrl: {
|
|
40598
|
+
...d.sandbox.remoteUrl,
|
|
40599
|
+
...p["sandbox"]?.["remoteUrl"] ?? {}
|
|
40729
40600
|
}
|
|
40730
40601
|
},
|
|
40731
40602
|
llm: sub("llm", d.llm)
|
|
@@ -40747,8 +40618,36 @@ function withRuntimeConfigDefaults(store) {
|
|
|
40747
40618
|
//#endregion
|
|
40748
40619
|
//#region src/core/interactionBridge.ts
|
|
40749
40620
|
/**
|
|
40621
|
+
* 渲染档 → 能力集。四档在 0.4.0 起 interaction/surface 全部等价,
|
|
40622
|
+
* 差别只剩「是否依赖 optional peer」。作为可注入值传入 CompositeUiBridge,
|
|
40623
|
+
* 便于宿主按实际装配情况覆盖(例如已确认某 peer 不可用)。
|
|
40624
|
+
* @experimental
|
|
40625
|
+
*/
|
|
40626
|
+
const DEFAULT_RENDERER_CAPABILITIES = {
|
|
40627
|
+
native: {
|
|
40628
|
+
interaction: true,
|
|
40629
|
+
surface: true
|
|
40630
|
+
},
|
|
40631
|
+
a2ui: {
|
|
40632
|
+
interaction: true,
|
|
40633
|
+
surface: true,
|
|
40634
|
+
requiresPeer: "@a2ui/lit"
|
|
40635
|
+
},
|
|
40636
|
+
openui: {
|
|
40637
|
+
interaction: true,
|
|
40638
|
+
surface: true,
|
|
40639
|
+
requiresPeer: "@openuidev/react-lang"
|
|
40640
|
+
},
|
|
40641
|
+
vercel: {
|
|
40642
|
+
interaction: true,
|
|
40643
|
+
surface: true,
|
|
40644
|
+
requiresPeer: "@json-render/react"
|
|
40645
|
+
}
|
|
40646
|
+
};
|
|
40647
|
+
/**
|
|
40750
40648
|
* 探测 A2UI Lit 渲染器是否可用(@a2ui/lit 为 optional peer,未安装时 import 失败)。
|
|
40751
40649
|
* Appearance/设置区据此对 A2UI 档置灰;仅动态 import,不强依赖。
|
|
40650
|
+
* @experimental
|
|
40752
40651
|
*/
|
|
40753
40652
|
async function probeA2uiAvailability() {
|
|
40754
40653
|
try {
|
|
@@ -40763,6 +40662,7 @@ async function probeA2uiAvailability() {
|
|
|
40763
40662
|
* 经 @lit/context 向 surface 子树注入 renderMarkdown(markdown-it + dompurify),
|
|
40764
40663
|
* 消除 "[MarkdownDirective] can't render markdown" 降级。
|
|
40765
40664
|
* 未安装时返回 false(宿主可据此保留产品化限制说明)。
|
|
40665
|
+
* @experimental
|
|
40766
40666
|
*/
|
|
40767
40667
|
async function configureA2uiMarkdown(mount) {
|
|
40768
40668
|
let deps;
|
|
@@ -40790,6 +40690,7 @@ async function configureA2uiMarkdown(mount) {
|
|
|
40790
40690
|
/**
|
|
40791
40691
|
* 探测 OpenUI 渲染器是否可用(@openuidev/react-lang 为 optional peer)。
|
|
40792
40692
|
* Appearance/设置区据此对 OpenUI 档置灰;仅动态 import,不强依赖。
|
|
40693
|
+
* @experimental
|
|
40793
40694
|
*/
|
|
40794
40695
|
async function probeOpenUiAvailability() {
|
|
40795
40696
|
try {
|
|
@@ -40799,135 +40700,52 @@ async function probeOpenUiAvailability() {
|
|
|
40799
40700
|
return false;
|
|
40800
40701
|
}
|
|
40801
40702
|
}
|
|
40802
|
-
/**
|
|
40803
|
-
|
|
40804
|
-
|
|
40805
|
-
|
|
40806
|
-
|
|
40807
|
-
|
|
40808
|
-
* - attach/detach 标记渲染视图是否挂载(未挂载时桥直接降级 native,不悬挂请求)。
|
|
40809
|
-
*/
|
|
40810
|
-
var OpenUiChannel = class {
|
|
40811
|
-
#current;
|
|
40812
|
-
#listeners = /* @__PURE__ */ new Set();
|
|
40813
|
-
#attached = 0;
|
|
40814
|
-
#failure;
|
|
40815
|
-
/** React useSyncExternalStore 兼容订阅 */
|
|
40816
|
-
subscribe = (listener) => {
|
|
40817
|
-
this.#listeners.add(listener);
|
|
40818
|
-
return () => this.#listeners.delete(listener);
|
|
40819
|
-
};
|
|
40820
|
-
get current() {
|
|
40821
|
-
return this.#current?.session;
|
|
40822
|
-
}
|
|
40823
|
-
get isAttached() {
|
|
40824
|
-
return this.#attached > 0;
|
|
40825
|
-
}
|
|
40826
|
-
/** react 层初始化失败原因(未安装 @openuidev/react-lang 等);记录后粘性生效 */
|
|
40827
|
-
get failure() {
|
|
40828
|
-
return this.#failure;
|
|
40829
|
-
}
|
|
40830
|
-
attach() {
|
|
40831
|
-
this.#attached += 1;
|
|
40832
|
-
}
|
|
40833
|
-
detach() {
|
|
40834
|
-
this.#attached = Math.max(0, this.#attached - 1);
|
|
40835
|
-
}
|
|
40836
|
-
request(input) {
|
|
40837
|
-
if (this.#current) this.#settle({
|
|
40838
|
-
id: this.#current.session.request.id,
|
|
40839
|
-
cancelled: true
|
|
40840
|
-
});
|
|
40841
|
-
return new Promise((resolve, reject) => {
|
|
40842
|
-
this.#current = {
|
|
40843
|
-
session: {
|
|
40844
|
-
request: input,
|
|
40845
|
-
lang: toOpenUiLang(input)
|
|
40846
|
-
},
|
|
40847
|
-
resolve,
|
|
40848
|
-
reject
|
|
40849
|
-
};
|
|
40850
|
-
this.#emit();
|
|
40851
|
-
});
|
|
40852
|
-
}
|
|
40853
|
-
/** runtime 交互超时/取消:以 cancelled resolve 挂起的 request(防悬挂 + 残留) */
|
|
40854
|
-
cancel(id) {
|
|
40855
|
-
if (this.#current?.session.request.id === id) this.#settle({
|
|
40856
|
-
id,
|
|
40857
|
-
cancelled: true
|
|
40858
|
-
});
|
|
40859
|
-
}
|
|
40860
|
-
/** react 层 OpenUI 动作回传(fromOpenUiAction:Allow → value:true;Deny/Cancel → cancelled:true) */
|
|
40861
|
-
handleAction(action) {
|
|
40862
|
-
if (!this.#current) return;
|
|
40863
|
-
this.#settle(fromOpenUiAction(action));
|
|
40864
|
-
}
|
|
40865
|
-
/** react 层初始化失败:挂起请求 reject 并记录原因(桥读取后降级 native) */
|
|
40866
|
-
fail(message) {
|
|
40867
|
-
this.#failure = message;
|
|
40868
|
-
const pending = this.#current;
|
|
40869
|
-
this.#current = void 0;
|
|
40870
|
-
this.#emit();
|
|
40871
|
-
pending?.reject(new Error(message));
|
|
40872
|
-
}
|
|
40873
|
-
#settle(response) {
|
|
40874
|
-
const pending = this.#current;
|
|
40875
|
-
this.#current = void 0;
|
|
40876
|
-
this.#emit();
|
|
40877
|
-
pending?.resolve(response);
|
|
40878
|
-
}
|
|
40879
|
-
#emit() {
|
|
40880
|
-
for (const listener of [...this.#listeners]) listener();
|
|
40881
|
-
}
|
|
40703
|
+
/** 渲染档在告警文案里的显示名(面向用户,不用内部 kind 字面量) */
|
|
40704
|
+
const RENDERER_LABEL = {
|
|
40705
|
+
native: "native",
|
|
40706
|
+
a2ui: "A2UI",
|
|
40707
|
+
openui: "OpenUI",
|
|
40708
|
+
vercel: "json-render"
|
|
40882
40709
|
};
|
|
40883
40710
|
/**
|
|
40884
40711
|
* 复合 UiBridge(P2/P3 渲染框架档):
|
|
40885
40712
|
* - streamingText / renderResult 始终委托 ReactBridgeState(结果块数据源不变);
|
|
40886
40713
|
* - 交互 request/cancel 按渲染档分发:native → ReactBridgeState(InteractionCard),
|
|
40887
|
-
*
|
|
40888
|
-
*
|
|
40889
|
-
*
|
|
40890
|
-
* -
|
|
40891
|
-
*
|
|
40714
|
+
* 其余三档 → SpecInteractionChannel(core 产出 catalog 节点树,react 层交给本档
|
|
40715
|
+
* 已有的 spec 渲染路径:A2uiSpecSurface / OpenUiSpecSurface / JsonRenderSpecSurface);
|
|
40716
|
+
* - 每次交互开始/结束发 interaction-requested/resolved 事件;
|
|
40717
|
+
* - 非 native 档初始化失败(optional peer 未安装等)降级 native + warning 事件,不阻断 run。
|
|
40718
|
+
* @stable
|
|
40892
40719
|
*/
|
|
40893
40720
|
var CompositeUiBridge = class {
|
|
40894
40721
|
#deps;
|
|
40895
|
-
#
|
|
40896
|
-
/**
|
|
40722
|
+
#capabilities;
|
|
40723
|
+
/** 非 native 档失败/未挂载后粘性降级 native(同一引擎内不逐请求重复告警) */
|
|
40897
40724
|
#downgraded = false;
|
|
40898
40725
|
constructor(deps) {
|
|
40899
40726
|
this.#deps = deps;
|
|
40727
|
+
this.#capabilities = deps.capabilities ?? DEFAULT_RENDERER_CAPABILITIES;
|
|
40900
40728
|
}
|
|
40901
|
-
/**
|
|
40729
|
+
/** 渲染档热切换:清降级状态(新档立即生效,无需重装配 runtime) */
|
|
40902
40730
|
reset() {
|
|
40903
|
-
this.#a2ui = void 0;
|
|
40904
40731
|
this.#downgraded = false;
|
|
40905
40732
|
}
|
|
40906
40733
|
async request(input) {
|
|
40907
40734
|
const renderer = this.#deps.getRenderer();
|
|
40908
|
-
if (
|
|
40909
|
-
const
|
|
40910
|
-
|
|
40911
|
-
else return this.#requestA2ui(bridge, input);
|
|
40912
|
-
}
|
|
40913
|
-
if (renderer === "openui" && !this.#downgraded) {
|
|
40914
|
-
const channel = this.#deps.getOpenUiChannel();
|
|
40735
|
+
if (this.#inTier(renderer)) {
|
|
40736
|
+
const channel = this.#deps.getInteractionChannel();
|
|
40737
|
+
const label = RENDERER_LABEL[renderer];
|
|
40915
40738
|
const failure = channel.failure;
|
|
40916
|
-
if (failure !== void 0) this.#downgrade(`The
|
|
40917
|
-
else if (!channel.isAttached) this.#downgrade(
|
|
40918
|
-
else return this.#
|
|
40739
|
+
if (failure !== void 0) this.#downgrade(`The ${label} renderer failed to initialize (${failure}); falling back to native interaction cards`);
|
|
40740
|
+
else if (!channel.isAttached) this.#downgrade(`The ${label} renderer is selected but its interaction view is not attached; falling back to native interaction cards`);
|
|
40741
|
+
else return this.#requestInTier(channel, label, input);
|
|
40919
40742
|
}
|
|
40920
40743
|
return this.#requestNative(input);
|
|
40921
40744
|
}
|
|
40922
|
-
/** runtime
|
|
40745
|
+
/** runtime 交互超时/取消:按档委托(通道 cancel 会以 cancelled resolve 挂起的 request) */
|
|
40923
40746
|
cancel(id) {
|
|
40924
|
-
|
|
40925
|
-
|
|
40926
|
-
this.#a2ui.bridge.cancel(id);
|
|
40927
|
-
return;
|
|
40928
|
-
}
|
|
40929
|
-
if (renderer === "openui" && !this.#downgraded) {
|
|
40930
|
-
this.#deps.getOpenUiChannel().cancel(id);
|
|
40747
|
+
if (this.#inTier(this.#deps.getRenderer())) {
|
|
40748
|
+
this.#deps.getInteractionChannel().cancel(id);
|
|
40931
40749
|
return;
|
|
40932
40750
|
}
|
|
40933
40751
|
this.#deps.reactBridge.cancel(id);
|
|
@@ -40947,36 +40765,11 @@ var CompositeUiBridge = class {
|
|
|
40947
40765
|
onTextDelta(runId, delta) {
|
|
40948
40766
|
return this.#deps.reactBridge.onTextDelta(runId, delta);
|
|
40949
40767
|
}
|
|
40950
|
-
/**
|
|
40951
|
-
#
|
|
40952
|
-
|
|
40953
|
-
if (!mount) return void 0;
|
|
40954
|
-
if (!this.#a2ui || this.#a2ui.mount !== mount) this.#a2ui = {
|
|
40955
|
-
mount,
|
|
40956
|
-
bridge: new LitRendererBridge({ mount })
|
|
40957
|
-
};
|
|
40958
|
-
return this.#a2ui.bridge;
|
|
40959
|
-
}
|
|
40960
|
-
async #requestA2ui(bridge, input) {
|
|
40961
|
-
this.#deps.emit({
|
|
40962
|
-
type: "interaction-requested",
|
|
40963
|
-
id: input.id,
|
|
40964
|
-
requestType: input.type
|
|
40965
|
-
});
|
|
40966
|
-
try {
|
|
40967
|
-
const response = await bridge.request(input);
|
|
40968
|
-
this.#emitResolved(input, response);
|
|
40969
|
-
return response;
|
|
40970
|
-
} catch (e) {
|
|
40971
|
-
this.#emitResolved(input, {
|
|
40972
|
-
id: input.id,
|
|
40973
|
-
cancelled: true
|
|
40974
|
-
});
|
|
40975
|
-
this.#downgrade(`The A2UI renderer failed to initialize (${messageOf(e)}); falling back to native interaction cards`);
|
|
40976
|
-
return this.#requestNative(input);
|
|
40977
|
-
}
|
|
40768
|
+
/** 本档能否自行渲染交互(能力表允许且未粘性降级) */
|
|
40769
|
+
#inTier(renderer) {
|
|
40770
|
+
return renderer !== "native" && this.#capabilities[renderer].interaction && !this.#downgraded;
|
|
40978
40771
|
}
|
|
40979
|
-
async #
|
|
40772
|
+
async #requestInTier(channel, label, input) {
|
|
40980
40773
|
this.#deps.emit({
|
|
40981
40774
|
type: "interaction-requested",
|
|
40982
40775
|
id: input.id,
|
|
@@ -40991,7 +40784,7 @@ var CompositeUiBridge = class {
|
|
|
40991
40784
|
id: input.id,
|
|
40992
40785
|
cancelled: true
|
|
40993
40786
|
});
|
|
40994
|
-
this.#downgrade(`The
|
|
40787
|
+
this.#downgrade(`The ${label} renderer failed to initialize (${messageOf(e)}); falling back to native interaction cards`);
|
|
40995
40788
|
return this.#requestNative(input);
|
|
40996
40789
|
}
|
|
40997
40790
|
}
|
|
@@ -41056,7 +40849,7 @@ function createDemoLlm() {
|
|
|
41056
40849
|
return reply ?? "";
|
|
41057
40850
|
};
|
|
41058
40851
|
return {
|
|
41059
|
-
complete: async () => ({ content: nextReply() }),
|
|
40852
|
+
complete: async () => ({ content: textParts(nextReply()) }),
|
|
41060
40853
|
async *stream() {
|
|
41061
40854
|
const content = nextReply();
|
|
41062
40855
|
const chunkSize = Math.max(1, Math.ceil(content.length / 3));
|
|
@@ -41103,6 +40896,7 @@ function createRuntimeLlm(config) {
|
|
|
41103
40896
|
/**
|
|
41104
40897
|
* 对话框引擎:装配 WebSkillRuntime + 会话持久化 + 事件分发。
|
|
41105
40898
|
* llmConfig.load() 是异步的,runtime 在首次 send 前懒装配(#ensureReady)。
|
|
40899
|
+
* @stable
|
|
41106
40900
|
*/
|
|
41107
40901
|
var ChatEngine = class {
|
|
41108
40902
|
bridge;
|
|
@@ -41119,10 +40913,8 @@ var ChatEngine = class {
|
|
|
41119
40913
|
#runSkills = /* @__PURE__ */ new Map();
|
|
41120
40914
|
/** 当前渲染框架档(复合 uiBridge 分发;setRenderer 热切换) */
|
|
41121
40915
|
#renderer;
|
|
41122
|
-
/**
|
|
41123
|
-
#
|
|
41124
|
-
/** openui 档交互通道(Chatbot 的 OpenUiInteraction attach 后生效) */
|
|
41125
|
-
#openUiChannel = new OpenUiChannel();
|
|
40916
|
+
/** 非 native 三档共用的交互通道(Chatbot 的 SpecInteraction attach 后生效) */
|
|
40917
|
+
#interactionChannel = new SpecInteractionChannel();
|
|
41126
40918
|
/** 装配时按 RuntimeConfig 应用(interaction 分发 + renderResult/streaming 透传 ReactBridgeState) */
|
|
41127
40919
|
#uiBridge;
|
|
41128
40920
|
/** RuntimeConfig.loop.maxHistoryMessages(装配时捕获,createSession 透传) */
|
|
@@ -41131,7 +40923,7 @@ var ChatEngine = class {
|
|
|
41131
40923
|
#surfaceDraftWrites = /* @__PURE__ */ new Map();
|
|
41132
40924
|
/** run trace 落盘(写失败降级 warn,不阻断对话) */
|
|
41133
40925
|
#traceStore;
|
|
41134
|
-
/**
|
|
40926
|
+
/** 会话落盘;缺省是本包内引用 `FsSessionStore` 的唯一处 */
|
|
41135
40927
|
#sessions;
|
|
41136
40928
|
constructor(adapter, options = {}) {
|
|
41137
40929
|
this.#adapter = adapter;
|
|
@@ -41141,7 +40933,7 @@ var ChatEngine = class {
|
|
|
41141
40933
|
root: `${this.#chatRoot}/traces`,
|
|
41142
40934
|
fs: adapter.storage
|
|
41143
40935
|
});
|
|
41144
|
-
this.#sessions = new FsSessionStore({
|
|
40936
|
+
this.#sessions = options.sessionStore ?? new FsSessionStore({
|
|
41145
40937
|
root: `${this.#chatRoot}/sessions`,
|
|
41146
40938
|
fs: adapter.storage
|
|
41147
40939
|
});
|
|
@@ -41159,8 +40951,7 @@ var ChatEngine = class {
|
|
|
41159
40951
|
this.#uiBridge = new CompositeUiBridge({
|
|
41160
40952
|
reactBridge: this.bridge,
|
|
41161
40953
|
getRenderer: () => this.#renderer,
|
|
41162
|
-
|
|
41163
|
-
getOpenUiChannel: () => this.#openUiChannel,
|
|
40954
|
+
getInteractionChannel: () => this.#interactionChannel,
|
|
41164
40955
|
emit: (event) => this.#emit(event)
|
|
41165
40956
|
});
|
|
41166
40957
|
}
|
|
@@ -41174,13 +40965,9 @@ var ChatEngine = class {
|
|
|
41174
40965
|
this.#renderer = renderer;
|
|
41175
40966
|
this.#uiBridge.reset();
|
|
41176
40967
|
}
|
|
41177
|
-
/**
|
|
41178
|
-
|
|
41179
|
-
this.#
|
|
41180
|
-
}
|
|
41181
|
-
/** openui 档交互通道(Chatbot 的 OpenUiInteraction 订阅/attach;core 只产出 lang 文本) */
|
|
41182
|
-
get openUiChannel() {
|
|
41183
|
-
return this.#openUiChannel;
|
|
40968
|
+
/** 非 native 三档共用的交互通道(Chatbot 的 SpecInteraction 订阅/attach;core 只产出 catalog 节点树) */
|
|
40969
|
+
get interactionChannel() {
|
|
40970
|
+
return this.#interactionChannel;
|
|
41184
40971
|
}
|
|
41185
40972
|
/** 探测 @a2ui/lit 是否安装(Appearance/设置区 A2UI 档置灰判定) */
|
|
41186
40973
|
probeA2uiAvailability() {
|
|
@@ -41207,8 +40994,19 @@ var ChatEngine = class {
|
|
|
41207
40994
|
reloadLlm() {
|
|
41208
40995
|
this.reloadConfig();
|
|
41209
40996
|
}
|
|
41210
|
-
|
|
41211
|
-
|
|
40997
|
+
/**
|
|
40998
|
+
* 会话列表页。归档会话也返回:UI 自己分区展示。
|
|
40999
|
+
* `limit` 不给默认值——缺省属于 `SessionStore` 实现,在这里兜底就等于只下推了一半。
|
|
41000
|
+
*/
|
|
41001
|
+
async listSessions(options = {}) {
|
|
41002
|
+
const page = await this.#sessions.list({
|
|
41003
|
+
includeArchived: true,
|
|
41004
|
+
...options
|
|
41005
|
+
});
|
|
41006
|
+
return {
|
|
41007
|
+
items: page.items.map(toSessionMeta),
|
|
41008
|
+
...page.nextCursor !== void 0 ? { nextCursor: page.nextCursor } : {}
|
|
41009
|
+
};
|
|
41212
41010
|
}
|
|
41213
41011
|
async createSession() {
|
|
41214
41012
|
const session = await this.#sessions.create({ id: newId("session") });
|
|
@@ -41218,10 +41016,23 @@ var ChatEngine = class {
|
|
|
41218
41016
|
createdAt: session.createdAt
|
|
41219
41017
|
};
|
|
41220
41018
|
}
|
|
41221
|
-
|
|
41222
|
-
|
|
41019
|
+
/**
|
|
41020
|
+
* 选中会话并取**最新**一页历史(页内时间升序)。
|
|
41021
|
+
* 返回全量 `ChatMessage[]` 的旧签名已移除:长会话下它强迫每个调用方拿全量。
|
|
41022
|
+
*/
|
|
41023
|
+
async selectSession(id, options = {}) {
|
|
41024
|
+
const page = await this.#sessions.listMessages(id, options);
|
|
41223
41025
|
this.#currentSessionId = id;
|
|
41224
|
-
return
|
|
41026
|
+
return page;
|
|
41027
|
+
}
|
|
41028
|
+
/** 向历史方向再取一页;`cursor` 只能来自上一页的 `nextCursor` */
|
|
41029
|
+
async loadMoreMessages(cursor, options = {}) {
|
|
41030
|
+
const sessionId = this.#currentSessionId;
|
|
41031
|
+
if (!sessionId) throw new WebSkillError("VALIDATION_FAILED", "Cannot load more messages: no active session");
|
|
41032
|
+
return this.#sessions.listMessages(sessionId, {
|
|
41033
|
+
cursor,
|
|
41034
|
+
...options
|
|
41035
|
+
});
|
|
41225
41036
|
}
|
|
41226
41037
|
async deleteSession(id) {
|
|
41227
41038
|
await this.#sessions.delete(id);
|
|
@@ -41338,7 +41149,7 @@ var ChatEngine = class {
|
|
|
41338
41149
|
cancel(runId) {
|
|
41339
41150
|
return this.#runtime?.cancel(runId) ?? false;
|
|
41340
41151
|
}
|
|
41341
|
-
/**
|
|
41152
|
+
/** 列出 interrupted run(InterruptedBanner 数据源);版本不受支持的项带 unsupported 标记 */
|
|
41342
41153
|
async listInterrupted() {
|
|
41343
41154
|
return this.#snapshotStore().list();
|
|
41344
41155
|
}
|
|
@@ -41444,6 +41255,21 @@ var ChatEngine = class {
|
|
|
41444
41255
|
return this.#wrappedRuntimeConfig;
|
|
41445
41256
|
}
|
|
41446
41257
|
#wrappedRuntimeConfig;
|
|
41258
|
+
/**
|
|
41259
|
+
* 治理 port → `WebSkillRuntimeDeps` 的逐字段透传(F1)。
|
|
41260
|
+
* 逐字段展开而不是整体 spread:`exactOptionalPropertyTypes` 下把 `undefined`
|
|
41261
|
+
* 显式传给可选字段与不传不等价,而「不传」才是关闭。
|
|
41262
|
+
*/
|
|
41263
|
+
#governanceDeps() {
|
|
41264
|
+
const g = this.#options.governance;
|
|
41265
|
+
if (g === void 0) return {};
|
|
41266
|
+
return {
|
|
41267
|
+
...g.skillStateGuard !== void 0 ? { skillStateGuard: g.skillStateGuard } : {},
|
|
41268
|
+
...g.skillIntegrityGuard !== void 0 ? { skillIntegrityGuard: g.skillIntegrityGuard } : {},
|
|
41269
|
+
...g.skillOutcomeReporter !== void 0 ? { skillOutcomeReporter: g.skillOutcomeReporter } : {},
|
|
41270
|
+
...g.catalogFilter !== void 0 ? { catalogFilter: g.catalogFilter } : {}
|
|
41271
|
+
};
|
|
41272
|
+
}
|
|
41447
41273
|
async #assemble() {
|
|
41448
41274
|
const fs = this.#adapter.storage;
|
|
41449
41275
|
const rc = await this.#runtimeConfigStore()?.load();
|
|
@@ -41482,8 +41308,10 @@ var ChatEngine = class {
|
|
|
41482
41308
|
root: `${this.#chatRoot}/memory`,
|
|
41483
41309
|
fs
|
|
41484
41310
|
}),
|
|
41311
|
+
...this.#options.hooks ? { hooks: this.#applyHooksConfig(this.#options.hooks, rc) } : {},
|
|
41485
41312
|
externalTools: [...pageSkillSource ? [pageSkillSource] : [], ...this.#options.generativeUi ? [createUiCatalogToolSource()] : []],
|
|
41486
41313
|
skillProviders: pageSkillSource ? [pageSkillSource] : [],
|
|
41314
|
+
...this.#governanceDeps(),
|
|
41487
41315
|
...Object.keys(loopConfig).length > 0 ? { config: loopConfig } : {},
|
|
41488
41316
|
...model ? { model } : {}
|
|
41489
41317
|
});
|
|
@@ -41495,33 +41323,26 @@ var ChatEngine = class {
|
|
|
41495
41323
|
runId: event.runId
|
|
41496
41324
|
});
|
|
41497
41325
|
}
|
|
41498
|
-
|
|
41326
|
+
const toolData = event.phase === "execute" && event.data.kind === "tool" ? event.data : void 0;
|
|
41327
|
+
if (!toolData) this.#emit({
|
|
41499
41328
|
type: "lifecycle",
|
|
41500
41329
|
runId: event.runId,
|
|
41501
|
-
phase: event.phase,
|
|
41502
41330
|
at: Date.parse(event.ts),
|
|
41331
|
+
phase: event.phase,
|
|
41503
41332
|
...event.data ? { data: event.data } : {}
|
|
41504
41333
|
});
|
|
41505
41334
|
if (event.phase === "activate") {
|
|
41506
|
-
const
|
|
41507
|
-
|
|
41508
|
-
|
|
41509
|
-
|
|
41510
|
-
|
|
41511
|
-
|
|
41512
|
-
|
|
41513
|
-
|
|
41514
|
-
|
|
41515
|
-
|
|
41516
|
-
}
|
|
41517
|
-
} else if (event.phase === "execute") {
|
|
41518
|
-
const data = event.data;
|
|
41519
|
-
if (data?.["type"] !== "tool") return;
|
|
41520
|
-
const status = data["status"];
|
|
41521
|
-
const name = data["name"];
|
|
41522
|
-
const callId = data["callId"];
|
|
41523
|
-
if (typeof name !== "string" || typeof callId !== "string") return;
|
|
41524
|
-
const args = typeof data["args"] === "string" ? { args: data["args"] } : {};
|
|
41335
|
+
const skills = this.#runSkills.get(event.runId) ?? /* @__PURE__ */ new Set();
|
|
41336
|
+
skills.add(event.data.skillName);
|
|
41337
|
+
this.#runSkills.set(event.runId, skills);
|
|
41338
|
+
this.#emit({
|
|
41339
|
+
type: "skill-activated",
|
|
41340
|
+
runId: event.runId,
|
|
41341
|
+
skills: [...skills].sort()
|
|
41342
|
+
});
|
|
41343
|
+
} else if (toolData) {
|
|
41344
|
+
const { status, callId, name } = toolData;
|
|
41345
|
+
const args = toolData.args === "" ? {} : { args: toolData.args };
|
|
41525
41346
|
if (status === "started") this.#emit({
|
|
41526
41347
|
type: "tool-started",
|
|
41527
41348
|
runId: event.runId,
|
|
@@ -41529,7 +41350,7 @@ var ChatEngine = class {
|
|
|
41529
41350
|
name,
|
|
41530
41351
|
...args
|
|
41531
41352
|
});
|
|
41532
|
-
else
|
|
41353
|
+
else this.#emit({
|
|
41533
41354
|
type: status === "completed" ? "tool-completed" : "tool-failed",
|
|
41534
41355
|
runId: event.runId,
|
|
41535
41356
|
callId,
|
|
@@ -41581,6 +41402,14 @@ var ChatEngine = class {
|
|
|
41581
41402
|
fs: this.#adapter.storage
|
|
41582
41403
|
});
|
|
41583
41404
|
}
|
|
41405
|
+
/** 钩子执行策略来自 console 编辑的 RuntimeConfig;钩子本身由宿主注册,UI 不碰函数 */
|
|
41406
|
+
#applyHooksConfig(hooks, rc) {
|
|
41407
|
+
if (rc) {
|
|
41408
|
+
hooks.timeoutMs = rc.hooks.timeoutMs;
|
|
41409
|
+
hooks.failOnHookError = rc.hooks.failOnHookError;
|
|
41410
|
+
}
|
|
41411
|
+
return hooks;
|
|
41412
|
+
}
|
|
41584
41413
|
/** 每个 session 一个 runtime session 句柄(跨 run 历史延续),Map 缓存 */
|
|
41585
41414
|
#sessionHandle(runtime, sessionId) {
|
|
41586
41415
|
let handle = this.#handles.get(sessionId);
|
|
@@ -41606,6 +41435,7 @@ var ChatEngine = class {
|
|
|
41606
41435
|
* chatbot 双语字典:全部 UI 文案的单一来源(英文为主,zh 条目齐全)。
|
|
41607
41436
|
* 特性区块(WelcomeScreen / SettingsDrawer 各节 / authorize 说明等)必须含
|
|
41608
41437
|
* title + description 双语条目——"会说话的 UI"的文案底座。
|
|
41438
|
+
* @stable
|
|
41609
41439
|
*/
|
|
41610
41440
|
const chatbotDictionary = defineDictionary({
|
|
41611
41441
|
en: {
|
|
@@ -41618,6 +41448,14 @@ const chatbotDictionary = defineDictionary({
|
|
|
41618
41448
|
"session.searchPlaceholder": "Search sessions…",
|
|
41619
41449
|
"session.empty": "No conversations yet.",
|
|
41620
41450
|
"session.delete": "Delete session: {title}",
|
|
41451
|
+
"session.rename": "Rename session: {title}",
|
|
41452
|
+
"session.renameInput": "New title for session: {title}",
|
|
41453
|
+
"session.archive": "Archive session: {title}",
|
|
41454
|
+
"session.unarchive": "Unarchive session: {title}",
|
|
41455
|
+
"session.archived": "Archived",
|
|
41456
|
+
"session.loadEarlier": "Load earlier sessions",
|
|
41457
|
+
"session.loading": "Loading…",
|
|
41458
|
+
"message.loadEarlier": "Load earlier messages",
|
|
41621
41459
|
"welcome.title": "The official WebSkill SDK chat",
|
|
41622
41460
|
"welcome.assistantTitle": "How can I help?",
|
|
41623
41461
|
"welcome.description": "This chat is the reference implementation of the WebSkill SDK. Ask in natural language: the agent routes your request to installed skills, asks for missing details with native forms, and shows you every step of the run.",
|
|
@@ -41737,6 +41575,7 @@ const chatbotDictionary = defineDictionary({
|
|
|
41737
41575
|
"vercel.preview.title": "Vercel AI SDK data contract",
|
|
41738
41576
|
"vercel.preview.badge": "Preview",
|
|
41739
41577
|
"vercel.preview.description": "This is the data contract for integrating the Vercel AI SDK — a payload preview, not a full runtime. The interaction renders as JSON instead of a form; cancel to end it.",
|
|
41578
|
+
"surface.legacy.placeholder": "Generative UI from an earlier version is no longer rendered.",
|
|
41740
41579
|
"error.title": "Something went wrong",
|
|
41741
41580
|
"error.suggestion": "Check the model configuration in Settings, or try again.",
|
|
41742
41581
|
"error.dismiss": "Dismiss"
|
|
@@ -41751,6 +41590,14 @@ const chatbotDictionary = defineDictionary({
|
|
|
41751
41590
|
"session.searchPlaceholder": "搜索会话…",
|
|
41752
41591
|
"session.empty": "暂无会话。",
|
|
41753
41592
|
"session.delete": "删除会话:{title}",
|
|
41593
|
+
"session.rename": "重命名会话:{title}",
|
|
41594
|
+
"session.renameInput": "会话新标题:{title}",
|
|
41595
|
+
"session.archive": "归档会话:{title}",
|
|
41596
|
+
"session.unarchive": "取消归档:{title}",
|
|
41597
|
+
"session.archived": "已归档",
|
|
41598
|
+
"session.loadEarlier": "加载更早的会话",
|
|
41599
|
+
"session.loading": "加载中…",
|
|
41600
|
+
"message.loadEarlier": "加载更早的消息",
|
|
41754
41601
|
"welcome.title": "WebSkill SDK 官方对话框",
|
|
41755
41602
|
"welcome.assistantTitle": "我可以帮你做什么?",
|
|
41756
41603
|
"welcome.description": "本对话框是 WebSkill SDK 的官方参考实现。用自然语言提问:Agent 会把请求路由到已安装的技能,用原生表单补齐缺失信息,并实时展示运行的每一步。",
|
|
@@ -41870,23 +41717,18 @@ const chatbotDictionary = defineDictionary({
|
|
|
41870
41717
|
"vercel.preview.title": "Vercel AI SDK 数据契约",
|
|
41871
41718
|
"vercel.preview.badge": "预览",
|
|
41872
41719
|
"vercel.preview.description": "这是接入 Vercel AI SDK 时的数据契约——payload 预览,非完整运行时。交互以 JSON 而非表单呈现;点击取消结束本次交互。",
|
|
41720
|
+
"surface.legacy.placeholder": "旧版本生成的界面已不再渲染。",
|
|
41873
41721
|
"error.title": "出错了",
|
|
41874
41722
|
"error.suggestion": "请检查设置中的模型配置,或重试。",
|
|
41875
41723
|
"error.dismiss": "关闭"
|
|
41876
41724
|
}
|
|
41877
41725
|
});
|
|
41878
41726
|
const i18n = createI18n(chatbotDictionary);
|
|
41879
|
-
/** chatbot 组件取文案:t('welcome.title') / t('tool.summary.other', { count: 3 }) */
|
|
41727
|
+
/** chatbot 组件取文案:t('welcome.title') / t('tool.summary.other', { count: 3 }) @stable */
|
|
41880
41728
|
const useT = i18n.useT;
|
|
41881
41729
|
|
|
41882
41730
|
//#endregion
|
|
41883
41731
|
//#region src/react/A2uiSurfaceHost.tsx
|
|
41884
|
-
function usesBasicCatalog(snapshot) {
|
|
41885
|
-
return snapshot.surface.kind === "metric" || snapshot.surface.kind === "file" && !snapshot.surface.actions?.length;
|
|
41886
|
-
}
|
|
41887
|
-
function specProps(snapshot) {
|
|
41888
|
-
return snapshot.surface.props;
|
|
41889
|
-
}
|
|
41890
41732
|
/**
|
|
41891
41733
|
* A2UI 回落原因(0.2.8 G2)。
|
|
41892
41734
|
* 之前这里是裸 `catch {}`:缺 optional peer 与真实渲染崩溃表现完全一致——都是静默回落、
|
|
@@ -41905,17 +41747,20 @@ function fallbackReason(error) {
|
|
|
41905
41747
|
return typeof code === "string" && code !== "" ? code : "a2ui-render-failed";
|
|
41906
41748
|
}
|
|
41907
41749
|
/**
|
|
41908
|
-
* catalog 声明树经 BYOC catalog 的 Lit 元素渲染。
|
|
41750
|
+
* `a2ui` 档:catalog 声明树经 BYOC catalog 的 Lit 元素渲染。
|
|
41909
41751
|
* 元素与协议里公布的 `catalog_definition` 派生自同一份 shape,因此这里
|
|
41910
41752
|
* 不需要第二套映射;缺 optional peer 时回落到 native 渲染而不是留白。
|
|
41753
|
+
*
|
|
41754
|
+
* 交互请求(路径 A)与模型产出的 surface(路径 B)共用本组件——这是 0.4.0 B4
|
|
41755
|
+
* 「同一档下命中同一个渲染入口」的落点,`data-testid` 因此对两条路径一致。
|
|
41911
41756
|
*/
|
|
41912
|
-
function A2uiSpecSurface({
|
|
41757
|
+
function A2uiSpecSurface({ spec, surfaceId, actions, onAction, registry, runId, draft, onDraftChange }) {
|
|
41913
41758
|
const mountRef = useRef(null);
|
|
41914
41759
|
const [fallback, setFallback] = useState();
|
|
41915
41760
|
const emit = useEffectEvent((actionId, value) => {
|
|
41916
|
-
const declared = (
|
|
41761
|
+
const declared = (actions ?? []).find((action) => action.id === actionId);
|
|
41917
41762
|
onAction?.({
|
|
41918
|
-
surfaceId
|
|
41763
|
+
surfaceId,
|
|
41919
41764
|
actionId,
|
|
41920
41765
|
intent: declared?.intent ?? "select",
|
|
41921
41766
|
...declared?.nonce ? { nonce: declared.nonce } : {},
|
|
@@ -41925,7 +41770,7 @@ function A2uiSpecSurface({ snapshot, onAction }) {
|
|
|
41925
41770
|
useEffect(() => {
|
|
41926
41771
|
let disposed = false;
|
|
41927
41772
|
let surfaceElement;
|
|
41928
|
-
const
|
|
41773
|
+
const a2uiSurfaceId = `webskill-spec-${surfaceId}`;
|
|
41929
41774
|
(async () => {
|
|
41930
41775
|
try {
|
|
41931
41776
|
const [{ MessageProcessor }, lit, catalog] = await Promise.all([
|
|
@@ -41936,10 +41781,11 @@ function A2uiSpecSurface({ snapshot, onAction }) {
|
|
|
41936
41781
|
lit.A2uiSurface;
|
|
41937
41782
|
const mount = mountRef.current;
|
|
41938
41783
|
if (disposed || !mount) return;
|
|
41784
|
+
configureA2uiMarkdown(mount);
|
|
41939
41785
|
const processor = new MessageProcessor([catalog, lit.basicCatalog], (action) => {
|
|
41940
41786
|
const decoded = fromA2uiSpecAction(action);
|
|
41941
41787
|
if (!decoded) return;
|
|
41942
|
-
const values = processor.getClientDataModel("v0.9.1")?.surfaces?.[
|
|
41788
|
+
const values = processor.getClientDataModel("v0.9.1")?.surfaces?.[a2uiSurfaceId]?.[A2UI_SPEC_FORM_PATH.slice(1)];
|
|
41943
41789
|
emit(decoded.actionId, values ?? {});
|
|
41944
41790
|
}, { version: "v0.9.1" });
|
|
41945
41791
|
processor.onSurfaceCreated((surface) => {
|
|
@@ -41948,58 +41794,9 @@ function A2uiSpecSurface({ snapshot, onAction }) {
|
|
|
41948
41794
|
surfaceElement.surface = surface;
|
|
41949
41795
|
mount.replaceChildren(surfaceElement);
|
|
41950
41796
|
});
|
|
41951
|
-
processor.processMessages(toA2uiSpecMessages(uiCatalog,
|
|
41952
|
-
} catch (error) {
|
|
41953
|
-
reportA2uiFallback(snapshot.surface.id, "spec", error);
|
|
41954
|
-
if (!disposed) setFallback(fallbackReason(error));
|
|
41955
|
-
}
|
|
41956
|
-
})();
|
|
41957
|
-
return () => {
|
|
41958
|
-
disposed = true;
|
|
41959
|
-
surfaceElement?.remove();
|
|
41960
|
-
};
|
|
41961
|
-
}, [snapshot]);
|
|
41962
|
-
if (fallback) {
|
|
41963
|
-
const surface = snapshot.surface;
|
|
41964
|
-
return /* @__PURE__ */ jsx("div", {
|
|
41965
|
-
"data-testid": "a2ui-spec-surface",
|
|
41966
|
-
"data-renderer": "native-fallback",
|
|
41967
|
-
"data-fallback-reason": fallback,
|
|
41968
|
-
children: /* @__PURE__ */ jsx(NativeSpecSurface, {
|
|
41969
|
-
surfaceId: surface.id,
|
|
41970
|
-
spec: specProps(snapshot).spec,
|
|
41971
|
-
actions: surface.actions ?? [],
|
|
41972
|
-
...onAction ? { onAction } : {}
|
|
41973
|
-
})
|
|
41974
|
-
});
|
|
41975
|
-
}
|
|
41976
|
-
return /* @__PURE__ */ jsx("div", {
|
|
41977
|
-
ref: mountRef,
|
|
41978
|
-
"data-testid": "a2ui-spec-surface",
|
|
41979
|
-
"data-webskill-provenance": "a2ui-catalog"
|
|
41980
|
-
});
|
|
41981
|
-
}
|
|
41982
|
-
function A2uiStandardSurface({ snapshot, registry }) {
|
|
41983
|
-
const mountRef = useRef(null);
|
|
41984
|
-
const [fallback, setFallback] = useState();
|
|
41985
|
-
useEffect(() => {
|
|
41986
|
-
let disposed = false;
|
|
41987
|
-
let surfaceElement;
|
|
41988
|
-
(async () => {
|
|
41989
|
-
try {
|
|
41990
|
-
const [{ MessageProcessor }, { A2uiSurface, basicCatalog }] = await Promise.all([import("@a2ui/web_core/v0_9"), import("@a2ui/lit/v0_9")]);
|
|
41991
|
-
const mount = mountRef.current;
|
|
41992
|
-
if (disposed || !mount) return;
|
|
41993
|
-
const processor = new MessageProcessor([basicCatalog], () => void 0, { version: "v0.9.1" });
|
|
41994
|
-
processor.onSurfaceCreated((surface) => {
|
|
41995
|
-
if (disposed) return;
|
|
41996
|
-
surfaceElement = mount.ownerDocument.createElement("a2ui-surface");
|
|
41997
|
-
surfaceElement.surface = surface;
|
|
41998
|
-
mount.replaceChildren(surfaceElement);
|
|
41999
|
-
});
|
|
42000
|
-
processor.processMessages(toA2uiSurfaceMessages(snapshot));
|
|
41797
|
+
processor.processMessages(toA2uiSpecMessages(uiCatalog, spec, { surfaceId: a2uiSurfaceId }));
|
|
42001
41798
|
} catch (error) {
|
|
42002
|
-
reportA2uiFallback(
|
|
41799
|
+
reportA2uiFallback(surfaceId, "spec", error);
|
|
42003
41800
|
if (!disposed) setFallback(fallbackReason(error));
|
|
42004
41801
|
}
|
|
42005
41802
|
})();
|
|
@@ -42007,65 +41804,52 @@ function A2uiStandardSurface({ snapshot, registry }) {
|
|
|
42007
41804
|
disposed = true;
|
|
42008
41805
|
surfaceElement?.remove();
|
|
42009
41806
|
};
|
|
42010
|
-
}, [
|
|
41807
|
+
}, [spec, surfaceId]);
|
|
42011
41808
|
if (fallback) return /* @__PURE__ */ jsx("div", {
|
|
42012
|
-
"data-testid": "a2ui-
|
|
41809
|
+
"data-testid": "a2ui-spec-surface",
|
|
42013
41810
|
"data-renderer": "native-fallback",
|
|
42014
41811
|
"data-fallback-reason": fallback,
|
|
42015
|
-
children: /* @__PURE__ */ jsx(
|
|
42016
|
-
|
|
42017
|
-
|
|
41812
|
+
children: /* @__PURE__ */ jsx(NativeSpecSurface, {
|
|
41813
|
+
surfaceId,
|
|
41814
|
+
spec,
|
|
41815
|
+
actions: actions ?? [],
|
|
41816
|
+
...registry ? { registry } : {},
|
|
41817
|
+
...runId ? { runId } : {},
|
|
41818
|
+
...draft ? { draft } : {},
|
|
41819
|
+
...onAction ? { onAction } : {},
|
|
41820
|
+
...onDraftChange ? { onDraftChange } : {}
|
|
42018
41821
|
})
|
|
42019
41822
|
});
|
|
42020
41823
|
return /* @__PURE__ */ jsx("div", {
|
|
42021
41824
|
ref: mountRef,
|
|
42022
|
-
"data-testid": "a2ui-
|
|
42023
|
-
"data-webskill-provenance": "a2ui-
|
|
41825
|
+
"data-testid": "a2ui-spec-surface",
|
|
41826
|
+
"data-webskill-provenance": "a2ui-catalog"
|
|
42024
41827
|
});
|
|
42025
41828
|
}
|
|
42026
|
-
/** Renders persisted
|
|
41829
|
+
/** Renders persisted WebSkill UI spec snapshots through the A2UI BYOC catalog. @experimental */
|
|
42027
41830
|
function A2uiSurfaceSnapshotHost({ snapshots, registry, onAction, drafts, onDraftChange }) {
|
|
42028
|
-
const specSnapshots = snapshots.filter((snapshot) => isUiSpecSurface(snapshot.surface));
|
|
42029
|
-
const rest = snapshots.filter((snapshot) => !isUiSpecSurface(snapshot.surface));
|
|
42030
|
-
const standardSnapshots = rest.filter(usesBasicCatalog);
|
|
42031
|
-
const extensionSnapshots = rest.filter((snapshot) => !usesBasicCatalog(snapshot));
|
|
42032
41831
|
if (snapshots.length === 0) return null;
|
|
42033
|
-
return /* @__PURE__ */
|
|
41832
|
+
return /* @__PURE__ */ jsx("div", {
|
|
42034
41833
|
"data-testid": "a2ui-surface-host",
|
|
42035
|
-
children:
|
|
42036
|
-
|
|
42037
|
-
|
|
42038
|
-
|
|
42039
|
-
|
|
42040
|
-
|
|
42041
|
-
|
|
42042
|
-
|
|
42043
|
-
|
|
42044
|
-
|
|
42045
|
-
"data-testid": "a2ui-surface-extension",
|
|
42046
|
-
"data-webskill-provenance": "a2ui-extension",
|
|
42047
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
42048
|
-
className: "sr-only",
|
|
42049
|
-
children: "WebSkill extension"
|
|
42050
|
-
}), /* @__PURE__ */ jsx(UiSurfaceSnapshotList, {
|
|
42051
|
-
snapshots: extensionSnapshots,
|
|
42052
|
-
...registry ? { registry } : {},
|
|
42053
|
-
...onAction ? { onAction } : {},
|
|
42054
|
-
...drafts ? { drafts } : {},
|
|
42055
|
-
...onDraftChange ? { onDraftChange } : {}
|
|
42056
|
-
})]
|
|
42057
|
-
}) : null
|
|
42058
|
-
]
|
|
41834
|
+
children: snapshots.map((snapshot) => /* @__PURE__ */ jsx(A2uiSpecSurface, {
|
|
41835
|
+
surfaceId: snapshot.id,
|
|
41836
|
+
spec: snapshot.node,
|
|
41837
|
+
actions: snapshot.actions ?? [],
|
|
41838
|
+
registry,
|
|
41839
|
+
onAction,
|
|
41840
|
+
runId: snapshot.runId,
|
|
41841
|
+
draft: drafts?.[snapshot.id],
|
|
41842
|
+
onDraftChange
|
|
41843
|
+
}, snapshot.id))
|
|
42059
41844
|
});
|
|
42060
41845
|
}
|
|
42061
|
-
/** Renders
|
|
41846
|
+
/** Renders WebSkill UI spec snapshots from live bridge state through the A2UI BYOC catalog. @experimental */
|
|
42062
41847
|
function A2uiSurfaceHost({ bridge, runId, registry }) {
|
|
42063
41848
|
const snapshots = useSyncExternalStore(bridge.subscribe, () => bridge.surfaceSnapshots);
|
|
42064
41849
|
const visibleSnapshots = runId === void 0 ? snapshots : snapshots.filter((snapshot) => snapshot.runId === runId);
|
|
42065
|
-
const actionableSnapshots = visibleSnapshots.filter((snapshot) => isUiSpecSurface(snapshot.surface) || !usesBasicCatalog(snapshot));
|
|
42066
41850
|
const handleAction = (event) => {
|
|
42067
|
-
const snapshot =
|
|
42068
|
-
const action = snapshot
|
|
41851
|
+
const snapshot = visibleSnapshots.find((candidate) => candidate.id === event.surfaceId);
|
|
41852
|
+
const action = snapshot?.actions?.find((candidate) => candidate.id === event.actionId);
|
|
42069
41853
|
if (!snapshot || !action) return;
|
|
42070
41854
|
const decoded = fromA2uiSurfaceAction(toA2uiSurfaceAction(snapshot, action, event.value));
|
|
42071
41855
|
if (!decoded?.runId || !decoded.nonce) return;
|
|
@@ -42246,7 +42030,7 @@ function lifecyclePart(step) {
|
|
|
42246
42030
|
phase: step.phase,
|
|
42247
42031
|
at: step.at,
|
|
42248
42032
|
...step.endedAt !== void 0 ? { endedAt: step.endedAt } : {},
|
|
42249
|
-
...step.
|
|
42033
|
+
...step.note !== void 0 ? { note: step.note } : {}
|
|
42250
42034
|
}
|
|
42251
42035
|
};
|
|
42252
42036
|
}
|
|
@@ -42441,7 +42225,7 @@ function useWebSkillAui({ messages, live, sessions, currentSessionId, sessionsLo
|
|
|
42441
42225
|
//#region src/react/AssistantUiShell.tsx
|
|
42442
42226
|
/**
|
|
42443
42227
|
* assistant-ui only owns the React thread primitives. WebSkill remains the
|
|
42444
|
-
* source of truth for messages, sessions, Runtime actions, and
|
|
42228
|
+
* source of truth for messages, sessions, Runtime actions, and UI spec surface data.
|
|
42445
42229
|
*/
|
|
42446
42230
|
function AssistantUiShellProvider({ children, ...props }) {
|
|
42447
42231
|
return /* @__PURE__ */ jsx(AuiProvider, {
|
|
@@ -42452,15 +42236,23 @@ function AssistantUiShellProvider({ children, ...props }) {
|
|
|
42452
42236
|
children: /* @__PURE__ */ jsx(ThreadPrimitive.ViewportProvider, { children })
|
|
42453
42237
|
});
|
|
42454
42238
|
}
|
|
42455
|
-
function AssistantUiMessageList({ messages, renderMessage }) {
|
|
42239
|
+
function AssistantUiMessageList({ messages, earlier, renderMessage }) {
|
|
42240
|
+
const t = useT();
|
|
42456
42241
|
const byId = useMemo(() => new Map(messages.map((message) => [message.id, message])), [messages]);
|
|
42457
|
-
return /* @__PURE__ */
|
|
42242
|
+
return /* @__PURE__ */ jsxs(ThreadPrimitive.Root, {
|
|
42458
42243
|
"data-testid": "assistant-ui-thread",
|
|
42459
42244
|
className: "flex w-full min-w-0 flex-col gap-4",
|
|
42460
|
-
children:
|
|
42245
|
+
children: [earlier ? /* @__PURE__ */ jsx("button", {
|
|
42246
|
+
type: "button",
|
|
42247
|
+
"data-testid": "load-earlier-messages",
|
|
42248
|
+
disabled: earlier.loading,
|
|
42249
|
+
onClick: earlier.onLoad,
|
|
42250
|
+
className: "self-center rounded-md border border-border px-3 py-1.5 text-sm text-muted transition-colors hover:bg-subtle hover:text-ink disabled:opacity-60",
|
|
42251
|
+
children: earlier.loading ? t("session.loading") : t("message.loadEarlier")
|
|
42252
|
+
}) : null, /* @__PURE__ */ jsx(ThreadPrimitive.Messages, { children: ({ message }) => /* @__PURE__ */ jsx(MessagePrimitive.Root, {
|
|
42461
42253
|
"data-webskill-message-role": message.role,
|
|
42462
42254
|
children: renderMessage(byId.get(message.id))
|
|
42463
|
-
}) })
|
|
42255
|
+
}) })]
|
|
42464
42256
|
});
|
|
42465
42257
|
}
|
|
42466
42258
|
/** Uses assistant-ui's scroll and accessibility viewport for the controlled external thread. */
|
|
@@ -42550,12 +42342,85 @@ function AssistantUiComposer({ running, disabled = false, placeholder, attachmen
|
|
|
42550
42342
|
})
|
|
42551
42343
|
});
|
|
42552
42344
|
}
|
|
42345
|
+
/**
|
|
42346
|
+
* 一行会话。归档区与常规区共用:两边只差 archive/unarchive 一个按钮,
|
|
42347
|
+
* 各写一份迟早会漂。重命名走 `aui.threads.item()`——assistant-ui 没有 Rename primitive,
|
|
42348
|
+
* 但 threads 客户端有 `rename` 方法(ChatEngine.renameSession 的入口)。
|
|
42349
|
+
*/
|
|
42350
|
+
function SessionRow({ id, title, active, archived, renaming, onNavigate, onStartRename, onEndRename }) {
|
|
42351
|
+
const t = useT();
|
|
42352
|
+
const aui = useAui();
|
|
42353
|
+
const iconButton = "inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted opacity-0 transition-opacity group-hover:opacity-100 focus-visible:opacity-100 hover:bg-subtle hover:text-ink";
|
|
42354
|
+
const commitRename = (next) => {
|
|
42355
|
+
const trimmed = next.trim();
|
|
42356
|
+
if (trimmed !== "" && trimmed !== title) aui.threads.item({ id }).rename(trimmed);
|
|
42357
|
+
onEndRename();
|
|
42358
|
+
};
|
|
42359
|
+
return /* @__PURE__ */ jsxs(ThreadListItemPrimitive.Root, {
|
|
42360
|
+
role: "listitem",
|
|
42361
|
+
"data-webskill-session-archived": archived ? "true" : void 0,
|
|
42362
|
+
className: "group flex items-center gap-1",
|
|
42363
|
+
children: [renaming ? /* @__PURE__ */ jsx("input", {
|
|
42364
|
+
autoFocus: true,
|
|
42365
|
+
"aria-label": t("session.renameInput", { title }),
|
|
42366
|
+
defaultValue: title,
|
|
42367
|
+
onBlur: (event) => commitRename(event.target.value),
|
|
42368
|
+
onKeyDown: (event) => {
|
|
42369
|
+
if (event.key === "Enter") commitRename(event.currentTarget.value);
|
|
42370
|
+
if (event.key === "Escape") onEndRename();
|
|
42371
|
+
},
|
|
42372
|
+
className: "min-w-0 flex-1 rounded-md border border-input bg-background px-2.5 py-2 text-sm text-ink outline-none focus:border-ring"
|
|
42373
|
+
}) : /* @__PURE__ */ jsx(ThreadListItemPrimitive.Trigger, {
|
|
42374
|
+
"data-webskill-thread-id": id,
|
|
42375
|
+
"aria-current": active ? "page" : void 0,
|
|
42376
|
+
onClick: onNavigate,
|
|
42377
|
+
className: `min-w-0 flex-1 truncate rounded-md px-2.5 py-2 text-left text-sm transition-colors ${active ? "bg-subtle font-medium text-ink" : "text-muted hover:bg-subtle hover:text-ink"}`,
|
|
42378
|
+
children: /* @__PURE__ */ jsx(ThreadListItemPrimitive.Title, { fallback: id })
|
|
42379
|
+
}), renaming ? null : /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
42380
|
+
/* @__PURE__ */ jsx("button", {
|
|
42381
|
+
type: "button",
|
|
42382
|
+
"aria-label": t("session.rename", { title }),
|
|
42383
|
+
onClick: onStartRename,
|
|
42384
|
+
className: iconButton,
|
|
42385
|
+
children: /* @__PURE__ */ jsx(Pencil, {
|
|
42386
|
+
className: "size-3.5",
|
|
42387
|
+
"aria-hidden": true
|
|
42388
|
+
})
|
|
42389
|
+
}),
|
|
42390
|
+
archived ? /* @__PURE__ */ jsx(ThreadListItemPrimitive.Unarchive, {
|
|
42391
|
+
"aria-label": t("session.unarchive", { title }),
|
|
42392
|
+
className: iconButton,
|
|
42393
|
+
children: /* @__PURE__ */ jsx(ArchiveRestore, {
|
|
42394
|
+
className: "size-3.5",
|
|
42395
|
+
"aria-hidden": true
|
|
42396
|
+
})
|
|
42397
|
+
}) : /* @__PURE__ */ jsx(ThreadListItemPrimitive.Archive, {
|
|
42398
|
+
"aria-label": t("session.archive", { title }),
|
|
42399
|
+
className: iconButton,
|
|
42400
|
+
children: /* @__PURE__ */ jsx(Archive, {
|
|
42401
|
+
className: "size-3.5",
|
|
42402
|
+
"aria-hidden": true
|
|
42403
|
+
})
|
|
42404
|
+
}),
|
|
42405
|
+
/* @__PURE__ */ jsx(ThreadListItemPrimitive.Delete, {
|
|
42406
|
+
"aria-label": t("session.delete", { title }),
|
|
42407
|
+
className: `${iconButton} hover:bg-danger-soft hover:text-danger`,
|
|
42408
|
+
children: /* @__PURE__ */ jsx(Trash2, {
|
|
42409
|
+
className: "size-3.5",
|
|
42410
|
+
"aria-hidden": true
|
|
42411
|
+
})
|
|
42412
|
+
})
|
|
42413
|
+
] })]
|
|
42414
|
+
});
|
|
42415
|
+
}
|
|
42553
42416
|
/** Sessions are read through the assistant-ui threads client, which ChatEngine drives. */
|
|
42554
|
-
function AssistantUiSessionList({ className = "", onNavigate }) {
|
|
42417
|
+
function AssistantUiSessionList({ className = "", onNavigate, hasEarlier = false, loadingEarlier = false, onLoadEarlier }) {
|
|
42555
42418
|
const t = useT();
|
|
42556
42419
|
const [query, setQuery] = useState("");
|
|
42420
|
+
const [renamingId, setRenamingId] = useState();
|
|
42557
42421
|
const normalizedQuery = query.trim().toLocaleLowerCase();
|
|
42558
42422
|
const threadIds = useAuiState((s) => s.threads.threadIds);
|
|
42423
|
+
const archivedThreadIds = useAuiState((s) => s.threads.archivedThreadIds);
|
|
42559
42424
|
const threadItems = useAuiState((s) => s.threads.threadItems);
|
|
42560
42425
|
const mainThreadId = useAuiState((s) => s.threads.mainThreadId);
|
|
42561
42426
|
const matches = useMemo(() => {
|
|
@@ -42565,6 +42430,7 @@ function AssistantUiSessionList({ className = "", onNavigate }) {
|
|
|
42565
42430
|
};
|
|
42566
42431
|
}, [threadItems, normalizedQuery]);
|
|
42567
42432
|
const visibleCount = threadIds.filter(matches).length;
|
|
42433
|
+
const visibleArchivedCount = archivedThreadIds.filter(matches).length;
|
|
42568
42434
|
return /* @__PURE__ */ jsxs(ThreadListPrimitive.Root, {
|
|
42569
42435
|
"data-testid": "assistant-ui-thread-list",
|
|
42570
42436
|
"aria-label": t("session.title"),
|
|
@@ -42600,32 +42466,53 @@ function AssistantUiSessionList({ className = "", onNavigate }) {
|
|
|
42600
42466
|
/* @__PURE__ */ jsxs("div", {
|
|
42601
42467
|
className: "min-h-0 flex-1 overflow-y-auto px-2 pb-3",
|
|
42602
42468
|
role: "list",
|
|
42603
|
-
children: [
|
|
42604
|
-
|
|
42605
|
-
|
|
42606
|
-
|
|
42607
|
-
|
|
42608
|
-
|
|
42609
|
-
|
|
42610
|
-
|
|
42611
|
-
|
|
42612
|
-
|
|
42613
|
-
|
|
42614
|
-
|
|
42615
|
-
|
|
42616
|
-
|
|
42617
|
-
|
|
42618
|
-
|
|
42619
|
-
|
|
42620
|
-
|
|
42621
|
-
|
|
42622
|
-
|
|
42623
|
-
|
|
42624
|
-
|
|
42625
|
-
|
|
42626
|
-
|
|
42627
|
-
|
|
42628
|
-
|
|
42469
|
+
children: [
|
|
42470
|
+
hasEarlier && onLoadEarlier ? /* @__PURE__ */ jsx("button", {
|
|
42471
|
+
type: "button",
|
|
42472
|
+
"data-testid": "load-earlier-sessions",
|
|
42473
|
+
disabled: loadingEarlier,
|
|
42474
|
+
onClick: onLoadEarlier,
|
|
42475
|
+
className: "mb-1 w-full rounded-md px-2.5 py-2 text-sm text-muted transition-colors hover:bg-subtle hover:text-ink disabled:opacity-60",
|
|
42476
|
+
children: loadingEarlier ? t("session.loading") : t("session.loadEarlier")
|
|
42477
|
+
}) : null,
|
|
42478
|
+
visibleCount === 0 ? /* @__PURE__ */ jsx("p", {
|
|
42479
|
+
className: "px-2 py-4 text-sm text-muted",
|
|
42480
|
+
children: t("session.empty")
|
|
42481
|
+
}) : null,
|
|
42482
|
+
/* @__PURE__ */ jsx(ThreadListPrimitive.Items, { children: ({ threadListItem }) => {
|
|
42483
|
+
if (!matches(threadListItem.id)) return null;
|
|
42484
|
+
return /* @__PURE__ */ jsx(SessionRow, {
|
|
42485
|
+
id: threadListItem.id,
|
|
42486
|
+
title: threadListItem.title ?? threadListItem.id,
|
|
42487
|
+
active: threadListItem.id === mainThreadId,
|
|
42488
|
+
archived: false,
|
|
42489
|
+
renaming: renamingId === threadListItem.id,
|
|
42490
|
+
onNavigate,
|
|
42491
|
+
onStartRename: () => setRenamingId(threadListItem.id),
|
|
42492
|
+
onEndRename: () => setRenamingId(void 0)
|
|
42493
|
+
});
|
|
42494
|
+
} }),
|
|
42495
|
+
visibleArchivedCount > 0 ? /* @__PURE__ */ jsx("p", {
|
|
42496
|
+
className: "px-2.5 pb-1 pt-4 text-xs font-medium uppercase tracking-wide text-muted",
|
|
42497
|
+
children: t("session.archived")
|
|
42498
|
+
}) : null,
|
|
42499
|
+
/* @__PURE__ */ jsx(ThreadListPrimitive.Items, {
|
|
42500
|
+
archived: true,
|
|
42501
|
+
children: ({ threadListItem }) => {
|
|
42502
|
+
if (!matches(threadListItem.id)) return null;
|
|
42503
|
+
return /* @__PURE__ */ jsx(SessionRow, {
|
|
42504
|
+
id: threadListItem.id,
|
|
42505
|
+
title: threadListItem.title ?? threadListItem.id,
|
|
42506
|
+
active: threadListItem.id === mainThreadId,
|
|
42507
|
+
archived: true,
|
|
42508
|
+
renaming: renamingId === threadListItem.id,
|
|
42509
|
+
onNavigate,
|
|
42510
|
+
onStartRename: () => setRenamingId(threadListItem.id),
|
|
42511
|
+
onEndRename: () => setRenamingId(void 0)
|
|
42512
|
+
});
|
|
42513
|
+
}
|
|
42514
|
+
})
|
|
42515
|
+
]
|
|
42629
42516
|
})
|
|
42630
42517
|
]
|
|
42631
42518
|
});
|
|
@@ -42805,8 +42692,7 @@ function LifecycleStep({ data }) {
|
|
|
42805
42692
|
const at = typeof data["at"] === "number" ? data["at"] : void 0;
|
|
42806
42693
|
const endedAt = typeof data["endedAt"] === "number" ? data["endedAt"] : void 0;
|
|
42807
42694
|
const duration = at !== void 0 && endedAt !== void 0 ? formatDuration(endedAt - at) : void 0;
|
|
42808
|
-
const
|
|
42809
|
-
const note = readString(detail, "strategy") ?? readString(detail, "type") ?? readString(detail, "reason");
|
|
42695
|
+
const note = readString(data, "note");
|
|
42810
42696
|
const label = t(key);
|
|
42811
42697
|
return /* @__PURE__ */ jsxs("li", {
|
|
42812
42698
|
"aria-label": duration ? `${label}, ${duration}` : label,
|
|
@@ -42978,279 +42864,18 @@ function WebSkillMessageParts() {
|
|
|
42978
42864
|
});
|
|
42979
42865
|
}
|
|
42980
42866
|
|
|
42981
|
-
//#endregion
|
|
42982
|
-
//#region src/react/OpenUiInteraction.tsx
|
|
42983
|
-
const inputClass = "w-full rounded-lg border border-border bg-surface px-3 py-2 text-sm text-ink transition-colors placeholder:text-muted hover:border-ring";
|
|
42984
|
-
/**
|
|
42985
|
-
* openui-lang 组件词汇的 ui-kit 视觉实现(与 @webskill/ui toOpenUiLang 的约定一致:
|
|
42986
|
-
* Form/Text/TextField/NumberField/BooleanField/SelectField/SubmitButton/CancelButton)。
|
|
42987
|
-
* 视觉对齐 native InteractionCard 的表单样式。
|
|
42988
|
-
*/
|
|
42989
|
-
function buildOpenUiLibrary(openui, z, options = {}) {
|
|
42990
|
-
const { defineComponent, createLibrary, useStateField, useTriggerAction } = openui;
|
|
42991
|
-
const requiredMark = (required) => required ? /* @__PURE__ */ jsx("span", {
|
|
42992
|
-
className: "text-danger",
|
|
42993
|
-
children: " *"
|
|
42994
|
-
}) : null;
|
|
42995
|
-
const TextField = defineComponent({
|
|
42996
|
-
name: "TextField",
|
|
42997
|
-
description: "text input",
|
|
42998
|
-
props: z.object({
|
|
42999
|
-
name: z.string(),
|
|
43000
|
-
label: z.string().optional(),
|
|
43001
|
-
required: z.boolean().optional(),
|
|
43002
|
-
defaultValue: z.string().nullable().optional()
|
|
43003
|
-
}),
|
|
43004
|
-
component: function TextFieldRenderer({ props }) {
|
|
43005
|
-
const field = useStateField(props.name, props.defaultValue ?? "");
|
|
43006
|
-
return /* @__PURE__ */ jsxs("label", {
|
|
43007
|
-
className: "flex flex-col gap-1 text-sm text-ink",
|
|
43008
|
-
children: [/* @__PURE__ */ jsxs("span", { children: [props.label ?? props.name, requiredMark(props.required)] }), /* @__PURE__ */ jsx("input", {
|
|
43009
|
-
className: inputClass,
|
|
43010
|
-
value: String(field.value ?? ""),
|
|
43011
|
-
onChange: (e) => field.setValue(e.target.value)
|
|
43012
|
-
})]
|
|
43013
|
-
});
|
|
43014
|
-
}
|
|
43015
|
-
});
|
|
43016
|
-
const NumberField = defineComponent({
|
|
43017
|
-
name: "NumberField",
|
|
43018
|
-
description: "number input",
|
|
43019
|
-
props: z.object({
|
|
43020
|
-
name: z.string(),
|
|
43021
|
-
label: z.string().optional(),
|
|
43022
|
-
required: z.boolean().optional()
|
|
43023
|
-
}),
|
|
43024
|
-
component: function NumberFieldRenderer({ props }) {
|
|
43025
|
-
const field = useStateField(props.name, null);
|
|
43026
|
-
return /* @__PURE__ */ jsxs("label", {
|
|
43027
|
-
className: "flex flex-col gap-1 text-sm text-ink",
|
|
43028
|
-
children: [/* @__PURE__ */ jsxs("span", { children: [props.label ?? props.name, requiredMark(props.required)] }), /* @__PURE__ */ jsx("input", {
|
|
43029
|
-
type: "number",
|
|
43030
|
-
className: inputClass,
|
|
43031
|
-
value: field.value === void 0 || field.value === null ? "" : String(field.value),
|
|
43032
|
-
onChange: (e) => field.setValue(e.target.value === "" ? void 0 : Number(e.target.value))
|
|
43033
|
-
})]
|
|
43034
|
-
});
|
|
43035
|
-
}
|
|
43036
|
-
});
|
|
43037
|
-
const BooleanField = defineComponent({
|
|
43038
|
-
name: "BooleanField",
|
|
43039
|
-
description: "checkbox",
|
|
43040
|
-
props: z.object({
|
|
43041
|
-
name: z.string(),
|
|
43042
|
-
label: z.string().optional(),
|
|
43043
|
-
defaultValue: z.boolean().optional()
|
|
43044
|
-
}),
|
|
43045
|
-
component: function BooleanFieldRenderer({ props }) {
|
|
43046
|
-
const field = useStateField(props.name, props.defaultValue ?? false);
|
|
43047
|
-
return /* @__PURE__ */ jsxs("label", {
|
|
43048
|
-
className: "flex items-center gap-2 text-sm text-ink",
|
|
43049
|
-
children: [/* @__PURE__ */ jsx("input", {
|
|
43050
|
-
type: "checkbox",
|
|
43051
|
-
className: "size-4 accent-primary",
|
|
43052
|
-
checked: field.value === true,
|
|
43053
|
-
onChange: (e) => field.setValue(e.target.checked)
|
|
43054
|
-
}), /* @__PURE__ */ jsx("span", { children: props.label ?? props.name })]
|
|
43055
|
-
});
|
|
43056
|
-
}
|
|
43057
|
-
});
|
|
43058
|
-
const SelectField = defineComponent({
|
|
43059
|
-
name: "SelectField",
|
|
43060
|
-
description: "select input",
|
|
43061
|
-
props: z.object({
|
|
43062
|
-
name: z.string(),
|
|
43063
|
-
label: z.string().optional(),
|
|
43064
|
-
options: z.array(z.object({
|
|
43065
|
-
label: z.string(),
|
|
43066
|
-
value: z.unknown()
|
|
43067
|
-
}))
|
|
43068
|
-
}),
|
|
43069
|
-
component: function SelectFieldRenderer({ props }) {
|
|
43070
|
-
const field = useStateField(props.name, props.options[0]?.value ?? "");
|
|
43071
|
-
return /* @__PURE__ */ jsxs("label", {
|
|
43072
|
-
className: "flex flex-col gap-1 text-sm text-ink",
|
|
43073
|
-
children: [/* @__PURE__ */ jsx("span", { children: props.label ?? props.name }), /* @__PURE__ */ jsx("select", {
|
|
43074
|
-
className: inputClass,
|
|
43075
|
-
value: JSON.stringify(field.value ?? ""),
|
|
43076
|
-
onChange: (e) => field.setValue(JSON.parse(e.target.value)),
|
|
43077
|
-
children: props.options.map((option, i) => /* @__PURE__ */ jsx("option", {
|
|
43078
|
-
value: JSON.stringify(option.value),
|
|
43079
|
-
children: option.label
|
|
43080
|
-
}, i))
|
|
43081
|
-
})]
|
|
43082
|
-
});
|
|
43083
|
-
}
|
|
43084
|
-
});
|
|
43085
|
-
const SubmitButton = defineComponent({
|
|
43086
|
-
name: "SubmitButton",
|
|
43087
|
-
description: "submit button",
|
|
43088
|
-
props: z.object({
|
|
43089
|
-
label: z.string(),
|
|
43090
|
-
actionType: z.string(),
|
|
43091
|
-
requestId: z.string()
|
|
43092
|
-
}),
|
|
43093
|
-
component: function SubmitButtonRenderer({ props }) {
|
|
43094
|
-
const trigger = useTriggerAction();
|
|
43095
|
-
return /* @__PURE__ */ jsx(Button, {
|
|
43096
|
-
onClick: () => void trigger(props.label, void 0, {
|
|
43097
|
-
type: props.actionType,
|
|
43098
|
-
params: { id: props.requestId }
|
|
43099
|
-
}),
|
|
43100
|
-
children: props.label
|
|
43101
|
-
});
|
|
43102
|
-
}
|
|
43103
|
-
});
|
|
43104
|
-
const CancelButton = defineComponent({
|
|
43105
|
-
name: "CancelButton",
|
|
43106
|
-
description: "cancel button",
|
|
43107
|
-
props: z.object({
|
|
43108
|
-
label: z.string(),
|
|
43109
|
-
actionType: z.string(),
|
|
43110
|
-
requestId: z.string()
|
|
43111
|
-
}),
|
|
43112
|
-
component: function CancelButtonRenderer({ props }) {
|
|
43113
|
-
const trigger = useTriggerAction();
|
|
43114
|
-
return /* @__PURE__ */ jsx(Button, {
|
|
43115
|
-
variant: "secondary",
|
|
43116
|
-
onClick: () => void trigger(props.label, void 0, {
|
|
43117
|
-
type: props.actionType,
|
|
43118
|
-
params: { id: props.requestId }
|
|
43119
|
-
}),
|
|
43120
|
-
children: props.label
|
|
43121
|
-
});
|
|
43122
|
-
}
|
|
43123
|
-
});
|
|
43124
|
-
const Text = defineComponent({
|
|
43125
|
-
name: "Text",
|
|
43126
|
-
description: "plain display text",
|
|
43127
|
-
props: z.object({ content: z.string() }),
|
|
43128
|
-
component: function TextRenderer({ props }) {
|
|
43129
|
-
return /* @__PURE__ */ jsx("p", {
|
|
43130
|
-
className: "text-sm break-words text-muted",
|
|
43131
|
-
children: props.content
|
|
43132
|
-
});
|
|
43133
|
-
}
|
|
43134
|
-
});
|
|
43135
|
-
const components = [
|
|
43136
|
-
defineComponent({
|
|
43137
|
-
name: "Form",
|
|
43138
|
-
description: "form container",
|
|
43139
|
-
props: z.object({
|
|
43140
|
-
title: z.string().nullable().optional(),
|
|
43141
|
-
children: z.array(z.any()).optional()
|
|
43142
|
-
}),
|
|
43143
|
-
component: function FormRenderer({ props, renderNode }) {
|
|
43144
|
-
return /* @__PURE__ */ jsxs("form", {
|
|
43145
|
-
className: "flex flex-col gap-3",
|
|
43146
|
-
onSubmit: (e) => {
|
|
43147
|
-
e.preventDefault();
|
|
43148
|
-
},
|
|
43149
|
-
children: [props.title ? /* @__PURE__ */ jsx("h3", {
|
|
43150
|
-
className: "font-display text-sm font-semibold text-ink",
|
|
43151
|
-
children: props.title
|
|
43152
|
-
}) : null, (props.children ?? []).map((child, i) => /* @__PURE__ */ jsx("div", { children: renderNode(child) }, i))]
|
|
43153
|
-
});
|
|
43154
|
-
}
|
|
43155
|
-
}),
|
|
43156
|
-
Text,
|
|
43157
|
-
TextField,
|
|
43158
|
-
NumberField,
|
|
43159
|
-
BooleanField,
|
|
43160
|
-
SelectField,
|
|
43161
|
-
SubmitButton,
|
|
43162
|
-
CancelButton
|
|
43163
|
-
];
|
|
43164
|
-
if (options.onSurfaceAction) {
|
|
43165
|
-
const WebSkillSurfaceHost = defineComponent({
|
|
43166
|
-
name: "WebSkillSurfaceHost",
|
|
43167
|
-
description: "controlled WebSkill structured UI surface",
|
|
43168
|
-
props: z.object({ descriptor: z.any() }),
|
|
43169
|
-
component: function WebSkillSurfaceHostRenderer({ props }) {
|
|
43170
|
-
if (props.descriptor?.type !== "webskill-surface") return null;
|
|
43171
|
-
return /* @__PURE__ */ jsx("div", {
|
|
43172
|
-
"data-webskill-provenance": props.descriptor.provenance,
|
|
43173
|
-
children: /* @__PURE__ */ jsx(UiSurfaceSnapshotList, {
|
|
43174
|
-
snapshots: [props.descriptor.snapshot],
|
|
43175
|
-
...options.registry ? { registry: options.registry } : {},
|
|
43176
|
-
onAction: options.onSurfaceAction,
|
|
43177
|
-
...options.drafts ? { drafts: options.drafts } : {},
|
|
43178
|
-
...options.onSurfaceDraftChange ? { onDraftChange: options.onSurfaceDraftChange } : {}
|
|
43179
|
-
})
|
|
43180
|
-
});
|
|
43181
|
-
}
|
|
43182
|
-
});
|
|
43183
|
-
components.push(WebSkillSurfaceHost);
|
|
43184
|
-
}
|
|
43185
|
-
return createLibrary({
|
|
43186
|
-
components,
|
|
43187
|
-
root: options.root ?? "Form"
|
|
43188
|
-
});
|
|
43189
|
-
}
|
|
43190
|
-
/**
|
|
43191
|
-
* openui 档交互视图:订阅 OpenUiChannel(core 产出 openui-lang 文本),动态加载
|
|
43192
|
-
* optional peer @openuidev/react-lang 的 Renderer 渲染;动作事件回传 channel.handleAction。
|
|
43193
|
-
* 模块加载失败 → channel.fail(桥粘性降级 native,InteractionCard 接管)。
|
|
43194
|
-
*/
|
|
43195
|
-
function OpenUiInteraction({ channel }) {
|
|
43196
|
-
const session = useSyncExternalStore(channel.subscribe, () => channel.current);
|
|
43197
|
-
const [ready, setReady] = useState();
|
|
43198
|
-
useEffect(() => {
|
|
43199
|
-
channel.attach();
|
|
43200
|
-
return () => channel.detach();
|
|
43201
|
-
}, [channel]);
|
|
43202
|
-
useEffect(() => {
|
|
43203
|
-
let cancelled = false;
|
|
43204
|
-
(async () => {
|
|
43205
|
-
try {
|
|
43206
|
-
const { openui, z } = await loadOpenUiPeers();
|
|
43207
|
-
if (!cancelled) setReady({
|
|
43208
|
-
Renderer: openui.Renderer,
|
|
43209
|
-
library: buildOpenUiLibrary(openui, z)
|
|
43210
|
-
});
|
|
43211
|
-
} catch (e) {
|
|
43212
|
-
if (!cancelled) channel.fail(messageOf(e));
|
|
43213
|
-
}
|
|
43214
|
-
})();
|
|
43215
|
-
return () => {
|
|
43216
|
-
cancelled = true;
|
|
43217
|
-
};
|
|
43218
|
-
}, [channel]);
|
|
43219
|
-
if (!session || !ready) return null;
|
|
43220
|
-
const { Renderer, library } = ready;
|
|
43221
|
-
return /* @__PURE__ */ jsx("div", {
|
|
43222
|
-
"data-testid": "openui-interaction",
|
|
43223
|
-
className: "rounded-card border border-border bg-surface px-4 py-4 shadow-card",
|
|
43224
|
-
children: /* @__PURE__ */ jsx(Renderer, {
|
|
43225
|
-
response: session.lang,
|
|
43226
|
-
library,
|
|
43227
|
-
onAction: (action) => channel.handleAction(action)
|
|
43228
|
-
})
|
|
43229
|
-
});
|
|
43230
|
-
}
|
|
43231
|
-
|
|
43232
42867
|
//#endregion
|
|
43233
42868
|
//#region src/react/OpenUiSurfaceHost.tsx
|
|
43234
|
-
/** Renders persisted
|
|
43235
|
-
function OpenUiSurfaceSnapshotHost({ snapshots,
|
|
43236
|
-
const [ready, setReady] = useState();
|
|
42869
|
+
/** Renders persisted UI spec snapshots through the OpenUI extension without a live bridge. @experimental */
|
|
42870
|
+
function OpenUiSurfaceSnapshotHost({ snapshots, onAction }) {
|
|
42871
|
+
const [ready, setReady] = useState(false);
|
|
43237
42872
|
const [fallbackReason, setFallbackReason] = useState();
|
|
43238
|
-
const emitAction = useEffectEvent((event) => onAction?.(event));
|
|
43239
42873
|
useEffect(() => {
|
|
43240
42874
|
let cancelled = false;
|
|
43241
42875
|
(async () => {
|
|
43242
42876
|
try {
|
|
43243
|
-
|
|
43244
|
-
if (!cancelled) setReady(
|
|
43245
|
-
Renderer: openui.Renderer,
|
|
43246
|
-
library: buildOpenUiLibrary(openui, z, {
|
|
43247
|
-
root: "WebSkillSurfaceHost",
|
|
43248
|
-
...registry ? { registry } : {},
|
|
43249
|
-
onSurfaceAction: emitAction,
|
|
43250
|
-
...drafts ? { drafts } : {},
|
|
43251
|
-
...onDraftChange ? { onSurfaceDraftChange: onDraftChange } : {}
|
|
43252
|
-
})
|
|
43253
|
-
});
|
|
42877
|
+
await loadOpenUiPeers();
|
|
42878
|
+
if (!cancelled) setReady(true);
|
|
43254
42879
|
} catch (error) {
|
|
43255
42880
|
const reason = error?.code === "UI_UNAVAILABLE" ? "openui-peer-missing" : "openui-load-failed";
|
|
43256
42881
|
if (reason !== "openui-peer-missing") console.warn("[webskill] OpenUI renderer unavailable, falling back to native", { error });
|
|
@@ -43260,63 +42885,40 @@ function OpenUiSurfaceSnapshotHost({ snapshots, registry, onAction, drafts, onDr
|
|
|
43260
42885
|
return () => {
|
|
43261
42886
|
cancelled = true;
|
|
43262
42887
|
};
|
|
43263
|
-
}, [
|
|
42888
|
+
}, []);
|
|
43264
42889
|
if (snapshots.length === 0) return null;
|
|
43265
|
-
|
|
43266
|
-
const legacy = snapshots.filter((snapshot) => !isUiSpecSurface(snapshot.surface));
|
|
43267
|
-
const specNodes = specs.map((snapshot) => {
|
|
43268
|
-
const surface = snapshot.surface;
|
|
43269
|
-
return /* @__PURE__ */ jsx(OpenUiSpecSurface, { spec: surface.props.spec }, surface.id);
|
|
43270
|
-
});
|
|
43271
|
-
if (!ready) return /* @__PURE__ */ jsxs("div", {
|
|
42890
|
+
return /* @__PURE__ */ jsx("div", {
|
|
43272
42891
|
"data-testid": "openui-surface-host",
|
|
43273
|
-
"data-renderer": "native-fallback",
|
|
42892
|
+
"data-renderer": ready ? "openui" : "native-fallback",
|
|
43274
42893
|
...fallbackReason ? { "data-fallback-reason": fallbackReason } : {},
|
|
43275
|
-
children:
|
|
43276
|
-
|
|
43277
|
-
|
|
43278
|
-
|
|
43279
|
-
...
|
|
43280
|
-
|
|
43281
|
-
}) : null]
|
|
43282
|
-
});
|
|
43283
|
-
const { Renderer, library } = ready;
|
|
43284
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
43285
|
-
"data-testid": "openui-surface-host",
|
|
43286
|
-
"data-renderer": "openui",
|
|
43287
|
-
children: [specNodes, legacy.map((snapshot) => /* @__PURE__ */ jsx(Renderer, {
|
|
43288
|
-
response: toOpenUiSurfaceLang(snapshot),
|
|
43289
|
-
library
|
|
43290
|
-
}, snapshot.surface.id))]
|
|
42894
|
+
children: snapshots.map((snapshot) => /* @__PURE__ */ jsx(OpenUiSpecSurface, {
|
|
42895
|
+
spec: snapshot.node,
|
|
42896
|
+
surfaceId: snapshot.id,
|
|
42897
|
+
actions: snapshot.actions ?? [],
|
|
42898
|
+
...onAction ? { onAction } : {}
|
|
42899
|
+
}, snapshot.id))
|
|
43291
42900
|
});
|
|
43292
42901
|
}
|
|
43293
|
-
/** Renders
|
|
43294
|
-
function OpenUiSurfaceHost({ bridge, runId
|
|
42902
|
+
/** Renders WebSkill UI spec snapshots through an OpenUI library extension. @experimental */
|
|
42903
|
+
function OpenUiSurfaceHost({ bridge, runId }) {
|
|
43295
42904
|
const snapshots = useSyncExternalStore(bridge.subscribe, () => bridge.surfaceSnapshots);
|
|
43296
42905
|
const visibleSnapshots = runId === void 0 ? snapshots : snapshots.filter((snapshot) => snapshot.runId === runId);
|
|
43297
42906
|
const handleAction = (event) => {
|
|
43298
|
-
const
|
|
43299
|
-
|
|
43300
|
-
|
|
43301
|
-
});
|
|
43302
|
-
if (!action?.runId || !action.nonce) return;
|
|
42907
|
+
const snapshot = visibleSnapshots.find((candidate) => candidate.id === event.surfaceId);
|
|
42908
|
+
const capability = snapshot?.actions?.find((candidate) => candidate.id === event.actionId);
|
|
42909
|
+
if (!snapshot?.runId || !capability?.nonce) return;
|
|
43303
42910
|
bridge.resolveSurfaceAction({
|
|
43304
|
-
runId:
|
|
43305
|
-
surfaceId:
|
|
43306
|
-
actionId:
|
|
43307
|
-
intent:
|
|
43308
|
-
nonce:
|
|
43309
|
-
...
|
|
43310
|
-
...action.cancelled ? { cancelled: true } : {}
|
|
42911
|
+
runId: snapshot.runId,
|
|
42912
|
+
surfaceId: event.surfaceId,
|
|
42913
|
+
actionId: event.actionId,
|
|
42914
|
+
intent: event.intent,
|
|
42915
|
+
nonce: capability.nonce,
|
|
42916
|
+
...event.value ? { value: event.value } : {}
|
|
43311
42917
|
});
|
|
43312
42918
|
};
|
|
43313
|
-
const drafts = runId ? bridge.surfaceDrafts(runId) : {};
|
|
43314
42919
|
return /* @__PURE__ */ jsx(OpenUiSurfaceSnapshotHost, {
|
|
43315
42920
|
snapshots: visibleSnapshots,
|
|
43316
|
-
|
|
43317
|
-
onAction: handleAction,
|
|
43318
|
-
drafts,
|
|
43319
|
-
onDraftChange: (event) => bridge.setSurfaceDraft(event.runId, event.surfaceId, event.value)
|
|
42921
|
+
onAction: handleAction
|
|
43320
42922
|
});
|
|
43321
42923
|
}
|
|
43322
42924
|
|
|
@@ -53394,6 +52996,7 @@ function Block({ block, runId, onDownload }) {
|
|
|
53394
52996
|
/**
|
|
53395
52997
|
* 结果块列表(AnimatePresence 逐块入场):markdown / json / table / chart / image / file。
|
|
53396
52998
|
* 历史消息(ChatMessage.blocks)与当前 run(ResultBlocksPro)共用的渲染形态。
|
|
52999
|
+
* @stable
|
|
53397
53000
|
*/
|
|
53398
53001
|
function ResultBlockList({ blocks, runId, onDownload }) {
|
|
53399
53002
|
return /* @__PURE__ */ jsx(AnimatePresence, {
|
|
@@ -53415,6 +53018,7 @@ function ResultBlockList({ blocks, runId, onDownload }) {
|
|
|
53415
53018
|
/**
|
|
53416
53019
|
* run 完成结果块渐进挂载(AnimatePresence 逐块入场):
|
|
53417
53020
|
* markdown / json / table / chart / image / file + artifact 下载卡。
|
|
53021
|
+
* @stable
|
|
53418
53022
|
*/
|
|
53419
53023
|
function ResultBlocksPro({ bridge, activeRunId, onDownload }) {
|
|
53420
53024
|
const t = useT();
|
|
@@ -53457,7 +53061,7 @@ function ResultBlocksPro({ bridge, activeRunId, onDownload }) {
|
|
|
53457
53061
|
|
|
53458
53062
|
//#endregion
|
|
53459
53063
|
//#region src/react/SkillBadges.tsx
|
|
53460
|
-
/** 消息底部展示该 run 激活的技能名徽章(无技能不渲染) */
|
|
53064
|
+
/** 消息底部展示该 run 激活的技能名徽章(无技能不渲染) @stable */
|
|
53461
53065
|
function SkillBadges({ skills }) {
|
|
53462
53066
|
const t = useT();
|
|
53463
53067
|
if (skills.length === 0) return null;
|
|
@@ -53483,56 +53087,42 @@ function SkillBadges({ skills }) {
|
|
|
53483
53087
|
|
|
53484
53088
|
//#endregion
|
|
53485
53089
|
//#region src/react/VercelSurfaceHost.tsx
|
|
53486
|
-
/** Renders persisted
|
|
53487
|
-
function VercelSurfaceSnapshotHost({ snapshots,
|
|
53488
|
-
|
|
53489
|
-
|
|
53490
|
-
const specs = dataParts.filter((part) => isUiSpecSurface(part.data.snapshot.surface));
|
|
53491
|
-
const legacy = dataParts.filter((part) => !isUiSpecSurface(part.data.snapshot.surface));
|
|
53492
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
53090
|
+
/** Renders persisted UI spec snapshots through the json-render registry without a live bridge. @experimental */
|
|
53091
|
+
function VercelSurfaceSnapshotHost({ snapshots, onAction }) {
|
|
53092
|
+
if (snapshots.length === 0) return null;
|
|
53093
|
+
return /* @__PURE__ */ jsx("div", {
|
|
53493
53094
|
"data-testid": "vercel-surface-snapshot-host",
|
|
53494
|
-
"data-surface-parts":
|
|
53495
|
-
children:
|
|
53496
|
-
|
|
53497
|
-
|
|
53498
|
-
|
|
53499
|
-
|
|
53500
|
-
|
|
53501
|
-
...onAction ? { onAction } : {},
|
|
53502
|
-
...drafts ? { drafts } : {},
|
|
53503
|
-
...onDraftChange ? { onDraftChange } : {}
|
|
53504
|
-
}) : null]
|
|
53095
|
+
"data-surface-parts": snapshots.length,
|
|
53096
|
+
children: snapshots.map((snapshot) => /* @__PURE__ */ jsx(JsonRenderSpecSurface, {
|
|
53097
|
+
spec: snapshot.node,
|
|
53098
|
+
surfaceId: snapshot.id,
|
|
53099
|
+
actions: snapshot.actions ?? [],
|
|
53100
|
+
...onAction ? { onAction } : {}
|
|
53101
|
+
}, snapshot.id))
|
|
53505
53102
|
});
|
|
53506
53103
|
}
|
|
53507
|
-
/** Consumes
|
|
53508
|
-
function VercelSurfaceHost({ bridge, runId
|
|
53104
|
+
/** Consumes WebSkill UI spec snapshots with a json-render surface renderer. @experimental */
|
|
53105
|
+
function VercelSurfaceHost({ bridge, runId }) {
|
|
53509
53106
|
const visibleSnapshots = useSyncExternalStore(bridge.subscribe, () => bridge.surfaceSnapshots).filter((snapshot) => runId === void 0 || snapshot.runId === runId);
|
|
53107
|
+
if (visibleSnapshots.length === 0) return null;
|
|
53510
53108
|
const handleAction = (event) => {
|
|
53511
|
-
const
|
|
53512
|
-
|
|
53513
|
-
|
|
53514
|
-
});
|
|
53515
|
-
if (!action?.runId || !action.nonce) return;
|
|
53109
|
+
const snapshot = visibleSnapshots.find((candidate) => candidate.id === event.surfaceId);
|
|
53110
|
+
const capability = snapshot?.actions?.find((candidate) => candidate.id === event.actionId);
|
|
53111
|
+
if (!snapshot?.runId || !capability?.nonce) return;
|
|
53516
53112
|
bridge.resolveSurfaceAction({
|
|
53517
|
-
runId:
|
|
53518
|
-
surfaceId:
|
|
53519
|
-
actionId:
|
|
53520
|
-
intent:
|
|
53521
|
-
nonce:
|
|
53522
|
-
...
|
|
53523
|
-
...action.cancelled ? { cancelled: true } : {}
|
|
53113
|
+
runId: snapshot.runId,
|
|
53114
|
+
surfaceId: event.surfaceId,
|
|
53115
|
+
actionId: event.actionId,
|
|
53116
|
+
intent: event.intent,
|
|
53117
|
+
nonce: capability.nonce,
|
|
53118
|
+
...event.value ? { value: event.value } : {}
|
|
53524
53119
|
});
|
|
53525
53120
|
};
|
|
53526
|
-
if (visibleSnapshots.length === 0) return null;
|
|
53527
|
-
const drafts = runId ? bridge.surfaceDrafts(runId) : {};
|
|
53528
53121
|
return /* @__PURE__ */ jsx("div", {
|
|
53529
53122
|
"data-testid": "vercel-surface-host",
|
|
53530
53123
|
children: /* @__PURE__ */ jsx(VercelSurfaceSnapshotHost, {
|
|
53531
53124
|
snapshots: visibleSnapshots,
|
|
53532
|
-
|
|
53533
|
-
onAction: handleAction,
|
|
53534
|
-
drafts,
|
|
53535
|
-
onDraftChange: (event) => bridge.setSurfaceDraft(event.runId, event.surfaceId, event.value)
|
|
53125
|
+
onAction: handleAction
|
|
53536
53126
|
})
|
|
53537
53127
|
});
|
|
53538
53128
|
}
|
|
@@ -53544,23 +53134,30 @@ function HistoricalSurfaces({ snapshots, renderer, registry }) {
|
|
|
53544
53134
|
snapshots,
|
|
53545
53135
|
...registry ? { registry } : {}
|
|
53546
53136
|
});
|
|
53547
|
-
if (renderer === "openui") return /* @__PURE__ */ jsx(OpenUiSurfaceSnapshotHost, {
|
|
53548
|
-
|
|
53549
|
-
...registry ? { registry } : {}
|
|
53550
|
-
});
|
|
53551
|
-
if (renderer === "vercel") return /* @__PURE__ */ jsx(VercelSurfaceSnapshotHost, {
|
|
53552
|
-
snapshots,
|
|
53553
|
-
...registry ? { registry } : {}
|
|
53554
|
-
});
|
|
53137
|
+
if (renderer === "openui") return /* @__PURE__ */ jsx(OpenUiSurfaceSnapshotHost, { snapshots });
|
|
53138
|
+
if (renderer === "vercel") return /* @__PURE__ */ jsx(VercelSurfaceSnapshotHost, { snapshots });
|
|
53555
53139
|
return /* @__PURE__ */ jsx(UiSurfaceSnapshotList, {
|
|
53556
53140
|
snapshots,
|
|
53557
53141
|
...registry ? { registry } : {}
|
|
53558
53142
|
});
|
|
53559
53143
|
}
|
|
53144
|
+
/**
|
|
53145
|
+
* 旧版本会话里的 surface 条目是六类 `{ surface: { kind } }`,没有节点树,任何渲染器都吃不下。
|
|
53146
|
+
* 判定只看渲染入口是否成立,不做深校验:深校验属于产出侧,历史消息只决定「渲染还是占位」。
|
|
53147
|
+
*/
|
|
53148
|
+
function isRenderableSpec(snapshot) {
|
|
53149
|
+
if (typeof snapshot !== "object" || snapshot === null) return false;
|
|
53150
|
+
const node = snapshot.node;
|
|
53151
|
+
if (typeof node !== "object" || node === null) return false;
|
|
53152
|
+
return typeof node.component === "string";
|
|
53153
|
+
}
|
|
53560
53154
|
/** WebSkill domain content rendered beneath a Base message without choosing its chat layout. */
|
|
53561
53155
|
function WebSkillMessageExtensions({ message, onDownload, surfaceRegistry, renderer }) {
|
|
53156
|
+
const t = useT();
|
|
53562
53157
|
if (message.role === "user") return null;
|
|
53563
53158
|
const blocks = message.blocks?.filter((block) => block.type !== "markdown" || block.text.trim() !== message.text.trim());
|
|
53159
|
+
const surfaces = message.surfaces ?? [];
|
|
53160
|
+
const renderable = surfaces.filter(isRenderableSpec);
|
|
53564
53161
|
return /* @__PURE__ */ jsxs("div", {
|
|
53565
53162
|
className: "min-w-0 w-full",
|
|
53566
53163
|
children: [
|
|
@@ -53569,11 +53166,16 @@ function WebSkillMessageExtensions({ message, onDownload, surfaceRegistry, rende
|
|
|
53569
53166
|
runId: message.runId ?? "",
|
|
53570
53167
|
...onDownload ? { onDownload } : {}
|
|
53571
53168
|
}) : null,
|
|
53572
|
-
|
|
53573
|
-
snapshots:
|
|
53169
|
+
renderable.length > 0 ? /* @__PURE__ */ jsx(HistoricalSurfaces, {
|
|
53170
|
+
snapshots: renderable,
|
|
53574
53171
|
...renderer ? { renderer } : {},
|
|
53575
53172
|
...surfaceRegistry ? { registry: surfaceRegistry } : {}
|
|
53576
53173
|
}) : null,
|
|
53174
|
+
renderable.length < surfaces.length ? /* @__PURE__ */ jsx("p", {
|
|
53175
|
+
"data-testid": "legacy-surface-placeholder",
|
|
53176
|
+
className: "my-2 rounded-lg border border-border bg-canvas px-3 py-2 text-xs text-muted",
|
|
53177
|
+
children: t("surface.legacy.placeholder")
|
|
53178
|
+
}) : null,
|
|
53577
53179
|
/* @__PURE__ */ jsx(SkillBadges, { skills: message.activeSkillNames ?? [] })
|
|
53578
53180
|
]
|
|
53579
53181
|
});
|
|
@@ -53790,23 +53392,35 @@ const start = (runId, at) => ({
|
|
|
53790
53392
|
text: "",
|
|
53791
53393
|
chunks: 0
|
|
53792
53394
|
});
|
|
53793
|
-
function appendPhase(live,
|
|
53794
|
-
const display = DISPLAY_PHASE[phase];
|
|
53395
|
+
function appendPhase(live, event) {
|
|
53396
|
+
const display = DISPLAY_PHASE[event.phase];
|
|
53795
53397
|
const last = live.phases.at(-1);
|
|
53796
53398
|
if (last?.phase === display) return live;
|
|
53797
53399
|
const closed = last ? [...live.phases.slice(0, -1), {
|
|
53798
53400
|
...last,
|
|
53799
|
-
endedAt: at
|
|
53401
|
+
endedAt: event.at
|
|
53800
53402
|
}] : [];
|
|
53403
|
+
const note = phaseNote(event);
|
|
53801
53404
|
return {
|
|
53802
53405
|
...live,
|
|
53803
53406
|
phases: [...closed, {
|
|
53804
53407
|
phase: display,
|
|
53805
|
-
at,
|
|
53806
|
-
...
|
|
53408
|
+
at: event.at,
|
|
53409
|
+
...note ? { note } : {}
|
|
53807
53410
|
}]
|
|
53808
53411
|
};
|
|
53809
53412
|
}
|
|
53413
|
+
/** 相位摘要:唯一读 `data` 的地方,此处事件还带着 `phase` 判别,下游不必再猜键名 */
|
|
53414
|
+
function phaseNote(event) {
|
|
53415
|
+
switch (event.phase) {
|
|
53416
|
+
case "route": return event.data.strategy;
|
|
53417
|
+
case "activate": return event.data.skillName;
|
|
53418
|
+
case "interact": return event.data.kind === "interaction" ? event.data.interactionType : event.data.actionId;
|
|
53419
|
+
case "complete":
|
|
53420
|
+
case "fail": return event.data.reason;
|
|
53421
|
+
default: return;
|
|
53422
|
+
}
|
|
53423
|
+
}
|
|
53810
53424
|
/**
|
|
53811
53425
|
* ChatEvent → 进行中 run 的 part 累积器。返回 undefined 表示当前没有进行中的 run。
|
|
53812
53426
|
* 只处理属于当前 runId 的事件,跨 run 的迟到事件被忽略。
|
|
@@ -53820,7 +53434,7 @@ function reduceLiveRun(live, event, at) {
|
|
|
53820
53434
|
}
|
|
53821
53435
|
if (!live || !("runId" in event) || event.runId !== live.runId) return live;
|
|
53822
53436
|
switch (event.type) {
|
|
53823
|
-
case "lifecycle": return appendPhase(live, event
|
|
53437
|
+
case "lifecycle": return appendPhase(live, event);
|
|
53824
53438
|
case "skill-activated": return {
|
|
53825
53439
|
...live,
|
|
53826
53440
|
skills: event.skills
|
|
@@ -53859,7 +53473,7 @@ function reduceLiveRun(live, event, at) {
|
|
|
53859
53473
|
|
|
53860
53474
|
//#endregion
|
|
53861
53475
|
//#region src/react/ErrorCard.tsx
|
|
53862
|
-
/** 结构化错误卡:错误码徽章 + 描述 + 建议(engine error 事件 / 失败 run) */
|
|
53476
|
+
/** 结构化错误卡:错误码徽章 + 描述 + 建议(engine error 事件 / 失败 run) @stable */
|
|
53863
53477
|
function ErrorCard({ code, message, onDismiss }) {
|
|
53864
53478
|
const t = useT();
|
|
53865
53479
|
return /* @__PURE__ */ jsx("div", {
|
|
@@ -53913,9 +53527,42 @@ function ErrorCard({ code, message, onDismiss }) {
|
|
|
53913
53527
|
});
|
|
53914
53528
|
}
|
|
53915
53529
|
|
|
53530
|
+
//#endregion
|
|
53531
|
+
//#region src/react/interactionLabels.ts
|
|
53532
|
+
/**
|
|
53533
|
+
* 交互卡的界面文案:生成器(`@webskill/ui`)与语言无关,本地化由持有字典的宿主注入。
|
|
53534
|
+
* 四档共用本函数,切换渲染档不会让同一个请求出现两套文案。
|
|
53535
|
+
*/
|
|
53536
|
+
function interactionLabels(request, t) {
|
|
53537
|
+
return {
|
|
53538
|
+
title: request.type === "form" && request.title ? request.title : t(`interaction.${request.type}.title`),
|
|
53539
|
+
submitLabel: t(request.type === "authorize" ? "interaction.allow" : request.type === "confirm" ? "interaction.confirm" : "interaction.submit"),
|
|
53540
|
+
cancelLabel: t(request.type === "authorize" ? "interaction.deny" : "interaction.cancel")
|
|
53541
|
+
};
|
|
53542
|
+
}
|
|
53543
|
+
|
|
53916
53544
|
//#endregion
|
|
53917
53545
|
//#region src/react/InteractionCard.tsx
|
|
53918
|
-
/**
|
|
53546
|
+
/** 交互表单的两个动作:与 surface 侧共用 catalog 的 submit / cancel 语义 */
|
|
53547
|
+
const INTERACTION_ACTIONS$1 = [{
|
|
53548
|
+
id: "submit",
|
|
53549
|
+
intent: "submit"
|
|
53550
|
+
}, {
|
|
53551
|
+
id: "cancel",
|
|
53552
|
+
intent: "cancel"
|
|
53553
|
+
}];
|
|
53554
|
+
const kindIcons = {
|
|
53555
|
+
ask: MessageCircleQuestionMark,
|
|
53556
|
+
confirm: CircleQuestionMark,
|
|
53557
|
+
form: ClipboardList,
|
|
53558
|
+
select: ListChecks,
|
|
53559
|
+
authorize: ShieldAlert
|
|
53560
|
+
};
|
|
53561
|
+
/**
|
|
53562
|
+
* 订阅 bridge.pending 渲染五类交互卡(native 档;其它档降级后也由它接管)。
|
|
53563
|
+
* 表单本体走 `NativeSpecSurface`——与 native 档 surface 侧同一个渲染入口。
|
|
53564
|
+
* @stable
|
|
53565
|
+
*/
|
|
53919
53566
|
function InteractionCard({ bridge }) {
|
|
53920
53567
|
const pending = useSyncExternalStore(bridge.subscribe, () => bridge.pending);
|
|
53921
53568
|
if (!pending) return null;
|
|
@@ -53924,102 +53571,25 @@ function InteractionCard({ bridge }) {
|
|
|
53924
53571
|
bridge
|
|
53925
53572
|
}, pending.id);
|
|
53926
53573
|
}
|
|
53927
|
-
/** 单个表单控件(ask/form 用;data-webskill-control 契约与 collectValues 对齐) */
|
|
53928
|
-
function Field({ control, invalid }) {
|
|
53929
|
-
const t = useT();
|
|
53930
|
-
const id = `webskill-field-${control.name}`;
|
|
53931
|
-
const label = /* @__PURE__ */ jsxs(Fragment$1, { children: [control.label, control.required ? /* @__PURE__ */ jsx("span", {
|
|
53932
|
-
className: "text-danger",
|
|
53933
|
-
children: " *"
|
|
53934
|
-
}) : null] });
|
|
53935
|
-
let element;
|
|
53936
|
-
switch (control.control) {
|
|
53937
|
-
case "boolean":
|
|
53938
|
-
element = /* @__PURE__ */ jsx(Checkbox, {
|
|
53939
|
-
id,
|
|
53940
|
-
"data-webskill-control": control.name,
|
|
53941
|
-
defaultChecked: control.defaultValue === true ? true : void 0,
|
|
53942
|
-
invalid
|
|
53943
|
-
});
|
|
53944
|
-
break;
|
|
53945
|
-
case "select":
|
|
53946
|
-
element = /* @__PURE__ */ jsx("select", {
|
|
53947
|
-
id,
|
|
53948
|
-
"data-webskill-control": control.name,
|
|
53949
|
-
"aria-invalid": invalid || void 0,
|
|
53950
|
-
className: "h-9 w-full rounded-md border border-input bg-surface px-3 text-sm text-ink shadow-xs outline-none transition-colors focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/20",
|
|
53951
|
-
...control.defaultValue !== void 0 ? { defaultValue: JSON.stringify(control.defaultValue) } : {},
|
|
53952
|
-
children: (control.options ?? []).map((option, i) => /* @__PURE__ */ jsx("option", {
|
|
53953
|
-
value: JSON.stringify(option.value),
|
|
53954
|
-
children: option.label
|
|
53955
|
-
}, i))
|
|
53956
|
-
});
|
|
53957
|
-
break;
|
|
53958
|
-
case "textarea":
|
|
53959
|
-
element = /* @__PURE__ */ jsx(Textarea, {
|
|
53960
|
-
id,
|
|
53961
|
-
"data-webskill-control": control.name,
|
|
53962
|
-
invalid,
|
|
53963
|
-
rows: 3,
|
|
53964
|
-
defaultValue: control.defaultValue !== void 0 ? String(control.defaultValue) : ""
|
|
53965
|
-
});
|
|
53966
|
-
break;
|
|
53967
|
-
default: element = /* @__PURE__ */ jsx(Input, {
|
|
53968
|
-
type: control.control === "number" ? "number" : "text",
|
|
53969
|
-
id,
|
|
53970
|
-
"data-webskill-control": control.name,
|
|
53971
|
-
invalid,
|
|
53972
|
-
defaultValue: control.defaultValue !== void 0 ? String(control.defaultValue) : ""
|
|
53973
|
-
});
|
|
53974
|
-
}
|
|
53975
|
-
return /* @__PURE__ */ jsx(FormField, {
|
|
53976
|
-
label,
|
|
53977
|
-
htmlFor: id,
|
|
53978
|
-
...control.description ? { description: control.description } : {},
|
|
53979
|
-
...invalid ? { error: t("interaction.required") } : {},
|
|
53980
|
-
children: element
|
|
53981
|
-
});
|
|
53982
|
-
}
|
|
53983
|
-
const kindIcons = {
|
|
53984
|
-
ask: MessageCircleQuestionMark,
|
|
53985
|
-
confirm: CircleQuestionMark,
|
|
53986
|
-
form: ClipboardList,
|
|
53987
|
-
select: ListChecks,
|
|
53988
|
-
authorize: ShieldAlert
|
|
53989
|
-
};
|
|
53990
53574
|
function ActiveInteractionCard({ request, bridge }) {
|
|
53991
53575
|
const t = useT();
|
|
53992
|
-
const
|
|
53993
|
-
const
|
|
53994
|
-
const
|
|
53995
|
-
const
|
|
53996
|
-
|
|
53997
|
-
|
|
53998
|
-
|
|
53999
|
-
|
|
54000
|
-
|
|
54001
|
-
cancelled: true
|
|
54002
|
-
});
|
|
54003
|
-
const submitForm = () => {
|
|
54004
|
-
if (!formRef.current) return;
|
|
54005
|
-
const { values, missingRequired } = collectValues(model.controls, formRef.current);
|
|
54006
|
-
if (missingRequired.length > 0) {
|
|
54007
|
-
setInvalid(missingRequired);
|
|
53576
|
+
const spec = interactionToUiSpec(request, interactionLabels(request, t));
|
|
53577
|
+
const isAuthorize = request.type === "authorize";
|
|
53578
|
+
const Icon = kindIcons[request.type];
|
|
53579
|
+
const handleAction = (event) => {
|
|
53580
|
+
if (event.intent !== "submit") {
|
|
53581
|
+
bridge.resolve({
|
|
53582
|
+
id: request.id,
|
|
53583
|
+
cancelled: true
|
|
53584
|
+
});
|
|
54008
53585
|
return;
|
|
54009
53586
|
}
|
|
54010
|
-
|
|
54011
|
-
|
|
54012
|
-
|
|
54013
|
-
|
|
54014
|
-
|
|
54015
|
-
|
|
54016
|
-
t,
|
|
54017
|
-
formRef,
|
|
54018
|
-
invalid,
|
|
54019
|
-
submitForm,
|
|
54020
|
-
resolve,
|
|
54021
|
-
cancel
|
|
54022
|
-
});
|
|
53587
|
+
const value = shapeInteractionValue(interactionToFormModel(request), event.value ?? {});
|
|
53588
|
+
bridge.resolve({
|
|
53589
|
+
id: request.id,
|
|
53590
|
+
value
|
|
53591
|
+
});
|
|
53592
|
+
};
|
|
54023
53593
|
return /* @__PURE__ */ jsxs(motion.div, {
|
|
54024
53594
|
...fadeInUp,
|
|
54025
53595
|
className: `rounded-card border shadow-card ${isAuthorize ? "border-warning/50 bg-warning-soft" : "border-border bg-surface"}`,
|
|
@@ -54031,132 +53601,51 @@ function ActiveInteractionCard({ request, bridge }) {
|
|
|
54031
53601
|
className: "size-4",
|
|
54032
53602
|
"aria-hidden": true
|
|
54033
53603
|
})
|
|
54034
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
54035
|
-
className: "min-w-0 flex-1",
|
|
54036
|
-
children: [
|
|
54037
|
-
|
|
54038
|
-
|
|
54039
|
-
|
|
54040
|
-
|
|
54041
|
-
|
|
54042
|
-
|
|
54043
|
-
|
|
53604
|
+
}), request.type === "authorize" ? /* @__PURE__ */ jsxs("div", {
|
|
53605
|
+
className: "flex min-w-0 flex-1 flex-col gap-2",
|
|
53606
|
+
children: [
|
|
53607
|
+
/* @__PURE__ */ jsxs("div", {
|
|
53608
|
+
className: "flex items-center gap-2",
|
|
53609
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
53610
|
+
className: "text-xs font-medium text-muted",
|
|
53611
|
+
children: t("interaction.authorize.capability")
|
|
53612
|
+
}), /* @__PURE__ */ jsx(Badge, {
|
|
53613
|
+
tone: "warning",
|
|
53614
|
+
children: request.capability
|
|
53615
|
+
})]
|
|
53616
|
+
}),
|
|
53617
|
+
/* @__PURE__ */ jsx("p", {
|
|
53618
|
+
className: "text-xs text-muted",
|
|
53619
|
+
children: t("interaction.authorize.description")
|
|
53620
|
+
}),
|
|
53621
|
+
request.details !== void 0 ? /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
|
|
53622
|
+
className: "mb-1 text-xs font-medium text-muted",
|
|
53623
|
+
children: t("interaction.authorize.details")
|
|
53624
|
+
}), /* @__PURE__ */ jsx("pre", {
|
|
53625
|
+
className: "max-h-40 overflow-auto rounded-lg border border-border bg-canvas p-3 font-mono text-xs text-ink",
|
|
53626
|
+
children: JSON.stringify(request.details, null, 2)
|
|
53627
|
+
})] }) : null
|
|
53628
|
+
]
|
|
53629
|
+
}) : null]
|
|
54044
53630
|
}), /* @__PURE__ */ jsx("div", {
|
|
54045
53631
|
className: "px-4 py-4",
|
|
54046
|
-
children:
|
|
54047
|
-
|
|
54048
|
-
|
|
54049
|
-
|
|
54050
|
-
|
|
54051
|
-
|
|
54052
|
-
switch (model.kind) {
|
|
54053
|
-
case "ask": return t("interaction.ask.title");
|
|
54054
|
-
case "confirm": return t("interaction.confirm.title");
|
|
54055
|
-
case "select": return t("interaction.select.title");
|
|
54056
|
-
case "authorize": return t("interaction.authorize.title");
|
|
54057
|
-
default: return t("interaction.form.title");
|
|
54058
|
-
}
|
|
54059
|
-
}
|
|
54060
|
-
function renderBody(model, request, deps) {
|
|
54061
|
-
const { t, formRef, invalid, submitForm, resolve, cancel } = deps;
|
|
54062
|
-
if (model.kind === "authorize") {
|
|
54063
|
-
const capability = request.type === "authorize" ? request.capability : void 0;
|
|
54064
|
-
const details = request.type === "authorize" ? request.details : void 0;
|
|
54065
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
54066
|
-
className: "flex flex-col gap-3",
|
|
54067
|
-
children: [
|
|
54068
|
-
capability ? /* @__PURE__ */ jsxs("div", {
|
|
54069
|
-
className: "flex items-center gap-2",
|
|
54070
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
54071
|
-
className: "text-xs font-medium text-muted",
|
|
54072
|
-
children: t("interaction.authorize.capability")
|
|
54073
|
-
}), /* @__PURE__ */ jsx(Badge, {
|
|
54074
|
-
tone: "warning",
|
|
54075
|
-
children: capability
|
|
54076
|
-
})]
|
|
54077
|
-
}) : null,
|
|
54078
|
-
/* @__PURE__ */ jsx("p", {
|
|
54079
|
-
className: "text-xs text-muted",
|
|
54080
|
-
children: t("interaction.authorize.description")
|
|
54081
|
-
}),
|
|
54082
|
-
details !== void 0 ? /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
|
|
54083
|
-
className: "mb-1 text-xs font-medium text-muted",
|
|
54084
|
-
children: t("interaction.authorize.details")
|
|
54085
|
-
}), /* @__PURE__ */ jsx("pre", {
|
|
54086
|
-
className: "max-h-40 overflow-auto rounded-lg border border-border bg-canvas p-3 font-mono text-xs text-ink",
|
|
54087
|
-
children: JSON.stringify(details, null, 2)
|
|
54088
|
-
})] }) : null,
|
|
54089
|
-
/* @__PURE__ */ jsxs("div", {
|
|
54090
|
-
className: "flex items-center gap-2",
|
|
54091
|
-
children: [/* @__PURE__ */ jsx(Button, {
|
|
54092
|
-
onClick: () => resolve(shapeInteractionValue(model, {})),
|
|
54093
|
-
children: t("interaction.allow")
|
|
54094
|
-
}), /* @__PURE__ */ jsx(Button, {
|
|
54095
|
-
variant: "danger",
|
|
54096
|
-
onClick: cancel,
|
|
54097
|
-
children: t("interaction.deny")
|
|
54098
|
-
})]
|
|
54099
|
-
})
|
|
54100
|
-
]
|
|
54101
|
-
});
|
|
54102
|
-
}
|
|
54103
|
-
if (model.kind === "confirm") return /* @__PURE__ */ jsxs("div", {
|
|
54104
|
-
className: "flex items-center gap-2",
|
|
54105
|
-
children: [/* @__PURE__ */ jsx(Button, {
|
|
54106
|
-
onClick: () => resolve(shapeInteractionValue(model, { confirmed: true })),
|
|
54107
|
-
children: t("interaction.confirm")
|
|
54108
|
-
}), /* @__PURE__ */ jsx(Button, {
|
|
54109
|
-
variant: "secondary",
|
|
54110
|
-
onClick: cancel,
|
|
54111
|
-
children: t("interaction.cancel")
|
|
54112
|
-
})]
|
|
54113
|
-
});
|
|
54114
|
-
if (model.kind === "select") return /* @__PURE__ */ jsxs("div", {
|
|
54115
|
-
className: "flex flex-col gap-3",
|
|
54116
|
-
children: [/* @__PURE__ */ jsx("ul", {
|
|
54117
|
-
className: "flex flex-col gap-1.5",
|
|
54118
|
-
children: (model.controls[0]?.options ?? []).map((option, i) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("button", {
|
|
54119
|
-
type: "button",
|
|
54120
|
-
onClick: () => resolve(shapeInteractionValue(model, { selected: option.value })),
|
|
54121
|
-
className: "w-full cursor-pointer rounded-lg border border-border bg-surface px-3.5 py-2.5 text-left text-sm text-ink transition-colors hover:border-ring hover:bg-subtle",
|
|
54122
|
-
children: option.label
|
|
54123
|
-
}) }, i))
|
|
54124
|
-
}), /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, {
|
|
54125
|
-
variant: "secondary",
|
|
54126
|
-
onClick: cancel,
|
|
54127
|
-
children: t("interaction.cancel")
|
|
54128
|
-
}) })]
|
|
54129
|
-
});
|
|
54130
|
-
return /* @__PURE__ */ jsxs("form", {
|
|
54131
|
-
ref: formRef,
|
|
54132
|
-
noValidate: true,
|
|
54133
|
-
className: "flex flex-col gap-3",
|
|
54134
|
-
onSubmit: (event) => {
|
|
54135
|
-
event.preventDefault();
|
|
54136
|
-
submitForm();
|
|
54137
|
-
},
|
|
54138
|
-
children: [model.controls.map((control) => /* @__PURE__ */ jsx(Field, {
|
|
54139
|
-
control,
|
|
54140
|
-
invalid: invalid.includes(control.name)
|
|
54141
|
-
}, control.name)), /* @__PURE__ */ jsxs("div", {
|
|
54142
|
-
className: "flex items-center gap-2",
|
|
54143
|
-
children: [/* @__PURE__ */ jsx(Button, {
|
|
54144
|
-
type: "submit",
|
|
54145
|
-
children: t("interaction.submit")
|
|
54146
|
-
}), /* @__PURE__ */ jsx(Button, {
|
|
54147
|
-
variant: "secondary",
|
|
54148
|
-
onClick: cancel,
|
|
54149
|
-
children: t("interaction.cancel")
|
|
54150
|
-
})]
|
|
53632
|
+
children: /* @__PURE__ */ jsx(NativeSpecSurface, {
|
|
53633
|
+
surfaceId: request.id,
|
|
53634
|
+
spec,
|
|
53635
|
+
actions: INTERACTION_ACTIONS$1,
|
|
53636
|
+
onAction: handleAction
|
|
53637
|
+
})
|
|
54151
53638
|
})]
|
|
54152
53639
|
});
|
|
54153
53640
|
}
|
|
54154
53641
|
|
|
54155
53642
|
//#endregion
|
|
54156
53643
|
//#region src/react/InterruptedBanner.tsx
|
|
53644
|
+
const resumable = (list) => list.filter((entry) => !isUnsupportedRunSnapshot(entry));
|
|
54157
53645
|
/**
|
|
54158
53646
|
* 未完成对话提示条:挂载/会话切换时检查 interrupted 快照,非空则顶部 banner
|
|
54159
53647
|
* + Resume(engine.resume 后等待中的表单重新进入 bridge.pending)。
|
|
53648
|
+
* @stable
|
|
54160
53649
|
*/
|
|
54161
53650
|
function InterruptedBanner({ engine, sessionId }) {
|
|
54162
53651
|
const t = useT();
|
|
@@ -54164,7 +53653,7 @@ function InterruptedBanner({ engine, sessionId }) {
|
|
|
54164
53653
|
useEffect(() => {
|
|
54165
53654
|
let cancelled = false;
|
|
54166
53655
|
engine.listInterrupted().then((list) => {
|
|
54167
|
-
if (!cancelled) setInterrupted(list);
|
|
53656
|
+
if (!cancelled) setInterrupted(resumable(list));
|
|
54168
53657
|
}).catch(() => {});
|
|
54169
53658
|
return () => {
|
|
54170
53659
|
cancelled = true;
|
|
@@ -54174,7 +53663,7 @@ function InterruptedBanner({ engine, sessionId }) {
|
|
|
54174
53663
|
if (!current) return null;
|
|
54175
53664
|
const resume = () => {
|
|
54176
53665
|
engine.resume(current.runId).then(async () => {
|
|
54177
|
-
setInterrupted(await engine.listInterrupted());
|
|
53666
|
+
setInterrupted(resumable(await engine.listInterrupted()));
|
|
54178
53667
|
});
|
|
54179
53668
|
};
|
|
54180
53669
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -54208,6 +53697,68 @@ function InterruptedBanner({ engine, sessionId }) {
|
|
|
54208
53697
|
});
|
|
54209
53698
|
}
|
|
54210
53699
|
|
|
53700
|
+
//#endregion
|
|
53701
|
+
//#region src/react/SpecInteraction.tsx
|
|
53702
|
+
/** 交互表单的两个动作:与 surface 侧共用 catalog 的 submit / cancel 语义 */
|
|
53703
|
+
const INTERACTION_ACTIONS = [{
|
|
53704
|
+
id: "submit",
|
|
53705
|
+
intent: "submit"
|
|
53706
|
+
}, {
|
|
53707
|
+
id: "cancel",
|
|
53708
|
+
intent: "cancel"
|
|
53709
|
+
}];
|
|
53710
|
+
/** 各档的 spec 渲染入口——交互(路径 A)与 surface(路径 B)在同一档下命中同一个组件 */
|
|
53711
|
+
const SURFACES = {
|
|
53712
|
+
a2ui: A2uiSpecSurface,
|
|
53713
|
+
openui: OpenUiSpecSurface,
|
|
53714
|
+
vercel: JsonRenderSpecSurface
|
|
53715
|
+
};
|
|
53716
|
+
/** optional peer 探测:缺包时通知通道,桥据此粘性降级 native(不悬挂请求、不阻断 run) */
|
|
53717
|
+
const PROBES = {
|
|
53718
|
+
a2ui: probeA2uiAvailability,
|
|
53719
|
+
openui: probeOpenUiAvailability,
|
|
53720
|
+
vercel: probeJsonRenderAvailability
|
|
53721
|
+
};
|
|
53722
|
+
const MISSING_PEER = {
|
|
53723
|
+
a2ui: "@a2ui/lit and @a2ui/web_core are not installed in this host",
|
|
53724
|
+
openui: "@openuidev/react-lang is not installed in this host",
|
|
53725
|
+
vercel: "@json-render/core and @json-render/react are not installed in this host"
|
|
53726
|
+
};
|
|
53727
|
+
/**
|
|
53728
|
+
* 非 native 三档的交互视图(路径 A):订阅 SpecInteractionChannel(core 产出 catalog
|
|
53729
|
+
* 节点树),交给本档 surface 侧同一个渲染入口渲染;提交/取消经 handleAction 回传。
|
|
53730
|
+
* 未挂载时桥直接降级 native(不悬挂请求)。
|
|
53731
|
+
* @experimental
|
|
53732
|
+
*/
|
|
53733
|
+
function SpecInteraction({ channel, renderer }) {
|
|
53734
|
+
const t = useT();
|
|
53735
|
+
const session = useSyncExternalStore(channel.subscribe, () => channel.current);
|
|
53736
|
+
useEffect(() => {
|
|
53737
|
+
channel.labelsFor = (request) => interactionLabels(request, t);
|
|
53738
|
+
}, [channel, t]);
|
|
53739
|
+
useEffect(() => {
|
|
53740
|
+
channel.attach();
|
|
53741
|
+
return () => channel.detach();
|
|
53742
|
+
}, [channel]);
|
|
53743
|
+
useEffect(() => {
|
|
53744
|
+
let cancelled = false;
|
|
53745
|
+
PROBES[renderer]().then((available) => {
|
|
53746
|
+
if (!cancelled && !available) channel.fail(MISSING_PEER[renderer]);
|
|
53747
|
+
});
|
|
53748
|
+
return () => {
|
|
53749
|
+
cancelled = true;
|
|
53750
|
+
};
|
|
53751
|
+
}, [channel, renderer]);
|
|
53752
|
+
if (!session) return null;
|
|
53753
|
+
const Surface = SURFACES[renderer];
|
|
53754
|
+
return /* @__PURE__ */ jsx(Surface, {
|
|
53755
|
+
surfaceId: session.request.id,
|
|
53756
|
+
spec: session.spec,
|
|
53757
|
+
actions: INTERACTION_ACTIONS,
|
|
53758
|
+
onAction: (event) => channel.handleAction(event)
|
|
53759
|
+
});
|
|
53760
|
+
}
|
|
53761
|
+
|
|
54211
53762
|
//#endregion
|
|
54212
53763
|
//#region src/react/SettingsDrawer.tsx
|
|
54213
53764
|
const PROVIDERS = [
|
|
@@ -54231,7 +53782,7 @@ function createProbeClient(provider, form) {
|
|
|
54231
53782
|
model: form.model
|
|
54232
53783
|
});
|
|
54233
53784
|
}
|
|
54234
|
-
/** 设置抽屉:LLM 配置(三协议供应商 / 能力探测 / Demo model 标识 / 流式与 temperature)+ 外观(主题/语言) */
|
|
53785
|
+
/** 设置抽屉:LLM 配置(三协议供应商 / 能力探测 / Demo model 标识 / 流式与 temperature)+ 外观(主题/语言) @stable */
|
|
54235
53786
|
function SettingsDrawer({ open, llmConfig, runtimeConfig, theme, locale, renderer, onAppearanceChange, onSaved, onClose }) {
|
|
54236
53787
|
const t = useT();
|
|
54237
53788
|
const [provider, setProvider] = useState("openai-compatible");
|
|
@@ -54601,53 +54152,6 @@ function useChatLayout(layout = "auto") {
|
|
|
54601
54152
|
};
|
|
54602
54153
|
}
|
|
54603
54154
|
|
|
54604
|
-
//#endregion
|
|
54605
|
-
//#region src/react/VercelPayloadPreview.tsx
|
|
54606
|
-
/**
|
|
54607
|
-
* vercel 档(payload 预览):不渲染表单,展示 InteractionRequest 经 toVercelToolInvocation
|
|
54608
|
-
* 转换后的 Vercel AI SDK 数据契约 JSON 卡。仅提供 Cancel 结束交互(非完整运行时)。
|
|
54609
|
-
*/
|
|
54610
|
-
function VercelPayloadPreview({ bridge }) {
|
|
54611
|
-
const t = useT();
|
|
54612
|
-
const pending = useSyncExternalStore(bridge.subscribe, () => bridge.pending);
|
|
54613
|
-
if (!pending) return null;
|
|
54614
|
-
const payload = toVercelToolInvocation(pending);
|
|
54615
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
54616
|
-
"data-testid": "vercel-payload-preview",
|
|
54617
|
-
className: "rounded-card border border-border bg-surface shadow-card",
|
|
54618
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
54619
|
-
className: "flex items-center gap-2 px-4 pt-4",
|
|
54620
|
-
children: [/* @__PURE__ */ jsx("h3", {
|
|
54621
|
-
className: "font-display text-sm font-semibold text-ink",
|
|
54622
|
-
children: t("vercel.preview.title")
|
|
54623
|
-
}), /* @__PURE__ */ jsx(Badge, {
|
|
54624
|
-
tone: "neutral",
|
|
54625
|
-
children: t("vercel.preview.badge")
|
|
54626
|
-
})]
|
|
54627
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
54628
|
-
className: "flex flex-col gap-3 px-4 py-4",
|
|
54629
|
-
children: [
|
|
54630
|
-
/* @__PURE__ */ jsx("p", {
|
|
54631
|
-
className: "text-xs text-muted",
|
|
54632
|
-
children: t("vercel.preview.description")
|
|
54633
|
-
}),
|
|
54634
|
-
/* @__PURE__ */ jsx("pre", {
|
|
54635
|
-
className: "max-h-64 overflow-auto rounded-lg border border-border bg-canvas p-3 font-mono text-xs text-ink",
|
|
54636
|
-
children: JSON.stringify(payload, null, 2)
|
|
54637
|
-
}),
|
|
54638
|
-
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, {
|
|
54639
|
-
variant: "secondary",
|
|
54640
|
-
onClick: () => bridge.resolve({
|
|
54641
|
-
id: pending.id,
|
|
54642
|
-
cancelled: true
|
|
54643
|
-
}),
|
|
54644
|
-
children: t("interaction.cancel")
|
|
54645
|
-
}) })
|
|
54646
|
-
]
|
|
54647
|
-
})]
|
|
54648
|
-
});
|
|
54649
|
-
}
|
|
54650
|
-
|
|
54651
54155
|
//#endregion
|
|
54652
54156
|
//#region src/react/Chatbot.tsx
|
|
54653
54157
|
const toErrorMessage = (e) => e instanceof Error ? e.message : String(e);
|
|
@@ -54670,14 +54174,17 @@ async function downloadArtifactFile(storage, chatRoot, file) {
|
|
|
54670
54174
|
/**
|
|
54671
54175
|
* ChatEngine owns message/session/runtime state while assistant-ui Base owns the
|
|
54672
54176
|
* presentation shell and accessible thread primitives.
|
|
54177
|
+
* @stable
|
|
54673
54178
|
*/
|
|
54674
|
-
function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, renderer: rendererProp, surfaceRegistry, layout = "auto", onAppearanceChange }) {
|
|
54179
|
+
function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, renderer: rendererProp, surfaceRegistry, layout = "auto", onAppearanceChange, onEngineReady }) {
|
|
54675
54180
|
const engine = useMemo(() => new ChatEngine(adapter, {
|
|
54676
54181
|
...config?.chatRoot ? { chatRoot: config.chatRoot } : {},
|
|
54677
54182
|
...config?.llm ? { llm: config.llm } : {},
|
|
54678
54183
|
...config?.loopConfig ? { loopConfig: config.loopConfig } : {},
|
|
54679
54184
|
...config?.runtimeConfig ? { runtimeConfig: config.runtimeConfig } : {},
|
|
54680
54185
|
...config?.generativeUi ? { generativeUi: true } : {},
|
|
54186
|
+
...config?.hooks ? { hooks: config.hooks } : {},
|
|
54187
|
+
...config?.governance ? { governance: config.governance } : {},
|
|
54681
54188
|
...rendererProp ? { renderer: rendererProp } : {}
|
|
54682
54189
|
}), [
|
|
54683
54190
|
adapter,
|
|
@@ -54686,8 +54193,13 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
|
|
|
54686
54193
|
config?.loopConfig,
|
|
54687
54194
|
config?.runtimeConfig,
|
|
54688
54195
|
config?.generativeUi,
|
|
54196
|
+
config?.hooks,
|
|
54197
|
+
config?.governance,
|
|
54689
54198
|
rendererProp
|
|
54690
54199
|
]);
|
|
54200
|
+
useEffect(() => {
|
|
54201
|
+
onEngineReady?.(engine);
|
|
54202
|
+
}, [engine, onEngineReady]);
|
|
54691
54203
|
const [theme, setTheme] = useState(themeProp ?? "light");
|
|
54692
54204
|
const [locale, setLocale] = useState(localeProp ?? "en");
|
|
54693
54205
|
const [renderer, setRenderer] = useState(rendererProp ?? "native");
|
|
@@ -54707,6 +54219,11 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
|
|
|
54707
54219
|
const [sessions, setSessions] = useState([]);
|
|
54708
54220
|
/** 首次 listSessions 未完成(threads 客户端的 isLoading) */
|
|
54709
54221
|
const [sessionsLoading, setSessionsLoading] = useState(true);
|
|
54222
|
+
/** 分页游标:非空即「还有更早的一页」。页大小归 SessionStore,这里不覆写 limit */
|
|
54223
|
+
const [sessionsCursor, setSessionsCursor] = useState();
|
|
54224
|
+
const [messagesCursor, setMessagesCursor] = useState();
|
|
54225
|
+
const [loadingEarlierSessions, setLoadingEarlierSessions] = useState(false);
|
|
54226
|
+
const [loadingEarlierMessages, setLoadingEarlierMessages] = useState(false);
|
|
54710
54227
|
const [currentSessionId, setCurrentSessionId] = useState();
|
|
54711
54228
|
const [sending, setSending] = useState(false);
|
|
54712
54229
|
/** 当前活跃 runId(run-started 捕获;Stop 按钮 engine.cancel 用) */
|
|
@@ -54716,14 +54233,15 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
|
|
|
54716
54233
|
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
54717
54234
|
/** 当前进行中 run 的 part 累积器(流式正文 / 工具 / 生命周期步进的唯一来源) */
|
|
54718
54235
|
const [live, setLive] = useState();
|
|
54719
|
-
/** a2ui 档交互容器显隐(interaction-requested/resolved 事件驱动) */
|
|
54720
|
-
const [a2uiActive, setA2uiActive] = useState(false);
|
|
54721
54236
|
const [interactionPending, setInteractionPending] = useState(false);
|
|
54722
54237
|
/** pending 交互归属的会话(跨会话查看时隐藏交互卡,防串台) */
|
|
54723
54238
|
const [interactionSessionId, setInteractionSessionId] = useState();
|
|
54724
54239
|
/** currentSessionId 的 ref 镜像(事件订阅闭包 [engine] 内读取最新值) */
|
|
54725
54240
|
const sessionRef = useRef(currentSessionId);
|
|
54726
54241
|
sessionRef.current = currentSessionId;
|
|
54242
|
+
/** sessions 的 ref 镜像(handleSend 判定「这次是否会生成标题」,不想为此进依赖表) */
|
|
54243
|
+
const sessionsRef = useRef(sessions);
|
|
54244
|
+
sessionsRef.current = sessions;
|
|
54727
54245
|
const { containerRef, resolved: resolvedLayout } = useChatLayout(layout);
|
|
54728
54246
|
/** 附件按钮只在存储确实可写时出现(R11:不渲染点了就报错的按钮) */
|
|
54729
54247
|
const [attachmentsReady, setAttachmentsReady] = useState(false);
|
|
@@ -54742,30 +54260,26 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
|
|
|
54742
54260
|
cancelled = true;
|
|
54743
54261
|
};
|
|
54744
54262
|
}, [adapter, engine]);
|
|
54745
|
-
/** a2ui 交互容器 ref:挂载即注入引擎(卸载传 null),引擎懒建 LitRendererBridge 渲染其中;
|
|
54746
|
-
同时为容器配置 @a2ui/markdown-it(optional peer,缺失时保持纯文本降级) */
|
|
54747
|
-
const interactionMountRef = useCallback((el) => {
|
|
54748
|
-
engine.setInteractionMount(el);
|
|
54749
|
-
if (el) configureA2uiMarkdown(el).then((configured) => {
|
|
54750
|
-
if (!configured) console.warn("A2UI markdown renderer is not configured: install @a2ui/markdown-it to render markdown in A2UI interactions");
|
|
54751
|
-
});
|
|
54752
|
-
}, [engine]);
|
|
54753
54263
|
const refreshSessions = useCallback(async () => {
|
|
54754
|
-
|
|
54264
|
+
const page = await engine.listSessions();
|
|
54265
|
+
setSessions(page.items);
|
|
54266
|
+
setSessionsCursor(page.nextCursor);
|
|
54755
54267
|
}, [engine]);
|
|
54756
54268
|
useEffect(() => {
|
|
54757
54269
|
let cancelled = false;
|
|
54758
54270
|
(async () => {
|
|
54759
|
-
const
|
|
54271
|
+
const page = await engine.listSessions();
|
|
54760
54272
|
if (cancelled) return;
|
|
54761
|
-
setSessions(
|
|
54273
|
+
setSessions(page.items);
|
|
54274
|
+
setSessionsCursor(page.nextCursor);
|
|
54762
54275
|
setSessionsLoading(false);
|
|
54763
|
-
const latest =
|
|
54276
|
+
const latest = page.items[page.items.length - 1];
|
|
54764
54277
|
if (!latest) return;
|
|
54765
54278
|
const history = await engine.selectSession(latest.id);
|
|
54766
54279
|
if (cancelled) return;
|
|
54767
54280
|
setCurrentSessionId(latest.id);
|
|
54768
|
-
setMessages(history);
|
|
54281
|
+
setMessages(history.items);
|
|
54282
|
+
setMessagesCursor(history.nextCursor);
|
|
54769
54283
|
})().catch((e) => {
|
|
54770
54284
|
if (!cancelled) {
|
|
54771
54285
|
setSessionsLoading(false);
|
|
@@ -54788,12 +54302,10 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
|
|
|
54788
54302
|
setMessages((prev) => prev.some((message) => message.id === event.message.id) ? prev : [...prev, event.message]);
|
|
54789
54303
|
break;
|
|
54790
54304
|
case "interaction-requested":
|
|
54791
|
-
setA2uiActive(true);
|
|
54792
54305
|
setInteractionPending(true);
|
|
54793
54306
|
setInteractionSessionId(sessionRef.current);
|
|
54794
54307
|
break;
|
|
54795
54308
|
case "interaction-resolved":
|
|
54796
|
-
setA2uiActive(false);
|
|
54797
54309
|
setInteractionPending(false);
|
|
54798
54310
|
setInteractionSessionId(void 0);
|
|
54799
54311
|
break;
|
|
@@ -54818,12 +54330,16 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
|
|
|
54818
54330
|
}), [engine]);
|
|
54819
54331
|
const handleSend = useCallback((text, attachments = []) => {
|
|
54820
54332
|
(async () => {
|
|
54821
|
-
|
|
54333
|
+
let sessionId = currentSessionId;
|
|
54334
|
+
if (!sessionId) {
|
|
54822
54335
|
const meta = await engine.createSession();
|
|
54336
|
+
sessionId = meta.id;
|
|
54823
54337
|
setCurrentSessionId(meta.id);
|
|
54824
54338
|
await refreshSessions();
|
|
54825
54339
|
}
|
|
54340
|
+
const needsTitle = sessionsRef.current.find((session) => session.id === sessionId)?.title === void 0;
|
|
54826
54341
|
await engine.send(text, attachments);
|
|
54342
|
+
if (needsTitle) await refreshSessions();
|
|
54827
54343
|
})().catch((e) => setError({ message: toErrorMessage(e) }));
|
|
54828
54344
|
}, [
|
|
54829
54345
|
engine,
|
|
@@ -54845,14 +54361,41 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
|
|
|
54845
54361
|
const handleSelect = useCallback((id) => {
|
|
54846
54362
|
engine.selectSession(id).then((history) => {
|
|
54847
54363
|
setCurrentSessionId(id);
|
|
54848
|
-
setMessages(history);
|
|
54364
|
+
setMessages(history.items);
|
|
54365
|
+
setMessagesCursor(history.nextCursor);
|
|
54849
54366
|
setDrawerOpen(false);
|
|
54850
54367
|
}).catch((e) => setError({ message: toErrorMessage(e) }));
|
|
54851
54368
|
}, [engine]);
|
|
54369
|
+
/** 向历史方向再取一页:页内升序,所以是**前插**而不是追加 */
|
|
54370
|
+
const handleLoadEarlierMessages = useCallback(() => {
|
|
54371
|
+
if (!messagesCursor || loadingEarlierMessages) return;
|
|
54372
|
+
setLoadingEarlierMessages(true);
|
|
54373
|
+
engine.loadMoreMessages(messagesCursor).then((page) => {
|
|
54374
|
+
setMessages((prev) => [...page.items, ...prev]);
|
|
54375
|
+
setMessagesCursor(page.nextCursor);
|
|
54376
|
+
}).catch((e) => setError({ message: toErrorMessage(e) })).finally(() => setLoadingEarlierMessages(false));
|
|
54377
|
+
}, [
|
|
54378
|
+
engine,
|
|
54379
|
+
messagesCursor,
|
|
54380
|
+
loadingEarlierMessages
|
|
54381
|
+
]);
|
|
54382
|
+
const handleLoadEarlierSessions = useCallback(() => {
|
|
54383
|
+
if (!sessionsCursor || loadingEarlierSessions) return;
|
|
54384
|
+
setLoadingEarlierSessions(true);
|
|
54385
|
+
engine.listSessions({ cursor: sessionsCursor }).then((page) => {
|
|
54386
|
+
setSessions((prev) => [...page.items, ...prev]);
|
|
54387
|
+
setSessionsCursor(page.nextCursor);
|
|
54388
|
+
}).catch((e) => setError({ message: toErrorMessage(e) })).finally(() => setLoadingEarlierSessions(false));
|
|
54389
|
+
}, [
|
|
54390
|
+
engine,
|
|
54391
|
+
sessionsCursor,
|
|
54392
|
+
loadingEarlierSessions
|
|
54393
|
+
]);
|
|
54852
54394
|
const handleCreate = useCallback(() => {
|
|
54853
54395
|
engine.createSession().then(async (meta) => {
|
|
54854
54396
|
setCurrentSessionId(meta.id);
|
|
54855
54397
|
setMessages([]);
|
|
54398
|
+
setMessagesCursor(void 0);
|
|
54856
54399
|
await refreshSessions();
|
|
54857
54400
|
}).catch((e) => setError({ message: toErrorMessage(e) }));
|
|
54858
54401
|
}, [engine, refreshSessions]);
|
|
@@ -54917,7 +54460,12 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
|
|
|
54917
54460
|
"data-layout": resolvedLayout,
|
|
54918
54461
|
className: `webskill-aui-shell flex h-full min-h-0 flex-row font-sans text-ink ${theme === "dark" ? "dark" : ""}`,
|
|
54919
54462
|
children: [
|
|
54920
|
-
/* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(AssistantUiSessionList, {
|
|
54463
|
+
/* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(AssistantUiSessionList, {
|
|
54464
|
+
className: "hidden lg:flex",
|
|
54465
|
+
hasEarlier: sessionsCursor !== void 0,
|
|
54466
|
+
loadingEarlier: loadingEarlierSessions,
|
|
54467
|
+
onLoadEarlier: handleLoadEarlierSessions
|
|
54468
|
+
}), /* @__PURE__ */ jsx(Sheet, {
|
|
54921
54469
|
open: drawerOpen,
|
|
54922
54470
|
onOpenChange: setDrawerOpen,
|
|
54923
54471
|
children: /* @__PURE__ */ jsx(SheetContent, {
|
|
@@ -54926,7 +54474,10 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
|
|
|
54926
54474
|
className: "p-0 lg:hidden",
|
|
54927
54475
|
children: /* @__PURE__ */ jsx(AssistantUiSessionList, {
|
|
54928
54476
|
className: "h-full w-full border-r-0",
|
|
54929
|
-
onNavigate: () => setDrawerOpen(false)
|
|
54477
|
+
onNavigate: () => setDrawerOpen(false),
|
|
54478
|
+
hasEarlier: sessionsCursor !== void 0,
|
|
54479
|
+
loadingEarlier: loadingEarlierSessions,
|
|
54480
|
+
onLoadEarlier: handleLoadEarlierSessions
|
|
54930
54481
|
})
|
|
54931
54482
|
})
|
|
54932
54483
|
})] }),
|
|
@@ -54959,6 +54510,10 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
|
|
|
54959
54510
|
}) : null,
|
|
54960
54511
|
/* @__PURE__ */ jsx(AssistantUiMessageList, {
|
|
54961
54512
|
messages,
|
|
54513
|
+
...messagesCursor !== void 0 ? { earlier: {
|
|
54514
|
+
loading: loadingEarlierMessages,
|
|
54515
|
+
onLoad: handleLoadEarlierMessages
|
|
54516
|
+
} } : {},
|
|
54962
54517
|
renderMessage: (message) => /* @__PURE__ */ jsx(AssistantUiMessage, {
|
|
54963
54518
|
message,
|
|
54964
54519
|
onRetry: handleRetry,
|
|
@@ -54971,18 +54526,14 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
|
|
|
54971
54526
|
}),
|
|
54972
54527
|
(() => {
|
|
54973
54528
|
const interactionVisible = interactionSessionId === void 0 || interactionSessionId === currentSessionId;
|
|
54974
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
54975
|
-
|
|
54976
|
-
|
|
54977
|
-
|
|
54978
|
-
|
|
54979
|
-
|
|
54980
|
-
|
|
54981
|
-
|
|
54982
|
-
children: /* @__PURE__ */ jsx(OpenUiInteraction, { channel: engine.openUiChannel })
|
|
54983
|
-
}) : null,
|
|
54984
|
-
interactionVisible ? renderer === "vercel" ? /* @__PURE__ */ jsx(VercelPayloadPreview, { bridge: engine.bridge }) : /* @__PURE__ */ jsx(InteractionCard, { bridge: engine.bridge }) : null
|
|
54985
|
-
] });
|
|
54529
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [renderer !== "native" ? /* @__PURE__ */ jsx("div", {
|
|
54530
|
+
"data-testid": "spec-interaction-slot",
|
|
54531
|
+
className: interactionVisible ? void 0 : "hidden",
|
|
54532
|
+
children: /* @__PURE__ */ jsx(SpecInteraction, {
|
|
54533
|
+
channel: engine.interactionChannel,
|
|
54534
|
+
renderer
|
|
54535
|
+
})
|
|
54536
|
+
}) : null, interactionVisible ? /* @__PURE__ */ jsx(InteractionCard, { bridge: engine.bridge }) : null] });
|
|
54986
54537
|
})(),
|
|
54987
54538
|
/* @__PURE__ */ jsx(ResultBlocksPro, {
|
|
54988
54539
|
bridge: engine.bridge,
|
|
@@ -54996,13 +54547,11 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
|
|
|
54996
54547
|
}) : null,
|
|
54997
54548
|
renderer === "vercel" && currentRunId ? /* @__PURE__ */ jsx(VercelSurfaceHost, {
|
|
54998
54549
|
bridge: engine.bridge,
|
|
54999
|
-
runId: currentRunId
|
|
55000
|
-
...surfaceRegistry ? { registry: surfaceRegistry } : {}
|
|
54550
|
+
runId: currentRunId
|
|
55001
54551
|
}) : null,
|
|
55002
54552
|
renderer === "openui" && currentRunId ? /* @__PURE__ */ jsx(OpenUiSurfaceHost, {
|
|
55003
54553
|
bridge: engine.bridge,
|
|
55004
|
-
runId: currentRunId
|
|
55005
|
-
...surfaceRegistry ? { registry: surfaceRegistry } : {}
|
|
54554
|
+
runId: currentRunId
|
|
55006
54555
|
}) : null,
|
|
55007
54556
|
renderer === "a2ui" && currentRunId ? /* @__PURE__ */ jsx(A2uiSurfaceHost, {
|
|
55008
54557
|
bridge: engine.bridge,
|
|
@@ -55044,4 +54593,52 @@ function Chatbot({ adapter, config, locale: localeProp, theme: themeProp, render
|
|
|
55044
54593
|
}
|
|
55045
54594
|
|
|
55046
54595
|
//#endregion
|
|
55047
|
-
|
|
54596
|
+
//#region src/react/VercelPayloadPreview.tsx
|
|
54597
|
+
/**
|
|
54598
|
+
* vercel 档(payload 预览):不渲染表单,展示 InteractionRequest 经 toVercelToolInvocation
|
|
54599
|
+
* 转换后的 Vercel AI SDK 数据契约 JSON 卡。仅提供 Cancel 结束交互(非完整运行时)。
|
|
54600
|
+
* @experimental
|
|
54601
|
+
*/
|
|
54602
|
+
function VercelPayloadPreview({ bridge }) {
|
|
54603
|
+
const t = useT();
|
|
54604
|
+
const pending = useSyncExternalStore(bridge.subscribe, () => bridge.pending);
|
|
54605
|
+
if (!pending) return null;
|
|
54606
|
+
const payload = toVercelToolInvocation(pending);
|
|
54607
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
54608
|
+
"data-testid": "vercel-payload-preview",
|
|
54609
|
+
className: "rounded-card border border-border bg-surface shadow-card",
|
|
54610
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
54611
|
+
className: "flex items-center gap-2 px-4 pt-4",
|
|
54612
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
54613
|
+
className: "font-display text-sm font-semibold text-ink",
|
|
54614
|
+
children: t("vercel.preview.title")
|
|
54615
|
+
}), /* @__PURE__ */ jsx(Badge, {
|
|
54616
|
+
tone: "neutral",
|
|
54617
|
+
children: t("vercel.preview.badge")
|
|
54618
|
+
})]
|
|
54619
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
54620
|
+
className: "flex flex-col gap-3 px-4 py-4",
|
|
54621
|
+
children: [
|
|
54622
|
+
/* @__PURE__ */ jsx("p", {
|
|
54623
|
+
className: "text-xs text-muted",
|
|
54624
|
+
children: t("vercel.preview.description")
|
|
54625
|
+
}),
|
|
54626
|
+
/* @__PURE__ */ jsx("pre", {
|
|
54627
|
+
className: "max-h-64 overflow-auto rounded-lg border border-border bg-canvas p-3 font-mono text-xs text-ink",
|
|
54628
|
+
children: JSON.stringify(payload, null, 2)
|
|
54629
|
+
}),
|
|
54630
|
+
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, {
|
|
54631
|
+
variant: "secondary",
|
|
54632
|
+
onClick: () => bridge.resolve({
|
|
54633
|
+
id: pending.id,
|
|
54634
|
+
cancelled: true
|
|
54635
|
+
}),
|
|
54636
|
+
children: t("interaction.cancel")
|
|
54637
|
+
}) })
|
|
54638
|
+
]
|
|
54639
|
+
})]
|
|
54640
|
+
});
|
|
54641
|
+
}
|
|
54642
|
+
|
|
54643
|
+
//#endregion
|
|
54644
|
+
export { A2uiSurfaceHost, A2uiSurfaceSnapshotHost, ChatEngine, Chatbot, CompositeUiBridge, DEFAULT_RENDERER_CAPABILITIES, ErrorCard, InteractionCard, InterruptedBanner, OpenUiSurfaceHost, OpenUiSurfaceSnapshotHost, ResultBlockList, ResultBlocksPro, SettingsDrawer, SkillBadges, SpecInteraction, VercelPayloadPreview, VercelSurfaceHost, VercelSurfaceSnapshotHost, chatbotDictionary, configureA2uiMarkdown, probeA2uiAvailability, probeOpenUiAvailability, useT };
|