@tangle-network/agent-app 0.42.4 → 0.42.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.
- package/dist/{DesignCanvas-AOIVN3SJ.js → DesignCanvas-GUTCY763.js} +2 -2
- package/dist/{DesignCanvasEditor-QQNAZRJQ.js → DesignCanvasEditor-ZO4V7H6A.js} +4 -4
- package/dist/{TimelineEditor-Z7C6BFP5.js → TimelineEditor-SNOAGBV6.js} +2 -2
- package/dist/brand/index.d.ts +35 -0
- package/dist/brand/index.js +89 -0
- package/dist/brand/index.js.map +1 -0
- package/dist/{chunk-YYYXGLLQ.js → chunk-6JYDS34Y.js} +184 -54
- package/dist/chunk-6JYDS34Y.js.map +1 -0
- package/dist/{chunk-FJUOBNIY.js → chunk-A5Z53E3A.js} +3 -3
- package/dist/{chunk-V5XZKHCL.js → chunk-AFQXKJAE.js} +132 -2
- package/dist/chunk-AFQXKJAE.js.map +1 -0
- package/dist/{chunk-S6WS2B32.js → chunk-EX3LD5G6.js} +322 -122
- package/dist/chunk-EX3LD5G6.js.map +1 -0
- package/dist/{chunk-DTS5TZRN.js → chunk-MFI4ZM7W.js} +2 -2
- package/dist/chunk-MFI4ZM7W.js.map +1 -0
- package/dist/{chunk-YEWTVDDT.js → chunk-OVUQNKLM.js} +379 -323
- package/dist/chunk-OVUQNKLM.js.map +1 -0
- package/dist/chunk-ZN5J47UX.js +1 -0
- package/dist/chunk-ZN5J47UX.js.map +1 -0
- package/dist/{command-stack-CkjelfK_.d.ts → command-stack-CcWi_2bN.d.ts} +15 -0
- package/dist/design-canvas-react/engine.d.ts +2 -2
- package/dist/design-canvas-react/engine.js +5 -6
- package/dist/design-canvas-react/index.d.ts +61 -8
- package/dist/design-canvas-react/index.js +10 -9
- package/dist/design-canvas-react/lazy.d.ts +2 -2
- package/dist/design-canvas-react/lazy.js +1 -1
- package/dist/{lazy-BHHqS8-j.d.ts → lazy-2XBVp1_e.d.ts} +6 -2
- package/dist/sequences-react/index.d.ts +94 -2
- package/dist/sequences-react/index.js +12 -2
- package/dist/sequences-react/index.js.map +1 -1
- package/dist/studio/index.d.ts +1 -1
- package/dist/studio/index.js +1 -1
- package/dist/studio-react/index.js +1 -1
- package/dist/web-react/index.d.ts +73 -6
- package/dist/web-react/index.js +453 -210
- package/dist/web-react/index.js.map +1 -1
- package/package.json +14 -9
- package/dist/chunk-DTS5TZRN.js.map +0 -1
- package/dist/chunk-S6WS2B32.js.map +0 -1
- package/dist/chunk-SQV7NUEM.js +0 -136
- package/dist/chunk-SQV7NUEM.js.map +0 -1
- package/dist/chunk-V5XZKHCL.js.map +0 -1
- package/dist/chunk-YEWTVDDT.js.map +0 -1
- package/dist/chunk-YYYXGLLQ.js.map +0 -1
- /package/dist/{DesignCanvas-AOIVN3SJ.js.map → DesignCanvas-GUTCY763.js.map} +0 -0
- /package/dist/{DesignCanvasEditor-QQNAZRJQ.js.map → DesignCanvasEditor-ZO4V7H6A.js.map} +0 -0
- /package/dist/{TimelineEditor-Z7C6BFP5.js.map → TimelineEditor-SNOAGBV6.js.map} +0 -0
- /package/dist/{chunk-FJUOBNIY.js.map → chunk-A5Z53E3A.js.map} +0 -0
package/dist/web-react/index.js
CHANGED
|
@@ -255,7 +255,7 @@ function ModelPicker({ value, onChange, models, loading, renderProviderBadge, re
|
|
|
255
255
|
]
|
|
256
256
|
}
|
|
257
257
|
),
|
|
258
|
-
open && /* @__PURE__ */ jsxs2("div", { className: "absolute bottom-full left-0 z-50 mb-2 w-[420px] overflow-hidden rounded-xl border border-border bg-card shadow-lg", children: [
|
|
258
|
+
open && /* @__PURE__ */ jsxs2("div", { className: "absolute bottom-full left-0 z-50 mb-2 w-[420px] max-w-[calc(100vw-2rem)] overflow-hidden rounded-xl border border-border bg-card shadow-lg", children: [
|
|
259
259
|
/* @__PURE__ */ jsx2("div", { className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 rounded-lg border border-border bg-background px-3 py-2", children: [
|
|
260
260
|
/* @__PURE__ */ jsx2(SearchGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
261
261
|
/* @__PURE__ */ jsx2(
|
|
@@ -290,16 +290,16 @@ function ModelPicker({ value, onChange, models, loading, renderProviderBadge, re
|
|
|
290
290
|
] })
|
|
291
291
|
] });
|
|
292
292
|
}
|
|
293
|
-
var
|
|
293
|
+
var DEFAULT_EFFORT_LEVELS = [
|
|
294
294
|
{ id: "off", label: "Off" },
|
|
295
|
-
{ id: "low", label: "
|
|
296
|
-
{ id: "medium", label: "
|
|
297
|
-
{ id: "high", label: "
|
|
295
|
+
{ id: "low", label: "Quick" },
|
|
296
|
+
{ id: "medium", label: "Standard" },
|
|
297
|
+
{ id: "high", label: "Extended" }
|
|
298
298
|
];
|
|
299
|
-
function EffortPicker({ value, onChange }) {
|
|
299
|
+
function EffortPicker({ value, onChange, levels = DEFAULT_EFFORT_LEVELS, label = "Thinking" }) {
|
|
300
300
|
const [open, setOpen] = useState2(false);
|
|
301
301
|
const { containerRef, triggerProps } = usePopover(open, setOpen);
|
|
302
|
-
const selected =
|
|
302
|
+
const selected = levels.find((l) => l.id === value) ?? levels[2] ?? levels[0];
|
|
303
303
|
return /* @__PURE__ */ jsxs2("div", { ref: containerRef, className: "relative inline-flex", children: [
|
|
304
304
|
/* @__PURE__ */ jsxs2(
|
|
305
305
|
"button",
|
|
@@ -307,16 +307,22 @@ function EffortPicker({ value, onChange }) {
|
|
|
307
307
|
type: "button",
|
|
308
308
|
...triggerProps,
|
|
309
309
|
onClick: () => setOpen(!open),
|
|
310
|
-
title: "Reasoning effort",
|
|
311
|
-
className: "inline-flex items-center gap-1.5 rounded-full border border-border bg-card px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-accent/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background",
|
|
310
|
+
title: label ? `${label} \u2014 how hard the agent reasons before answering` : "Reasoning effort",
|
|
311
|
+
className: "inline-flex min-h-[36px] items-center gap-1.5 rounded-full border border-border bg-card px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-accent/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background",
|
|
312
312
|
children: [
|
|
313
313
|
/* @__PURE__ */ jsx2(SparkleGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
314
|
-
/* @__PURE__ */
|
|
314
|
+
/* @__PURE__ */ jsxs2("span", { children: [
|
|
315
|
+
label ? /* @__PURE__ */ jsxs2("span", { className: "text-muted-foreground", children: [
|
|
316
|
+
label,
|
|
317
|
+
": "
|
|
318
|
+
] }) : null,
|
|
319
|
+
selected?.label
|
|
320
|
+
] }),
|
|
315
321
|
/* @__PURE__ */ jsx2(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
316
322
|
]
|
|
317
323
|
}
|
|
318
324
|
),
|
|
319
|
-
open && /* @__PURE__ */ jsx2("div", { role: "menu", className: "absolute bottom-full left-0 z-50 mb-2 w-
|
|
325
|
+
open && /* @__PURE__ */ jsx2("div", { role: "menu", className: "absolute bottom-full left-0 z-50 mb-2 w-40 overflow-hidden rounded-xl border border-border bg-card p-1 shadow-lg", children: levels.map((l) => /* @__PURE__ */ jsx2(
|
|
320
326
|
"button",
|
|
321
327
|
{
|
|
322
328
|
type: "button",
|
|
@@ -326,7 +332,7 @@ function EffortPicker({ value, onChange }) {
|
|
|
326
332
|
onChange(l.id);
|
|
327
333
|
setOpen(false);
|
|
328
334
|
},
|
|
329
|
-
className: `flex w-full items-center rounded-md px-3 py-2 text-left text-sm transition ${POPOVER_OPTION_FOCUS} ${l.id === value ? "bg-primary/10 font-medium" : "hover:bg-accent/30"}`,
|
|
335
|
+
className: `flex min-h-[40px] w-full items-center rounded-md px-3 py-2 text-left text-sm transition ${POPOVER_OPTION_FOCUS} ${l.id === value ? "bg-primary/10 font-medium" : "hover:bg-accent/30"}`,
|
|
330
336
|
children: l.label
|
|
331
337
|
},
|
|
332
338
|
l.id
|
|
@@ -334,6 +340,24 @@ function EffortPicker({ value, onChange }) {
|
|
|
334
340
|
] });
|
|
335
341
|
}
|
|
336
342
|
|
|
343
|
+
// src/web-react/brand-mark.tsx
|
|
344
|
+
import { lazy, Suspense } from "react";
|
|
345
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
346
|
+
function MarkSpacer({ size = 24, className }) {
|
|
347
|
+
return /* @__PURE__ */ jsx3("span", { "aria-hidden": true, style: { display: "inline-block", width: size, height: size }, className });
|
|
348
|
+
}
|
|
349
|
+
var LazyKnot = lazy(async () => {
|
|
350
|
+
try {
|
|
351
|
+
const mod = await import("../brand/index.js");
|
|
352
|
+
return { default: mod.TangleKnot };
|
|
353
|
+
} catch {
|
|
354
|
+
return { default: MarkSpacer };
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
function BrandMark({ size = 24, className }) {
|
|
358
|
+
return /* @__PURE__ */ jsx3(Suspense, { fallback: /* @__PURE__ */ jsx3(MarkSpacer, { size, className }), children: /* @__PURE__ */ jsx3(LazyKnot, { size, className }) });
|
|
359
|
+
}
|
|
360
|
+
|
|
337
361
|
// src/web-react/chat-stream.ts
|
|
338
362
|
function dispatchChatStreamLine(line, cb) {
|
|
339
363
|
let receivedContent = false;
|
|
@@ -461,7 +485,7 @@ async function streamChatTurn(opts) {
|
|
|
461
485
|
|
|
462
486
|
// src/web-react/mission-activity.tsx
|
|
463
487
|
import { useCallback, useEffect as useEffect3, useState as useState3 } from "react";
|
|
464
|
-
import { Fragment as Fragment2, jsx as
|
|
488
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
465
489
|
var LIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "running"]);
|
|
466
490
|
var OK_STATUSES = /* @__PURE__ */ new Set(["completed", "done", "succeeded"]);
|
|
467
491
|
var ERROR_STATUSES = /* @__PURE__ */ new Set(["failed", "error", "cancelled", "aborted"]);
|
|
@@ -508,15 +532,15 @@ function waterfallLayout(trace) {
|
|
|
508
532
|
});
|
|
509
533
|
}
|
|
510
534
|
function ChevronGlyph({ className }) {
|
|
511
|
-
return /* @__PURE__ */
|
|
535
|
+
return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx4("path", { d: "m6 9 6 6 6-6" }) });
|
|
512
536
|
}
|
|
513
537
|
function RefreshGlyph({ className }) {
|
|
514
|
-
return /* @__PURE__ */
|
|
538
|
+
return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx4("path", { d: "M21 12a9 9 0 1 1-2.64-6.36M21 3v6h-6" }) });
|
|
515
539
|
}
|
|
516
540
|
function CopyGlyph({ className }) {
|
|
517
541
|
return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
518
|
-
/* @__PURE__ */
|
|
519
|
-
/* @__PURE__ */
|
|
542
|
+
/* @__PURE__ */ jsx4("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
|
|
543
|
+
/* @__PURE__ */ jsx4("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
520
544
|
] });
|
|
521
545
|
}
|
|
522
546
|
function TraceIdCopy({ traceId }) {
|
|
@@ -540,23 +564,23 @@ function TraceIdCopy({ traceId }) {
|
|
|
540
564
|
"aria-label": "Copy trace id",
|
|
541
565
|
className: "inline-flex min-w-0 items-center gap-1.5 rounded text-left font-mono text-muted-foreground transition hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-card",
|
|
542
566
|
children: [
|
|
543
|
-
/* @__PURE__ */
|
|
544
|
-
/* @__PURE__ */
|
|
545
|
-
copied && /* @__PURE__ */
|
|
567
|
+
/* @__PURE__ */ jsx4("span", { className: "truncate", children: traceId }),
|
|
568
|
+
/* @__PURE__ */ jsx4(CopyGlyph, { className: "h-3 w-3 shrink-0" }),
|
|
569
|
+
copied && /* @__PURE__ */ jsx4("span", { className: "shrink-0 not-italic text-success", children: "copied" })
|
|
546
570
|
]
|
|
547
571
|
}
|
|
548
572
|
);
|
|
549
573
|
}
|
|
550
574
|
function StatusDot({ tone }) {
|
|
551
575
|
return /* @__PURE__ */ jsxs3("span", { className: "inline-flex items-center", children: [
|
|
552
|
-
/* @__PURE__ */
|
|
576
|
+
/* @__PURE__ */ jsx4(
|
|
553
577
|
"span",
|
|
554
578
|
{
|
|
555
579
|
"aria-hidden": true,
|
|
556
580
|
className: `h-2 w-2 shrink-0 rounded-full ${tone === "live" ? "animate-pulse bg-warning" : tone === "ok" ? "bg-success" : tone === "error" ? "bg-destructive" : "bg-muted-foreground/40"}`
|
|
557
581
|
}
|
|
558
582
|
),
|
|
559
|
-
/* @__PURE__ */
|
|
583
|
+
/* @__PURE__ */ jsx4("span", { className: "sr-only", children: tone })
|
|
560
584
|
] });
|
|
561
585
|
}
|
|
562
586
|
var BAR_CLASS = {
|
|
@@ -570,15 +594,15 @@ function FlowWaterfall({ trace }) {
|
|
|
570
594
|
const cost = formatActivityCost(trace.costUsd);
|
|
571
595
|
return /* @__PURE__ */ jsxs3("div", { className: "space-y-1", children: [
|
|
572
596
|
rows.map((row, i) => /* @__PURE__ */ jsxs3("div", { className: "grid grid-cols-[minmax(0,2fr)_minmax(0,3fr)_auto] items-center gap-2", children: [
|
|
573
|
-
/* @__PURE__ */
|
|
574
|
-
/* @__PURE__ */
|
|
597
|
+
/* @__PURE__ */ jsx4("span", { className: "truncate font-mono text-[11px] text-muted-foreground", title: row.name, children: row.name }),
|
|
598
|
+
/* @__PURE__ */ jsx4("div", { className: "relative h-2 rounded-sm bg-muted/40", children: /* @__PURE__ */ jsx4(
|
|
575
599
|
"div",
|
|
576
600
|
{
|
|
577
601
|
className: `absolute inset-y-0 rounded-sm ${row.ok ? BAR_CLASS[row.kind] : "bg-destructive/80"} ${row.approx ? "opacity-70" : ""}`,
|
|
578
602
|
style: { left: `${row.offsetPct}%`, width: `${row.widthPct}%` }
|
|
579
603
|
}
|
|
580
604
|
) }),
|
|
581
|
-
/* @__PURE__ */
|
|
605
|
+
/* @__PURE__ */ jsx4("span", { className: "shrink-0 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: row.durationLabel })
|
|
582
606
|
] }, i)),
|
|
583
607
|
/* @__PURE__ */ jsxs3("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
|
|
584
608
|
(trace.totalMs / 1e3).toFixed(1),
|
|
@@ -596,19 +620,19 @@ function MissionActivityLane({ activity, startedAt, nowMs }) {
|
|
|
596
620
|
const cost = formatActivityCost(run.costUsd);
|
|
597
621
|
const duration = formatActivityDuration(run.durationMs);
|
|
598
622
|
return /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
|
|
599
|
-
/* @__PURE__ */
|
|
623
|
+
/* @__PURE__ */ jsx4(StatusDot, { tone }),
|
|
600
624
|
/* @__PURE__ */ jsxs3("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
601
|
-
/* @__PURE__ */
|
|
625
|
+
/* @__PURE__ */ jsx4("span", { className: "font-medium", children: run.tool }),
|
|
602
626
|
/* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
|
|
603
627
|
" \u2014 ",
|
|
604
628
|
run.detail
|
|
605
629
|
] })
|
|
606
630
|
] }),
|
|
607
|
-
tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */
|
|
631
|
+
tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */ jsx4("span", { className: "shrink-0 rounded-full bg-warning/10 px-1.5 py-0.5 font-mono text-[10px] text-warning", children: [run.iteration !== void 0 ? `iter ${run.iteration}` : null, run.phase ?? null].filter(Boolean).join(" \xB7 ") }),
|
|
608
632
|
/* @__PURE__ */ jsxs3("span", { className: "flex shrink-0 items-center gap-1.5 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: [
|
|
609
|
-
tone !== "live" && tone !== "ok" && /* @__PURE__ */
|
|
610
|
-
cost && /* @__PURE__ */
|
|
611
|
-
duration && /* @__PURE__ */
|
|
633
|
+
tone !== "live" && tone !== "ok" && /* @__PURE__ */ jsx4("span", { children: run.status }),
|
|
634
|
+
cost && /* @__PURE__ */ jsx4("span", { children: cost }),
|
|
635
|
+
duration && /* @__PURE__ */ jsx4("span", { children: duration })
|
|
612
636
|
] })
|
|
613
637
|
] }, run.taskId);
|
|
614
638
|
}),
|
|
@@ -619,12 +643,12 @@ function MissionActivityLane({ activity, startedAt, nowMs }) {
|
|
|
619
643
|
onClick: () => setExpanded((v) => !v),
|
|
620
644
|
className: "flex items-center gap-1 py-0.5 text-[10px] font-medium text-muted-foreground/70 transition hover:text-foreground",
|
|
621
645
|
children: [
|
|
622
|
-
/* @__PURE__ */
|
|
646
|
+
/* @__PURE__ */ jsx4(ChevronGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
|
|
623
647
|
"timeline"
|
|
624
648
|
]
|
|
625
649
|
}
|
|
626
650
|
),
|
|
627
|
-
expanded && /* @__PURE__ */
|
|
651
|
+
expanded && /* @__PURE__ */ jsx4("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx4(
|
|
628
652
|
FlowWaterfall,
|
|
629
653
|
{
|
|
630
654
|
trace: stepActivityFlowTrace(activity, {
|
|
@@ -645,39 +669,39 @@ function ActivityRow({
|
|
|
645
669
|
const duration = formatActivityDuration(record.durationMs);
|
|
646
670
|
return /* @__PURE__ */ jsxs3("div", { className: "rounded-lg border border-border/60 bg-card", children: [
|
|
647
671
|
/* @__PURE__ */ jsxs3("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm", children: [
|
|
648
|
-
/* @__PURE__ */
|
|
672
|
+
/* @__PURE__ */ jsx4(StatusDot, { tone }),
|
|
649
673
|
/* @__PURE__ */ jsxs3("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
650
|
-
/* @__PURE__ */
|
|
674
|
+
/* @__PURE__ */ jsx4("span", { className: "font-medium", children: record.tool }),
|
|
651
675
|
/* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
|
|
652
676
|
" \u2014 ",
|
|
653
677
|
record.detail
|
|
654
678
|
] })
|
|
655
679
|
] }),
|
|
656
|
-
tone === "live" && (record.iteration !== void 0 || record.phase !== void 0) && /* @__PURE__ */
|
|
657
|
-
/* @__PURE__ */
|
|
680
|
+
tone === "live" && (record.iteration !== void 0 || record.phase !== void 0) && /* @__PURE__ */ jsx4("span", { className: "shrink-0 rounded-full bg-warning/10 px-2 py-0.5 font-mono text-[10px] text-warning", children: [record.iteration !== void 0 ? `iter ${record.iteration}` : null, record.phase ?? null].filter(Boolean).join(" \xB7 ") }),
|
|
681
|
+
/* @__PURE__ */ jsx4(
|
|
658
682
|
"span",
|
|
659
683
|
{
|
|
660
684
|
className: `shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium ${tone === "ok" ? "bg-success/10 text-success" : tone === "error" ? "bg-destructive/10 text-destructive" : tone === "live" ? "bg-warning/10 text-warning" : "bg-muted/60 text-muted-foreground"}`,
|
|
661
685
|
children: record.status
|
|
662
686
|
}
|
|
663
687
|
),
|
|
664
|
-
cost && /* @__PURE__ */
|
|
665
|
-
/* @__PURE__ */
|
|
688
|
+
cost && /* @__PURE__ */ jsx4("span", { className: "shrink-0 font-mono text-[11px] tabular-nums text-muted-foreground", children: cost }),
|
|
689
|
+
/* @__PURE__ */ jsx4(ChevronGlyph, { className: `h-3 w-3 shrink-0 text-muted-foreground transition-transform ${open ? "rotate-180" : ""}` })
|
|
666
690
|
] }),
|
|
667
691
|
open && /* @__PURE__ */ jsxs3("div", { className: "space-y-2.5 border-t border-border/40 px-3 py-2.5", children: [
|
|
668
|
-
record.durationMs !== void 0 && /* @__PURE__ */
|
|
692
|
+
record.durationMs !== void 0 && /* @__PURE__ */ jsx4("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx4(FlowWaterfall, { trace: stepActivityFlowTrace([record]) }) }),
|
|
669
693
|
/* @__PURE__ */ jsxs3("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 font-mono text-[11px]", children: [
|
|
670
|
-
/* @__PURE__ */
|
|
671
|
-
/* @__PURE__ */
|
|
672
|
-
/* @__PURE__ */
|
|
673
|
-
/* @__PURE__ */
|
|
694
|
+
/* @__PURE__ */ jsx4("dt", { className: "text-muted-foreground/60", children: "task" }),
|
|
695
|
+
/* @__PURE__ */ jsx4("dd", { className: "truncate text-muted-foreground", children: record.taskId }),
|
|
696
|
+
/* @__PURE__ */ jsx4("dt", { className: "text-muted-foreground/60", children: "started" }),
|
|
697
|
+
/* @__PURE__ */ jsx4("dd", { className: "text-muted-foreground", children: new Date(record.startedAt).toLocaleString() }),
|
|
674
698
|
duration && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
675
|
-
/* @__PURE__ */
|
|
676
|
-
/* @__PURE__ */
|
|
699
|
+
/* @__PURE__ */ jsx4("dt", { className: "text-muted-foreground/60", children: "duration" }),
|
|
700
|
+
/* @__PURE__ */ jsx4("dd", { className: "text-muted-foreground", children: duration })
|
|
677
701
|
] }),
|
|
678
702
|
record.traceId && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
679
|
-
/* @__PURE__ */
|
|
680
|
-
/* @__PURE__ */
|
|
703
|
+
/* @__PURE__ */ jsx4("dt", { className: "text-muted-foreground/60", children: "trace" }),
|
|
704
|
+
/* @__PURE__ */ jsx4("dd", { className: "min-w-0", children: /* @__PURE__ */ jsx4(TraceIdCopy, { traceId: record.traceId }) })
|
|
681
705
|
] })
|
|
682
706
|
] }),
|
|
683
707
|
record.missionRef && renderMissionRef?.(record.missionRef, record)
|
|
@@ -710,8 +734,8 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
|
|
|
710
734
|
}, [load]);
|
|
711
735
|
return /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
|
|
712
736
|
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
|
|
713
|
-
/* @__PURE__ */
|
|
714
|
-
/* @__PURE__ */
|
|
737
|
+
/* @__PURE__ */ jsx4("h2", { className: "flex-1 text-sm font-semibold", children: title }),
|
|
738
|
+
/* @__PURE__ */ jsx4(
|
|
715
739
|
"button",
|
|
716
740
|
{
|
|
717
741
|
type: "button",
|
|
@@ -719,14 +743,14 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
|
|
|
719
743
|
disabled: loading,
|
|
720
744
|
"aria-label": "Refresh",
|
|
721
745
|
className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground disabled:opacity-50",
|
|
722
|
-
children: /* @__PURE__ */
|
|
746
|
+
children: /* @__PURE__ */ jsx4(RefreshGlyph, { className: `h-3.5 w-3.5 ${loading ? "animate-spin" : ""}` })
|
|
723
747
|
}
|
|
724
748
|
)
|
|
725
749
|
] }),
|
|
726
|
-
error && /* @__PURE__ */
|
|
727
|
-
!error && rows.length === 0 && !loading && /* @__PURE__ */
|
|
728
|
-
/* @__PURE__ */
|
|
729
|
-
cursor && /* @__PURE__ */
|
|
750
|
+
error && /* @__PURE__ */ jsx4("p", { role: "alert", className: "rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: error }),
|
|
751
|
+
!error && rows.length === 0 && !loading && /* @__PURE__ */ jsx4("p", { className: "px-1 text-sm text-muted-foreground", children: emptyLabel }),
|
|
752
|
+
/* @__PURE__ */ jsx4("div", { className: "space-y-1.5", children: rows.map((record) => /* @__PURE__ */ jsx4(ActivityRow, { record, renderMissionRef }, record.taskId)) }),
|
|
753
|
+
cursor && /* @__PURE__ */ jsx4(
|
|
730
754
|
"button",
|
|
731
755
|
{
|
|
732
756
|
type: "button",
|
|
@@ -901,9 +925,9 @@ function tabTerminalConnectionId(storageKey = DEFAULT_TERMINAL_CID_KEY) {
|
|
|
901
925
|
}
|
|
902
926
|
|
|
903
927
|
// src/web-react/workspace-terminal-panel.tsx
|
|
904
|
-
import { lazy, Suspense } from "react";
|
|
905
|
-
import { Fragment as Fragment3, jsx as
|
|
906
|
-
var TerminalView =
|
|
928
|
+
import { lazy as lazy2, Suspense as Suspense2 } from "react";
|
|
929
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
930
|
+
var TerminalView = lazy2(
|
|
907
931
|
() => import("@tangle-network/sandbox-ui/terminal").then((m) => ({ default: m.TerminalView }))
|
|
908
932
|
);
|
|
909
933
|
var TONE_DOT = {
|
|
@@ -935,18 +959,18 @@ function WorkspaceTerminalPanel({
|
|
|
935
959
|
return /* @__PURE__ */ jsxs4("div", { className: `flex h-full min-h-0 flex-col overflow-hidden rounded-xl border border-border bg-card ${className ?? ""}`, children: [
|
|
936
960
|
/* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-3 border-b border-border px-4 py-2.5", children: [
|
|
937
961
|
/* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
|
|
938
|
-
/* @__PURE__ */
|
|
939
|
-
subtitle && /* @__PURE__ */
|
|
962
|
+
/* @__PURE__ */ jsx5("p", { className: "truncate text-sm font-medium text-foreground", children: title }),
|
|
963
|
+
subtitle && /* @__PURE__ */ jsx5("p", { className: "truncate text-xs text-muted-foreground", children: subtitle })
|
|
940
964
|
] }),
|
|
941
965
|
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
|
|
942
966
|
/* @__PURE__ */ jsxs4("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
943
|
-
/* @__PURE__ */
|
|
967
|
+
/* @__PURE__ */ jsx5("span", { className: `h-1.5 w-1.5 rounded-full ${TONE_DOT[status.tone]}`, "aria-hidden": true }),
|
|
944
968
|
status.label
|
|
945
969
|
] }),
|
|
946
970
|
headerExtra
|
|
947
971
|
] })
|
|
948
972
|
] }),
|
|
949
|
-
/* @__PURE__ */
|
|
973
|
+
/* @__PURE__ */ jsx5("div", { className: "relative min-h-0 flex-1", children: ready ? /* @__PURE__ */ jsx5(Suspense2, { fallback: /* @__PURE__ */ jsx5(TerminalMessage, { children: "Loading terminal\u2026" }), children: /* @__PURE__ */ jsx5(
|
|
950
974
|
TerminalView,
|
|
951
975
|
{
|
|
952
976
|
apiUrl,
|
|
@@ -956,9 +980,9 @@ function WorkspaceTerminalPanel({
|
|
|
956
980
|
subtitle,
|
|
957
981
|
isActive
|
|
958
982
|
}
|
|
959
|
-
) }) : /* @__PURE__ */
|
|
960
|
-
/* @__PURE__ */
|
|
961
|
-
onRetry && /* @__PURE__ */
|
|
983
|
+
) }) : /* @__PURE__ */ jsx5(TerminalMessage, { children: connection.error ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
984
|
+
/* @__PURE__ */ jsx5("p", { className: "text-sm text-destructive", children: connection.error }),
|
|
985
|
+
onRetry && /* @__PURE__ */ jsx5(
|
|
962
986
|
"button",
|
|
963
987
|
{
|
|
964
988
|
type: "button",
|
|
@@ -967,9 +991,9 @@ function WorkspaceTerminalPanel({
|
|
|
967
991
|
children: "Reconnect"
|
|
968
992
|
}
|
|
969
993
|
)
|
|
970
|
-
] }) : connection.loading ? /* @__PURE__ */
|
|
971
|
-
/* @__PURE__ */
|
|
972
|
-
onRetry && /* @__PURE__ */
|
|
994
|
+
] }) : connection.loading ? /* @__PURE__ */ jsx5("p", { className: "text-sm text-muted-foreground", children: connection.status === "provisioning" ? "Provisioning sandbox\u2026" : "Connecting\u2026" }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
995
|
+
/* @__PURE__ */ jsx5("p", { className: "text-sm text-muted-foreground", children: "Terminal not connected." }),
|
|
996
|
+
onRetry && /* @__PURE__ */ jsx5(
|
|
973
997
|
"button",
|
|
974
998
|
{
|
|
975
999
|
type: "button",
|
|
@@ -982,13 +1006,13 @@ function WorkspaceTerminalPanel({
|
|
|
982
1006
|
] });
|
|
983
1007
|
}
|
|
984
1008
|
function TerminalMessage({ children }) {
|
|
985
|
-
return /* @__PURE__ */
|
|
1009
|
+
return /* @__PURE__ */ jsx5("div", { className: "absolute inset-0 flex flex-col items-center justify-center p-6 text-center", children });
|
|
986
1010
|
}
|
|
987
1011
|
|
|
988
1012
|
// src/web-react/seat-paywall.tsx
|
|
989
|
-
import { jsx as
|
|
1013
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
990
1014
|
function CheckGlyph() {
|
|
991
|
-
return /* @__PURE__ */
|
|
1015
|
+
return /* @__PURE__ */ jsx6(
|
|
992
1016
|
"svg",
|
|
993
1017
|
{
|
|
994
1018
|
className: "h-4 w-4 shrink-0 text-primary",
|
|
@@ -999,14 +1023,14 @@ function CheckGlyph() {
|
|
|
999
1023
|
strokeLinecap: "round",
|
|
1000
1024
|
strokeLinejoin: "round",
|
|
1001
1025
|
"aria-hidden": true,
|
|
1002
|
-
children: /* @__PURE__ */
|
|
1026
|
+
children: /* @__PURE__ */ jsx6("path", { d: "M20 6 9 17l-5-5" })
|
|
1003
1027
|
}
|
|
1004
1028
|
);
|
|
1005
1029
|
}
|
|
1006
1030
|
function Benefit({ children }) {
|
|
1007
1031
|
return /* @__PURE__ */ jsxs5("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
|
|
1008
|
-
/* @__PURE__ */
|
|
1009
|
-
/* @__PURE__ */
|
|
1032
|
+
/* @__PURE__ */ jsx6("span", { className: "mt-0.5", children: /* @__PURE__ */ jsx6(CheckGlyph, {}) }),
|
|
1033
|
+
/* @__PURE__ */ jsx6("span", { children })
|
|
1010
1034
|
] });
|
|
1011
1035
|
}
|
|
1012
1036
|
function SeatPaywall({
|
|
@@ -1020,30 +1044,30 @@ function SeatPaywall({
|
|
|
1020
1044
|
footnote
|
|
1021
1045
|
}) {
|
|
1022
1046
|
const { pending, run } = usePending();
|
|
1023
|
-
return /* @__PURE__ */
|
|
1024
|
-
/* @__PURE__ */
|
|
1047
|
+
return /* @__PURE__ */ jsx6("div", { className: "flex min-h-[60vh] w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxs5("div", { className: "w-full max-w-md rounded-2xl border border-border bg-card p-8 shadow-sm", children: [
|
|
1048
|
+
/* @__PURE__ */ jsx6("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: product }),
|
|
1025
1049
|
/* @__PURE__ */ jsxs5("h1", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: [
|
|
1026
1050
|
"Unlock ",
|
|
1027
1051
|
product
|
|
1028
1052
|
] }),
|
|
1029
|
-
tagline && /* @__PURE__ */
|
|
1053
|
+
tagline && /* @__PURE__ */ jsx6("p", { className: "mt-2 text-sm text-muted-foreground", children: tagline }),
|
|
1030
1054
|
/* @__PURE__ */ jsxs5("div", { className: "mt-6 flex items-baseline gap-1.5", children: [
|
|
1031
1055
|
/* @__PURE__ */ jsxs5("span", { className: "text-3xl font-semibold text-foreground", children: [
|
|
1032
1056
|
"$",
|
|
1033
1057
|
priceUsd
|
|
1034
1058
|
] }),
|
|
1035
|
-
/* @__PURE__ */
|
|
1059
|
+
/* @__PURE__ */ jsx6("span", { className: "text-sm text-muted-foreground", children: "/mo" })
|
|
1036
1060
|
] }),
|
|
1037
1061
|
/* @__PURE__ */ jsxs5("p", { className: "mt-1 text-sm text-muted-foreground", children: [
|
|
1038
1062
|
"Includes $",
|
|
1039
1063
|
includedUsageUsd,
|
|
1040
1064
|
"/mo of AI usage"
|
|
1041
1065
|
] }),
|
|
1042
|
-
/* @__PURE__ */
|
|
1066
|
+
/* @__PURE__ */ jsx6("ul", { className: "mt-6 space-y-2.5", children: (benefits ?? [
|
|
1043
1067
|
`Full access to ${product}`,
|
|
1044
1068
|
`$${includedUsageUsd}/mo of AI usage included, every month`
|
|
1045
|
-
]).map((benefit, i) => /* @__PURE__ */
|
|
1046
|
-
/* @__PURE__ */
|
|
1069
|
+
]).map((benefit, i) => /* @__PURE__ */ jsx6(Benefit, { children: benefit }, i)) }),
|
|
1070
|
+
/* @__PURE__ */ jsx6(
|
|
1047
1071
|
"button",
|
|
1048
1072
|
{
|
|
1049
1073
|
type: "button",
|
|
@@ -1053,13 +1077,13 @@ function SeatPaywall({
|
|
|
1053
1077
|
children: pending ? "Opening checkout\u2026" : ctaLabel ?? `Unlock ${product}`
|
|
1054
1078
|
}
|
|
1055
1079
|
),
|
|
1056
|
-
footnote && /* @__PURE__ */
|
|
1080
|
+
footnote && /* @__PURE__ */ jsx6("p", { className: "mt-3 text-center text-xs text-muted-foreground/70", children: footnote })
|
|
1057
1081
|
] }) });
|
|
1058
1082
|
}
|
|
1059
1083
|
|
|
1060
1084
|
// src/web-react/agent-session-controls.tsx
|
|
1061
1085
|
import { useMemo as useMemo2, useState as useState5 } from "react";
|
|
1062
|
-
import { jsx as
|
|
1086
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1063
1087
|
var HARNESS_LABELS = {
|
|
1064
1088
|
opencode: "OpenCode (any model)",
|
|
1065
1089
|
"claude-code": "Claude Code (Anthropic)",
|
|
@@ -1079,12 +1103,12 @@ function harnessLabel(h) {
|
|
|
1079
1103
|
return HARNESS_LABELS[h] ?? h;
|
|
1080
1104
|
}
|
|
1081
1105
|
function ChevronDown2({ className }) {
|
|
1082
|
-
return /* @__PURE__ */
|
|
1106
|
+
return /* @__PURE__ */ jsx7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx7("path", { d: "m6 9 6 6 6-6" }) });
|
|
1083
1107
|
}
|
|
1084
1108
|
function GearGlyph({ className }) {
|
|
1085
1109
|
return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
1086
|
-
/* @__PURE__ */
|
|
1087
|
-
/* @__PURE__ */
|
|
1110
|
+
/* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "3" }),
|
|
1111
|
+
/* @__PURE__ */ jsx7("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
|
|
1088
1112
|
] });
|
|
1089
1113
|
}
|
|
1090
1114
|
var FOCUS_RING = "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background";
|
|
@@ -1106,12 +1130,12 @@ function HarnessPicker({
|
|
|
1106
1130
|
title: "Agent backend",
|
|
1107
1131
|
className: `inline-flex w-full items-center justify-between gap-1.5 rounded-lg border border-border bg-card px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-accent/30 ${FOCUS_RING}`,
|
|
1108
1132
|
children: [
|
|
1109
|
-
/* @__PURE__ */
|
|
1110
|
-
/* @__PURE__ */
|
|
1133
|
+
/* @__PURE__ */ jsx7("span", { className: "truncate", children: harnessLabel(value) }),
|
|
1134
|
+
/* @__PURE__ */ jsx7(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
1111
1135
|
]
|
|
1112
1136
|
}
|
|
1113
1137
|
),
|
|
1114
|
-
open && /* @__PURE__ */
|
|
1138
|
+
open && /* @__PURE__ */ jsx7("div", { role: "menu", className: "absolute bottom-full left-0 z-50 mb-2 max-h-64 w-full min-w-[220px] overflow-y-auto rounded-xl border border-border bg-card p-1 shadow-lg", children: options.map((h) => /* @__PURE__ */ jsx7(
|
|
1115
1139
|
"button",
|
|
1116
1140
|
{
|
|
1117
1141
|
type: "button",
|
|
@@ -1162,7 +1186,7 @@ function AgentSessionControls(props) {
|
|
|
1162
1186
|
const { containerRef: popoverRef, triggerProps } = usePopover(open, setOpen);
|
|
1163
1187
|
const selectedModel = models.find((m) => m.id === model);
|
|
1164
1188
|
const showEffort = selectedModel?.supportsReasoning ?? true;
|
|
1165
|
-
const modelPicker = /* @__PURE__ */
|
|
1189
|
+
const modelPicker = /* @__PURE__ */ jsx7(
|
|
1166
1190
|
ModelPicker,
|
|
1167
1191
|
{
|
|
1168
1192
|
value: model,
|
|
@@ -1175,15 +1199,15 @@ function AgentSessionControls(props) {
|
|
|
1175
1199
|
if (layout === "inline") {
|
|
1176
1200
|
return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
|
|
1177
1201
|
modelPicker,
|
|
1178
|
-
showHarness && /* @__PURE__ */
|
|
1179
|
-
showEffort && /* @__PURE__ */
|
|
1202
|
+
showHarness && /* @__PURE__ */ jsx7(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
|
|
1203
|
+
showEffort && /* @__PURE__ */ jsx7(EffortPicker, { value: effort, onChange: onEffortChange })
|
|
1180
1204
|
] });
|
|
1181
1205
|
}
|
|
1182
1206
|
const hasAdvanced = showHarness || showEffort;
|
|
1183
1207
|
return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
|
|
1184
1208
|
modelPicker,
|
|
1185
1209
|
hasAdvanced && /* @__PURE__ */ jsxs6("div", { ref: popoverRef, className: "relative inline-flex", children: [
|
|
1186
|
-
/* @__PURE__ */
|
|
1210
|
+
/* @__PURE__ */ jsx7(
|
|
1187
1211
|
"button",
|
|
1188
1212
|
{
|
|
1189
1213
|
type: "button",
|
|
@@ -1192,19 +1216,19 @@ function AgentSessionControls(props) {
|
|
|
1192
1216
|
title: "Model settings \u2014 pick the agent backend and how hard it thinks",
|
|
1193
1217
|
className: `flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground data-[state=open]:bg-muted ${FOCUS_RING}`,
|
|
1194
1218
|
"data-state": open ? "open" : "closed",
|
|
1195
|
-
children: /* @__PURE__ */
|
|
1219
|
+
children: /* @__PURE__ */ jsx7(GearGlyph, { className: "h-4 w-4" })
|
|
1196
1220
|
}
|
|
1197
1221
|
),
|
|
1198
1222
|
open && /* @__PURE__ */ jsxs6("div", { className: "absolute bottom-full left-0 z-50 mb-2 w-72 space-y-3 rounded-xl border border-border bg-card p-3 shadow-lg", children: [
|
|
1199
1223
|
showHarness && /* @__PURE__ */ jsxs6("div", { className: "space-y-1.5", children: [
|
|
1200
|
-
/* @__PURE__ */
|
|
1201
|
-
/* @__PURE__ */
|
|
1202
|
-
/* @__PURE__ */
|
|
1224
|
+
/* @__PURE__ */ jsx7("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
|
|
1225
|
+
/* @__PURE__ */ jsx7(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
|
|
1226
|
+
/* @__PURE__ */ jsx7("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "The engine that runs the agent. Switching it keeps your model choice compatible." })
|
|
1203
1227
|
] }),
|
|
1204
1228
|
showEffort && /* @__PURE__ */ jsxs6("div", { className: "space-y-1.5", children: [
|
|
1205
|
-
/* @__PURE__ */
|
|
1206
|
-
/* @__PURE__ */
|
|
1207
|
-
/* @__PURE__ */
|
|
1229
|
+
/* @__PURE__ */ jsx7("p", { className: "text-xs font-medium text-foreground", children: "Thinking" }),
|
|
1230
|
+
/* @__PURE__ */ jsx7(EffortPicker, { value: effort, onChange: onEffortChange, label: "" }),
|
|
1231
|
+
/* @__PURE__ */ jsx7("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "How hard the agent thinks before answering. Higher is slower but more thorough." })
|
|
1208
1232
|
] })
|
|
1209
1233
|
] })
|
|
1210
1234
|
] })
|
|
@@ -1212,7 +1236,7 @@ function AgentSessionControls(props) {
|
|
|
1212
1236
|
}
|
|
1213
1237
|
|
|
1214
1238
|
// src/web-react/index.tsx
|
|
1215
|
-
import { Fragment as Fragment4, jsx as
|
|
1239
|
+
import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1216
1240
|
function formatModelCost(msg, models) {
|
|
1217
1241
|
if (msg.promptTokens == null && msg.completionTokens == null) return null;
|
|
1218
1242
|
const pricing = models.find((m) => m.id === msg.modelUsed)?.pricing;
|
|
@@ -1228,39 +1252,39 @@ function formatTokensPerSecond(msg) {
|
|
|
1228
1252
|
function RunDrillIn({ run, onClose }) {
|
|
1229
1253
|
return /* @__PURE__ */ jsxs7("div", { className: "fixed inset-y-0 right-0 z-50 flex w-[480px] max-w-full flex-col border-l border-border bg-card shadow-xl", children: [
|
|
1230
1254
|
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
|
|
1231
|
-
/* @__PURE__ */
|
|
1255
|
+
/* @__PURE__ */ jsx8(
|
|
1232
1256
|
"span",
|
|
1233
1257
|
{
|
|
1234
1258
|
className: `h-2 w-2 shrink-0 rounded-full ${run.status === "running" ? "bg-warning" : run.status === "error" ? "bg-destructive" : "bg-success"}`
|
|
1235
1259
|
}
|
|
1236
1260
|
),
|
|
1237
1261
|
/* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
|
|
1238
|
-
/* @__PURE__ */
|
|
1239
|
-
/* @__PURE__ */
|
|
1262
|
+
/* @__PURE__ */ jsx8("p", { className: "truncate text-sm font-semibold", children: run.title }),
|
|
1263
|
+
/* @__PURE__ */ jsx8("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
|
|
1240
1264
|
] }),
|
|
1241
|
-
/* @__PURE__ */
|
|
1265
|
+
/* @__PURE__ */ jsx8(
|
|
1242
1266
|
"button",
|
|
1243
1267
|
{
|
|
1244
1268
|
type: "button",
|
|
1245
1269
|
onClick: onClose,
|
|
1246
1270
|
"aria-label": "Close",
|
|
1247
1271
|
className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground",
|
|
1248
|
-
children: /* @__PURE__ */
|
|
1272
|
+
children: /* @__PURE__ */ jsx8("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx8("path", { d: "M18 6 6 18M6 6l12 12" }) })
|
|
1249
1273
|
}
|
|
1250
1274
|
)
|
|
1251
1275
|
] }),
|
|
1252
1276
|
/* @__PURE__ */ jsxs7("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
|
|
1253
|
-
run.steps.length === 0 && /* @__PURE__ */
|
|
1277
|
+
run.steps.length === 0 && /* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
|
|
1254
1278
|
run.steps.map((step, i) => /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border border-border/60 bg-background", children: [
|
|
1255
1279
|
/* @__PURE__ */ jsxs7("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
|
|
1256
|
-
/* @__PURE__ */
|
|
1257
|
-
/* @__PURE__ */
|
|
1258
|
-
/* @__PURE__ */
|
|
1280
|
+
/* @__PURE__ */ jsx8("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
|
|
1281
|
+
/* @__PURE__ */ jsx8("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
|
|
1282
|
+
/* @__PURE__ */ jsx8("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
|
|
1259
1283
|
] }),
|
|
1260
|
-
step.detail && /* @__PURE__ */
|
|
1284
|
+
step.detail && /* @__PURE__ */ jsx8("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap px-3 py-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: step.detail })
|
|
1261
1285
|
] }, i))
|
|
1262
1286
|
] }),
|
|
1263
|
-
/* @__PURE__ */
|
|
1287
|
+
/* @__PURE__ */ jsx8("p", { className: "border-t border-border px-4 py-2 text-[11px] text-muted-foreground", children: "Readonly drill-in. Follow up in the main chat." })
|
|
1264
1288
|
] });
|
|
1265
1289
|
}
|
|
1266
1290
|
function pendingApprovalOf(call) {
|
|
@@ -1268,54 +1292,108 @@ function pendingApprovalOf(call) {
|
|
|
1268
1292
|
if (!outcome?.ok || outcome.result?.status !== "queued_for_approval" || !outcome.result.proposalId) return null;
|
|
1269
1293
|
return { proposalId: outcome.result.proposalId };
|
|
1270
1294
|
}
|
|
1295
|
+
function ChatEmptyState({
|
|
1296
|
+
productName = "Agent",
|
|
1297
|
+
headline = "Ask the agent to do something",
|
|
1298
|
+
subline = "Describe the outcome you want. The agent works through it step by step, and pauses for your approval before anything irreversible.",
|
|
1299
|
+
doors
|
|
1300
|
+
}) {
|
|
1301
|
+
return /* @__PURE__ */ jsxs7("div", { className: "mx-auto flex w-full max-w-2xl flex-col items-center px-6 py-12 text-center sm:py-20", children: [
|
|
1302
|
+
/* @__PURE__ */ jsx8("span", { className: "mb-5 inline-flex h-14 w-14 items-center justify-center rounded-2xl bg-primary/10 ring-1 ring-primary/15", children: /* @__PURE__ */ jsx8(BrandMark, { size: 32, className: "shrink-0" }) }),
|
|
1303
|
+
/* @__PURE__ */ jsx8("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: productName }),
|
|
1304
|
+
/* @__PURE__ */ jsx8("h2", { className: "mt-1.5 text-balance text-2xl font-semibold leading-tight text-foreground sm:text-[28px]", children: headline }),
|
|
1305
|
+
subline && /* @__PURE__ */ jsx8("p", { className: "mt-3 max-w-md text-[15px] leading-relaxed text-muted-foreground", children: subline }),
|
|
1306
|
+
doors && doors.length > 0 && /* @__PURE__ */ jsx8("div", { className: "mt-7 grid w-full gap-2.5 sm:grid-cols-3", children: doors.slice(0, 3).map((door, i) => /* @__PURE__ */ jsxs7(
|
|
1307
|
+
"button",
|
|
1308
|
+
{
|
|
1309
|
+
type: "button",
|
|
1310
|
+
onClick: door.onSelect,
|
|
1311
|
+
className: "group flex min-h-[44px] flex-col items-start rounded-xl border border-border bg-card px-4 py-3 text-left transition hover:border-primary/40 hover:bg-accent/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
1312
|
+
children: [
|
|
1313
|
+
/* @__PURE__ */ jsx8("span", { className: "text-sm font-semibold text-foreground", children: door.label }),
|
|
1314
|
+
door.description && /* @__PURE__ */ jsx8("span", { className: "mt-0.5 text-[12px] leading-snug text-muted-foreground", children: door.description })
|
|
1315
|
+
]
|
|
1316
|
+
},
|
|
1317
|
+
i
|
|
1318
|
+
)) })
|
|
1319
|
+
] });
|
|
1320
|
+
}
|
|
1271
1321
|
function ToolGlyph({ name, className }) {
|
|
1272
1322
|
if (name.startsWith("sandbox_")) {
|
|
1273
1323
|
return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
1274
|
-
/* @__PURE__ */
|
|
1275
|
-
/* @__PURE__ */
|
|
1324
|
+
/* @__PURE__ */ jsx8("polyline", { points: "4 17 10 11 4 5" }),
|
|
1325
|
+
/* @__PURE__ */ jsx8("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
|
|
1276
1326
|
] });
|
|
1277
1327
|
}
|
|
1278
1328
|
if (name === "submit_proposal") {
|
|
1279
1329
|
return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
1280
|
-
/* @__PURE__ */
|
|
1281
|
-
/* @__PURE__ */
|
|
1330
|
+
/* @__PURE__ */ jsx8("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
1331
|
+
/* @__PURE__ */ jsx8("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
|
|
1282
1332
|
] });
|
|
1283
1333
|
}
|
|
1284
1334
|
if (name === "schedule_followup") {
|
|
1285
1335
|
return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
|
|
1286
|
-
/* @__PURE__ */
|
|
1287
|
-
/* @__PURE__ */
|
|
1336
|
+
/* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "9" }),
|
|
1337
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 7v5l3 3" })
|
|
1288
1338
|
] });
|
|
1289
1339
|
}
|
|
1290
1340
|
return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
1291
|
-
/* @__PURE__ */
|
|
1292
|
-
/* @__PURE__ */
|
|
1341
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
|
|
1342
|
+
/* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "4" })
|
|
1293
1343
|
] });
|
|
1294
1344
|
}
|
|
1295
1345
|
function toolOutcomeOf(call) {
|
|
1296
1346
|
return call.result;
|
|
1297
1347
|
}
|
|
1348
|
+
function blockKindOf(call) {
|
|
1349
|
+
if (call.name === "submit_proposal") return "proposal";
|
|
1350
|
+
if (call.name === "schedule_followup") return "followup";
|
|
1351
|
+
if (call.name.startsWith("sandbox_")) return "command";
|
|
1352
|
+
return "generic";
|
|
1353
|
+
}
|
|
1298
1354
|
function friendlyToolTitle(call) {
|
|
1299
1355
|
const a = call.args ?? {};
|
|
1300
1356
|
switch (call.name) {
|
|
1301
1357
|
case "submit_proposal":
|
|
1302
|
-
return
|
|
1358
|
+
return a.title ? `Approve: ${String(a.title)}?` : "Approve this action?";
|
|
1303
1359
|
case "sandbox_create":
|
|
1304
|
-
return `
|
|
1360
|
+
return `Created sandbox (${String(a.environment ?? "universal")})`;
|
|
1305
1361
|
case "sandbox_run_command":
|
|
1306
|
-
return
|
|
1362
|
+
return `Ran ${String(a.command ?? "command")}`;
|
|
1307
1363
|
case "sandbox_destroy":
|
|
1308
|
-
return `
|
|
1364
|
+
return `Destroyed sandbox ${String(a.sandbox_id ?? "")}`;
|
|
1309
1365
|
case "schedule_followup":
|
|
1310
|
-
return `
|
|
1366
|
+
return `Scheduled: ${String(a.title ?? "follow-up")}`;
|
|
1311
1367
|
case "render_ui":
|
|
1312
|
-
return `
|
|
1368
|
+
return `Rendered view \xB7 ${String(a.title ?? "")}`;
|
|
1313
1369
|
case "add_citation":
|
|
1314
|
-
return `
|
|
1370
|
+
return `Cited ${String(a.path ?? "")}`;
|
|
1315
1371
|
default:
|
|
1316
1372
|
return call.name;
|
|
1317
1373
|
}
|
|
1318
1374
|
}
|
|
1375
|
+
function proposalPreview(call) {
|
|
1376
|
+
const a = call.args ?? {};
|
|
1377
|
+
const asString = (v) => typeof v === "string" && v.trim() ? v.trim() : null;
|
|
1378
|
+
const asList = (v) => Array.isArray(v) ? v.map((x) => typeof x === "string" ? x : null).filter((x) => !!x) : asString(v) ? [asString(v)] : [];
|
|
1379
|
+
const verbPhrase = asString(a.summary) ?? asString(a.description) ?? (asString(a.type) ? `${String(a.type).replace(/_/g, " ")}${asString(a.title) ? `: ${asString(a.title)}` : ""}` : null);
|
|
1380
|
+
const destinations = [
|
|
1381
|
+
...asList(a.destinations),
|
|
1382
|
+
...asList(a.channels),
|
|
1383
|
+
...asList(a.targets),
|
|
1384
|
+
...asList(a.platforms)
|
|
1385
|
+
];
|
|
1386
|
+
const dest = destinations.length ? ` to ${destinations.join(" and ")}` : "";
|
|
1387
|
+
const summary = verbPhrase ? `${verbPhrase}${dest}` : destinations.length ? `Publish to ${destinations.join(" and ")}` : null;
|
|
1388
|
+
const meta = [];
|
|
1389
|
+
const cost = a.cost ?? a.price ?? a.estimatedCost;
|
|
1390
|
+
if (typeof cost === "number" && cost > 0) meta.push(`~$${cost < 0.01 ? cost.toFixed(4) : cost.toFixed(2)}`);
|
|
1391
|
+
else if (asString(cost)) meta.push(asString(cost));
|
|
1392
|
+
const reach = a.reach ?? a.audience ?? a.estimatedReach;
|
|
1393
|
+
if (typeof reach === "number" && reach > 0) meta.push(`reaches ~${reach.toLocaleString()}`);
|
|
1394
|
+
else if (asString(reach)) meta.push(asString(reach));
|
|
1395
|
+
return { summary, meta };
|
|
1396
|
+
}
|
|
1319
1397
|
function truncate(v, max = 240) {
|
|
1320
1398
|
const s = typeof v === "string" ? v : JSON.stringify(v);
|
|
1321
1399
|
return s.length > max ? `${s.slice(0, max)}\u2026` : s;
|
|
@@ -1323,9 +1401,9 @@ function truncate(v, max = 240) {
|
|
|
1323
1401
|
function KvRows({ data }) {
|
|
1324
1402
|
const entries = Object.entries(data).filter(([, v]) => v !== void 0 && v !== null && v !== "");
|
|
1325
1403
|
if (!entries.length) return null;
|
|
1326
|
-
return /* @__PURE__ */
|
|
1327
|
-
/* @__PURE__ */
|
|
1328
|
-
/* @__PURE__ */
|
|
1404
|
+
return /* @__PURE__ */ jsx8("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs7("div", { className: "contents", children: [
|
|
1405
|
+
/* @__PURE__ */ jsx8("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
|
|
1406
|
+
/* @__PURE__ */ jsx8("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
|
|
1329
1407
|
] }, k)) });
|
|
1330
1408
|
}
|
|
1331
1409
|
function ShellDetail({ call }) {
|
|
@@ -1333,29 +1411,101 @@ function ShellDetail({ call }) {
|
|
|
1333
1411
|
const r = outcome?.result ?? {};
|
|
1334
1412
|
return /* @__PURE__ */ jsxs7("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
|
|
1335
1413
|
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
|
|
1336
|
-
/* @__PURE__ */
|
|
1337
|
-
/* @__PURE__ */
|
|
1414
|
+
/* @__PURE__ */ jsx8("span", { className: "select-none text-zinc-500", children: "$" }),
|
|
1415
|
+
/* @__PURE__ */ jsx8("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
|
|
1338
1416
|
r.exitCode != null && /* @__PURE__ */ jsxs7("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
|
|
1339
1417
|
"exit ",
|
|
1340
1418
|
r.exitCode
|
|
1341
1419
|
] })
|
|
1342
1420
|
] }),
|
|
1343
|
-
/* @__PURE__ */
|
|
1421
|
+
/* @__PURE__ */ jsx8("pre", { className: "max-h-56 overflow-auto whitespace-pre-wrap px-3 pb-2.5 pt-1.5 text-zinc-300", children: outcome?.ok === false ? outcome.message ?? "failed" : [r.stdout, r.stderr].filter(Boolean).join("\n") || "(no output)" })
|
|
1344
1422
|
] });
|
|
1345
1423
|
}
|
|
1346
1424
|
function DefaultToolDetail({ call }) {
|
|
1347
1425
|
const outcome = toolOutcomeOf(call);
|
|
1348
1426
|
return /* @__PURE__ */ jsxs7("div", { className: "space-y-2", children: [
|
|
1349
1427
|
call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs7("div", { children: [
|
|
1350
|
-
/* @__PURE__ */
|
|
1351
|
-
/* @__PURE__ */
|
|
1428
|
+
/* @__PURE__ */ jsx8("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
|
|
1429
|
+
/* @__PURE__ */ jsx8(KvRows, { data: call.args })
|
|
1352
1430
|
] }),
|
|
1353
1431
|
outcome && /* @__PURE__ */ jsxs7("div", { children: [
|
|
1354
|
-
/* @__PURE__ */
|
|
1355
|
-
outcome.ok === false ? /* @__PURE__ */
|
|
1432
|
+
/* @__PURE__ */ jsx8("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: outcome.ok === false ? "Failed" : "Result" }),
|
|
1433
|
+
outcome.ok === false ? /* @__PURE__ */ jsx8("p", { className: "text-xs text-destructive", children: outcome.message ?? "Tool failed" }) : outcome.result && typeof outcome.result === "object" ? /* @__PURE__ */ jsx8(KvRows, { data: outcome.result }) : /* @__PURE__ */ jsx8("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(outcome.result) })
|
|
1356
1434
|
] })
|
|
1357
1435
|
] });
|
|
1358
1436
|
}
|
|
1437
|
+
function ProposalCard({
|
|
1438
|
+
call,
|
|
1439
|
+
message,
|
|
1440
|
+
pending,
|
|
1441
|
+
approval,
|
|
1442
|
+
renderers
|
|
1443
|
+
}) {
|
|
1444
|
+
const [expanded, setExpanded] = useState6(false);
|
|
1445
|
+
const { summary, meta } = proposalPreview(call);
|
|
1446
|
+
const custom = renderers?.[call.name]?.(call, message);
|
|
1447
|
+
const { pending: deciding, run: decide } = usePending();
|
|
1448
|
+
return /* @__PURE__ */ jsxs7("div", { className: "w-full max-w-full rounded-xl border border-warning/50 bg-warning/[0.06] text-sm shadow-sm ring-1 ring-warning/10", children: [
|
|
1449
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-start gap-2.5 px-4 pt-3.5", children: [
|
|
1450
|
+
/* @__PURE__ */ jsx8("span", { className: "mt-0.5 inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-warning/15 text-warning", children: /* @__PURE__ */ jsx8(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
|
|
1451
|
+
/* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
|
|
1452
|
+
/* @__PURE__ */ jsx8("p", { className: "text-[10px] font-semibold uppercase tracking-wider text-warning-foreground", children: "Needs your approval" }),
|
|
1453
|
+
/* @__PURE__ */ jsx8("p", { className: "mt-0.5 text-[15px] font-semibold leading-snug text-foreground", children: friendlyToolTitle(call) }),
|
|
1454
|
+
summary && /* @__PURE__ */ jsx8("p", { className: "mt-1 text-[13px] leading-relaxed text-muted-foreground", children: summary }),
|
|
1455
|
+
meta.length > 0 && /* @__PURE__ */ jsx8("div", { className: "mt-1.5 flex flex-wrap items-center gap-1.5", children: meta.map((m, i) => /* @__PURE__ */ jsx8("span", { className: "rounded-full bg-muted/60 px-2 py-0.5 text-[11px] font-medium text-muted-foreground", children: m }, i)) })
|
|
1456
|
+
] })
|
|
1457
|
+
] }),
|
|
1458
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-center gap-2 px-4 pb-3.5 pt-3", children: [
|
|
1459
|
+
approval ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
1460
|
+
/* @__PURE__ */ jsx8(
|
|
1461
|
+
"button",
|
|
1462
|
+
{
|
|
1463
|
+
type: "button",
|
|
1464
|
+
disabled: deciding,
|
|
1465
|
+
onClick: () => decide(() => approval.onApprove(pending.proposalId, call.id)),
|
|
1466
|
+
className: "inline-flex min-h-[40px] flex-1 items-center justify-center rounded-lg bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground shadow-sm transition hover:bg-primary/90 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card disabled:cursor-not-allowed disabled:opacity-60 sm:flex-none sm:min-w-[160px]",
|
|
1467
|
+
children: "Approve & run"
|
|
1468
|
+
}
|
|
1469
|
+
),
|
|
1470
|
+
/* @__PURE__ */ jsx8(
|
|
1471
|
+
"button",
|
|
1472
|
+
{
|
|
1473
|
+
type: "button",
|
|
1474
|
+
disabled: deciding,
|
|
1475
|
+
onClick: () => decide(() => approval.onReject(pending.proposalId, call.id)),
|
|
1476
|
+
className: "inline-flex min-h-[40px] items-center justify-center rounded-lg border border-border bg-transparent px-4 py-2 text-sm font-medium text-muted-foreground transition hover:bg-accent/30 hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card disabled:cursor-not-allowed disabled:opacity-60",
|
|
1477
|
+
children: "Reject"
|
|
1478
|
+
}
|
|
1479
|
+
)
|
|
1480
|
+
] }) : /* @__PURE__ */ jsx8("span", { className: "text-[12px] font-medium text-muted-foreground", children: "Awaiting approval\u2026" }),
|
|
1481
|
+
/* @__PURE__ */ jsxs7(
|
|
1482
|
+
"button",
|
|
1483
|
+
{
|
|
1484
|
+
type: "button",
|
|
1485
|
+
onClick: () => setExpanded((v) => !v),
|
|
1486
|
+
"aria-expanded": expanded,
|
|
1487
|
+
className: "ml-auto inline-flex items-center gap-1 rounded text-[12px] font-medium text-muted-foreground transition hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1488
|
+
children: [
|
|
1489
|
+
expanded ? "Hide details" : "View details",
|
|
1490
|
+
/* @__PURE__ */ jsx8(ChevronDown, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` })
|
|
1491
|
+
]
|
|
1492
|
+
}
|
|
1493
|
+
)
|
|
1494
|
+
] }),
|
|
1495
|
+
expanded && /* @__PURE__ */ jsx8("div", { className: "border-t border-warning/20 px-4 py-3 text-xs", children: custom ?? /* @__PURE__ */ jsx8(DefaultToolDetail, { call }) })
|
|
1496
|
+
] });
|
|
1497
|
+
}
|
|
1498
|
+
function FollowupCard({ call }) {
|
|
1499
|
+
const a = call.args ?? {};
|
|
1500
|
+
const when = typeof a.when === "string" ? a.when : typeof a.at === "string" ? a.at : typeof a.schedule === "string" ? a.schedule : null;
|
|
1501
|
+
return /* @__PURE__ */ jsxs7("div", { className: "w-fit min-w-[260px] max-w-full rounded-lg border border-border/60 border-l-2 border-l-primary/60 bg-muted/20 px-3 py-2 text-sm", children: [
|
|
1502
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
1503
|
+
/* @__PURE__ */ jsx8(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-primary/80" }),
|
|
1504
|
+
/* @__PURE__ */ jsx8("span", { className: "min-w-0 flex-1 truncate font-medium text-foreground", children: friendlyToolTitle(call) })
|
|
1505
|
+
] }),
|
|
1506
|
+
when && /* @__PURE__ */ jsx8("p", { className: "mt-0.5 pl-[22px] text-[12px] text-muted-foreground", children: when })
|
|
1507
|
+
] });
|
|
1508
|
+
}
|
|
1359
1509
|
function ToolCallCard({
|
|
1360
1510
|
call,
|
|
1361
1511
|
message,
|
|
@@ -1365,13 +1515,29 @@ function ToolCallCard({
|
|
|
1365
1515
|
}) {
|
|
1366
1516
|
const [expanded, setExpanded] = useState6(false);
|
|
1367
1517
|
const pending = call.status === "done" ? pendingApprovalOf(call) : null;
|
|
1518
|
+
const kind = blockKindOf(call);
|
|
1368
1519
|
const failed = call.status === "error" || toolOutcomeOf(call)?.ok === false;
|
|
1369
1520
|
const custom = renderers?.[call.name]?.(call, message);
|
|
1370
|
-
|
|
1521
|
+
if (pending) {
|
|
1522
|
+
return /* @__PURE__ */ jsx8(
|
|
1523
|
+
ProposalCard,
|
|
1524
|
+
{
|
|
1525
|
+
call,
|
|
1526
|
+
message,
|
|
1527
|
+
pending,
|
|
1528
|
+
approval,
|
|
1529
|
+
renderers
|
|
1530
|
+
}
|
|
1531
|
+
);
|
|
1532
|
+
}
|
|
1533
|
+
if (kind === "followup" && !failed) {
|
|
1534
|
+
return /* @__PURE__ */ jsx8(FollowupCard, { call });
|
|
1535
|
+
}
|
|
1536
|
+
const isCommand = kind === "command";
|
|
1371
1537
|
return /* @__PURE__ */ jsxs7(
|
|
1372
1538
|
"div",
|
|
1373
1539
|
{
|
|
1374
|
-
className: `w-fit min-w-[280px] max-w-full rounded-lg border text-xs transition ${
|
|
1540
|
+
className: `w-fit min-w-[280px] max-w-full rounded-lg border text-xs transition ${failed ? "border-destructive/40 bg-destructive/5" : "border-border/60 bg-muted/20"}`,
|
|
1375
1541
|
children: [
|
|
1376
1542
|
/* @__PURE__ */ jsxs7("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
|
|
1377
1543
|
/* @__PURE__ */ jsxs7(
|
|
@@ -1382,41 +1548,25 @@ function ToolCallCard({
|
|
|
1382
1548
|
"aria-expanded": expanded,
|
|
1383
1549
|
className: "flex min-w-0 flex-1 items-center gap-2 rounded text-left focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1384
1550
|
children: [
|
|
1385
|
-
/* @__PURE__ */
|
|
1551
|
+
/* @__PURE__ */ jsx8(
|
|
1386
1552
|
"span",
|
|
1387
1553
|
{
|
|
1388
|
-
className: `h-2 w-2 shrink-0 rounded-full ${call.status === "running" ? "animate-pulse bg-warning" :
|
|
1554
|
+
className: `h-2 w-2 shrink-0 rounded-full ${call.status === "running" ? "animate-pulse bg-warning" : failed ? "bg-destructive" : "bg-success"}`
|
|
1389
1555
|
}
|
|
1390
1556
|
),
|
|
1391
|
-
/* @__PURE__ */
|
|
1392
|
-
/* @__PURE__ */
|
|
1557
|
+
/* @__PURE__ */ jsx8(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
1558
|
+
/* @__PURE__ */ jsx8(
|
|
1559
|
+
"span",
|
|
1560
|
+
{
|
|
1561
|
+
className: `min-w-0 flex-1 truncate ${isCommand ? "font-mono text-[12px] tracking-tight text-foreground/90" : "font-medium"}`,
|
|
1562
|
+
children: friendlyToolTitle(call)
|
|
1563
|
+
}
|
|
1564
|
+
)
|
|
1393
1565
|
]
|
|
1394
1566
|
}
|
|
1395
1567
|
),
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
"button",
|
|
1399
|
-
{
|
|
1400
|
-
type: "button",
|
|
1401
|
-
disabled: deciding,
|
|
1402
|
-
onClick: () => decide(() => approval.onApprove(pending.proposalId, call.id)),
|
|
1403
|
-
className: "rounded bg-success px-2 py-0.5 text-[11px] font-semibold text-success-foreground transition hover:bg-success/90 disabled:cursor-not-allowed disabled:opacity-60",
|
|
1404
|
-
children: "Approve"
|
|
1405
|
-
}
|
|
1406
|
-
),
|
|
1407
|
-
/* @__PURE__ */ jsx7(
|
|
1408
|
-
"button",
|
|
1409
|
-
{
|
|
1410
|
-
type: "button",
|
|
1411
|
-
disabled: deciding,
|
|
1412
|
-
onClick: () => decide(() => approval.onReject(pending.proposalId, call.id)),
|
|
1413
|
-
className: "rounded border border-border bg-card px-2 py-0.5 text-[11px] font-medium text-foreground transition hover:bg-accent/30 disabled:cursor-not-allowed disabled:opacity-60",
|
|
1414
|
-
children: "Reject"
|
|
1415
|
-
}
|
|
1416
|
-
)
|
|
1417
|
-
] }),
|
|
1418
|
-
/* @__PURE__ */ jsx7("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : pending ? "awaiting approval" : failed ? "failed" : "done" }),
|
|
1419
|
-
/* @__PURE__ */ jsx7(
|
|
1568
|
+
/* @__PURE__ */ jsx8("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : failed ? "failed" : "done" }),
|
|
1569
|
+
/* @__PURE__ */ jsx8(
|
|
1420
1570
|
"button",
|
|
1421
1571
|
{
|
|
1422
1572
|
type: "button",
|
|
@@ -1424,13 +1574,13 @@ function ToolCallCard({
|
|
|
1424
1574
|
"aria-label": expanded ? "Collapse details" : "Expand details",
|
|
1425
1575
|
"aria-expanded": expanded,
|
|
1426
1576
|
className: "shrink-0 rounded p-0.5 focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1427
|
-
children: /* @__PURE__ */
|
|
1577
|
+
children: /* @__PURE__ */ jsx8(ChevronDown, { className: `h-3 w-3 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
|
|
1428
1578
|
}
|
|
1429
1579
|
)
|
|
1430
1580
|
] }),
|
|
1431
1581
|
expanded && /* @__PURE__ */ jsxs7("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
|
|
1432
|
-
custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */
|
|
1433
|
-
onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */
|
|
1582
|
+
custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx8(ShellDetail, { call }) : /* @__PURE__ */ jsx8(DefaultToolDetail, { call })),
|
|
1583
|
+
onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx8(
|
|
1434
1584
|
"button",
|
|
1435
1585
|
{
|
|
1436
1586
|
type: "button",
|
|
@@ -1444,6 +1594,73 @@ function ToolCallCard({
|
|
|
1444
1594
|
}
|
|
1445
1595
|
);
|
|
1446
1596
|
}
|
|
1597
|
+
function StreamingCaret() {
|
|
1598
|
+
return /* @__PURE__ */ jsx8(
|
|
1599
|
+
"span",
|
|
1600
|
+
{
|
|
1601
|
+
className: "ml-0.5 inline-block h-[1.1em] w-[3px] translate-y-[2px] animate-pulse rounded-sm bg-foreground/70",
|
|
1602
|
+
"aria-hidden": true
|
|
1603
|
+
}
|
|
1604
|
+
);
|
|
1605
|
+
}
|
|
1606
|
+
function SegmentText({
|
|
1607
|
+
content,
|
|
1608
|
+
streaming,
|
|
1609
|
+
showCaret,
|
|
1610
|
+
renderBody
|
|
1611
|
+
}) {
|
|
1612
|
+
const text = useSmoothText(content, streaming);
|
|
1613
|
+
const body = useMemo3(() => renderBody(text), [renderBody, text]);
|
|
1614
|
+
if (!content.trim() && !showCaret) return null;
|
|
1615
|
+
return /* @__PURE__ */ jsxs7("div", { className: "text-base leading-[1.75]", children: [
|
|
1616
|
+
body,
|
|
1617
|
+
showCaret && /* @__PURE__ */ jsx8(StreamingCaret, {})
|
|
1618
|
+
] });
|
|
1619
|
+
}
|
|
1620
|
+
function SegmentedBody({
|
|
1621
|
+
segments,
|
|
1622
|
+
msg,
|
|
1623
|
+
streaming,
|
|
1624
|
+
renderBody,
|
|
1625
|
+
approval,
|
|
1626
|
+
onToolCallClick,
|
|
1627
|
+
toolRenderers
|
|
1628
|
+
}) {
|
|
1629
|
+
const lastIndex = segments.length - 1;
|
|
1630
|
+
const segmentToolIds = new Set(
|
|
1631
|
+
segments.flatMap((s) => s.kind === "tool" ? [s.call.id] : [])
|
|
1632
|
+
);
|
|
1633
|
+
const leftoverToolCalls = (msg.toolCalls ?? []).filter(
|
|
1634
|
+
(tc) => !segmentToolIds.has(tc.id)
|
|
1635
|
+
);
|
|
1636
|
+
const renderToolCard = (call) => /* @__PURE__ */ jsx8(
|
|
1637
|
+
ToolCallCard,
|
|
1638
|
+
{
|
|
1639
|
+
call,
|
|
1640
|
+
message: msg,
|
|
1641
|
+
approval,
|
|
1642
|
+
onOpenRun: onToolCallClick,
|
|
1643
|
+
renderers: toolRenderers
|
|
1644
|
+
},
|
|
1645
|
+
`tool-${call.id}`
|
|
1646
|
+
);
|
|
1647
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-2", children: [
|
|
1648
|
+
segments.map(
|
|
1649
|
+
(seg, i) => seg.kind === "text" ? /* @__PURE__ */ jsx8(
|
|
1650
|
+
SegmentText,
|
|
1651
|
+
{
|
|
1652
|
+
content: seg.content,
|
|
1653
|
+
streaming: streaming && i === lastIndex,
|
|
1654
|
+
showCaret: streaming && i === lastIndex,
|
|
1655
|
+
renderBody
|
|
1656
|
+
},
|
|
1657
|
+
`text-${i}`
|
|
1658
|
+
) : renderToolCard(seg.call)
|
|
1659
|
+
),
|
|
1660
|
+
leftoverToolCalls.map(renderToolCard),
|
|
1661
|
+
streaming && segments[lastIndex]?.kind === "tool" && /* @__PURE__ */ jsx8(StreamingCaret, {})
|
|
1662
|
+
] });
|
|
1663
|
+
}
|
|
1447
1664
|
function AssistantMessageImpl({
|
|
1448
1665
|
msg,
|
|
1449
1666
|
streaming,
|
|
@@ -1458,45 +1675,60 @@ function AssistantMessageImpl({
|
|
|
1458
1675
|
const content = useSmoothText(msg.content, streaming);
|
|
1459
1676
|
const reasoning = useSmoothText(msg.reasoning ?? "", streaming);
|
|
1460
1677
|
const body = useMemo3(() => renderBody(content), [renderBody, content]);
|
|
1678
|
+
const segments = msg.segments;
|
|
1679
|
+
const hasAnswerText = content !== "" || (segments?.some((s) => s.kind === "text" && s.content.trim() !== "") ?? false);
|
|
1461
1680
|
const reasoningScrollRef = useRef4(null);
|
|
1462
1681
|
const thinkStartRef = useRef4(null);
|
|
1463
1682
|
const thinkMsRef = useRef4(null);
|
|
1464
|
-
if (streaming && reasoning && !
|
|
1683
|
+
if (streaming && reasoning && !hasAnswerText && thinkStartRef.current === null) {
|
|
1465
1684
|
thinkStartRef.current = performance.now();
|
|
1466
1685
|
}
|
|
1467
|
-
if (
|
|
1686
|
+
if (hasAnswerText && thinkStartRef.current !== null && thinkMsRef.current === null) {
|
|
1468
1687
|
thinkMsRef.current = performance.now() - thinkStartRef.current;
|
|
1469
1688
|
}
|
|
1470
1689
|
useEffect5(() => {
|
|
1471
1690
|
const el = reasoningScrollRef.current;
|
|
1472
|
-
if (el && streaming && !
|
|
1473
|
-
}, [reasoning, streaming,
|
|
1691
|
+
if (el && streaming && !hasAnswerText) el.scrollTop = el.scrollHeight;
|
|
1692
|
+
}, [reasoning, streaming, hasAnswerText]);
|
|
1474
1693
|
return /* @__PURE__ */ jsxs7("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
|
|
1475
1694
|
/* @__PURE__ */ jsxs7("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
|
|
1476
|
-
/* @__PURE__ */
|
|
1477
|
-
msg.modelUsed && /* @__PURE__ */
|
|
1478
|
-
formatTokensPerSecond(msg) && /* @__PURE__ */
|
|
1479
|
-
formatModelCost(msg, models) && /* @__PURE__ */
|
|
1480
|
-
] }),
|
|
1481
|
-
reasoning && /* @__PURE__ */ jsxs7("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !content, children: [
|
|
1482
|
-
/* @__PURE__ */ jsx7("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !content ? /* @__PURE__ */ jsx7("span", { className: "animate-pulse", children: "Thinking\u2026" }) : thinkMsRef.current != null ? `Thought for ${Math.max(1, Math.round(thinkMsRef.current / 1e3))}s` : "Thought process" }),
|
|
1483
|
-
/* @__PURE__ */ jsx7("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground", children: reasoning })
|
|
1695
|
+
/* @__PURE__ */ jsx8("span", { className: "font-semibold uppercase", children: agentLabel }),
|
|
1696
|
+
msg.modelUsed && /* @__PURE__ */ jsx8("span", { className: "font-mono normal-case", children: msg.modelUsed }),
|
|
1697
|
+
formatTokensPerSecond(msg) && /* @__PURE__ */ jsx8("span", { children: formatTokensPerSecond(msg) }),
|
|
1698
|
+
formatModelCost(msg, models) && /* @__PURE__ */ jsx8("span", { children: formatModelCost(msg, models) })
|
|
1484
1699
|
] }),
|
|
1485
|
-
/* @__PURE__ */ jsxs7("
|
|
1486
|
-
|
|
1487
|
-
|
|
1700
|
+
reasoning && /* @__PURE__ */ jsxs7("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !hasAnswerText, children: [
|
|
1701
|
+
/* @__PURE__ */ jsx8("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !hasAnswerText ? /* @__PURE__ */ jsx8("span", { className: "animate-pulse", children: "Thinking\u2026" }) : thinkMsRef.current != null ? `Thought for ${Math.max(1, Math.round(thinkMsRef.current / 1e3))}s` : "Thought process" }),
|
|
1702
|
+
/* @__PURE__ */ jsx8("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground", children: reasoning })
|
|
1488
1703
|
] }),
|
|
1489
|
-
|
|
1490
|
-
|
|
1704
|
+
segments && segments.length > 0 ? /* @__PURE__ */ jsx8(
|
|
1705
|
+
SegmentedBody,
|
|
1491
1706
|
{
|
|
1492
|
-
|
|
1493
|
-
|
|
1707
|
+
segments,
|
|
1708
|
+
msg,
|
|
1709
|
+
streaming,
|
|
1710
|
+
renderBody,
|
|
1494
1711
|
approval,
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
}
|
|
1498
|
-
|
|
1499
|
-
|
|
1712
|
+
onToolCallClick,
|
|
1713
|
+
toolRenderers
|
|
1714
|
+
}
|
|
1715
|
+
) : /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
1716
|
+
/* @__PURE__ */ jsxs7("div", { className: "text-base leading-[1.75]", children: [
|
|
1717
|
+
body,
|
|
1718
|
+
streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx8(StreamingCaret, {})
|
|
1719
|
+
] }),
|
|
1720
|
+
msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */ jsx8("div", { className: "mt-2 flex flex-col gap-1.5", children: msg.toolCalls.map((tc) => /* @__PURE__ */ jsx8(
|
|
1721
|
+
ToolCallCard,
|
|
1722
|
+
{
|
|
1723
|
+
call: tc,
|
|
1724
|
+
message: msg,
|
|
1725
|
+
approval,
|
|
1726
|
+
onOpenRun: onToolCallClick,
|
|
1727
|
+
renderers: toolRenderers
|
|
1728
|
+
},
|
|
1729
|
+
tc.id
|
|
1730
|
+
)) })
|
|
1731
|
+
] }),
|
|
1500
1732
|
renderExtras?.(msg)
|
|
1501
1733
|
] });
|
|
1502
1734
|
}
|
|
@@ -1508,22 +1740,22 @@ function ThinkingRow({ agentLabel }) {
|
|
|
1508
1740
|
return () => clearInterval(id);
|
|
1509
1741
|
}, []);
|
|
1510
1742
|
return /* @__PURE__ */ jsxs7("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
|
|
1511
|
-
/* @__PURE__ */
|
|
1743
|
+
/* @__PURE__ */ jsx8("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
|
|
1512
1744
|
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
|
|
1513
|
-
/* @__PURE__ */
|
|
1745
|
+
/* @__PURE__ */ jsx8("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx8("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
|
|
1514
1746
|
"Thinking",
|
|
1515
1747
|
seconds >= 3 ? ` \xB7 ${seconds}s` : "..."
|
|
1516
1748
|
] })
|
|
1517
1749
|
] });
|
|
1518
1750
|
}
|
|
1519
1751
|
function StreamErrorRow({ message, onRetry }) {
|
|
1520
|
-
return /* @__PURE__ */
|
|
1752
|
+
return /* @__PURE__ */ jsx8("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs7("div", { role: "alert", className: "flex items-start gap-2.5 rounded-lg border border-destructive/40 bg-destructive/5 px-3 py-2.5 text-sm text-destructive", children: [
|
|
1521
1753
|
/* @__PURE__ */ jsxs7("svg", { className: "mt-0.5 h-4 w-4 shrink-0", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
1522
|
-
/* @__PURE__ */
|
|
1523
|
-
/* @__PURE__ */
|
|
1754
|
+
/* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "9" }),
|
|
1755
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 8v4m0 4h.01" })
|
|
1524
1756
|
] }),
|
|
1525
|
-
/* @__PURE__ */
|
|
1526
|
-
onRetry && /* @__PURE__ */
|
|
1757
|
+
/* @__PURE__ */ jsx8("span", { className: "min-w-0 flex-1 break-words", children: message }),
|
|
1758
|
+
onRetry && /* @__PURE__ */ jsx8(
|
|
1527
1759
|
"button",
|
|
1528
1760
|
{
|
|
1529
1761
|
type: "button",
|
|
@@ -1547,20 +1779,29 @@ function ChatMessages({
|
|
|
1547
1779
|
toolRenderers,
|
|
1548
1780
|
error,
|
|
1549
1781
|
onRetry,
|
|
1550
|
-
renderEmpty
|
|
1782
|
+
renderEmpty,
|
|
1783
|
+
emptyState,
|
|
1784
|
+
header
|
|
1551
1785
|
}) {
|
|
1552
1786
|
const renderBody = useMemo3(
|
|
1553
|
-
() => renderMarkdown ?? ((content) => /* @__PURE__ */
|
|
1787
|
+
() => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx8("p", { className: "whitespace-pre-wrap", children: content })),
|
|
1554
1788
|
[renderMarkdown]
|
|
1555
1789
|
);
|
|
1556
1790
|
const lastIsUser = messages[messages.length - 1]?.role === "user";
|
|
1557
|
-
if (messages.length === 0 && !loading && !error
|
|
1791
|
+
if (messages.length === 0 && !loading && !error) {
|
|
1792
|
+
const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */ jsx8(ChatEmptyState, { ...emptyState });
|
|
1793
|
+
return /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
1794
|
+
header,
|
|
1795
|
+
empty
|
|
1796
|
+
] });
|
|
1797
|
+
}
|
|
1558
1798
|
return /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
1799
|
+
header,
|
|
1559
1800
|
messages.map(
|
|
1560
|
-
(msg) => msg.role === "user" ? /* @__PURE__ */
|
|
1561
|
-
/* @__PURE__ */
|
|
1562
|
-
/* @__PURE__ */
|
|
1563
|
-
] }) }, msg.id) : /* @__PURE__ */
|
|
1801
|
+
(msg) => msg.role === "user" ? /* @__PURE__ */ jsx8("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs7("div", { className: "ml-auto w-fit max-w-[85%]", children: [
|
|
1802
|
+
/* @__PURE__ */ jsx8("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
|
|
1803
|
+
/* @__PURE__ */ jsx8("div", { className: "rounded-2xl rounded-tr-md bg-primary/10 px-4 py-2.5 text-base leading-relaxed", children: /* @__PURE__ */ jsx8("p", { className: "whitespace-pre-wrap", children: msg.content }) })
|
|
1804
|
+
] }) }, msg.id) : /* @__PURE__ */ jsx8(
|
|
1564
1805
|
AssistantMessage,
|
|
1565
1806
|
{
|
|
1566
1807
|
msg,
|
|
@@ -1576,14 +1817,16 @@ function ChatMessages({
|
|
|
1576
1817
|
msg.id
|
|
1577
1818
|
)
|
|
1578
1819
|
),
|
|
1579
|
-
loading && lastIsUser && /* @__PURE__ */
|
|
1580
|
-
error && !loading && /* @__PURE__ */
|
|
1820
|
+
loading && lastIsUser && /* @__PURE__ */ jsx8(ThinkingRow, { agentLabel }),
|
|
1821
|
+
error && !loading && /* @__PURE__ */ jsx8(StreamErrorRow, { message: error, onRetry })
|
|
1581
1822
|
] });
|
|
1582
1823
|
}
|
|
1583
1824
|
export {
|
|
1584
1825
|
AgentActivityPanel,
|
|
1585
1826
|
AgentSessionControls,
|
|
1827
|
+
ChatEmptyState,
|
|
1586
1828
|
ChatMessages,
|
|
1829
|
+
DEFAULT_EFFORT_LEVELS,
|
|
1587
1830
|
EffortPicker,
|
|
1588
1831
|
FlowWaterfall,
|
|
1589
1832
|
MissionActivityLane,
|