@webless/agent 0.2.9 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/embed.cjs CHANGED
@@ -237,6 +237,54 @@ function clearPersistedAgentSession(visitorSessionId, options) {
237
237
  }
238
238
 
239
239
  // src/runtime/client.ts
240
+ function isTurnBoundary(event) {
241
+ return event.type === "session.waiting" || event.type === "session.completed" || event.type === "session.failed";
242
+ }
243
+ function applyMessageEvent(event, rendered, handlers) {
244
+ const step = mapStepLabel(event);
245
+ if (step) handlers.onStep?.(step.label, step.detail);
246
+ if (event.type === "session.failed") {
247
+ throw new Error(event.data.message || event.data.code);
248
+ }
249
+ if (event.type === "message.completed") {
250
+ handlers.onComplete?.();
251
+ }
252
+ if (event.type !== "message.appended") return rendered;
253
+ const { messageDelta, messageSoFar } = event.data;
254
+ let delta = messageDelta;
255
+ let next = rendered;
256
+ if (messageSoFar.startsWith(rendered)) {
257
+ delta = messageSoFar.slice(rendered.length);
258
+ next = messageSoFar;
259
+ } else if (messageDelta) {
260
+ next += messageDelta;
261
+ }
262
+ if (delta) handlers.onDelta(delta);
263
+ return next;
264
+ }
265
+ function latestTurnEvents(events) {
266
+ let startIndex = -1;
267
+ for (let index = events.length - 1; index >= 0; index -= 1) {
268
+ if (events[index]?.type === "message.received") {
269
+ startIndex = index;
270
+ break;
271
+ }
272
+ }
273
+ return startIndex >= 0 ? events.slice(startIndex) : [];
274
+ }
275
+ function renderTurn(events) {
276
+ let rendered = "";
277
+ for (const event of events) {
278
+ if (event.type !== "message.appended") continue;
279
+ const { messageDelta, messageSoFar } = event.data;
280
+ if (messageSoFar.startsWith(rendered)) {
281
+ rendered = messageSoFar;
282
+ } else if (messageDelta) {
283
+ rendered += messageDelta;
284
+ }
285
+ }
286
+ return rendered;
287
+ }
240
288
  function mapStepLabel(event) {
241
289
  if (event.type !== "step.started") return null;
242
290
  const stepIndex = event.data.stepIndex;
@@ -272,8 +320,13 @@ var AgentSession = class {
272
320
  return this.session?.state.sessionId ?? loadPersistedAgentSession(this.visitorSessionId, this.storeOptions)?.sessionId;
273
321
  }
274
322
  reset() {
275
- void this.activeResponse?.cancel().catch(() => {
276
- });
323
+ if (this.activeResponse) {
324
+ void this.activeResponse.cancel().catch(() => {
325
+ });
326
+ } else {
327
+ void this.session?.cancel().catch(() => {
328
+ });
329
+ }
277
330
  this.activeResponse = void 0;
278
331
  this.session = void 0;
279
332
  clearPersistedAgentSession(this.visitorSessionId, this.storeOptions);
@@ -298,7 +351,8 @@ var AgentSession = class {
298
351
  if (this.client && this.clientHost === config.host) {
299
352
  return this.client;
300
353
  }
301
- this.reset();
354
+ this.activeResponse = void 0;
355
+ this.session = void 0;
302
356
  this.client = new import_client2.Client({
303
357
  auth: { bearer: () => this.capability.getAccessToken() },
304
358
  host: config.host,
@@ -347,28 +401,20 @@ var AgentSession = class {
347
401
  this.persistSessionCursor(session);
348
402
  }
349
403
  this.activeResponse = response;
404
+ let streamIndex = session?.state.streamIndex ?? 0;
350
405
  let rendered = "";
351
406
  try {
352
407
  for await (const event of response) {
353
408
  if (signal.aborted) break;
354
- const step = mapStepLabel(event);
355
- if (step) handlers.onStep?.(step.label, step.detail);
356
- if (event.type === "message.appended") {
357
- const { messageDelta, messageSoFar } = event.data;
358
- let delta = messageDelta;
359
- if (messageSoFar.startsWith(rendered)) {
360
- delta = messageSoFar.slice(rendered.length);
361
- rendered = messageSoFar;
362
- } else if (messageDelta) {
363
- rendered += messageDelta;
364
- }
365
- if (delta) handlers.onDelta(delta);
366
- }
367
- if (event.type === "message.completed") {
368
- handlers.onComplete?.();
369
- }
370
- if (event.type === "session.failed") {
371
- throw new Error(event.data.message || event.data.code);
409
+ rendered = applyMessageEvent(event, rendered, handlers);
410
+ streamIndex += 1;
411
+ if (session) {
412
+ savePersistedAgentSession(
413
+ this.visitorSessionId,
414
+ session.state.sessionId,
415
+ streamIndex,
416
+ this.storeOptions
417
+ );
372
418
  }
373
419
  }
374
420
  } finally {
@@ -380,15 +426,83 @@ var AgentSession = class {
380
426
  if (!rendered.trim() && !signal.aborted) {
381
427
  throw new Error("Empty response from runtime");
382
428
  }
383
- if (signal.aborted) {
384
- await response.cancel().catch(() => {
385
- });
429
+ return rendered.trim();
430
+ }
431
+ async resumeTurn(message, signal, handlers, initialText = "") {
432
+ const persisted = loadPersistedAgentSession(this.visitorSessionId, this.storeOptions);
433
+ if (!persisted) return null;
434
+ const client = this.ensureClient();
435
+ const attached = client.sessions.attach(persisted.sessionId, {
436
+ streamIndex: persisted.streamIndex
437
+ });
438
+ const snapshot = await withCapabilityRefresh(
439
+ this.capability,
440
+ () => attached.snapshot({ signal })
441
+ );
442
+ const turnEvents = latestTurnEvents(snapshot.events);
443
+ const received = turnEvents[0];
444
+ if (received?.type !== "message.received" || received.data.message !== message) {
445
+ return null;
446
+ }
447
+ let rendered = renderTurn(turnEvents);
448
+ if (rendered.startsWith(initialText)) {
449
+ const missedText = rendered.slice(initialText.length);
450
+ if (missedText) handlers.onDelta(missedText);
451
+ } else if (initialText.startsWith(rendered)) {
452
+ rendered = initialText;
453
+ } else if (!initialText.startsWith(rendered)) {
454
+ rendered = initialText + rendered;
455
+ }
456
+ let session = client.sessions.attach(snapshot.session.sessionId, {
457
+ streamIndex: snapshot.session.streamIndex
458
+ });
459
+ this.session = session;
460
+ this.persistSessionCursor(session);
461
+ let snapshotBoundary;
462
+ for (let index = turnEvents.length - 1; index >= 0; index -= 1) {
463
+ const event = turnEvents[index];
464
+ if (event && isTurnBoundary(event)) {
465
+ snapshotBoundary = event;
466
+ break;
467
+ }
468
+ }
469
+ if (snapshotBoundary) {
470
+ if (snapshotBoundary.type === "session.failed") {
471
+ throw new Error(snapshotBoundary.data.message || snapshotBoundary.data.code);
472
+ }
473
+ handlers.onComplete?.();
474
+ if (!rendered.trim()) throw new Error("Empty response from runtime");
475
+ return rendered.trim();
476
+ }
477
+ let streamIndex = snapshot.session.streamIndex;
478
+ for await (const event of session.stream({ signal })) {
479
+ if (signal.aborted) break;
480
+ rendered = applyMessageEvent(event, rendered, handlers);
481
+ streamIndex += 1;
482
+ savePersistedAgentSession(
483
+ this.visitorSessionId,
484
+ session.state.sessionId,
485
+ streamIndex,
486
+ this.storeOptions
487
+ );
488
+ if (isTurnBoundary(event)) break;
489
+ }
490
+ session = client.sessions.attach(session.state.sessionId, { streamIndex });
491
+ this.session = session;
492
+ this.persistSessionCursor(session);
493
+ if (!rendered.trim() && !signal.aborted) {
494
+ throw new Error("Empty response from runtime");
386
495
  }
387
496
  return rendered.trim();
388
497
  }
389
498
  cancelActive() {
390
- this.activeResponse?.cancel().catch(() => {
391
- });
499
+ if (this.activeResponse) {
500
+ this.activeResponse.cancel().catch(() => {
501
+ });
502
+ } else {
503
+ this.session?.cancel().catch(() => {
504
+ });
505
+ }
392
506
  }
393
507
  };
394
508
  function createAgentClient(options) {
@@ -422,6 +536,12 @@ function createAgentClient(options) {
422
536
  sendOptions.signal ?? new AbortController().signal,
423
537
  sendOptions.handlers
424
538
  ),
539
+ resumeTurn: (resumeOptions) => session.resumeTurn(
540
+ resumeOptions.message,
541
+ resumeOptions.signal ?? new AbortController().signal,
542
+ resumeOptions.handlers,
543
+ resumeOptions.initialText
544
+ ),
425
545
  reset: () => session.reset(),
426
546
  cancelActive: () => session.cancelActive(),
427
547
  getActiveSessionId: () => session.getActiveSessionId()
@@ -450,6 +570,58 @@ function formatAgentError(error) {
450
570
  return "Runtime request failed";
451
571
  }
452
572
 
573
+ // src/react/persisted-conversation.ts
574
+ var CONVERSATION_VERSION = 1;
575
+ function conversationKey(storageKeyPrefix, visitorSessionId) {
576
+ return `${storageKeyPrefix}:conversation:${visitorSessionId}`;
577
+ }
578
+ function parseMessage(value) {
579
+ if (typeof value !== "object" || value === null) return null;
580
+ const record = value;
581
+ if (typeof record.id !== "string" || record.role !== "agent" && record.role !== "visitor" || typeof record.text !== "string" || typeof record.createdAt !== "number" || !Number.isFinite(record.createdAt)) {
582
+ return null;
583
+ }
584
+ return {
585
+ id: record.id,
586
+ role: record.role,
587
+ text: record.text,
588
+ createdAt: record.createdAt
589
+ };
590
+ }
591
+ function loadPersistedAgentConversation(storageKeyPrefix, visitorSessionId) {
592
+ if (typeof sessionStorage === "undefined") return null;
593
+ const raw = sessionStorage.getItem(conversationKey(storageKeyPrefix, visitorSessionId));
594
+ if (!raw) return null;
595
+ try {
596
+ const value = JSON.parse(raw);
597
+ if (typeof value !== "object" || value === null) return null;
598
+ const record = value;
599
+ if (record.version !== CONVERSATION_VERSION || !Array.isArray(record.messages) || typeof record.pending !== "boolean" || typeof record.streamingText !== "string") {
600
+ return null;
601
+ }
602
+ const messages = record.messages.map(parseMessage);
603
+ if (messages.some((message) => message === null)) return null;
604
+ return {
605
+ messages: messages.filter((message) => message !== null),
606
+ pending: record.pending,
607
+ streamingText: record.streamingText
608
+ };
609
+ } catch {
610
+ return null;
611
+ }
612
+ }
613
+ function savePersistedAgentConversation(storageKeyPrefix, visitorSessionId, conversation) {
614
+ if (typeof sessionStorage === "undefined") return;
615
+ sessionStorage.setItem(
616
+ conversationKey(storageKeyPrefix, visitorSessionId),
617
+ JSON.stringify({ version: CONVERSATION_VERSION, ...conversation })
618
+ );
619
+ }
620
+ function clearPersistedAgentConversation(storageKeyPrefix, visitorSessionId) {
621
+ if (typeof sessionStorage === "undefined") return;
622
+ sessionStorage.removeItem(conversationKey(storageKeyPrefix, visitorSessionId));
623
+ }
624
+
453
625
  // src/react/hooks/useAgentChat.ts
454
626
  var GREETING_MESSAGE = {
455
627
  id: "greeting",
@@ -466,6 +638,15 @@ var INITIAL_STATE = {
466
638
  streamingText: "",
467
639
  error: null
468
640
  };
641
+ function stateFromConversation(conversation) {
642
+ if (!conversation || conversation.messages.length === 0) return INITIAL_STATE;
643
+ return {
644
+ ...INITIAL_STATE,
645
+ messages: conversation.messages,
646
+ phase: conversation.pending ? conversation.streamingText ? "streaming" : "thinking" : "complete",
647
+ streamingText: conversation.streamingText
648
+ };
649
+ }
469
650
  var STATUS_SEQUENCE = [
470
651
  { id: "s1", label: "Starting Eve session", ms: 400 },
471
652
  { id: "s2", label: "Connecting to runtime", ms: 500 }
@@ -497,8 +678,6 @@ function useAgentChat({
497
678
  visitorSessionId,
498
679
  storageKeyPrefix
499
680
  }) {
500
- const [state, setState] = (0, import_react.useState)(INITIAL_STATE);
501
- const runRef = (0, import_react.useRef)(null);
502
681
  const resolvedStorageKeyPrefix = (0, import_react.useMemo)(
503
682
  () => storageKeyPrefix?.trim() || buildAgentStorageKeyPrefix({ customerId, indexId, version, runtimeOrigin }),
504
683
  [customerId, indexId, runtimeOrigin, storageKeyPrefix, version]
@@ -507,6 +686,12 @@ function useAgentChat({
507
686
  () => visitorSessionId?.trim() || getOrCreateVisitorSessionId({ storageKeyPrefix: resolvedStorageKeyPrefix }),
508
687
  [resolvedStorageKeyPrefix, visitorSessionId]
509
688
  );
689
+ const [state, setState] = (0, import_react.useState)(
690
+ () => stateFromConversation(
691
+ loadPersistedAgentConversation(resolvedStorageKeyPrefix, visitorId)
692
+ )
693
+ );
694
+ const runRef = (0, import_react.useRef)(null);
510
695
  const clientRef = (0, import_react.useRef)(
511
696
  createAgentClient({
512
697
  customerId,
@@ -517,20 +702,15 @@ function useAgentChat({
517
702
  storageKeyPrefix: resolvedStorageKeyPrefix
518
703
  })
519
704
  );
520
- const identityRef = (0, import_react.useRef)(null);
521
705
  const identityKey = `${customerId ?? ""}|${indexId}|${version ?? "published"}|${runtimeOrigin ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}`;
706
+ const identityRef = (0, import_react.useRef)(identityKey);
522
707
  (0, import_react.useEffect)(() => {
523
- if (identityRef.current === null) {
524
- identityRef.current = identityKey;
525
- return;
526
- }
527
708
  if (identityRef.current === identityKey) {
528
709
  return;
529
710
  }
530
711
  identityRef.current = identityKey;
531
712
  runRef.current?.abort();
532
713
  runRef.current = null;
533
- clientRef.current.reset();
534
714
  clientRef.current = createAgentClient({
535
715
  customerId,
536
716
  indexId,
@@ -539,81 +719,81 @@ function useAgentChat({
539
719
  visitorSessionId: visitorId,
540
720
  storageKeyPrefix: resolvedStorageKeyPrefix
541
721
  });
542
- setState(INITIAL_STATE);
722
+ setState(
723
+ stateFromConversation(
724
+ loadPersistedAgentConversation(resolvedStorageKeyPrefix, visitorId)
725
+ )
726
+ );
543
727
  }, [customerId, identityKey, indexId, runtimeOrigin, resolvedStorageKeyPrefix, version, visitorId]);
728
+ (0, import_react.useEffect)(() => {
729
+ if (!hasVisitorMessages(state.messages)) return;
730
+ savePersistedAgentConversation(resolvedStorageKeyPrefix, visitorId, {
731
+ messages: state.messages,
732
+ pending: isAgentBusy(state.phase),
733
+ streamingText: state.streamingText
734
+ });
735
+ }, [resolvedStorageKeyPrefix, state.messages, state.phase, state.streamingText, visitorId]);
544
736
  const reset = (0, import_react.useCallback)(() => {
545
737
  runRef.current?.abort();
546
738
  runRef.current = null;
547
739
  clientRef.current.reset();
740
+ clearPersistedAgentConversation(resolvedStorageKeyPrefix, visitorId);
548
741
  setState(INITIAL_STATE);
549
- }, []);
550
- const submit = (0, import_react.useCallback)(
551
- async (visitorText) => {
552
- runRef.current?.abort();
553
- clientRef.current.cancelActive();
554
- const controller = new AbortController();
555
- runRef.current = controller;
742
+ }, [resolvedStorageKeyPrefix, visitorId]);
743
+ const runTurn = (0, import_react.useCallback)(
744
+ async (input) => {
745
+ const { controller, initialText = "", resume, visitorText } = input;
556
746
  const { signal } = controller;
557
747
  const isActiveRun = () => runRef.current === controller && !signal.aborted;
558
- const visitorMessage = {
559
- id: `visitor-${Date.now()}`,
560
- role: "visitor",
561
- text: visitorText,
562
- createdAt: Date.now()
563
- };
564
- setState((prev) => ({
565
- ...prev,
566
- phase: "thinking",
567
- messages: [...prev.messages, visitorMessage],
568
- toolSteps: [{ id: "s1", label: "Starting Eve session", state: "active" }],
569
- journey: null,
570
- followUps: [],
571
- streamingText: "",
572
- error: null
573
- }));
574
748
  try {
575
- let streamStarted = false;
576
- const planningPromise = runStatusSequence(signal, (step) => {
749
+ let streamStarted = Boolean(initialText);
750
+ let streamed = initialText;
751
+ const planningPromise = resume ? Promise.resolve() : runStatusSequence(signal, (step) => {
577
752
  if (streamStarted || !isActiveRun()) return;
578
753
  setState((prev) => ({ ...prev, phase: "running-tools", toolSteps: [step] }));
579
754
  });
580
- let streamed = "";
581
- const finalText = await clientRef.current.sendTurn(visitorText, {
582
- signal,
583
- handlers: {
584
- onStep: (label, detail) => {
585
- if (streamStarted || !isActiveRun()) return;
755
+ const handlers = {
756
+ onStep: (label, detail) => {
757
+ if (streamStarted || !isActiveRun()) return;
758
+ setState((prev) => ({
759
+ ...prev,
760
+ phase: "running-tools",
761
+ toolSteps: [{ id: `step-${label}`, label, detail, state: "active" }]
762
+ }));
763
+ },
764
+ onDelta: (delta) => {
765
+ if (!isActiveRun()) return;
766
+ void planningPromise.catch(() => {
767
+ });
768
+ if (!streamStarted) {
769
+ streamStarted = true;
586
770
  setState((prev) => ({
587
771
  ...prev,
588
- phase: "running-tools",
589
- toolSteps: [{ id: `step-${label}`, label, detail, state: "active" }]
772
+ phase: "streaming",
773
+ toolSteps: [],
774
+ streamingText: ""
590
775
  }));
591
- },
592
- onDelta: (delta) => {
593
- if (!isActiveRun()) return;
594
- void planningPromise.catch(() => {
595
- });
596
- if (!streamStarted) {
597
- streamStarted = true;
598
- setState((prev) => ({
599
- ...prev,
600
- phase: "streaming",
601
- toolSteps: [],
602
- streamingText: ""
603
- }));
604
- }
605
- streamed += delta;
606
- setState((prev) => ({ ...prev, phase: "streaming", streamingText: streamed }));
607
- },
608
- onComplete: () => {
609
- if (!isActiveRun()) return;
610
- streamStarted = true;
611
776
  }
777
+ streamed += delta;
778
+ setState((prev) => ({ ...prev, phase: "streaming", streamingText: streamed }));
779
+ },
780
+ onComplete: () => {
781
+ if (!isActiveRun()) return;
782
+ streamStarted = true;
612
783
  }
613
- });
784
+ };
785
+ let finalText = resume ? await clientRef.current.resumeTurn({
786
+ handlers,
787
+ initialText,
788
+ message: visitorText,
789
+ signal
790
+ }) : await clientRef.current.sendTurn(visitorText, { handlers, signal });
791
+ if (resume && finalText === null) {
792
+ finalText = await clientRef.current.sendTurn(visitorText, { handlers, signal });
793
+ }
614
794
  await planningPromise.catch(() => {
615
795
  });
616
- if (!isActiveRun()) return;
796
+ if (!isActiveRun() || finalText === null) return;
617
797
  const agentMessage = {
618
798
  id: `agent-${Date.now()}`,
619
799
  role: "agent",
@@ -629,6 +809,7 @@ function useAgentChat({
629
809
  followUps: [],
630
810
  journey: null
631
811
  }));
812
+ runRef.current = null;
632
813
  } catch (error) {
633
814
  if (error instanceof DOMException && error.name === "AbortError") return;
634
815
  if (!isActiveRun()) return;
@@ -641,14 +822,66 @@ function useAgentChat({
641
822
  streamingText: "",
642
823
  error: message
643
824
  }));
825
+ runRef.current = null;
644
826
  }
645
827
  },
646
- [customerId, indexId, runtimeOrigin, resolvedStorageKeyPrefix, version, visitorId]
828
+ []
829
+ );
830
+ const submit = (0, import_react.useCallback)(
831
+ async (visitorText) => {
832
+ if (runRef.current) {
833
+ runRef.current.abort();
834
+ clientRef.current.cancelActive();
835
+ }
836
+ const controller = new AbortController();
837
+ runRef.current = controller;
838
+ const visitorMessage = {
839
+ id: `visitor-${Date.now()}`,
840
+ role: "visitor",
841
+ text: visitorText,
842
+ createdAt: Date.now()
843
+ };
844
+ setState((prev) => ({
845
+ ...prev,
846
+ phase: "thinking",
847
+ messages: [...prev.messages, visitorMessage],
848
+ toolSteps: [{ id: "s1", label: "Starting Eve session", state: "active" }],
849
+ journey: null,
850
+ followUps: [],
851
+ streamingText: "",
852
+ error: null
853
+ }));
854
+ await runTurn({ controller, resume: false, visitorText });
855
+ },
856
+ [runTurn]
647
857
  );
858
+ (0, import_react.useEffect)(() => {
859
+ const conversation = loadPersistedAgentConversation(
860
+ resolvedStorageKeyPrefix,
861
+ visitorId
862
+ );
863
+ if (!conversation?.pending) return;
864
+ const visitorMessage = [...conversation.messages].reverse().find((message) => message.role === "visitor");
865
+ if (!visitorMessage) return;
866
+ const controller = new AbortController();
867
+ runRef.current = controller;
868
+ void runTurn({
869
+ controller,
870
+ initialText: conversation.streamingText,
871
+ resume: true,
872
+ visitorText: visitorMessage.text
873
+ });
874
+ return () => {
875
+ if (runRef.current === controller) {
876
+ runRef.current = null;
877
+ }
878
+ controller.abort();
879
+ };
880
+ }, [identityKey, resolvedStorageKeyPrefix, runTurn, visitorId]);
648
881
  (0, import_react.useEffect)(() => {
649
882
  return () => {
650
883
  runRef.current?.abort();
651
- clientRef.current.cancelActive();
884
+ runRef.current = null;
652
885
  };
653
886
  }, []);
654
887
  return {
@@ -669,6 +902,9 @@ function createIdleSuggestions() {
669
902
  { id: "idle-3", label: "What should I ask you?" }
670
903
  ];
671
904
  }
905
+ function isAgentBusy(phase) {
906
+ return phase === "thinking" || phase === "running-tools" || phase === "streaming";
907
+ }
672
908
 
673
909
  // src/react/hooks/useIsMobile.ts
674
910
  var import_react2 = require("react");
@@ -873,15 +1109,27 @@ function FollowUpChips({
873
1109
  }
874
1110
 
875
1111
  // src/react/components/MessageBubble/MessageBubble.tsx
1112
+ var import_streamdown = require("streamdown");
1113
+ var import_styles = require("streamdown/styles.css");
876
1114
  var import_jsx_runtime5 = require("react/jsx-runtime");
877
1115
  function MessageBubble({ message }) {
878
1116
  if (message.role === "visitor") {
879
1117
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "message-bubble__text", children: message.text }) });
880
1118
  }
881
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("article", { className: "message-bubble message-bubble--agent", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "message-bubble__text", children: [
882
- message.text,
883
- message.streaming ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "tool-timeline__cursor", "aria-hidden": "true" }) : null
884
- ] }) });
1119
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("article", { className: "message-bubble message-bubble--agent", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "message-bubble__text", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1120
+ import_streamdown.Streamdown,
1121
+ {
1122
+ animated: true,
1123
+ caret: "circle",
1124
+ className: "message-bubble__markdown",
1125
+ controls: false,
1126
+ isAnimating: message.streaming,
1127
+ linkSafety: { enabled: false },
1128
+ mode: message.streaming ? "streaming" : "static",
1129
+ skipHtml: true,
1130
+ children: message.text
1131
+ }
1132
+ ) }) });
885
1133
  }
886
1134
 
887
1135
  // src/react/components/AgentRail/AgentRail.tsx