@runtypelabs/persona 3.37.0 → 4.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.
Files changed (55) hide show
  1. package/README.md +4 -5
  2. package/dist/animations/glyph-cycle.d.cts +1 -1
  3. package/dist/animations/glyph-cycle.d.ts +1 -1
  4. package/dist/animations/{types-DgYsuwXL.d.cts → types-B_xbfvR0.d.cts} +263 -181
  5. package/dist/animations/{types-DgYsuwXL.d.ts → types-B_xbfvR0.d.ts} +263 -181
  6. package/dist/animations/wipe.d.cts +1 -1
  7. package/dist/animations/wipe.d.ts +1 -1
  8. package/dist/codegen.cjs +1 -1
  9. package/dist/codegen.js +1 -1
  10. package/dist/index.cjs +54 -52
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.cts +328 -839
  13. package/dist/index.d.ts +328 -839
  14. package/dist/index.global.js +41 -39
  15. package/dist/index.global.js.map +1 -1
  16. package/dist/index.js +54 -52
  17. package/dist/index.js.map +1 -1
  18. package/dist/install.global.js +1 -1
  19. package/dist/install.global.js.map +1 -1
  20. package/dist/smart-dom-reader.d.cts +269 -192
  21. package/dist/smart-dom-reader.d.ts +269 -192
  22. package/dist/theme-editor-preview.cjs +55 -53
  23. package/dist/theme-editor-preview.d.cts +269 -192
  24. package/dist/theme-editor-preview.d.ts +269 -192
  25. package/dist/theme-editor-preview.js +57 -55
  26. package/dist/theme-editor.d.cts +269 -192
  27. package/dist/theme-editor.d.ts +269 -192
  28. package/dist/widget.css +14 -0
  29. package/package.json +1 -1
  30. package/src/client.test.ts +446 -1041
  31. package/src/client.ts +684 -967
  32. package/src/components/message-bubble.ts +7 -0
  33. package/src/components/tool-bubble.ts +46 -33
  34. package/src/generated/runtype-openapi-contract.ts +210 -714
  35. package/src/index-core.ts +2 -3
  36. package/src/install.test.ts +1 -34
  37. package/src/install.ts +1 -26
  38. package/src/runtime/init.test.ts +8 -67
  39. package/src/runtime/init.ts +2 -17
  40. package/src/session.test.ts +8 -8
  41. package/src/session.ts +1 -1
  42. package/src/styles/widget.css +14 -0
  43. package/src/types.ts +12 -13
  44. package/src/ui.postprocess.test.ts +107 -0
  45. package/src/ui.ts +45 -5
  46. package/src/utils/__fixtures__/unified-translator.oracle.ts +62 -14
  47. package/src/utils/copy-selection.test.ts +37 -0
  48. package/src/utils/copy-selection.ts +19 -0
  49. package/src/utils/event-stream-capture.test.ts +9 -64
  50. package/src/utils/streaming-table.test.ts +100 -0
  51. package/src/utils/streaming-table.ts +103 -0
  52. package/src/utils/sequence-buffer.test.ts +0 -256
  53. package/src/utils/sequence-buffer.ts +0 -130
  54. package/src/utils/unified-event-bridge.test.ts +0 -263
  55. package/src/utils/unified-event-bridge.ts +0 -431
@@ -795,6 +795,13 @@ export const createStandardBubble = (
795
795
  const contentDiv = document.createElement("div");
796
796
  contentDiv.classList.add("persona-message-content");
797
797
 
798
+ // While streaming, lock table column widths (see widget.css) so rows append
799
+ // without per-chunk horizontal reflow. The class is dropped on the final,
800
+ // non-streaming render, relaxing tables to natural content-fit widths.
801
+ if (message.streaming) {
802
+ contentDiv.classList.add("persona-content-streaming");
803
+ }
804
+
798
805
  if (streamAnimationActive && streamPlugin) {
799
806
  if (streamPlugin.containerClass) {
800
807
  contentDiv.classList.add(streamPlugin.containerClass);
@@ -45,6 +45,22 @@ const getToolPreviewText = (message: AgentWidgetMessage, maxLines: number): stri
45
45
  .join("\n");
46
46
  };
47
47
 
48
+ /**
49
+ * Apply the colors for a tool-bubble code block (Arguments / Activity / Result).
50
+ *
51
+ * Defaults are theme-aware tokens so the blocks stay readable in dark themes.
52
+ */
53
+ const applyToolCodeBlockColors = (
54
+ pre: HTMLElement,
55
+ toolCallConfig: NonNullable<AgentWidgetConfig["toolCall"]>
56
+ ): void => {
57
+ pre.style.backgroundColor =
58
+ toolCallConfig.codeBlockBackgroundColor ?? "var(--persona-container, #f3f4f6)";
59
+ pre.style.borderColor =
60
+ toolCallConfig.codeBlockBorderColor ?? "var(--persona-border, #e5e7eb)";
61
+ pre.style.color = toolCallConfig.codeBlockTextColor ?? "var(--persona-text, #171717)";
62
+ };
63
+
48
64
  const getToolSummaryText = (
49
65
  message: AgentWidgetMessage,
50
66
  config?: AgentWidgetConfig
@@ -95,7 +111,14 @@ export const updateToolBubbleUI = (messageId: string, bubble: HTMLElement, confi
95
111
  const toggleIcon = headerMeta?.querySelector(':scope > .persona-flex.persona-items-center') as HTMLElement;
96
112
  if (toggleIcon) {
97
113
  toggleIcon.innerHTML = "";
98
- const iconColor = toolCallConfig.toggleTextColor || toolCallConfig.headerTextColor || "currentColor";
114
+ // Default the toggle chevron to the tool-call title color so it stays
115
+ // readable on whatever surface the title does. The title falls back to
116
+ // `.persona-text-persona-primary` (var(--persona-primary)) when no
117
+ // `headerTextColor` is set, so mirror that here instead of `currentColor`.
118
+ const iconColor =
119
+ toolCallConfig.toggleTextColor ||
120
+ toolCallConfig.headerTextColor ||
121
+ "var(--persona-primary, #171717)";
99
122
  const chevronIcon = renderLucideIcon(expanded ? "chevron-up" : "chevron-down", 16, iconColor, 2);
100
123
  if (chevronIcon) {
101
124
  toggleIcon.appendChild(chevronIcon);
@@ -328,7 +351,14 @@ export const createToolBubble = (message: AgentWidgetMessage, config?: AgentWidg
328
351
  let toggleIcon: HTMLElement | null = null;
329
352
  if (expandable) {
330
353
  toggleIcon = createElement("div", "persona-flex persona-items-center");
331
- const iconColor = toolCallConfig.toggleTextColor || toolCallConfig.headerTextColor || "currentColor";
354
+ // Default the toggle chevron to the tool-call title color so it stays
355
+ // readable on whatever surface the title does. The title falls back to
356
+ // `.persona-text-persona-primary` (var(--persona-primary)) when no
357
+ // `headerTextColor` is set, so mirror that here instead of `currentColor`.
358
+ const iconColor =
359
+ toolCallConfig.toggleTextColor ||
360
+ toolCallConfig.headerTextColor ||
361
+ "var(--persona-primary, #171717)";
332
362
  const chevronIcon = renderLucideIcon(expanded ? "chevron-up" : "chevron-down", 16, iconColor, 2);
333
363
  if (chevronIcon) {
334
364
  toggleIcon.appendChild(chevronIcon);
@@ -425,20 +455,12 @@ export const createToolBubble = (message: AgentWidgetMessage, config?: AgentWidg
425
455
  argsLabel.textContent = "Arguments";
426
456
  const argsPre = createElement(
427
457
  "pre",
428
- "persona-max-h-48 persona-overflow-auto persona-whitespace-pre-wrap persona-rounded-lg persona-border persona-border-gray-100 persona-bg-white persona-px-3 persona-py-2 persona-text-xs persona-text-persona-primary"
458
+ "persona-max-h-48 persona-overflow-auto persona-whitespace-pre-wrap persona-rounded-lg persona-border persona-px-3 persona-py-2 persona-text-xs"
429
459
  );
430
460
  // Ensure font size matches header text (0.75rem / 12px)
431
461
  argsPre.style.fontSize = "0.75rem";
432
462
  argsPre.style.lineHeight = "1rem";
433
- if (toolCallConfig.codeBlockBackgroundColor) {
434
- argsPre.style.backgroundColor = toolCallConfig.codeBlockBackgroundColor;
435
- }
436
- if (toolCallConfig.codeBlockBorderColor) {
437
- argsPre.style.borderColor = toolCallConfig.codeBlockBorderColor;
438
- }
439
- if (toolCallConfig.codeBlockTextColor) {
440
- argsPre.style.color = toolCallConfig.codeBlockTextColor;
441
- }
463
+ applyToolCodeBlockColors(argsPre, toolCallConfig);
442
464
  argsPre.textContent = formatUnknownValue(tool.args);
443
465
  argsBlock.append(argsLabel, argsPre);
444
466
  content.appendChild(argsBlock);
@@ -456,20 +478,12 @@ export const createToolBubble = (message: AgentWidgetMessage, config?: AgentWidg
456
478
  logsLabel.textContent = "Activity";
457
479
  const logsPre = createElement(
458
480
  "pre",
459
- "persona-max-h-48 persona-overflow-auto persona-whitespace-pre-wrap persona-rounded-lg persona-border persona-border-gray-100 persona-bg-white persona-px-3 persona-py-2 persona-text-xs persona-text-persona-primary"
481
+ "persona-max-h-48 persona-overflow-auto persona-whitespace-pre-wrap persona-rounded-lg persona-border persona-px-3 persona-py-2 persona-text-xs"
460
482
  );
461
483
  // Ensure font size matches header text (0.75rem / 12px)
462
484
  logsPre.style.fontSize = "0.75rem";
463
485
  logsPre.style.lineHeight = "1rem";
464
- if (toolCallConfig.codeBlockBackgroundColor) {
465
- logsPre.style.backgroundColor = toolCallConfig.codeBlockBackgroundColor;
466
- }
467
- if (toolCallConfig.codeBlockBorderColor) {
468
- logsPre.style.borderColor = toolCallConfig.codeBlockBorderColor;
469
- }
470
- if (toolCallConfig.codeBlockTextColor) {
471
- logsPre.style.color = toolCallConfig.codeBlockTextColor;
472
- }
486
+ applyToolCodeBlockColors(logsPre, toolCallConfig);
473
487
  logsPre.textContent = tool.chunks.join("");
474
488
  logsBlock.append(logsLabel, logsPre);
475
489
  content.appendChild(logsBlock);
@@ -487,20 +501,12 @@ export const createToolBubble = (message: AgentWidgetMessage, config?: AgentWidg
487
501
  resultLabel.textContent = "Result";
488
502
  const resultPre = createElement(
489
503
  "pre",
490
- "persona-max-h-48 persona-overflow-auto persona-whitespace-pre-wrap persona-rounded-lg persona-border persona-border-gray-100 persona-bg-white persona-px-3 persona-py-2 persona-text-xs persona-text-persona-primary"
504
+ "persona-max-h-48 persona-overflow-auto persona-whitespace-pre-wrap persona-rounded-lg persona-border persona-px-3 persona-py-2 persona-text-xs"
491
505
  );
492
506
  // Ensure font size matches header text (0.75rem / 12px)
493
507
  resultPre.style.fontSize = "0.75rem";
494
508
  resultPre.style.lineHeight = "1rem";
495
- if (toolCallConfig.codeBlockBackgroundColor) {
496
- resultPre.style.backgroundColor = toolCallConfig.codeBlockBackgroundColor;
497
- }
498
- if (toolCallConfig.codeBlockBorderColor) {
499
- resultPre.style.borderColor = toolCallConfig.codeBlockBorderColor;
500
- }
501
- if (toolCallConfig.codeBlockTextColor) {
502
- resultPre.style.color = toolCallConfig.codeBlockTextColor;
503
- }
509
+ applyToolCodeBlockColors(resultPre, toolCallConfig);
504
510
  resultPre.textContent = formatUnknownValue(tool.result);
505
511
  resultBlock.append(resultLabel, resultPre);
506
512
  content.appendChild(resultBlock);
@@ -522,7 +528,14 @@ export const createToolBubble = (message: AgentWidgetMessage, config?: AgentWidg
522
528
  header.setAttribute("aria-expanded", expanded ? "true" : "false");
523
529
  if (toggleIcon) {
524
530
  toggleIcon.innerHTML = "";
525
- const iconColor = toolCallConfig.toggleTextColor || toolCallConfig.headerTextColor || "currentColor";
531
+ // Default the toggle chevron to the tool-call title color so it stays
532
+ // readable on whatever surface the title does. The title falls back to
533
+ // `.persona-text-persona-primary` (var(--persona-primary)) when no
534
+ // `headerTextColor` is set, so mirror that here instead of `currentColor`.
535
+ const iconColor =
536
+ toolCallConfig.toggleTextColor ||
537
+ toolCallConfig.headerTextColor ||
538
+ "var(--persona-primary, #171717)";
526
539
  const chevronIcon = renderLucideIcon(expanded ? "chevron-up" : "chevron-down", 16, iconColor, 2);
527
540
  if (chevronIcon) {
528
541
  toggleIcon.appendChild(chevronIcon);