@tangle-network/sandbox-ui 7.0.4 → 7.0.6

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 (44) hide show
  1. package/README.md +2 -0
  2. package/dist/{AgentTree-Dzy6lrfP.js → AgentTree-B1iTTYNe.js} +1 -1
  3. package/dist/{use-follow-tail-Df965WQi.js → ConversationRowView-C4TXICBT.js} +2 -2
  4. package/dist/{ResearchReport-DKWDmzdK.js → ResearchReport-kYGwgHC7.js} +2 -2
  5. package/dist/{chat-B_5Lwevm.js → chat-DcaqQX2X.js} +32 -28
  6. package/dist/chat.d.ts +1 -1
  7. package/dist/chat.js +1 -1
  8. package/dist/{dashboard-C7QJJw7-.js → dashboard-C1pNlewR.js} +1 -1
  9. package/dist/dashboard.js +1 -1
  10. package/dist/globals.css +44 -68
  11. package/dist/hooks.d.ts +2 -2
  12. package/dist/hooks.js +2 -2
  13. package/dist/{index-PolYo7h9.d.ts → index-CGHJonni.d.ts} +65 -2
  14. package/dist/index-CvHul4IJ.d.ts +26 -0
  15. package/dist/{index-1Q4Jtlic.d.ts → index-PxmhpV0y.d.ts} +1 -17
  16. package/dist/index.d.ts +5 -5
  17. package/dist/index.js +11 -11
  18. package/dist/primitives-l-Qv14bS.js +23 -0
  19. package/dist/primitives.d.ts +2 -2
  20. package/dist/primitives.js +1 -1
  21. package/dist/record/ResearchReport.js +1 -1
  22. package/dist/{record-Cc_WNtG8.js → record-Dmyq0jfl.js} +2 -2
  23. package/dist/record.js +1 -1
  24. package/dist/report-viewer.js +75 -75
  25. package/dist/run/live.js +1 -1
  26. package/dist/run/record.js +3 -3
  27. package/dist/run-C9GGriUv.js +238 -0
  28. package/dist/run.d.ts +2 -2
  29. package/dist/run.js +6 -6
  30. package/dist/runtime-viewer/AgentGraphCanvas-P_PFS2Ko-B7S6Fwwy.js +563 -0
  31. package/dist/runtime-viewer/{latest-events-CMbdBLcT-uhVN4JLh.js → latest-events-wofY6ifW-B8_bfLwI.js} +581 -112
  32. package/dist/styles.css +44 -68
  33. package/dist/terminal.js +1 -1
  34. package/dist/{trace-workspace-EArXc0uP.js → trace-workspace-mq1NcP7e.js} +80 -49
  35. package/dist/{workbench-D0ALR40M.js → workbench-BUrlhR-P.js} +3 -2
  36. package/dist/workbench.js +1 -1
  37. package/dist/workspace-viewer.js +10599 -10460
  38. package/package.json +13 -11
  39. package/tests/visual/content-share.mjs +35 -0
  40. package/dist/index-CEtc2U5v.d.ts +0 -26
  41. package/dist/primitives-znfPK9NP.js +0 -23
  42. package/dist/run-CpJ_COuz.js +0 -5
  43. package/dist/runtime-viewer/AgentGraphCanvas-xHVW-YRV-Ch1fnK9k.js +0 -957
  44. /package/dist/{terminal-nUCznZRj.js → terminal-view-nUCznZRj.js} +0 -0
package/dist/styles.css CHANGED
@@ -26,8 +26,6 @@
26
26
  --color-violet-400: oklch(70.2% 0.183 293.541);
27
27
  --color-violet-500: oklch(60.6% 0.25 292.717);
28
28
  --color-zinc-400: oklch(70.5% 0.015 286.067);
29
- --color-neutral-400: oklch(70.8% 0 none);
30
- --color-neutral-500: oklch(55.6% 0 none);
31
29
  --color-black: #000;
32
30
  --color-white: #fff;
33
31
  --spacing: 0.25rem;
@@ -81,10 +79,8 @@
81
79
  --animate-spin: spin 1s linear infinite;
82
80
  --animate-ping: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
83
81
  --animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
84
- --animate-bounce: bounce 1s infinite;
85
82
  --blur-sm: 8px;
86
83
  --blur-md: 12px;
87
- --blur-xl: 24px;
88
84
  --default-transition-duration: 150ms;
89
85
  --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
90
86
  --default-font-family: var(--font-sans);
@@ -548,6 +544,9 @@
548
544
  .m-0 {
549
545
  margin: 0px;
550
546
  }
547
+ .m-1 {
548
+ margin: var(--spacing);
549
+ }
551
550
  .m-4 {
552
551
  margin: calc(var(--spacing) * 4);
553
552
  }
@@ -856,6 +855,10 @@
856
855
  width: var(--control-height-sm,2rem);
857
856
  height: var(--control-height-sm,2rem);
858
857
  }
858
+ .size-auto {
859
+ width: auto;
860
+ height: auto;
861
+ }
859
862
  .size-full {
860
863
  width: 100%;
861
864
  height: 100%;
@@ -1049,9 +1052,6 @@
1049
1052
  .h-\[650px\] {
1050
1053
  height: 650px;
1051
1054
  }
1052
- .h-\[680px\] {
1053
- height: 680px;
1054
- }
1055
1055
  .h-\[720px\] {
1056
1056
  height: 720px;
1057
1057
  }
@@ -1874,12 +1874,12 @@
1874
1874
  .transform {
1875
1875
  transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);
1876
1876
  }
1877
+ .transform-none {
1878
+ transform: none;
1879
+ }
1877
1880
  .animate-\[tangle-breathe_var\(--motion-ambient\)_infinite\] {
1878
1881
  animation: tangle-breathe var(--motion-ambient) infinite;
1879
1882
  }
1880
- .animate-bounce {
1881
- animation: var(--animate-bounce);
1882
- }
1883
1883
  .animate-ping {
1884
1884
  animation: var(--animate-ping);
1885
1885
  }
@@ -2069,12 +2069,6 @@
2069
2069
  .gap-10 {
2070
2070
  gap: calc(var(--spacing) * 10);
2071
2071
  }
2072
- .gap-\[3px\] {
2073
- gap: 3px;
2074
- }
2075
- .gap-\[5px\] {
2076
- gap: 5px;
2077
- }
2078
2072
  .gap-px {
2079
2073
  gap: 1px;
2080
2074
  }
@@ -2280,6 +2274,9 @@
2280
2274
  .rounded-\[var\(--radius-md\)\] {
2281
2275
  border-radius: var(--radius-md);
2282
2276
  }
2277
+ .rounded-\[var\(--radius-panel\)\] {
2278
+ border-radius: var(--radius-panel);
2279
+ }
2283
2280
  .rounded-\[var\(--radius-sm\)\] {
2284
2281
  border-radius: var(--radius-sm);
2285
2282
  }
@@ -2614,9 +2611,6 @@
2614
2611
  border-color: color-mix(in oklab, var(--color-green-500) 30%, transparent);
2615
2612
  }
2616
2613
  }
2617
- .border-muted-foreground {
2618
- border-color: hsl(var(--muted-foreground));
2619
- }
2620
2614
  .border-primary {
2621
2615
  border-color: hsl(var(--primary));
2622
2616
  }
@@ -2842,6 +2836,9 @@
2842
2836
  .bg-\[var\(--surface-info-bg\)\] {
2843
2837
  background-color: var(--surface-info-bg);
2844
2838
  }
2839
+ .bg-\[var\(--surface-info-text\)\] {
2840
+ background-color: var(--surface-info-text);
2841
+ }
2845
2842
  .bg-\[var\(--surface-neutral-bg\)\] {
2846
2843
  background-color: var(--surface-neutral-bg);
2847
2844
  }
@@ -2971,9 +2968,6 @@
2971
2968
  background-color: color-mix(in oklab, var(--color-black) 80%, transparent);
2972
2969
  }
2973
2970
  }
2974
- .bg-blue-500 {
2975
- background-color: var(--color-blue-500);
2976
- }
2977
2971
  .bg-blue-500\/15 {
2978
2972
  background-color: color-mix(in srgb, oklch(62.3% 0.214 259.815) 15%, transparent);
2979
2973
  @supports (color: color-mix(in lab, red, red)) {
@@ -3046,9 +3040,6 @@
3046
3040
  .bg-green-400 {
3047
3041
  background-color: var(--color-green-400);
3048
3042
  }
3049
- .bg-green-500 {
3050
- background-color: var(--color-green-500);
3051
- }
3052
3043
  .bg-green-600\/20 {
3053
3044
  background-color: color-mix(in srgb, oklch(62.7% 0.194 149.214) 20%, transparent);
3054
3045
  @supports (color: color-mix(in lab, red, red)) {
@@ -3142,9 +3133,6 @@
3142
3133
  background-color: color-mix(in oklab, hsl(var(--primary)) 4%, transparent);
3143
3134
  }
3144
3135
  }
3145
- .bg-red-500 {
3146
- background-color: var(--color-red-500);
3147
- }
3148
3136
  .bg-red-500\/10 {
3149
3137
  background-color: color-mix(in srgb, oklch(63.7% 0.237 25.331) 10%, transparent);
3150
3138
  @supports (color: color-mix(in lab, red, red)) {
@@ -3220,9 +3208,6 @@
3220
3208
  background-color: color-mix(in oklab, var(--color-white) 40%, transparent);
3221
3209
  }
3222
3210
  }
3223
- .bg-yellow-500 {
3224
- background-color: var(--color-yellow-500);
3225
- }
3226
3211
  .bg-yellow-600\/20 {
3227
3212
  background-color: color-mix(in srgb, oklch(68.1% 0.162 75.834) 20%, transparent);
3228
3213
  @supports (color: color-mix(in lab, red, red)) {
@@ -3807,14 +3792,6 @@
3807
3792
  --tw-font-weight: var(--font-weight-semibold);
3808
3793
  font-weight: var(--font-weight-semibold);
3809
3794
  }
3810
- .tracking-\[0\.1em\] {
3811
- --tw-tracking: 0.1em;
3812
- letter-spacing: 0.1em;
3813
- }
3814
- .tracking-\[0\.08em\] {
3815
- --tw-tracking: 0.08em;
3816
- letter-spacing: 0.08em;
3817
- }
3818
3795
  .tracking-\[0\.09em\] {
3819
3796
  --tw-tracking: 0.09em;
3820
3797
  letter-spacing: 0.09em;
@@ -3823,10 +3800,6 @@
3823
3800
  --tw-tracking: 0.12em;
3824
3801
  letter-spacing: 0.12em;
3825
3802
  }
3826
- .tracking-\[0\.14em\] {
3827
- --tw-tracking: 0.14em;
3828
- letter-spacing: 0.14em;
3829
- }
3830
3803
  .tracking-\[0\.16em\] {
3831
3804
  --tw-tracking: 0.16em;
3832
3805
  letter-spacing: 0.16em;
@@ -3839,10 +3812,6 @@
3839
3812
  --tw-tracking: var(--tracking-tight,-0.02em);
3840
3813
  letter-spacing: var(--tracking-tight,-0.02em);
3841
3814
  }
3842
- .tracking-\[var\(--tracking-wide\,0\.08em\)\] {
3843
- --tw-tracking: var(--tracking-wide,0.08em);
3844
- letter-spacing: var(--tracking-wide,0.08em);
3845
- }
3846
3815
  .tracking-normal {
3847
3816
  --tw-tracking: var(--tracking-normal);
3848
3817
  letter-spacing: var(--tracking-normal);
@@ -4157,9 +4126,6 @@
4157
4126
  color: color-mix(in oklab, hsl(var(--muted-foreground)) 90%, transparent);
4158
4127
  }
4159
4128
  }
4160
- .text-neutral-400 {
4161
- color: var(--color-neutral-400);
4162
- }
4163
4129
  .text-popover-foreground {
4164
4130
  color: hsl(var(--popover-foreground));
4165
4131
  }
@@ -4437,6 +4403,10 @@
4437
4403
  --tw-blur: blur(8px);
4438
4404
  filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
4439
4405
  }
4406
+ .grayscale {
4407
+ --tw-grayscale: grayscale(100%);
4408
+ filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
4409
+ }
4440
4410
  .\!filter {
4441
4411
  filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,) !important;
4442
4412
  }
@@ -4458,11 +4428,6 @@
4458
4428
  -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
4459
4429
  backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
4460
4430
  }
4461
- .backdrop-blur-xl {
4462
- --tw-backdrop-blur: blur(var(--blur-xl));
4463
- -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
4464
- backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
4465
- }
4466
4431
  .transition {
4467
4432
  transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;
4468
4433
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
@@ -4513,6 +4478,11 @@
4513
4478
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
4514
4479
  transition-duration: var(--tw-duration, var(--default-transition-duration));
4515
4480
  }
4481
+ .transition-\[transform\,opacity\] {
4482
+ transition-property: transform,opacity;
4483
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
4484
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
4485
+ }
4516
4486
  .transition-\[transform\,width\] {
4517
4487
  transition-property: transform,width;
4518
4488
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
@@ -4621,6 +4591,9 @@
4621
4591
  .group-focus-within\:opacity-100:is(:where(.group):focus-within *) {
4622
4592
  opacity: 100%;
4623
4593
  }
4594
+ .group-focus-within\/expandable\:opacity-100:is(:where(.group\/expandable):focus-within *) {
4595
+ opacity: 100%;
4596
+ }
4624
4597
  @media (hover: hover) {
4625
4598
  .group-hover\:block:is(:where(.group):hover *) {
4626
4599
  display: block;
@@ -4669,6 +4642,9 @@
4669
4642
  .group-hover\/brand\:opacity-100:is(:where(.group\/brand):hover *) {
4670
4643
  opacity: 100%;
4671
4644
  }
4645
+ .group-hover\/expandable\:opacity-100:is(:where(.group\/expandable):hover *) {
4646
+ opacity: 100%;
4647
+ }
4672
4648
  .group-hover\/sub\:opacity-100:is(:where(.group\/sub):hover *) {
4673
4649
  opacity: 100%;
4674
4650
  }
@@ -5273,6 +5249,10 @@
5273
5249
  --tw-brightness: brightness(110%);
5274
5250
  filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
5275
5251
  }
5252
+ .hover\:grayscale-0:hover {
5253
+ --tw-grayscale: grayscale(0%);
5254
+ filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
5255
+ }
5276
5256
  }
5277
5257
  .focus\:border-\[var\(--focus-border\)\]:focus {
5278
5258
  border-color: var(--focus-border);
@@ -5943,6 +5923,9 @@
5943
5923
  .sm\:\!block {
5944
5924
  display: block !important;
5945
5925
  }
5926
+ .sm\:block {
5927
+ display: block;
5928
+ }
5946
5929
  .sm\:flex {
5947
5930
  display: flex;
5948
5931
  }
@@ -5973,6 +5956,9 @@
5973
5956
  .sm\:max-w-lg {
5974
5957
  max-width: var(--container-lg);
5975
5958
  }
5959
+ .sm\:max-w-none {
5960
+ max-width: none;
5961
+ }
5976
5962
  .sm\:max-w-sm {
5977
5963
  max-width: var(--container-sm);
5978
5964
  }
@@ -6276,9 +6262,6 @@
6276
6262
  }
6277
6263
  }
6278
6264
  @media (prefers-color-scheme: dark) {
6279
- .dark\:text-neutral-500 {
6280
- color: var(--color-neutral-500);
6281
- }
6282
6265
  .dark\:text-white {
6283
6266
  color: var(--color-white);
6284
6267
  }
@@ -6325,6 +6308,9 @@
6325
6308
  font-size: var(--text-base);
6326
6309
  line-height: var(--tw-leading, var(--text-base--line-height));
6327
6310
  }
6311
+ .pointer-coarse\:opacity-100 {
6312
+ opacity: 100%;
6313
+ }
6328
6314
  .pointer-coarse\:before\:absolute::before {
6329
6315
  content: var(--tw-content);
6330
6316
  position: absolute;
@@ -11715,16 +11701,6 @@
11715
11701
  opacity: 0.5;
11716
11702
  }
11717
11703
  }
11718
- @keyframes bounce {
11719
- 0%, 100% {
11720
- transform: translateY(-25%);
11721
- animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
11722
- }
11723
- 50% {
11724
- transform: none;
11725
- animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
11726
- }
11727
- }
11728
11704
  @layer properties {
11729
11705
  @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
11730
11706
  *, ::before, ::after, ::backdrop {
package/dist/terminal.js CHANGED
@@ -1 +1 @@
1
- export { t as DEFAULT_TERMINAL_THEME, n as TerminalView } from "./terminal-nUCznZRj.js";
1
+ export { t as DEFAULT_TERMINAL_THEME, n as TerminalView } from "./terminal-view-nUCznZRj.js";
@@ -2,17 +2,17 @@ import { t as cn$1 } from "./utils-BER_bdgE.js";
2
2
  import { i as modelBrandFor, t as ModelBrandStack } from "./model-brand-BQlarCIo.js";
3
3
  import { t as ProviderIcon } from "./provider-logo-CPKRPHcS.js";
4
4
  import { t as AgentGraph } from "./AgentGraph-BGWx9hhS.js";
5
- import { s as timelineItems, t as useFollowTail } from "./use-follow-tail-Df965WQi.js";
5
+ import { O as useFollowTail, o as timelineItems } from "./ConversationRowView-C4TXICBT.js";
6
6
  import { Button, SegmentedControl } from "@tangle-network/ui/primitives";
7
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
- import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
8
+ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
9
9
  import { ArrowLeft, ChevronRight, X } from "lucide-react";
10
10
  import { formatCost, formatCount, formatSpanDuration } from "@tangle-network/ui/utils";
11
11
  import { activityTiming } from "@tangle-network/charts/react/agent-graph/presentation";
12
12
  import { AgentTimeline, AgentTimelineColumn } from "@tangle-network/ui/chat";
13
+ import { useEventStream, usePhone as usePhone$1 } from "@tangle-network/ui/hooks";
13
14
  import { RunStatusIcon, runStatus } from "@tangle-network/ui/run";
14
15
  import { FlowWaterfall, toolGlyph } from "@tangle-network/charts/react";
15
- import { useEventStream } from "@tangle-network/ui/hooks";
16
16
  // src/run/trace-waterfall.tsx
17
17
  /** Agent and model spans show their lab/host mark; tool spans show their provider's mark. Unknown keeps the kind glyph. */
18
18
  function traceSpanMark(span) {
@@ -427,16 +427,60 @@ function useAgentStream(url, openEventSource, history) {
427
427
  } } : {}
428
428
  };
429
429
  }
430
- // src/run/agent-inspector.tsx
431
- /** Below the tablet breakpoint the inspector is a full-screen sheet over the run, never a squeezed side pane. */
432
- const PHONE = "(max-width: 767px)";
433
- function usePhone() {
434
- return useSyncExternalStore((notify) => {
435
- const query = matchMedia(PHONE);
436
- query.addEventListener("change", notify);
437
- return () => query.removeEventListener("change", notify);
438
- }, () => matchMedia(PHONE).matches, () => false);
430
+ /** One agent's conversation as of a cursor: its stream, the entries said by then, and the sentence shown when none are. */
431
+ function useAgentConversation(url, openEventSource, { cursor = null, startedAt, agentStartMs, silent: why } = {}) {
432
+ const stream = useAgentStream(url, openEventSource);
433
+ const origin = useMemo(() => {
434
+ if (startedAt !== void 0) return startedAt;
435
+ const first = stream.entries[0]?.at;
436
+ return agentStartMs !== void 0 && first !== void 0 ? first - agentStartMs : void 0;
437
+ }, [
438
+ startedAt,
439
+ agentStartMs,
440
+ stream.entries
441
+ ]);
442
+ const shown = cursor === null || origin === void 0 ? stream.entries : stream.entries.filter((entry) => entry.at - origin <= cursor);
443
+ const live = stream.alive && !stream.error && cursor === null;
444
+ const ended = !stream.alive && !stream.error;
445
+ const items = useMemo(() => timelineItems(shown, live), [shown, live]);
446
+ const silent = why || "No conversation was recorded for this agent.";
447
+ return {
448
+ stream,
449
+ shown,
450
+ items,
451
+ live,
452
+ ended,
453
+ note: !url ? silent : cursor !== null && origin === void 0 ? "This conversation has no timestamps to replay at the cursor." : items.length > 0 || live ? void 0 : stream.error ? ended ? stream.error : `Reconnecting… ${stream.error}` : ended ? silent : "No messages yet.",
454
+ silent
455
+ };
456
+ }
457
+ /** The conversation's rows, or the one sentence that stands in for them. */
458
+ function AgentConversationView({ conversation, className }) {
459
+ const { items, live, note, stream, ended } = conversation;
460
+ if (note === void 0) return /* @__PURE__ */ jsx(AgentTimelineColumn, {
461
+ className: className ?? "max-w-[46rem] p-0",
462
+ children: /* @__PURE__ */ jsx(AgentTimeline, {
463
+ items,
464
+ isThinking: live && items.length === 0
465
+ })
466
+ });
467
+ return /* @__PURE__ */ jsx("p", {
468
+ className: "m-0 py-1 text-sm text-muted-foreground",
469
+ "data-stream": stream.error ? "reconnecting" : ended ? "ended" : "empty",
470
+ children: note
471
+ });
472
+ }
473
+ /** The pill that offers the newest output after the reader scrolled up. */
474
+ function NewOutputPill({ unseen, onJump }) {
475
+ if (!unseen) return null;
476
+ return /* @__PURE__ */ jsx("button", {
477
+ type: "button",
478
+ onClick: onJump,
479
+ className: "absolute bottom-14 left-1/2 -translate-x-1/2 rounded-full border border-border bg-background px-3 py-1 text-xs shadow-sm",
480
+ children: "New output"
481
+ });
439
482
  }
483
+ // src/run/agent-inspector.tsx
440
484
  const WIDTH_KEY = "sandbox-ui:trace-inspector-width";
441
485
  const MIN_PX = 360;
442
486
  const MIN_LEFT_PX = 320;
@@ -859,16 +903,13 @@ function TraceWorkspace({ trace, streamUrl, openEventSource, events, onTimeChang
859
903
  const { defaultLayout = "tree", ...graphOptions } = agentGraph ?? {};
860
904
  const [graphLayout, setGraphLayout] = useState(defaultLayout);
861
905
  const [cursor, setCursor] = useState(null);
862
- const stream = useAgentStream(selected && streamUrl ? streamUrl(selected) : void 0, openEventSource);
863
- const origin = useMemo(() => {
864
- if (waterfall.startedAt !== void 0) return waterfall.startedAt;
865
- const first = stream.entries[0]?.at;
866
- return agent && first !== void 0 ? first - agent.startMs : void 0;
867
- }, [
868
- waterfall.startedAt,
869
- agent,
870
- stream.entries
871
- ]);
906
+ const conversation = useAgentConversation(selected && streamUrl ? streamUrl(selected) : void 0, openEventSource, {
907
+ cursor,
908
+ startedAt: waterfall.startedAt,
909
+ agentStartMs: agent?.startMs,
910
+ silent: agentId ? transcriptNote?.(agentId) : void 0
911
+ });
912
+ const { shown, items, live, note, silent } = conversation;
872
913
  const graph = useMemo(() => agentGraphAt(trace.spans, byId, cursor, waterfall.startedAt, agentCards, agentGraph?.edges), [
873
914
  trace,
874
915
  byId,
@@ -884,34 +925,17 @@ function TraceWorkspace({ trace, streamUrl, openEventSource, events, onTimeChang
884
925
  value
885
926
  });
886
927
  const graphNow = cursor !== null && waterfall.startedAt !== void 0 ? waterfall.startedAt + cursor : void 0;
887
- const shown = cursor === null || origin === void 0 ? stream.entries : stream.entries.filter((entry) => entry.at - origin <= cursor);
888
- const live = stream.alive && !stream.error && cursor === null;
889
- const ended = !stream.alive && !stream.error;
890
- const items = useMemo(() => timelineItems(shown, live), [shown, live]);
891
928
  const scroller = useRef(null);
892
929
  const { unseen, jump } = useFollowTail(scroller, {
893
930
  identity: showConversation ? selected : void 0,
894
931
  content: items
895
932
  });
896
933
  const root = useRef(null);
897
- const phone = usePhone(), split = useSplit(root);
934
+ const phone = usePhone$1(), split = useSplit(root);
898
935
  const mode = phone ? "sheet" : docked ? "docked" : "overlay";
899
936
  const status = live ? "running" : selectedNode?.status ?? runStatus(agent?.status ?? "unknown");
900
937
  const failure = facts.find((fact) => fact.label === "Failure")?.value ?? (status === "failed" ? selectedNode?.result ?? void 0 : void 0);
901
938
  const said = (text) => !!text && shown.some((entry) => entry.kind === "message" && entry.role === "user" && entry.content.trim() === text.trim());
902
- const silent = agentId && transcriptNote?.(agentId) || "No conversation was recorded for this agent.";
903
- const note = !streamUrl ? silent : cursor !== null && origin === void 0 ? "This conversation has no timestamps to replay at the cursor." : items.length > 0 || live ? void 0 : stream.error ? ended ? stream.error : `Reconnecting… ${stream.error}` : ended ? silent : "No messages yet.";
904
- const conversation = note === void 0 ? /* @__PURE__ */ jsx(AgentTimelineColumn, {
905
- className: "max-w-[46rem] p-0",
906
- children: /* @__PURE__ */ jsx(AgentTimeline, {
907
- items,
908
- isThinking: live && items.length === 0
909
- })
910
- }) : /* @__PURE__ */ jsx("p", {
911
- className: "m-0 py-1 text-sm text-muted-foreground",
912
- "data-stream": stream.error ? "reconnecting" : ended ? "ended" : "empty",
913
- children: note
914
- });
915
939
  const left = /* @__PURE__ */ jsxs(Fragment, { children: [
916
940
  /* @__PURE__ */ jsx("div", {
917
941
  className: cn$1("flex min-h-[320px] min-w-0 flex-1 flex-col", showConversation && mode === "overlay" && "lg:mr-[420px]"),
@@ -939,13 +963,20 @@ function TraceWorkspace({ trace, streamUrl, openEventSource, events, onTimeChang
939
963
  value: graphLayout,
940
964
  onValueChange: setGraphLayout,
941
965
  className: "absolute right-2 top-1 z-10",
942
- options: [{
943
- value: "tree",
944
- label: "Tree"
945
- }, {
946
- value: "hub",
947
- label: "Hub"
948
- }]
966
+ options: [
967
+ {
968
+ value: "grid",
969
+ label: "Grid"
970
+ },
971
+ {
972
+ value: "tree",
973
+ label: "Tree"
974
+ },
975
+ {
976
+ value: "hub",
977
+ label: "Hub"
978
+ }
979
+ ]
949
980
  }), /* @__PURE__ */ jsx(AgentGraph, {
950
981
  ...graphOptions,
951
982
  layout: graphLayout,
@@ -1008,8 +1039,8 @@ function TraceWorkspace({ trace, streamUrl, openEventSource, events, onTimeChang
1008
1039
  onClose: () => select(void 0),
1009
1040
  mode,
1010
1041
  style: mode === "docked" ? { width: split.width } : void 0,
1011
- children: conversation
1042
+ children: /* @__PURE__ */ jsx(AgentConversationView, { conversation })
1012
1043
  })] })]
1013
1044
  });
1014
1045
  }
1015
- export { TraceWaterfall as a, useEventStream as i, foldAgentRows as n, traceSpanMark as o, useAgentStream as r, TraceWorkspace as t };
1046
+ export { useAgentConversation as a, useEventStream as c, NewOutputPill as i, TraceWaterfall as l, usePhone$1 as n, foldAgentRows as o, AgentConversationView as r, useAgentStream as s, TraceWorkspace as t, traceSpanMark as u };
@@ -1,8 +1,9 @@
1
1
  import { t as cn$1 } from "./utils-BER_bdgE.js";
2
2
  import { t as revealInScroller } from "./reveal-in-scroller-CzKwuqCG.js";
3
3
  import { t as VirtualList } from "./VirtualList-DcSGbEtA.js";
4
- import { a as PortsList } from "./dashboard-C7QJJw7-.js";
5
- import { n as TerminalView } from "./terminal-nUCznZRj.js";
4
+ import { a as PortsList } from "./dashboard-C1pNlewR.js";
5
+ import { n as TerminalView } from "./terminal-view-nUCznZRj.js";
6
+ import "./terminal.js";
6
7
  import { n as buildUnifiedPatch, r as computeDiffStats, t as DiffView } from "./diff-view-B9mNeTLF.js";
7
8
  import { t as CodeView } from "./code-view-BlhCS1SD.js";
8
9
  import { n as PreviewView } from "./embedded-app-view-DXsoPale.js";
package/dist/workbench.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as GitStatusBadge, i as DiffStatsBadge, n as ChangesPane, o as PanelHeader, r as SandboxArtifactPane, s as PillTabs, t as JsonView } from "./workbench-D0ALR40M.js";
1
+ import { a as GitStatusBadge, i as DiffStatsBadge, n as ChangesPane, o as PanelHeader, r as SandboxArtifactPane, s as PillTabs, t as JsonView } from "./workbench-BUrlhR-P.js";
2
2
  import { a as CodeSurface, i as CODE_THEME, n as buildUnifiedPatch, r as computeDiffStats, t as DiffView } from "./diff-view-B9mNeTLF.js";
3
3
  import { n as FileBreadcrumb, t as CodeView } from "./code-view-BlhCS1SD.js";
4
4
  import { n as PreviewView, t as EmbeddedAppView } from "./embedded-app-view-DXsoPale.js";