@tangle-network/agent-app 0.27.2 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DesignCanvas-AOIVN3SJ.js +12 -0
- package/dist/DesignCanvasEditor-IB2FMBBD.js +13 -0
- package/dist/InviteAcceptPage-EUOGZO2X.js +7 -0
- package/dist/MembersPanel-4CGUQRPF.js +8 -0
- package/dist/MembersPanel-4CGUQRPF.js.map +1 -0
- package/dist/{TimelineEditor-JDG54OBP.js → TimelineEditor-Z7C6BFP5.js} +2 -2
- package/dist/TimelineEditor-Z7C6BFP5.js.map +1 -0
- package/dist/access-ChAHG4Tp.d.ts +539 -0
- package/dist/{apply-Cp8c3K9D.d.ts → apply-Gk4raT2j.d.ts} +3 -1
- package/dist/{chunk-AFDROJ64.js → chunk-2QI7XV2T.js} +1 -1
- package/dist/chunk-2QI7XV2T.js.map +1 -0
- package/dist/chunk-3G334FVA.js +162 -0
- package/dist/chunk-3G334FVA.js.map +1 -0
- package/dist/chunk-3SVAA3MA.js +41 -0
- package/dist/chunk-3SVAA3MA.js.map +1 -0
- package/dist/{chunk-LUE4HO5C.js → chunk-4IQMTTNE.js} +10 -10
- package/dist/chunk-4IQMTTNE.js.map +1 -0
- package/dist/chunk-535V6BH6.js +128 -0
- package/dist/chunk-535V6BH6.js.map +1 -0
- package/dist/chunk-63CE7FEZ.js +63 -0
- package/dist/chunk-63CE7FEZ.js.map +1 -0
- package/dist/{chunk-5RT6KY4G.js → chunk-GQRL6VNU.js} +1 -1
- package/dist/chunk-GQRL6VNU.js.map +1 -0
- package/dist/{chunk-SCG5JJ4C.js → chunk-HFC4BTWJ.js} +32 -4
- package/dist/chunk-HFC4BTWJ.js.map +1 -0
- package/dist/{chunk-7QCIYDGC.js → chunk-IOREXWLM.js} +2 -2
- package/dist/{chunk-6UOE5CTA.js → chunk-JT6HHO5P.js} +5 -10
- package/dist/chunk-JT6HHO5P.js.map +1 -0
- package/dist/{chunk-JZAJE3JL.js → chunk-M2EBUDZ7.js} +19 -5
- package/dist/chunk-M2EBUDZ7.js.map +1 -0
- package/dist/{chunk-HABVCJJT.js → chunk-N4ZFKQ5C.js} +271 -404
- package/dist/chunk-N4ZFKQ5C.js.map +1 -0
- package/dist/chunk-S5CAJX6O.js +14 -0
- package/dist/chunk-S5CAJX6O.js.map +1 -0
- package/dist/{chunk-RJ2ZHK5D.js → chunk-S6WS2B32.js} +132 -7
- package/dist/chunk-S6WS2B32.js.map +1 -0
- package/dist/chunk-SQV7NUEM.js +136 -0
- package/dist/chunk-SQV7NUEM.js.map +1 -0
- package/dist/chunk-UAKFCMWK.js +1 -0
- package/dist/chunk-UAKFCMWK.js.map +1 -0
- package/dist/chunk-V5XZKHCL.js +296 -0
- package/dist/chunk-V5XZKHCL.js.map +1 -0
- package/dist/chunk-XWJXZ6WE.js +604 -0
- package/dist/chunk-XWJXZ6WE.js.map +1 -0
- package/dist/chunk-Y2SZVW35.js +125 -0
- package/dist/chunk-Y2SZVW35.js.map +1 -0
- package/dist/{chunk-27LQXQSS.js → chunk-YEWTVDDT.js} +224 -767
- package/dist/chunk-YEWTVDDT.js.map +1 -0
- package/dist/{chunk-UDXMR3AD.js → chunk-YNALYIQ3.js} +56 -18
- package/dist/chunk-YNALYIQ3.js.map +1 -0
- package/dist/command-stack-CkjelfK_.d.ts +267 -0
- package/dist/design-canvas/drizzle.d.ts +2 -2
- package/dist/design-canvas/index.d.ts +7 -6
- package/dist/design-canvas/index.js +3 -2
- package/dist/design-canvas-react/engine.d.ts +349 -0
- package/dist/design-canvas-react/engine.js +86 -0
- package/dist/design-canvas-react/engine.js.map +1 -0
- package/dist/design-canvas-react/index.d.ts +69 -649
- package/dist/design-canvas-react/index.js +84 -173
- package/dist/design-canvas-react/index.js.map +1 -1
- package/dist/design-canvas-react/lazy.d.ts +6 -0
- package/dist/design-canvas-react/lazy.js +9 -0
- package/dist/design-canvas-react/lazy.js.map +1 -0
- package/dist/{export-presets-Dl5Aa5xj.d.ts → export-presets-DAsU5Wal.d.ts} +2 -143
- package/dist/flow-types-Cb_AblZs.d.ts +25 -0
- package/dist/index.d.ts +11 -8
- package/dist/index.js +21 -8
- package/dist/lazy-BHHqS8-j.d.ts +72 -0
- package/dist/missions/index.d.ts +12 -0
- package/dist/missions/index.js +1 -1
- package/dist/{model-BHLN208Z.d.ts → model-BBwyOuWG.d.ts} +3 -1
- package/dist/operations-DLIvvD00.d.ts +144 -0
- package/dist/platform/index.js +1 -1
- package/dist/roles-CLtYKHHl.d.ts +49 -0
- package/dist/runtime/index.d.ts +33 -33
- package/dist/runtime/index.js +1 -1
- package/dist/sequences/index.d.ts +1 -1
- package/dist/sequences/index.js +2 -1
- package/dist/sequences-react/index.d.ts +15 -1
- package/dist/sequences-react/index.js +2 -2
- package/dist/{store-CUStmtdH.d.ts → store-CFyxgTlD.d.ts} +1 -1
- package/dist/teams/drizzle.d.ts +42 -0
- package/dist/teams/drizzle.js +194 -0
- package/dist/teams/drizzle.js.map +1 -0
- package/dist/teams/index.d.ts +44 -0
- package/dist/teams/index.js +39 -0
- package/dist/teams/index.js.map +1 -0
- package/dist/teams/members-api.d.ts +152 -0
- package/dist/teams/members-api.js +261 -0
- package/dist/teams/members-api.js.map +1 -0
- package/dist/teams-react/index.d.ts +81 -0
- package/dist/teams-react/index.js +12 -0
- package/dist/teams-react/index.js.map +1 -0
- package/dist/teams-react/lazy.d.ts +9 -0
- package/dist/teams-react/lazy.js +13 -0
- package/dist/teams-react/lazy.js.map +1 -0
- package/dist/theme/index.d.ts +80 -0
- package/dist/theme/index.js +14 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/tailwind-preset.d.ts +65 -0
- package/dist/theme/tailwind-preset.js +33 -0
- package/dist/theme/tailwind-preset.js.map +1 -0
- package/dist/theme/tokens.css +95 -0
- package/dist/trace/index.d.ts +2 -18
- package/dist/trace/index.js +2 -2
- package/dist/web/index.d.ts +25 -2
- package/dist/web/index.js +3 -1
- package/dist/web-react/index.d.ts +71 -31
- package/dist/web-react/index.js +625 -486
- package/dist/web-react/index.js.map +1 -1
- package/package.json +53 -3
- package/dist/DesignCanvas-73IUJJUP.js +0 -10
- package/dist/DesignCanvasEditor-6F2UTOSW.js +0 -9
- package/dist/chunk-27LQXQSS.js.map +0 -1
- package/dist/chunk-5RT6KY4G.js.map +0 -1
- package/dist/chunk-6UOE5CTA.js.map +0 -1
- package/dist/chunk-AFDROJ64.js.map +0 -1
- package/dist/chunk-HABVCJJT.js.map +0 -1
- package/dist/chunk-JZAJE3JL.js.map +0 -1
- package/dist/chunk-LUE4HO5C.js.map +0 -1
- package/dist/chunk-RJ2ZHK5D.js.map +0 -1
- package/dist/chunk-SCG5JJ4C.js.map +0 -1
- package/dist/chunk-UDXMR3AD.js.map +0 -1
- /package/dist/{DesignCanvas-73IUJJUP.js.map → DesignCanvas-AOIVN3SJ.js.map} +0 -0
- /package/dist/{DesignCanvasEditor-6F2UTOSW.js.map → DesignCanvasEditor-IB2FMBBD.js.map} +0 -0
- /package/dist/{TimelineEditor-JDG54OBP.js.map → InviteAcceptPage-EUOGZO2X.js.map} +0 -0
- /package/dist/{chunk-7QCIYDGC.js.map → chunk-IOREXWLM.js.map} +0 -0
package/dist/web-react/index.js
CHANGED
|
@@ -1,13 +1,56 @@
|
|
|
1
1
|
import {
|
|
2
2
|
stepActivityFlowTrace
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-2QI7XV2T.js";
|
|
4
4
|
import {
|
|
5
5
|
snapHarnessToModel,
|
|
6
6
|
snapModelToHarness
|
|
7
7
|
} from "../chunk-5VXPDXZJ.js";
|
|
8
8
|
|
|
9
9
|
// src/web-react/index.tsx
|
|
10
|
-
import { useEffect as useEffect5, useMemo as
|
|
10
|
+
import { useEffect as useEffect5, useMemo as useMemo3, useRef as useRef3, useState as useState6, memo } from "react";
|
|
11
|
+
|
|
12
|
+
// src/web-react/smooth-text.ts
|
|
13
|
+
import { useEffect, useRef, useState } from "react";
|
|
14
|
+
function nextRevealCount(shown, targetLength, dtMs, opts = {}) {
|
|
15
|
+
if (shown >= targetLength) return targetLength;
|
|
16
|
+
const base = opts.baseCharsPerSecond ?? 90;
|
|
17
|
+
const catchUp = opts.catchUpPerChar ?? 5;
|
|
18
|
+
const max = opts.maxCharsPerSecond ?? 2400;
|
|
19
|
+
const backlog = targetLength - shown;
|
|
20
|
+
const rate = Math.min(max, base + backlog * catchUp);
|
|
21
|
+
return Math.min(targetLength, shown + rate * dtMs / 1e3);
|
|
22
|
+
}
|
|
23
|
+
function useSmoothText(target, enabled, opts) {
|
|
24
|
+
const [, force] = useState(0);
|
|
25
|
+
const shownRef = useRef(0);
|
|
26
|
+
const lastTargetRef = useRef("");
|
|
27
|
+
if (!target.startsWith(lastTargetRef.current.slice(0, Math.floor(shownRef.current)))) {
|
|
28
|
+
shownRef.current = 0;
|
|
29
|
+
}
|
|
30
|
+
lastTargetRef.current = target;
|
|
31
|
+
if (!enabled) shownRef.current = target.length;
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (!enabled) return;
|
|
34
|
+
let raf = 0;
|
|
35
|
+
let last = null;
|
|
36
|
+
const tick = (t) => {
|
|
37
|
+
const dt = last == null ? 16 : Math.min(t - last, 100);
|
|
38
|
+
last = t;
|
|
39
|
+
const targetLen = lastTargetRef.current.length;
|
|
40
|
+
if (shownRef.current < targetLen) {
|
|
41
|
+
shownRef.current = nextRevealCount(shownRef.current, targetLen, dt, opts);
|
|
42
|
+
force((n) => n + 1);
|
|
43
|
+
raf = requestAnimationFrame(tick);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
raf = requestAnimationFrame(tick);
|
|
47
|
+
return () => cancelAnimationFrame(raf);
|
|
48
|
+
}, [enabled, target]);
|
|
49
|
+
return target.slice(0, Math.floor(shownRef.current));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/web-react/controls.tsx
|
|
53
|
+
import { useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";
|
|
11
54
|
|
|
12
55
|
// src/web-react/provider-logo.tsx
|
|
13
56
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -49,44 +92,246 @@ function ProviderLogo({ provider, size = 16 }) {
|
|
|
49
92
|
] });
|
|
50
93
|
}
|
|
51
94
|
|
|
52
|
-
// src/web-react/
|
|
53
|
-
import {
|
|
54
|
-
function
|
|
55
|
-
|
|
56
|
-
const base = opts.baseCharsPerSecond ?? 90;
|
|
57
|
-
const catchUp = opts.catchUpPerChar ?? 5;
|
|
58
|
-
const max = opts.maxCharsPerSecond ?? 2400;
|
|
59
|
-
const backlog = targetLength - shown;
|
|
60
|
-
const rate = Math.min(max, base + backlog * catchUp);
|
|
61
|
-
return Math.min(targetLength, shown + rate * dtMs / 1e3);
|
|
95
|
+
// src/web-react/controls.tsx
|
|
96
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
97
|
+
function ChevronDown({ className }) {
|
|
98
|
+
return /* @__PURE__ */ jsx2("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx2("path", { d: "m6 9 6 6 6-6" }) });
|
|
62
99
|
}
|
|
63
|
-
function
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
100
|
+
function SearchGlyph({ className }) {
|
|
101
|
+
return /* @__PURE__ */ jsxs2("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
102
|
+
/* @__PURE__ */ jsx2("circle", { cx: "11", cy: "11", r: "8" }),
|
|
103
|
+
/* @__PURE__ */ jsx2("path", { d: "m21 21-4.3-4.3" })
|
|
104
|
+
] });
|
|
105
|
+
}
|
|
106
|
+
function SparkleGlyph({ className }) {
|
|
107
|
+
return /* @__PURE__ */ jsx2("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx2("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3M5.6 5.6l2.1 2.1m8.6 8.6 2.1 2.1m0-12.8-2.1 2.1M7.7 16.3l-2.1 2.1" }) });
|
|
108
|
+
}
|
|
109
|
+
function usePopover(open, setOpen) {
|
|
110
|
+
const containerRef = useRef2(null);
|
|
111
|
+
const triggerRef = useRef2(null);
|
|
112
|
+
useEffect2(() => {
|
|
113
|
+
if (!open) return;
|
|
114
|
+
function onMouseDown(e) {
|
|
115
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) setOpen(false);
|
|
116
|
+
}
|
|
117
|
+
function onKeyDown(e) {
|
|
118
|
+
if (e.key === "Escape") {
|
|
119
|
+
setOpen(false);
|
|
120
|
+
triggerRef.current?.focus();
|
|
83
121
|
}
|
|
84
|
-
|
|
122
|
+
}
|
|
123
|
+
document.addEventListener("mousedown", onMouseDown);
|
|
124
|
+
document.addEventListener("keydown", onKeyDown);
|
|
125
|
+
return () => {
|
|
126
|
+
document.removeEventListener("mousedown", onMouseDown);
|
|
127
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
85
128
|
};
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
129
|
+
}, [open, setOpen]);
|
|
130
|
+
return {
|
|
131
|
+
containerRef,
|
|
132
|
+
triggerRef,
|
|
133
|
+
triggerProps: {
|
|
134
|
+
ref: triggerRef,
|
|
135
|
+
"aria-haspopup": true,
|
|
136
|
+
"aria-expanded": open
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
var POPOVER_OPTION_FOCUS = "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-card";
|
|
141
|
+
function usePending() {
|
|
142
|
+
const [pending, setPending] = useState2(false);
|
|
143
|
+
const inFlight = useRef2(false);
|
|
144
|
+
const mounted = useRef2(true);
|
|
145
|
+
useEffect2(() => {
|
|
146
|
+
mounted.current = true;
|
|
147
|
+
return () => {
|
|
148
|
+
mounted.current = false;
|
|
149
|
+
};
|
|
150
|
+
}, []);
|
|
151
|
+
const run = (action) => {
|
|
152
|
+
if (inFlight.current) return;
|
|
153
|
+
let result;
|
|
154
|
+
try {
|
|
155
|
+
result = action();
|
|
156
|
+
} catch {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (!(result instanceof Promise)) return;
|
|
160
|
+
inFlight.current = true;
|
|
161
|
+
setPending(true);
|
|
162
|
+
void result.finally(() => {
|
|
163
|
+
inFlight.current = false;
|
|
164
|
+
if (mounted.current) setPending(false);
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
return { pending, run };
|
|
168
|
+
}
|
|
169
|
+
function formatPrice(p) {
|
|
170
|
+
if (!p) return void 0;
|
|
171
|
+
const n = Number(p);
|
|
172
|
+
if (isNaN(n) || n === 0) return void 0;
|
|
173
|
+
const perM = n * 1e6;
|
|
174
|
+
return perM >= 1 ? `$${perM.toFixed(0)}/M` : `$${perM.toFixed(2)}/M`;
|
|
175
|
+
}
|
|
176
|
+
function formatContext(len) {
|
|
177
|
+
if (!len) return void 0;
|
|
178
|
+
if (len >= 1e6) return `${(len / 1e6).toFixed(1)}M ctx`;
|
|
179
|
+
if (len >= 1e3) return `${Math.round(len / 1e3)}K ctx`;
|
|
180
|
+
return `${len} ctx`;
|
|
181
|
+
}
|
|
182
|
+
function SectionHeader({ children }) {
|
|
183
|
+
return /* @__PURE__ */ jsx2("div", { className: "px-3 pb-1 pt-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children });
|
|
184
|
+
}
|
|
185
|
+
function ModelRow({
|
|
186
|
+
model,
|
|
187
|
+
selected,
|
|
188
|
+
onSelect,
|
|
189
|
+
renderProviderBadge
|
|
190
|
+
}) {
|
|
191
|
+
const price = formatPrice(model.pricing?.prompt);
|
|
192
|
+
const ctx = formatContext(model.contextLength);
|
|
193
|
+
return /* @__PURE__ */ jsxs2(
|
|
194
|
+
"button",
|
|
195
|
+
{
|
|
196
|
+
type: "button",
|
|
197
|
+
onClick: onSelect,
|
|
198
|
+
className: `flex w-full items-center gap-2.5 rounded-md px-3 py-2.5 text-left text-sm transition ${POPOVER_OPTION_FOCUS} ${selected ? "bg-primary/10 font-medium" : "hover:bg-accent/30"}`,
|
|
199
|
+
children: [
|
|
200
|
+
renderProviderBadge ? renderProviderBadge(model.provider) : /* @__PURE__ */ jsx2(ProviderLogo, { provider: model.provider, size: 16 }),
|
|
201
|
+
/* @__PURE__ */ jsx2("span", { className: "truncate", children: model.name }),
|
|
202
|
+
!model.supportsTools && /* @__PURE__ */ jsx2("span", { className: "shrink-0 rounded bg-muted/60 px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground", children: "no tools" }),
|
|
203
|
+
/* @__PURE__ */ jsxs2("span", { className: "ml-auto flex shrink-0 items-center gap-2 text-xs text-muted-foreground", children: [
|
|
204
|
+
ctx && /* @__PURE__ */ jsx2("span", { children: ctx }),
|
|
205
|
+
price && /* @__PURE__ */ jsx2("span", { children: price })
|
|
206
|
+
] })
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
function ModelPicker({ value, onChange, models, loading, renderProviderBadge, recommendedLabel = "Recommended" }) {
|
|
212
|
+
const [open, setOpen] = useState2(false);
|
|
213
|
+
const [query, setQuery] = useState2("");
|
|
214
|
+
const { containerRef, triggerProps } = usePopover(open, setOpen);
|
|
215
|
+
const inputRef = useRef2(null);
|
|
216
|
+
useEffect2(() => {
|
|
217
|
+
if (open) inputRef.current?.focus();
|
|
218
|
+
}, [open]);
|
|
219
|
+
const selected = models.find((m) => m.id === value);
|
|
220
|
+
const filtered = useMemo(() => {
|
|
221
|
+
const q = query.trim().toLowerCase();
|
|
222
|
+
if (!q) return null;
|
|
223
|
+
return models.filter(
|
|
224
|
+
(m) => m.id.toLowerCase().includes(q) || m.name.toLowerCase().includes(q) || (m.description?.toLowerCase() ?? "").includes(q) || m.provider.toLowerCase().includes(q)
|
|
225
|
+
);
|
|
226
|
+
}, [models, query]);
|
|
227
|
+
const sections = useMemo(() => {
|
|
228
|
+
const recommended = models.filter((m) => m.featured);
|
|
229
|
+
const byProvider = [];
|
|
230
|
+
for (const m of models) {
|
|
231
|
+
if (m.featured) continue;
|
|
232
|
+
const last = byProvider[byProvider.length - 1];
|
|
233
|
+
if (last && last.provider === m.provider) last.items.push(m);
|
|
234
|
+
else byProvider.push({ provider: m.provider, items: [m] });
|
|
235
|
+
}
|
|
236
|
+
return { recommended, byProvider };
|
|
237
|
+
}, [models]);
|
|
238
|
+
const select = (id) => {
|
|
239
|
+
onChange(id);
|
|
240
|
+
setOpen(false);
|
|
241
|
+
setQuery("");
|
|
242
|
+
};
|
|
243
|
+
return /* @__PURE__ */ jsxs2("div", { ref: containerRef, className: "relative inline-flex", children: [
|
|
244
|
+
/* @__PURE__ */ jsxs2(
|
|
245
|
+
"button",
|
|
246
|
+
{
|
|
247
|
+
type: "button",
|
|
248
|
+
...triggerProps,
|
|
249
|
+
onClick: () => setOpen(!open),
|
|
250
|
+
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",
|
|
251
|
+
children: [
|
|
252
|
+
selected ? renderProviderBadge ? renderProviderBadge(selected.provider) : /* @__PURE__ */ jsx2(ProviderLogo, { provider: selected.provider, size: 16 }) : /* @__PURE__ */ jsx2(SparkleGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
253
|
+
/* @__PURE__ */ jsx2("span", { className: "max-w-[160px] truncate", children: selected?.name ?? value }),
|
|
254
|
+
/* @__PURE__ */ jsx2(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
255
|
+
]
|
|
256
|
+
}
|
|
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: [
|
|
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
|
+
/* @__PURE__ */ jsx2(SearchGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
261
|
+
/* @__PURE__ */ jsx2(
|
|
262
|
+
"input",
|
|
263
|
+
{
|
|
264
|
+
ref: inputRef,
|
|
265
|
+
type: "text",
|
|
266
|
+
value: query,
|
|
267
|
+
onChange: (e) => setQuery(e.target.value),
|
|
268
|
+
placeholder: "Search models...",
|
|
269
|
+
className: "flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
|
|
270
|
+
}
|
|
271
|
+
)
|
|
272
|
+
] }) }),
|
|
273
|
+
/* @__PURE__ */ jsxs2("div", { className: "max-h-[400px] overflow-y-auto p-1 pb-2", children: [
|
|
274
|
+
loading && /* @__PURE__ */ jsx2("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "Loading models..." }),
|
|
275
|
+
!loading && filtered && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
276
|
+
filtered.length === 0 && /* @__PURE__ */ jsx2("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "No models match your search" }),
|
|
277
|
+
filtered.map((m) => /* @__PURE__ */ jsx2(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
|
|
278
|
+
] }),
|
|
279
|
+
!loading && !filtered && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
280
|
+
sections.recommended.length > 0 && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
281
|
+
/* @__PURE__ */ jsx2(SectionHeader, { children: recommendedLabel }),
|
|
282
|
+
sections.recommended.map((m) => /* @__PURE__ */ jsx2(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
|
|
283
|
+
] }),
|
|
284
|
+
sections.byProvider.map((g) => /* @__PURE__ */ jsxs2("div", { children: [
|
|
285
|
+
/* @__PURE__ */ jsx2(SectionHeader, { children: g.provider }),
|
|
286
|
+
g.items.map((m) => /* @__PURE__ */ jsx2(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
|
|
287
|
+
] }, g.provider))
|
|
288
|
+
] })
|
|
289
|
+
] })
|
|
290
|
+
] })
|
|
291
|
+
] });
|
|
292
|
+
}
|
|
293
|
+
var EFFORT_LEVELS = [
|
|
294
|
+
{ id: "off", label: "Off" },
|
|
295
|
+
{ id: "low", label: "Low" },
|
|
296
|
+
{ id: "medium", label: "Medium" },
|
|
297
|
+
{ id: "high", label: "High" }
|
|
298
|
+
];
|
|
299
|
+
function EffortPicker({ value, onChange }) {
|
|
300
|
+
const [open, setOpen] = useState2(false);
|
|
301
|
+
const { containerRef, triggerProps } = usePopover(open, setOpen);
|
|
302
|
+
const selected = EFFORT_LEVELS.find((l) => l.id === value) ?? EFFORT_LEVELS[2];
|
|
303
|
+
return /* @__PURE__ */ jsxs2("div", { ref: containerRef, className: "relative inline-flex", children: [
|
|
304
|
+
/* @__PURE__ */ jsxs2(
|
|
305
|
+
"button",
|
|
306
|
+
{
|
|
307
|
+
type: "button",
|
|
308
|
+
...triggerProps,
|
|
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",
|
|
312
|
+
children: [
|
|
313
|
+
/* @__PURE__ */ jsx2(SparkleGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
314
|
+
/* @__PURE__ */ jsx2("span", { children: selected.label }),
|
|
315
|
+
/* @__PURE__ */ jsx2(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
316
|
+
]
|
|
317
|
+
}
|
|
318
|
+
),
|
|
319
|
+
open && /* @__PURE__ */ jsx2("div", { role: "menu", className: "absolute bottom-full left-0 z-50 mb-2 w-36 overflow-hidden rounded-xl border border-border bg-card p-1 shadow-lg", children: EFFORT_LEVELS.map((l) => /* @__PURE__ */ jsx2(
|
|
320
|
+
"button",
|
|
321
|
+
{
|
|
322
|
+
type: "button",
|
|
323
|
+
role: "menuitemradio",
|
|
324
|
+
"aria-checked": l.id === value,
|
|
325
|
+
onClick: () => {
|
|
326
|
+
onChange(l.id);
|
|
327
|
+
setOpen(false);
|
|
328
|
+
},
|
|
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"}`,
|
|
330
|
+
children: l.label
|
|
331
|
+
},
|
|
332
|
+
l.id
|
|
333
|
+
)) })
|
|
334
|
+
] });
|
|
90
335
|
}
|
|
91
336
|
|
|
92
337
|
// src/web-react/chat-stream.ts
|
|
@@ -215,8 +460,8 @@ async function streamChatTurn(opts) {
|
|
|
215
460
|
}
|
|
216
461
|
|
|
217
462
|
// src/web-react/mission-activity.tsx
|
|
218
|
-
import { useCallback, useEffect as
|
|
219
|
-
import { Fragment, jsx as
|
|
463
|
+
import { useCallback, useEffect as useEffect3, useState as useState3 } from "react";
|
|
464
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
220
465
|
var LIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "running"]);
|
|
221
466
|
var OK_STATUSES = /* @__PURE__ */ new Set(["completed", "done", "succeeded"]);
|
|
222
467
|
var ERROR_STATUSES = /* @__PURE__ */ new Set(["failed", "error", "cancelled", "aborted"]);
|
|
@@ -263,19 +508,57 @@ function waterfallLayout(trace) {
|
|
|
263
508
|
});
|
|
264
509
|
}
|
|
265
510
|
function ChevronGlyph({ className }) {
|
|
266
|
-
return /* @__PURE__ */
|
|
511
|
+
return /* @__PURE__ */ jsx3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx3("path", { d: "m6 9 6 6 6-6" }) });
|
|
267
512
|
}
|
|
268
513
|
function RefreshGlyph({ className }) {
|
|
269
|
-
return /* @__PURE__ */
|
|
514
|
+
return /* @__PURE__ */ jsx3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx3("path", { d: "M21 12a9 9 0 1 1-2.64-6.36M21 3v6h-6" }) });
|
|
270
515
|
}
|
|
271
|
-
function
|
|
272
|
-
return /* @__PURE__ */
|
|
273
|
-
"
|
|
516
|
+
function CopyGlyph({ className }) {
|
|
517
|
+
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__ */ jsx3("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
|
|
519
|
+
/* @__PURE__ */ jsx3("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
520
|
+
] });
|
|
521
|
+
}
|
|
522
|
+
function TraceIdCopy({ traceId }) {
|
|
523
|
+
const [copied, setCopied] = useState3(false);
|
|
524
|
+
const copy = useCallback(() => {
|
|
525
|
+
void navigator.clipboard?.writeText(traceId).then(
|
|
526
|
+
() => {
|
|
527
|
+
setCopied(true);
|
|
528
|
+
setTimeout(() => setCopied(false), 1200);
|
|
529
|
+
},
|
|
530
|
+
() => {
|
|
531
|
+
}
|
|
532
|
+
);
|
|
533
|
+
}, [traceId]);
|
|
534
|
+
return /* @__PURE__ */ jsxs3(
|
|
535
|
+
"button",
|
|
274
536
|
{
|
|
275
|
-
|
|
537
|
+
type: "button",
|
|
538
|
+
onClick: copy,
|
|
539
|
+
title: "Copy trace id",
|
|
540
|
+
"aria-label": "Copy trace id",
|
|
541
|
+
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
|
+
children: [
|
|
543
|
+
/* @__PURE__ */ jsx3("span", { className: "truncate", children: traceId }),
|
|
544
|
+
/* @__PURE__ */ jsx3(CopyGlyph, { className: "h-3 w-3 shrink-0" }),
|
|
545
|
+
copied && /* @__PURE__ */ jsx3("span", { className: "shrink-0 not-italic text-success", children: "copied" })
|
|
546
|
+
]
|
|
276
547
|
}
|
|
277
548
|
);
|
|
278
549
|
}
|
|
550
|
+
function StatusDot({ tone }) {
|
|
551
|
+
return /* @__PURE__ */ jsxs3("span", { className: "inline-flex items-center", children: [
|
|
552
|
+
/* @__PURE__ */ jsx3(
|
|
553
|
+
"span",
|
|
554
|
+
{
|
|
555
|
+
"aria-hidden": true,
|
|
556
|
+
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
|
+
}
|
|
558
|
+
),
|
|
559
|
+
/* @__PURE__ */ jsx3("span", { className: "sr-only", children: tone })
|
|
560
|
+
] });
|
|
561
|
+
}
|
|
279
562
|
var BAR_CLASS = {
|
|
280
563
|
pipeline: "bg-muted-foreground/30",
|
|
281
564
|
model: "bg-primary/60",
|
|
@@ -285,19 +568,19 @@ function FlowWaterfall({ trace }) {
|
|
|
285
568
|
const rows = waterfallLayout(trace);
|
|
286
569
|
if (rows.length === 0) return null;
|
|
287
570
|
const cost = formatActivityCost(trace.costUsd);
|
|
288
|
-
return /* @__PURE__ */
|
|
289
|
-
rows.map((row, i) => /* @__PURE__ */
|
|
290
|
-
/* @__PURE__ */
|
|
291
|
-
/* @__PURE__ */
|
|
571
|
+
return /* @__PURE__ */ jsxs3("div", { className: "space-y-1", children: [
|
|
572
|
+
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__ */ jsx3("span", { className: "truncate font-mono text-[11px] text-muted-foreground", title: row.name, children: row.name }),
|
|
574
|
+
/* @__PURE__ */ jsx3("div", { className: "relative h-2 rounded-sm bg-muted/40", children: /* @__PURE__ */ jsx3(
|
|
292
575
|
"div",
|
|
293
576
|
{
|
|
294
|
-
className: `absolute inset-y-0 rounded-sm ${row.ok ? BAR_CLASS[row.kind] : "bg-
|
|
577
|
+
className: `absolute inset-y-0 rounded-sm ${row.ok ? BAR_CLASS[row.kind] : "bg-destructive/80"} ${row.approx ? "opacity-70" : ""}`,
|
|
295
578
|
style: { left: `${row.offsetPct}%`, width: `${row.widthPct}%` }
|
|
296
579
|
}
|
|
297
580
|
) }),
|
|
298
|
-
/* @__PURE__ */
|
|
581
|
+
/* @__PURE__ */ jsx3("span", { className: "shrink-0 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: row.durationLabel })
|
|
299
582
|
] }, i)),
|
|
300
|
-
/* @__PURE__ */
|
|
583
|
+
/* @__PURE__ */ jsxs3("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
|
|
301
584
|
(trace.totalMs / 1e3).toFixed(1),
|
|
302
585
|
"s",
|
|
303
586
|
cost ? ` \xB7 ${cost}` : ""
|
|
@@ -305,43 +588,43 @@ function FlowWaterfall({ trace }) {
|
|
|
305
588
|
] });
|
|
306
589
|
}
|
|
307
590
|
function MissionActivityLane({ activity, startedAt, nowMs }) {
|
|
308
|
-
const [expanded, setExpanded] =
|
|
591
|
+
const [expanded, setExpanded] = useState3(false);
|
|
309
592
|
if (activity.length === 0) return null;
|
|
310
|
-
return /* @__PURE__ */
|
|
593
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mt-1 border-l border-border/50 pl-3", children: [
|
|
311
594
|
activity.map((run) => {
|
|
312
595
|
const tone = activityTone(run.status);
|
|
313
596
|
const cost = formatActivityCost(run.costUsd);
|
|
314
597
|
const duration = formatActivityDuration(run.durationMs);
|
|
315
|
-
return /* @__PURE__ */
|
|
316
|
-
/* @__PURE__ */
|
|
317
|
-
/* @__PURE__ */
|
|
318
|
-
/* @__PURE__ */
|
|
319
|
-
/* @__PURE__ */
|
|
598
|
+
return /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
|
|
599
|
+
/* @__PURE__ */ jsx3(StatusDot, { tone }),
|
|
600
|
+
/* @__PURE__ */ jsxs3("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
601
|
+
/* @__PURE__ */ jsx3("span", { className: "font-medium", children: run.tool }),
|
|
602
|
+
/* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
|
|
320
603
|
" \u2014 ",
|
|
321
604
|
run.detail
|
|
322
605
|
] })
|
|
323
606
|
] }),
|
|
324
|
-
tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */
|
|
325
|
-
/* @__PURE__ */
|
|
326
|
-
tone !== "live" && tone !== "ok" && /* @__PURE__ */
|
|
327
|
-
cost && /* @__PURE__ */
|
|
328
|
-
duration && /* @__PURE__ */
|
|
607
|
+
tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */ jsx3("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
|
+
/* @__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__ */ jsx3("span", { children: run.status }),
|
|
610
|
+
cost && /* @__PURE__ */ jsx3("span", { children: cost }),
|
|
611
|
+
duration && /* @__PURE__ */ jsx3("span", { children: duration })
|
|
329
612
|
] })
|
|
330
613
|
] }, run.taskId);
|
|
331
614
|
}),
|
|
332
|
-
/* @__PURE__ */
|
|
615
|
+
/* @__PURE__ */ jsxs3(
|
|
333
616
|
"button",
|
|
334
617
|
{
|
|
335
618
|
type: "button",
|
|
336
619
|
onClick: () => setExpanded((v) => !v),
|
|
337
620
|
className: "flex items-center gap-1 py-0.5 text-[10px] font-medium text-muted-foreground/70 transition hover:text-foreground",
|
|
338
621
|
children: [
|
|
339
|
-
/* @__PURE__ */
|
|
622
|
+
/* @__PURE__ */ jsx3(ChevronGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
|
|
340
623
|
"timeline"
|
|
341
624
|
]
|
|
342
625
|
}
|
|
343
626
|
),
|
|
344
|
-
expanded && /* @__PURE__ */
|
|
627
|
+
expanded && /* @__PURE__ */ jsx3("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx3(
|
|
345
628
|
FlowWaterfall,
|
|
346
629
|
{
|
|
347
630
|
trace: stepActivityFlowTrace(activity, {
|
|
@@ -356,44 +639,45 @@ function ActivityRow({
|
|
|
356
639
|
record,
|
|
357
640
|
renderMissionRef
|
|
358
641
|
}) {
|
|
359
|
-
const [open, setOpen] =
|
|
642
|
+
const [open, setOpen] = useState3(false);
|
|
360
643
|
const tone = activityTone(record.status);
|
|
361
644
|
const cost = formatActivityCost(record.costUsd);
|
|
362
645
|
const duration = formatActivityDuration(record.durationMs);
|
|
363
|
-
return /* @__PURE__ */
|
|
364
|
-
/* @__PURE__ */
|
|
365
|
-
/* @__PURE__ */
|
|
366
|
-
/* @__PURE__ */
|
|
367
|
-
/* @__PURE__ */
|
|
368
|
-
/* @__PURE__ */
|
|
646
|
+
return /* @__PURE__ */ jsxs3("div", { className: "rounded-lg border border-border/60 bg-card", children: [
|
|
647
|
+
/* @__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__ */ jsx3(StatusDot, { tone }),
|
|
649
|
+
/* @__PURE__ */ jsxs3("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
650
|
+
/* @__PURE__ */ jsx3("span", { className: "font-medium", children: record.tool }),
|
|
651
|
+
/* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
|
|
369
652
|
" \u2014 ",
|
|
370
653
|
record.detail
|
|
371
654
|
] })
|
|
372
655
|
] }),
|
|
373
|
-
tone === "live" && (record.iteration !== void 0 || record.phase !== void 0) && /* @__PURE__ */
|
|
374
|
-
/* @__PURE__ */
|
|
656
|
+
tone === "live" && (record.iteration !== void 0 || record.phase !== void 0) && /* @__PURE__ */ jsx3("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 ") }),
|
|
657
|
+
/* @__PURE__ */ jsx3(
|
|
375
658
|
"span",
|
|
376
659
|
{
|
|
377
|
-
className: `shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium ${tone === "ok" ? "bg-
|
|
660
|
+
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"}`,
|
|
378
661
|
children: record.status
|
|
379
662
|
}
|
|
380
663
|
),
|
|
381
|
-
cost && /* @__PURE__ */
|
|
382
|
-
/* @__PURE__ */
|
|
664
|
+
cost && /* @__PURE__ */ jsx3("span", { className: "shrink-0 font-mono text-[11px] tabular-nums text-muted-foreground", children: cost }),
|
|
665
|
+
/* @__PURE__ */ jsx3(ChevronGlyph, { className: `h-3 w-3 shrink-0 text-muted-foreground transition-transform ${open ? "rotate-180" : ""}` })
|
|
383
666
|
] }),
|
|
384
|
-
open && /* @__PURE__ */
|
|
385
|
-
/* @__PURE__ */
|
|
386
|
-
|
|
387
|
-
/* @__PURE__ */
|
|
388
|
-
/* @__PURE__ */
|
|
389
|
-
/* @__PURE__ */
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
/* @__PURE__ */
|
|
667
|
+
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__ */ jsx3("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx3(FlowWaterfall, { trace: stepActivityFlowTrace([record]) }) }),
|
|
669
|
+
/* @__PURE__ */ jsxs3("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 font-mono text-[11px]", children: [
|
|
670
|
+
/* @__PURE__ */ jsx3("dt", { className: "text-muted-foreground/60", children: "task" }),
|
|
671
|
+
/* @__PURE__ */ jsx3("dd", { className: "truncate text-muted-foreground", children: record.taskId }),
|
|
672
|
+
/* @__PURE__ */ jsx3("dt", { className: "text-muted-foreground/60", children: "started" }),
|
|
673
|
+
/* @__PURE__ */ jsx3("dd", { className: "text-muted-foreground", children: new Date(record.startedAt).toLocaleString() }),
|
|
674
|
+
duration && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
675
|
+
/* @__PURE__ */ jsx3("dt", { className: "text-muted-foreground/60", children: "duration" }),
|
|
676
|
+
/* @__PURE__ */ jsx3("dd", { className: "text-muted-foreground", children: duration })
|
|
393
677
|
] }),
|
|
394
|
-
record.traceId && /* @__PURE__ */
|
|
395
|
-
/* @__PURE__ */
|
|
396
|
-
/* @__PURE__ */
|
|
678
|
+
record.traceId && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
679
|
+
/* @__PURE__ */ jsx3("dt", { className: "text-muted-foreground/60", children: "trace" }),
|
|
680
|
+
/* @__PURE__ */ jsx3("dd", { className: "min-w-0", children: /* @__PURE__ */ jsx3(TraceIdCopy, { traceId: record.traceId }) })
|
|
397
681
|
] })
|
|
398
682
|
] }),
|
|
399
683
|
record.missionRef && renderMissionRef?.(record.missionRef, record)
|
|
@@ -401,10 +685,10 @@ function ActivityRow({
|
|
|
401
685
|
] });
|
|
402
686
|
}
|
|
403
687
|
function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent activity", emptyLabel = "No agent runs yet." }) {
|
|
404
|
-
const [rows, setRows] =
|
|
405
|
-
const [cursor, setCursor] =
|
|
406
|
-
const [loading, setLoading] =
|
|
407
|
-
const [error, setError] =
|
|
688
|
+
const [rows, setRows] = useState3([]);
|
|
689
|
+
const [cursor, setCursor] = useState3(void 0);
|
|
690
|
+
const [loading, setLoading] = useState3(false);
|
|
691
|
+
const [error, setError] = useState3(null);
|
|
408
692
|
const load = useCallback(
|
|
409
693
|
async (from) => {
|
|
410
694
|
setLoading(true);
|
|
@@ -421,13 +705,13 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
|
|
|
421
705
|
},
|
|
422
706
|
[fetchActivity]
|
|
423
707
|
);
|
|
424
|
-
|
|
708
|
+
useEffect3(() => {
|
|
425
709
|
void load();
|
|
426
710
|
}, [load]);
|
|
427
|
-
return /* @__PURE__ */
|
|
428
|
-
/* @__PURE__ */
|
|
429
|
-
/* @__PURE__ */
|
|
430
|
-
/* @__PURE__ */
|
|
711
|
+
return /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
|
|
712
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
|
|
713
|
+
/* @__PURE__ */ jsx3("h2", { className: "flex-1 text-sm font-semibold", children: title }),
|
|
714
|
+
/* @__PURE__ */ jsx3(
|
|
431
715
|
"button",
|
|
432
716
|
{
|
|
433
717
|
type: "button",
|
|
@@ -435,14 +719,14 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
|
|
|
435
719
|
disabled: loading,
|
|
436
720
|
"aria-label": "Refresh",
|
|
437
721
|
className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground disabled:opacity-50",
|
|
438
|
-
children: /* @__PURE__ */
|
|
722
|
+
children: /* @__PURE__ */ jsx3(RefreshGlyph, { className: `h-3.5 w-3.5 ${loading ? "animate-spin" : ""}` })
|
|
439
723
|
}
|
|
440
724
|
)
|
|
441
725
|
] }),
|
|
442
|
-
error && /* @__PURE__ */
|
|
443
|
-
!error && rows.length === 0 && !loading && /* @__PURE__ */
|
|
444
|
-
/* @__PURE__ */
|
|
445
|
-
cursor && /* @__PURE__ */
|
|
726
|
+
error && /* @__PURE__ */ jsx3("p", { role: "alert", className: "rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: error }),
|
|
727
|
+
!error && rows.length === 0 && !loading && /* @__PURE__ */ jsx3("p", { className: "px-1 text-sm text-muted-foreground", children: emptyLabel }),
|
|
728
|
+
/* @__PURE__ */ jsx3("div", { className: "space-y-1.5", children: rows.map((record) => /* @__PURE__ */ jsx3(ActivityRow, { record, renderMissionRef }, record.taskId)) }),
|
|
729
|
+
cursor && /* @__PURE__ */ jsx3(
|
|
446
730
|
"button",
|
|
447
731
|
{
|
|
448
732
|
type: "button",
|
|
@@ -456,7 +740,7 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
|
|
|
456
740
|
}
|
|
457
741
|
|
|
458
742
|
// src/web-react/sandbox-terminal.ts
|
|
459
|
-
import { useCallback as useCallback2, useEffect as
|
|
743
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useState as useState4 } from "react";
|
|
460
744
|
var DEFAULT_PROVISION_POLL_INTERVAL_MS = 2e3;
|
|
461
745
|
var DEFAULT_PROVISION_POLL_TIMEOUT_MS = 9e4;
|
|
462
746
|
var DEFAULT_TOKEN_REFRESH_SKEW_MS = 12e4;
|
|
@@ -470,7 +754,7 @@ var EMPTY_CONNECTION = {
|
|
|
470
754
|
loading: false
|
|
471
755
|
};
|
|
472
756
|
function useSandboxTerminalConnection(opts) {
|
|
473
|
-
const [conn, setConn] =
|
|
757
|
+
const [conn, setConn] = useState4(EMPTY_CONNECTION);
|
|
474
758
|
const fetcher = opts.fetcher ?? fetch;
|
|
475
759
|
const pollIntervalMs = opts.provisionPollIntervalMs ?? DEFAULT_PROVISION_POLL_INTERVAL_MS;
|
|
476
760
|
const pollTimeoutMs = opts.provisionPollTimeoutMs ?? DEFAULT_PROVISION_POLL_TIMEOUT_MS;
|
|
@@ -552,10 +836,10 @@ function useSandboxTerminalConnection(opts) {
|
|
|
552
836
|
}
|
|
553
837
|
}
|
|
554
838
|
}, [connectionUrl, fetcher, pollIntervalMs, pollTimeoutMs]);
|
|
555
|
-
|
|
839
|
+
useEffect4(() => {
|
|
556
840
|
void connect();
|
|
557
841
|
}, [connect]);
|
|
558
|
-
|
|
842
|
+
useEffect4(() => {
|
|
559
843
|
if (!conn.runtimeUrl || !conn.token || !conn.expiresAt) return;
|
|
560
844
|
const refreshAt = Date.parse(conn.expiresAt) - Date.now() - refreshSkewMs;
|
|
561
845
|
if (!Number.isFinite(refreshAt)) {
|
|
@@ -582,9 +866,9 @@ function sleep(ms) {
|
|
|
582
866
|
}
|
|
583
867
|
|
|
584
868
|
// src/web-react/seat-paywall.tsx
|
|
585
|
-
import { jsx as
|
|
869
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
586
870
|
function CheckGlyph() {
|
|
587
|
-
return /* @__PURE__ */
|
|
871
|
+
return /* @__PURE__ */ jsx4(
|
|
588
872
|
"svg",
|
|
589
873
|
{
|
|
590
874
|
className: "h-4 w-4 shrink-0 text-primary",
|
|
@@ -595,14 +879,14 @@ function CheckGlyph() {
|
|
|
595
879
|
strokeLinecap: "round",
|
|
596
880
|
strokeLinejoin: "round",
|
|
597
881
|
"aria-hidden": true,
|
|
598
|
-
children: /* @__PURE__ */
|
|
882
|
+
children: /* @__PURE__ */ jsx4("path", { d: "M20 6 9 17l-5-5" })
|
|
599
883
|
}
|
|
600
884
|
);
|
|
601
885
|
}
|
|
602
886
|
function Benefit({ children }) {
|
|
603
|
-
return /* @__PURE__ */
|
|
604
|
-
/* @__PURE__ */
|
|
605
|
-
/* @__PURE__ */
|
|
887
|
+
return /* @__PURE__ */ jsxs4("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
|
|
888
|
+
/* @__PURE__ */ jsx4("span", { className: "mt-0.5", children: /* @__PURE__ */ jsx4(CheckGlyph, {}) }),
|
|
889
|
+
/* @__PURE__ */ jsx4("span", { children })
|
|
606
890
|
] });
|
|
607
891
|
}
|
|
608
892
|
function SeatPaywall({
|
|
@@ -613,53 +897,55 @@ function SeatPaywall({
|
|
|
613
897
|
tagline,
|
|
614
898
|
ctaLabel
|
|
615
899
|
}) {
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
/* @__PURE__ */
|
|
900
|
+
const { pending, run } = usePending();
|
|
901
|
+
return /* @__PURE__ */ jsx4("div", { className: "flex min-h-[60vh] w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxs4("div", { className: "w-full max-w-md rounded-2xl border border-border bg-card p-8 shadow-sm", children: [
|
|
902
|
+
/* @__PURE__ */ jsx4("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: product }),
|
|
903
|
+
/* @__PURE__ */ jsxs4("h1", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: [
|
|
619
904
|
"Unlock ",
|
|
620
905
|
product
|
|
621
906
|
] }),
|
|
622
|
-
tagline && /* @__PURE__ */
|
|
623
|
-
/* @__PURE__ */
|
|
624
|
-
/* @__PURE__ */
|
|
907
|
+
tagline && /* @__PURE__ */ jsx4("p", { className: "mt-2 text-sm text-muted-foreground", children: tagline }),
|
|
908
|
+
/* @__PURE__ */ jsxs4("div", { className: "mt-6 flex items-baseline gap-1.5", children: [
|
|
909
|
+
/* @__PURE__ */ jsxs4("span", { className: "text-3xl font-semibold text-foreground", children: [
|
|
625
910
|
"$",
|
|
626
911
|
priceUsd
|
|
627
912
|
] }),
|
|
628
|
-
/* @__PURE__ */
|
|
913
|
+
/* @__PURE__ */ jsx4("span", { className: "text-sm text-muted-foreground", children: "/mo" })
|
|
629
914
|
] }),
|
|
630
|
-
/* @__PURE__ */
|
|
915
|
+
/* @__PURE__ */ jsxs4("p", { className: "mt-1 text-sm text-muted-foreground", children: [
|
|
631
916
|
"Includes $",
|
|
632
917
|
includedUsageUsd,
|
|
633
918
|
"/mo of AI usage"
|
|
634
919
|
] }),
|
|
635
|
-
/* @__PURE__ */
|
|
636
|
-
/* @__PURE__ */
|
|
920
|
+
/* @__PURE__ */ jsxs4("ul", { className: "mt-6 space-y-2.5", children: [
|
|
921
|
+
/* @__PURE__ */ jsxs4(Benefit, { children: [
|
|
637
922
|
"Full access to ",
|
|
638
923
|
product
|
|
639
924
|
] }),
|
|
640
|
-
/* @__PURE__ */
|
|
925
|
+
/* @__PURE__ */ jsxs4(Benefit, { children: [
|
|
641
926
|
"$",
|
|
642
927
|
includedUsageUsd,
|
|
643
928
|
"/mo of AI usage included, every month"
|
|
644
929
|
] }),
|
|
645
|
-
/* @__PURE__ */
|
|
930
|
+
/* @__PURE__ */ jsx4(Benefit, { children: "One Tangle wallet across every product you run" })
|
|
646
931
|
] }),
|
|
647
|
-
/* @__PURE__ */
|
|
932
|
+
/* @__PURE__ */ jsx4(
|
|
648
933
|
"button",
|
|
649
934
|
{
|
|
650
935
|
type: "button",
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
936
|
+
disabled: pending,
|
|
937
|
+
onClick: () => run(onCheckout),
|
|
938
|
+
className: "mt-7 inline-flex w-full items-center justify-center rounded-xl bg-primary px-4 py-2.5 text-sm font-medium text-primary-foreground transition hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-70",
|
|
939
|
+
children: pending ? "Opening checkout\u2026" : ctaLabel ?? `Unlock ${product}`
|
|
654
940
|
}
|
|
655
941
|
),
|
|
656
|
-
/* @__PURE__ */
|
|
942
|
+
/* @__PURE__ */ jsx4("p", { className: "mt-3 text-center text-xs text-muted-foreground/70", children: "Cancel anytime." })
|
|
657
943
|
] }) });
|
|
658
944
|
}
|
|
659
945
|
|
|
660
946
|
// src/web-react/agent-session-controls.tsx
|
|
661
|
-
import {
|
|
662
|
-
import { jsx as
|
|
947
|
+
import { useMemo as useMemo2, useState as useState5 } from "react";
|
|
948
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
663
949
|
var HARNESS_LABELS = {
|
|
664
950
|
opencode: "OpenCode (any model)",
|
|
665
951
|
"claude-code": "Claude Code (Anthropic)",
|
|
@@ -678,58 +964,50 @@ var HARNESS_LABELS = {
|
|
|
678
964
|
function harnessLabel(h) {
|
|
679
965
|
return HARNESS_LABELS[h] ?? h;
|
|
680
966
|
}
|
|
681
|
-
function
|
|
682
|
-
return /* @__PURE__ */
|
|
967
|
+
function ChevronDown2({ className }) {
|
|
968
|
+
return /* @__PURE__ */ jsx5("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx5("path", { d: "m6 9 6 6 6-6" }) });
|
|
683
969
|
}
|
|
684
970
|
function GearGlyph({ className }) {
|
|
685
|
-
return /* @__PURE__ */
|
|
686
|
-
/* @__PURE__ */
|
|
687
|
-
/* @__PURE__ */
|
|
971
|
+
return /* @__PURE__ */ jsxs5("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
972
|
+
/* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "3" }),
|
|
973
|
+
/* @__PURE__ */ jsx5("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" })
|
|
688
974
|
] });
|
|
689
975
|
}
|
|
690
|
-
|
|
691
|
-
const ref = useRef2(null);
|
|
692
|
-
useEffect4(() => {
|
|
693
|
-
if (!active) return;
|
|
694
|
-
function handler(e) {
|
|
695
|
-
if (ref.current && !ref.current.contains(e.target)) onOutside();
|
|
696
|
-
}
|
|
697
|
-
document.addEventListener("mousedown", handler);
|
|
698
|
-
return () => document.removeEventListener("mousedown", handler);
|
|
699
|
-
}, [active, onOutside]);
|
|
700
|
-
return ref;
|
|
701
|
-
}
|
|
976
|
+
var FOCUS_RING = "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background";
|
|
702
977
|
function HarnessPicker({
|
|
703
978
|
value,
|
|
704
979
|
onChange,
|
|
705
980
|
available
|
|
706
981
|
}) {
|
|
707
|
-
const [open, setOpen] =
|
|
708
|
-
const containerRef =
|
|
982
|
+
const [open, setOpen] = useState5(false);
|
|
983
|
+
const { containerRef, triggerProps } = usePopover(open, setOpen);
|
|
709
984
|
const options = available ?? Object.keys(HARNESS_LABELS);
|
|
710
|
-
return /* @__PURE__ */
|
|
711
|
-
/* @__PURE__ */
|
|
985
|
+
return /* @__PURE__ */ jsxs5("div", { ref: containerRef, className: "relative inline-flex", children: [
|
|
986
|
+
/* @__PURE__ */ jsxs5(
|
|
712
987
|
"button",
|
|
713
988
|
{
|
|
714
989
|
type: "button",
|
|
715
|
-
|
|
990
|
+
...triggerProps,
|
|
991
|
+
onClick: () => setOpen(!open),
|
|
716
992
|
title: "Agent backend",
|
|
717
|
-
className:
|
|
993
|
+
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}`,
|
|
718
994
|
children: [
|
|
719
|
-
/* @__PURE__ */
|
|
720
|
-
/* @__PURE__ */
|
|
995
|
+
/* @__PURE__ */ jsx5("span", { className: "truncate", children: harnessLabel(value) }),
|
|
996
|
+
/* @__PURE__ */ jsx5(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
721
997
|
]
|
|
722
998
|
}
|
|
723
999
|
),
|
|
724
|
-
open && /* @__PURE__ */
|
|
1000
|
+
open && /* @__PURE__ */ jsx5("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__ */ jsx5(
|
|
725
1001
|
"button",
|
|
726
1002
|
{
|
|
727
1003
|
type: "button",
|
|
1004
|
+
role: "menuitemradio",
|
|
1005
|
+
"aria-checked": h === value,
|
|
728
1006
|
onClick: () => {
|
|
729
1007
|
onChange(h);
|
|
730
1008
|
setOpen(false);
|
|
731
1009
|
},
|
|
732
|
-
className: `flex w-full items-center rounded-md px-3 py-2 text-left text-sm transition ${h === value ? "bg-primary/10 font-medium" : "hover:bg-accent/30"}`,
|
|
1010
|
+
className: `flex w-full items-center rounded-md px-3 py-2 text-left text-sm transition ${FOCUS_RING} ${h === value ? "bg-primary/10 font-medium" : "hover:bg-accent/30"}`,
|
|
733
1011
|
children: harnessLabel(h)
|
|
734
1012
|
},
|
|
735
1013
|
h
|
|
@@ -738,7 +1016,7 @@ function HarnessPicker({
|
|
|
738
1016
|
}
|
|
739
1017
|
function useCoherentHandlers(props) {
|
|
740
1018
|
const { model, models, harness, onModelChange, onHarnessChange } = props;
|
|
741
|
-
const canonicalIds =
|
|
1019
|
+
const canonicalIds = useMemo2(() => models.map((m) => m.id), [models]);
|
|
742
1020
|
const onModel = (next) => {
|
|
743
1021
|
onModelChange(next);
|
|
744
1022
|
const nextHarness = snapHarnessToModel(harness, next);
|
|
@@ -766,11 +1044,11 @@ function AgentSessionControls(props) {
|
|
|
766
1044
|
className
|
|
767
1045
|
} = props;
|
|
768
1046
|
const { onModel, onHarness } = useCoherentHandlers(props);
|
|
769
|
-
const [open, setOpen] =
|
|
770
|
-
const popoverRef =
|
|
1047
|
+
const [open, setOpen] = useState5(false);
|
|
1048
|
+
const { containerRef: popoverRef, triggerProps } = usePopover(open, setOpen);
|
|
771
1049
|
const selectedModel = models.find((m) => m.id === model);
|
|
772
1050
|
const showEffort = selectedModel?.supportsReasoning ?? true;
|
|
773
|
-
const modelPicker = /* @__PURE__ */
|
|
1051
|
+
const modelPicker = /* @__PURE__ */ jsx5(
|
|
774
1052
|
ModelPicker,
|
|
775
1053
|
{
|
|
776
1054
|
value: model,
|
|
@@ -781,37 +1059,38 @@ function AgentSessionControls(props) {
|
|
|
781
1059
|
}
|
|
782
1060
|
);
|
|
783
1061
|
if (layout === "inline") {
|
|
784
|
-
return /* @__PURE__ */
|
|
1062
|
+
return /* @__PURE__ */ jsxs5("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
|
|
785
1063
|
modelPicker,
|
|
786
|
-
showHarness && /* @__PURE__ */
|
|
787
|
-
showEffort && /* @__PURE__ */
|
|
1064
|
+
showHarness && /* @__PURE__ */ jsx5(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
|
|
1065
|
+
showEffort && /* @__PURE__ */ jsx5(EffortPicker, { value: effort, onChange: onEffortChange })
|
|
788
1066
|
] });
|
|
789
1067
|
}
|
|
790
1068
|
const hasAdvanced = showHarness || showEffort;
|
|
791
|
-
return /* @__PURE__ */
|
|
1069
|
+
return /* @__PURE__ */ jsxs5("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
|
|
792
1070
|
modelPicker,
|
|
793
|
-
hasAdvanced && /* @__PURE__ */
|
|
794
|
-
/* @__PURE__ */
|
|
1071
|
+
hasAdvanced && /* @__PURE__ */ jsxs5("div", { ref: popoverRef, className: "relative inline-flex", children: [
|
|
1072
|
+
/* @__PURE__ */ jsx5(
|
|
795
1073
|
"button",
|
|
796
1074
|
{
|
|
797
1075
|
type: "button",
|
|
798
|
-
|
|
1076
|
+
...triggerProps,
|
|
1077
|
+
onClick: () => setOpen(!open),
|
|
799
1078
|
title: "Model settings \u2014 pick the agent backend and how hard it thinks",
|
|
800
|
-
className:
|
|
1079
|
+
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}`,
|
|
801
1080
|
"data-state": open ? "open" : "closed",
|
|
802
|
-
children: /* @__PURE__ */
|
|
1081
|
+
children: /* @__PURE__ */ jsx5(GearGlyph, { className: "h-4 w-4" })
|
|
803
1082
|
}
|
|
804
1083
|
),
|
|
805
|
-
open && /* @__PURE__ */
|
|
806
|
-
showHarness && /* @__PURE__ */
|
|
807
|
-
/* @__PURE__ */
|
|
808
|
-
/* @__PURE__ */
|
|
809
|
-
/* @__PURE__ */
|
|
1084
|
+
open && /* @__PURE__ */ jsxs5("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: [
|
|
1085
|
+
showHarness && /* @__PURE__ */ jsxs5("div", { className: "space-y-1.5", children: [
|
|
1086
|
+
/* @__PURE__ */ jsx5("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
|
|
1087
|
+
/* @__PURE__ */ jsx5(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
|
|
1088
|
+
/* @__PURE__ */ jsx5("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "The engine that runs the agent. Switching it keeps your model choice compatible." })
|
|
810
1089
|
] }),
|
|
811
|
-
showEffort && /* @__PURE__ */
|
|
812
|
-
/* @__PURE__ */
|
|
813
|
-
/* @__PURE__ */
|
|
814
|
-
/* @__PURE__ */
|
|
1090
|
+
showEffort && /* @__PURE__ */ jsxs5("div", { className: "space-y-1.5", children: [
|
|
1091
|
+
/* @__PURE__ */ jsx5("p", { className: "text-xs font-medium text-foreground", children: "Reasoning effort" }),
|
|
1092
|
+
/* @__PURE__ */ jsx5(EffortPicker, { value: effort, onChange: onEffortChange }),
|
|
1093
|
+
/* @__PURE__ */ jsx5("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "How hard the agent thinks before answering. Higher is slower but more thorough." })
|
|
815
1094
|
] })
|
|
816
1095
|
] })
|
|
817
1096
|
] })
|
|
@@ -819,30 +1098,7 @@ function AgentSessionControls(props) {
|
|
|
819
1098
|
}
|
|
820
1099
|
|
|
821
1100
|
// src/web-react/index.tsx
|
|
822
|
-
import { Fragment as
|
|
823
|
-
function ChevronDown2({ className }) {
|
|
824
|
-
return /* @__PURE__ */ jsx5("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx5("path", { d: "m6 9 6 6 6-6" }) });
|
|
825
|
-
}
|
|
826
|
-
function SearchGlyph({ className }) {
|
|
827
|
-
return /* @__PURE__ */ jsxs5("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
828
|
-
/* @__PURE__ */ jsx5("circle", { cx: "11", cy: "11", r: "8" }),
|
|
829
|
-
/* @__PURE__ */ jsx5("path", { d: "m21 21-4.3-4.3" })
|
|
830
|
-
] });
|
|
831
|
-
}
|
|
832
|
-
function SparkleGlyph({ className }) {
|
|
833
|
-
return /* @__PURE__ */ jsx5("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx5("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3M5.6 5.6l2.1 2.1m8.6 8.6 2.1 2.1m0-12.8-2.1 2.1M7.7 16.3l-2.1 2.1" }) });
|
|
834
|
-
}
|
|
835
|
-
function useClickOutside2(onOutside) {
|
|
836
|
-
const ref = useRef3(null);
|
|
837
|
-
useEffect5(() => {
|
|
838
|
-
function handler(e) {
|
|
839
|
-
if (ref.current && !ref.current.contains(e.target)) onOutside();
|
|
840
|
-
}
|
|
841
|
-
document.addEventListener("mousedown", handler);
|
|
842
|
-
return () => document.removeEventListener("mousedown", handler);
|
|
843
|
-
});
|
|
844
|
-
return ref;
|
|
845
|
-
}
|
|
1101
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
846
1102
|
function formatModelCost(msg, models) {
|
|
847
1103
|
if (msg.promptTokens == null && msg.completionTokens == null) return null;
|
|
848
1104
|
const pricing = models.find((m) => m.id === msg.modelUsed)?.pricing;
|
|
@@ -855,205 +1111,42 @@ function formatTokensPerSecond(msg) {
|
|
|
855
1111
|
if (msg.completionTokens == null || !msg.durationMs) return null;
|
|
856
1112
|
return `${Math.round(msg.completionTokens / (msg.durationMs / 1e3))} tok/s`;
|
|
857
1113
|
}
|
|
858
|
-
function formatPrice(p) {
|
|
859
|
-
if (!p) return void 0;
|
|
860
|
-
const n = Number(p);
|
|
861
|
-
if (isNaN(n) || n === 0) return void 0;
|
|
862
|
-
const perM = n * 1e6;
|
|
863
|
-
return perM >= 1 ? `$${perM.toFixed(0)}/M` : `$${perM.toFixed(2)}/M`;
|
|
864
|
-
}
|
|
865
|
-
function formatContext(len) {
|
|
866
|
-
if (!len) return void 0;
|
|
867
|
-
if (len >= 1e6) return `${(len / 1e6).toFixed(1)}M ctx`;
|
|
868
|
-
if (len >= 1e3) return `${Math.round(len / 1e3)}K ctx`;
|
|
869
|
-
return `${len} ctx`;
|
|
870
|
-
}
|
|
871
|
-
function SectionHeader({ children }) {
|
|
872
|
-
return /* @__PURE__ */ jsx5("div", { className: "px-3 pb-1 pt-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground/70", children });
|
|
873
|
-
}
|
|
874
|
-
function ModelRow({
|
|
875
|
-
model,
|
|
876
|
-
selected,
|
|
877
|
-
onSelect,
|
|
878
|
-
renderProviderBadge
|
|
879
|
-
}) {
|
|
880
|
-
const price = formatPrice(model.pricing?.prompt);
|
|
881
|
-
const ctx = formatContext(model.contextLength);
|
|
882
|
-
return /* @__PURE__ */ jsxs5(
|
|
883
|
-
"button",
|
|
884
|
-
{
|
|
885
|
-
type: "button",
|
|
886
|
-
onClick: onSelect,
|
|
887
|
-
className: `flex w-full items-center gap-2.5 rounded-md px-3 py-2.5 text-left text-sm transition ${selected ? "bg-primary/10 font-medium" : "hover:bg-accent/30"}`,
|
|
888
|
-
children: [
|
|
889
|
-
renderProviderBadge ? renderProviderBadge(model.provider) : /* @__PURE__ */ jsx5(ProviderLogo, { provider: model.provider, size: 16 }),
|
|
890
|
-
/* @__PURE__ */ jsx5("span", { className: "truncate", children: model.name }),
|
|
891
|
-
!model.supportsTools && /* @__PURE__ */ jsx5("span", { className: "shrink-0 rounded bg-muted/60 px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground", children: "no tools" }),
|
|
892
|
-
/* @__PURE__ */ jsxs5("span", { className: "ml-auto flex shrink-0 items-center gap-2 text-xs text-muted-foreground", children: [
|
|
893
|
-
ctx && /* @__PURE__ */ jsx5("span", { children: ctx }),
|
|
894
|
-
price && /* @__PURE__ */ jsx5("span", { children: price })
|
|
895
|
-
] })
|
|
896
|
-
]
|
|
897
|
-
}
|
|
898
|
-
);
|
|
899
|
-
}
|
|
900
|
-
function ModelPicker({ value, onChange, models, loading, renderProviderBadge, recommendedLabel = "Recommended" }) {
|
|
901
|
-
const [open, setOpen] = useState5(false);
|
|
902
|
-
const [query, setQuery] = useState5("");
|
|
903
|
-
const containerRef = useClickOutside2(() => setOpen(false));
|
|
904
|
-
const inputRef = useRef3(null);
|
|
905
|
-
useEffect5(() => {
|
|
906
|
-
if (open) inputRef.current?.focus();
|
|
907
|
-
}, [open]);
|
|
908
|
-
const selected = models.find((m) => m.id === value);
|
|
909
|
-
const filtered = useMemo2(() => {
|
|
910
|
-
const q = query.trim().toLowerCase();
|
|
911
|
-
if (!q) return null;
|
|
912
|
-
return models.filter(
|
|
913
|
-
(m) => m.id.toLowerCase().includes(q) || m.name.toLowerCase().includes(q) || (m.description?.toLowerCase() ?? "").includes(q) || m.provider.toLowerCase().includes(q)
|
|
914
|
-
);
|
|
915
|
-
}, [models, query]);
|
|
916
|
-
const sections = useMemo2(() => {
|
|
917
|
-
const recommended = models.filter((m) => m.featured);
|
|
918
|
-
const byProvider = [];
|
|
919
|
-
for (const m of models) {
|
|
920
|
-
if (m.featured) continue;
|
|
921
|
-
const last = byProvider[byProvider.length - 1];
|
|
922
|
-
if (last && last.provider === m.provider) last.items.push(m);
|
|
923
|
-
else byProvider.push({ provider: m.provider, items: [m] });
|
|
924
|
-
}
|
|
925
|
-
return { recommended, byProvider };
|
|
926
|
-
}, [models]);
|
|
927
|
-
const select = (id) => {
|
|
928
|
-
onChange(id);
|
|
929
|
-
setOpen(false);
|
|
930
|
-
setQuery("");
|
|
931
|
-
};
|
|
932
|
-
return /* @__PURE__ */ jsxs5("div", { ref: containerRef, className: "relative inline-flex", children: [
|
|
933
|
-
/* @__PURE__ */ jsxs5(
|
|
934
|
-
"button",
|
|
935
|
-
{
|
|
936
|
-
type: "button",
|
|
937
|
-
onClick: () => setOpen((v) => !v),
|
|
938
|
-
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",
|
|
939
|
-
children: [
|
|
940
|
-
selected ? renderProviderBadge ? renderProviderBadge(selected.provider) : /* @__PURE__ */ jsx5(ProviderLogo, { provider: selected.provider, size: 16 }) : /* @__PURE__ */ jsx5(SparkleGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
941
|
-
/* @__PURE__ */ jsx5("span", { className: "max-w-[160px] truncate", children: selected?.name ?? value }),
|
|
942
|
-
/* @__PURE__ */ jsx5(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
943
|
-
]
|
|
944
|
-
}
|
|
945
|
-
),
|
|
946
|
-
open && /* @__PURE__ */ jsxs5("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: [
|
|
947
|
-
/* @__PURE__ */ jsx5("div", { className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2 rounded-lg border border-border bg-background px-3 py-2", children: [
|
|
948
|
-
/* @__PURE__ */ jsx5(SearchGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
949
|
-
/* @__PURE__ */ jsx5(
|
|
950
|
-
"input",
|
|
951
|
-
{
|
|
952
|
-
ref: inputRef,
|
|
953
|
-
type: "text",
|
|
954
|
-
value: query,
|
|
955
|
-
onChange: (e) => setQuery(e.target.value),
|
|
956
|
-
placeholder: "Search models...",
|
|
957
|
-
className: "flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
|
|
958
|
-
}
|
|
959
|
-
)
|
|
960
|
-
] }) }),
|
|
961
|
-
/* @__PURE__ */ jsxs5("div", { className: "max-h-[400px] overflow-y-auto p-1 pb-2", children: [
|
|
962
|
-
loading && /* @__PURE__ */ jsx5("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "Loading models..." }),
|
|
963
|
-
!loading && filtered && /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
964
|
-
filtered.length === 0 && /* @__PURE__ */ jsx5("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "No models match your search" }),
|
|
965
|
-
filtered.map((m) => /* @__PURE__ */ jsx5(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
|
|
966
|
-
] }),
|
|
967
|
-
!loading && !filtered && /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
968
|
-
sections.recommended.length > 0 && /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
969
|
-
/* @__PURE__ */ jsx5(SectionHeader, { children: recommendedLabel }),
|
|
970
|
-
sections.recommended.map((m) => /* @__PURE__ */ jsx5(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
|
|
971
|
-
] }),
|
|
972
|
-
sections.byProvider.map((g) => /* @__PURE__ */ jsxs5("div", { children: [
|
|
973
|
-
/* @__PURE__ */ jsx5(SectionHeader, { children: g.provider }),
|
|
974
|
-
g.items.map((m) => /* @__PURE__ */ jsx5(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
|
|
975
|
-
] }, g.provider))
|
|
976
|
-
] })
|
|
977
|
-
] })
|
|
978
|
-
] })
|
|
979
|
-
] });
|
|
980
|
-
}
|
|
981
|
-
var EFFORT_LEVELS = [
|
|
982
|
-
{ id: "off", label: "Off" },
|
|
983
|
-
{ id: "low", label: "Low" },
|
|
984
|
-
{ id: "medium", label: "Medium" },
|
|
985
|
-
{ id: "high", label: "High" }
|
|
986
|
-
];
|
|
987
|
-
function EffortPicker({ value, onChange }) {
|
|
988
|
-
const [open, setOpen] = useState5(false);
|
|
989
|
-
const containerRef = useClickOutside2(() => setOpen(false));
|
|
990
|
-
const selected = EFFORT_LEVELS.find((l) => l.id === value) ?? EFFORT_LEVELS[2];
|
|
991
|
-
return /* @__PURE__ */ jsxs5("div", { ref: containerRef, className: "relative inline-flex", children: [
|
|
992
|
-
/* @__PURE__ */ jsxs5(
|
|
993
|
-
"button",
|
|
994
|
-
{
|
|
995
|
-
type: "button",
|
|
996
|
-
onClick: () => setOpen((v) => !v),
|
|
997
|
-
title: "Reasoning effort",
|
|
998
|
-
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",
|
|
999
|
-
children: [
|
|
1000
|
-
/* @__PURE__ */ jsx5(SparkleGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
1001
|
-
/* @__PURE__ */ jsx5("span", { children: selected.label }),
|
|
1002
|
-
/* @__PURE__ */ jsx5(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
1003
|
-
]
|
|
1004
|
-
}
|
|
1005
|
-
),
|
|
1006
|
-
open && /* @__PURE__ */ jsx5("div", { className: "absolute bottom-full left-0 z-50 mb-2 w-36 overflow-hidden rounded-xl border border-border bg-card p-1 shadow-lg", children: EFFORT_LEVELS.map((l) => /* @__PURE__ */ jsx5(
|
|
1007
|
-
"button",
|
|
1008
|
-
{
|
|
1009
|
-
type: "button",
|
|
1010
|
-
onClick: () => {
|
|
1011
|
-
onChange(l.id);
|
|
1012
|
-
setOpen(false);
|
|
1013
|
-
},
|
|
1014
|
-
className: `flex w-full items-center rounded-md px-3 py-2 text-left text-sm transition ${l.id === value ? "bg-primary/10 font-medium" : "hover:bg-accent/30"}`,
|
|
1015
|
-
children: l.label
|
|
1016
|
-
},
|
|
1017
|
-
l.id
|
|
1018
|
-
)) })
|
|
1019
|
-
] });
|
|
1020
|
-
}
|
|
1021
1114
|
function RunDrillIn({ run, onClose }) {
|
|
1022
|
-
return /* @__PURE__ */
|
|
1023
|
-
/* @__PURE__ */
|
|
1024
|
-
/* @__PURE__ */
|
|
1115
|
+
return /* @__PURE__ */ jsxs6("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: [
|
|
1116
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
|
|
1117
|
+
/* @__PURE__ */ jsx6(
|
|
1025
1118
|
"span",
|
|
1026
1119
|
{
|
|
1027
|
-
className: `h-2 w-2 shrink-0 rounded-full ${run.status === "running" ? "bg-
|
|
1120
|
+
className: `h-2 w-2 shrink-0 rounded-full ${run.status === "running" ? "bg-warning" : run.status === "error" ? "bg-destructive" : "bg-success"}`
|
|
1028
1121
|
}
|
|
1029
1122
|
),
|
|
1030
|
-
/* @__PURE__ */
|
|
1031
|
-
/* @__PURE__ */
|
|
1032
|
-
/* @__PURE__ */
|
|
1123
|
+
/* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1", children: [
|
|
1124
|
+
/* @__PURE__ */ jsx6("p", { className: "truncate text-sm font-semibold", children: run.title }),
|
|
1125
|
+
/* @__PURE__ */ jsx6("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
|
|
1033
1126
|
] }),
|
|
1034
|
-
/* @__PURE__ */
|
|
1127
|
+
/* @__PURE__ */ jsx6(
|
|
1035
1128
|
"button",
|
|
1036
1129
|
{
|
|
1037
1130
|
type: "button",
|
|
1038
1131
|
onClick: onClose,
|
|
1039
1132
|
"aria-label": "Close",
|
|
1040
1133
|
className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground",
|
|
1041
|
-
children: /* @__PURE__ */
|
|
1134
|
+
children: /* @__PURE__ */ jsx6("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx6("path", { d: "M18 6 6 18M6 6l12 12" }) })
|
|
1042
1135
|
}
|
|
1043
1136
|
)
|
|
1044
1137
|
] }),
|
|
1045
|
-
/* @__PURE__ */
|
|
1046
|
-
run.steps.length === 0 && /* @__PURE__ */
|
|
1047
|
-
run.steps.map((step, i) => /* @__PURE__ */
|
|
1048
|
-
/* @__PURE__ */
|
|
1049
|
-
/* @__PURE__ */
|
|
1050
|
-
/* @__PURE__ */
|
|
1051
|
-
/* @__PURE__ */
|
|
1138
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
|
|
1139
|
+
run.steps.length === 0 && /* @__PURE__ */ jsx6("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
|
|
1140
|
+
run.steps.map((step, i) => /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-border/60 bg-background", children: [
|
|
1141
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
|
|
1142
|
+
/* @__PURE__ */ jsx6("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
|
|
1143
|
+
/* @__PURE__ */ jsx6("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
|
|
1144
|
+
/* @__PURE__ */ jsx6("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
|
|
1052
1145
|
] }),
|
|
1053
|
-
step.detail && /* @__PURE__ */
|
|
1146
|
+
step.detail && /* @__PURE__ */ jsx6("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 })
|
|
1054
1147
|
] }, i))
|
|
1055
1148
|
] }),
|
|
1056
|
-
/* @__PURE__ */
|
|
1149
|
+
/* @__PURE__ */ jsx6("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." })
|
|
1057
1150
|
] });
|
|
1058
1151
|
}
|
|
1059
1152
|
function pendingApprovalOf(call) {
|
|
@@ -1063,26 +1156,26 @@ function pendingApprovalOf(call) {
|
|
|
1063
1156
|
}
|
|
1064
1157
|
function ToolGlyph({ name, className }) {
|
|
1065
1158
|
if (name.startsWith("sandbox_")) {
|
|
1066
|
-
return /* @__PURE__ */
|
|
1067
|
-
/* @__PURE__ */
|
|
1068
|
-
/* @__PURE__ */
|
|
1159
|
+
return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
1160
|
+
/* @__PURE__ */ jsx6("polyline", { points: "4 17 10 11 4 5" }),
|
|
1161
|
+
/* @__PURE__ */ jsx6("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
|
|
1069
1162
|
] });
|
|
1070
1163
|
}
|
|
1071
1164
|
if (name === "submit_proposal") {
|
|
1072
|
-
return /* @__PURE__ */
|
|
1073
|
-
/* @__PURE__ */
|
|
1074
|
-
/* @__PURE__ */
|
|
1165
|
+
return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
1166
|
+
/* @__PURE__ */ jsx6("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
1167
|
+
/* @__PURE__ */ jsx6("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
|
|
1075
1168
|
] });
|
|
1076
1169
|
}
|
|
1077
1170
|
if (name === "schedule_followup") {
|
|
1078
|
-
return /* @__PURE__ */
|
|
1079
|
-
/* @__PURE__ */
|
|
1080
|
-
/* @__PURE__ */
|
|
1171
|
+
return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
|
|
1172
|
+
/* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "9" }),
|
|
1173
|
+
/* @__PURE__ */ jsx6("path", { d: "M12 7v5l3 3" })
|
|
1081
1174
|
] });
|
|
1082
1175
|
}
|
|
1083
|
-
return /* @__PURE__ */
|
|
1084
|
-
/* @__PURE__ */
|
|
1085
|
-
/* @__PURE__ */
|
|
1176
|
+
return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
1177
|
+
/* @__PURE__ */ jsx6("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
|
|
1178
|
+
/* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "4" })
|
|
1086
1179
|
] });
|
|
1087
1180
|
}
|
|
1088
1181
|
function toolOutcomeOf(call) {
|
|
@@ -1116,36 +1209,36 @@ function truncate(v, max = 240) {
|
|
|
1116
1209
|
function KvRows({ data }) {
|
|
1117
1210
|
const entries = Object.entries(data).filter(([, v]) => v !== void 0 && v !== null && v !== "");
|
|
1118
1211
|
if (!entries.length) return null;
|
|
1119
|
-
return /* @__PURE__ */
|
|
1120
|
-
/* @__PURE__ */
|
|
1121
|
-
/* @__PURE__ */
|
|
1212
|
+
return /* @__PURE__ */ jsx6("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs6("div", { className: "contents", children: [
|
|
1213
|
+
/* @__PURE__ */ jsx6("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
|
|
1214
|
+
/* @__PURE__ */ jsx6("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
|
|
1122
1215
|
] }, k)) });
|
|
1123
1216
|
}
|
|
1124
1217
|
function ShellDetail({ call }) {
|
|
1125
1218
|
const outcome = toolOutcomeOf(call);
|
|
1126
1219
|
const r = outcome?.result ?? {};
|
|
1127
|
-
return /* @__PURE__ */
|
|
1128
|
-
/* @__PURE__ */
|
|
1129
|
-
/* @__PURE__ */
|
|
1130
|
-
/* @__PURE__ */
|
|
1131
|
-
r.exitCode != null && /* @__PURE__ */
|
|
1220
|
+
return /* @__PURE__ */ jsxs6("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
|
|
1221
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
|
|
1222
|
+
/* @__PURE__ */ jsx6("span", { className: "select-none text-zinc-500", children: "$" }),
|
|
1223
|
+
/* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
|
|
1224
|
+
r.exitCode != null && /* @__PURE__ */ jsxs6("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
|
|
1132
1225
|
"exit ",
|
|
1133
1226
|
r.exitCode
|
|
1134
1227
|
] })
|
|
1135
1228
|
] }),
|
|
1136
|
-
/* @__PURE__ */
|
|
1229
|
+
/* @__PURE__ */ jsx6("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)" })
|
|
1137
1230
|
] });
|
|
1138
1231
|
}
|
|
1139
1232
|
function DefaultToolDetail({ call }) {
|
|
1140
1233
|
const outcome = toolOutcomeOf(call);
|
|
1141
|
-
return /* @__PURE__ */
|
|
1142
|
-
call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */
|
|
1143
|
-
/* @__PURE__ */
|
|
1144
|
-
/* @__PURE__ */
|
|
1234
|
+
return /* @__PURE__ */ jsxs6("div", { className: "space-y-2", children: [
|
|
1235
|
+
call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs6("div", { children: [
|
|
1236
|
+
/* @__PURE__ */ jsx6("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
|
|
1237
|
+
/* @__PURE__ */ jsx6(KvRows, { data: call.args })
|
|
1145
1238
|
] }),
|
|
1146
|
-
outcome && /* @__PURE__ */
|
|
1147
|
-
/* @__PURE__ */
|
|
1148
|
-
outcome.ok === false ? /* @__PURE__ */
|
|
1239
|
+
outcome && /* @__PURE__ */ jsxs6("div", { children: [
|
|
1240
|
+
/* @__PURE__ */ jsx6("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: outcome.ok === false ? "Failed" : "Result" }),
|
|
1241
|
+
outcome.ok === false ? /* @__PURE__ */ jsx6("p", { className: "text-xs text-destructive", children: outcome.message ?? "Tool failed" }) : outcome.result && typeof outcome.result === "object" ? /* @__PURE__ */ jsx6(KvRows, { data: outcome.result }) : /* @__PURE__ */ jsx6("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(outcome.result) })
|
|
1149
1242
|
] })
|
|
1150
1243
|
] });
|
|
1151
1244
|
}
|
|
@@ -1156,58 +1249,74 @@ function ToolCallCard({
|
|
|
1156
1249
|
onOpenRun,
|
|
1157
1250
|
renderers
|
|
1158
1251
|
}) {
|
|
1159
|
-
const [expanded, setExpanded] =
|
|
1252
|
+
const [expanded, setExpanded] = useState6(false);
|
|
1160
1253
|
const pending = call.status === "done" ? pendingApprovalOf(call) : null;
|
|
1161
1254
|
const failed = call.status === "error" || toolOutcomeOf(call)?.ok === false;
|
|
1162
1255
|
const custom = renderers?.[call.name]?.(call, message);
|
|
1163
|
-
|
|
1256
|
+
const { pending: deciding, run: decide } = usePending();
|
|
1257
|
+
return /* @__PURE__ */ jsxs6(
|
|
1164
1258
|
"div",
|
|
1165
1259
|
{
|
|
1166
|
-
className: `w-fit min-w-[280px] max-w-full rounded-lg border text-xs transition ${pending ? "border-
|
|
1260
|
+
className: `w-fit min-w-[280px] max-w-full rounded-lg border text-xs transition ${pending ? "border-warning/40 bg-warning/5" : failed ? "border-destructive/40 bg-destructive/5" : "border-border/60 bg-muted/20"}`,
|
|
1167
1261
|
children: [
|
|
1168
|
-
/* @__PURE__ */
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
}
|
|
1180
|
-
),
|
|
1181
|
-
/* @__PURE__ */ jsx5(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
1182
|
-
/* @__PURE__ */ jsx5("span", { className: "min-w-0 flex-1 truncate font-medium", children: friendlyToolTitle(call) }),
|
|
1183
|
-
pending && approval && /* @__PURE__ */ jsxs5("span", { className: "flex shrink-0 items-center gap-1", onClick: (e) => e.stopPropagation(), children: [
|
|
1184
|
-
/* @__PURE__ */ jsx5(
|
|
1185
|
-
"button",
|
|
1262
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
|
|
1263
|
+
/* @__PURE__ */ jsxs6(
|
|
1264
|
+
"button",
|
|
1265
|
+
{
|
|
1266
|
+
type: "button",
|
|
1267
|
+
onClick: () => setExpanded((v) => !v),
|
|
1268
|
+
"aria-expanded": expanded,
|
|
1269
|
+
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",
|
|
1270
|
+
children: [
|
|
1271
|
+
/* @__PURE__ */ jsx6(
|
|
1272
|
+
"span",
|
|
1186
1273
|
{
|
|
1187
|
-
|
|
1188
|
-
onClick: () => approval.onApprove(pending.proposalId, call.id),
|
|
1189
|
-
className: "rounded bg-green-600/90 px-2 py-0.5 text-[11px] font-semibold text-white transition hover:bg-green-600",
|
|
1190
|
-
children: "Approve"
|
|
1274
|
+
className: `h-2 w-2 shrink-0 rounded-full ${call.status === "running" ? "animate-pulse bg-warning" : pending ? "bg-warning" : failed ? "bg-destructive" : "bg-success"}`
|
|
1191
1275
|
}
|
|
1192
1276
|
),
|
|
1193
|
-
/* @__PURE__ */
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1277
|
+
/* @__PURE__ */ jsx6(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
1278
|
+
/* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 truncate font-medium", children: friendlyToolTitle(call) })
|
|
1279
|
+
]
|
|
1280
|
+
}
|
|
1281
|
+
),
|
|
1282
|
+
pending && approval && /* @__PURE__ */ jsxs6("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
1283
|
+
/* @__PURE__ */ jsx6(
|
|
1284
|
+
"button",
|
|
1285
|
+
{
|
|
1286
|
+
type: "button",
|
|
1287
|
+
disabled: deciding,
|
|
1288
|
+
onClick: () => decide(() => approval.onApprove(pending.proposalId, call.id)),
|
|
1289
|
+
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",
|
|
1290
|
+
children: "Approve"
|
|
1291
|
+
}
|
|
1292
|
+
),
|
|
1293
|
+
/* @__PURE__ */ jsx6(
|
|
1294
|
+
"button",
|
|
1295
|
+
{
|
|
1296
|
+
type: "button",
|
|
1297
|
+
disabled: deciding,
|
|
1298
|
+
onClick: () => decide(() => approval.onReject(pending.proposalId, call.id)),
|
|
1299
|
+
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",
|
|
1300
|
+
children: "Reject"
|
|
1301
|
+
}
|
|
1302
|
+
)
|
|
1303
|
+
] }),
|
|
1304
|
+
/* @__PURE__ */ jsx6("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : pending ? "awaiting approval" : failed ? "failed" : "done" }),
|
|
1305
|
+
/* @__PURE__ */ jsx6(
|
|
1306
|
+
"button",
|
|
1307
|
+
{
|
|
1308
|
+
type: "button",
|
|
1309
|
+
onClick: () => setExpanded((v) => !v),
|
|
1310
|
+
"aria-label": expanded ? "Collapse details" : "Expand details",
|
|
1311
|
+
"aria-expanded": expanded,
|
|
1312
|
+
className: "shrink-0 rounded p-0.5 focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1313
|
+
children: /* @__PURE__ */ jsx6(ChevronDown, { className: `h-3 w-3 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
|
|
1314
|
+
}
|
|
1315
|
+
)
|
|
1316
|
+
] }),
|
|
1317
|
+
expanded && /* @__PURE__ */ jsxs6("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
|
|
1318
|
+
custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx6(ShellDetail, { call }) : /* @__PURE__ */ jsx6(DefaultToolDetail, { call })),
|
|
1319
|
+
onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx6(
|
|
1211
1320
|
"button",
|
|
1212
1321
|
{
|
|
1213
1322
|
type: "button",
|
|
@@ -1221,7 +1330,7 @@ function ToolCallCard({
|
|
|
1221
1330
|
}
|
|
1222
1331
|
);
|
|
1223
1332
|
}
|
|
1224
|
-
function
|
|
1333
|
+
function AssistantMessageImpl({
|
|
1225
1334
|
msg,
|
|
1226
1335
|
streaming,
|
|
1227
1336
|
models,
|
|
@@ -1234,6 +1343,7 @@ function AssistantMessage({
|
|
|
1234
1343
|
}) {
|
|
1235
1344
|
const content = useSmoothText(msg.content, streaming);
|
|
1236
1345
|
const reasoning = useSmoothText(msg.reasoning ?? "", streaming);
|
|
1346
|
+
const body = useMemo3(() => renderBody(content), [renderBody, content]);
|
|
1237
1347
|
const reasoningScrollRef = useRef3(null);
|
|
1238
1348
|
const thinkStartRef = useRef3(null);
|
|
1239
1349
|
const thinkMsRef = useRef3(null);
|
|
@@ -1247,22 +1357,22 @@ function AssistantMessage({
|
|
|
1247
1357
|
const el = reasoningScrollRef.current;
|
|
1248
1358
|
if (el && streaming && !content) el.scrollTop = el.scrollHeight;
|
|
1249
1359
|
}, [reasoning, streaming, content]);
|
|
1250
|
-
return /* @__PURE__ */
|
|
1251
|
-
/* @__PURE__ */
|
|
1252
|
-
/* @__PURE__ */
|
|
1253
|
-
msg.modelUsed && /* @__PURE__ */
|
|
1254
|
-
formatTokensPerSecond(msg) && /* @__PURE__ */
|
|
1255
|
-
formatModelCost(msg, models) && /* @__PURE__ */
|
|
1360
|
+
return /* @__PURE__ */ jsxs6("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
|
|
1361
|
+
/* @__PURE__ */ jsxs6("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
|
|
1362
|
+
/* @__PURE__ */ jsx6("span", { className: "font-semibold uppercase", children: agentLabel }),
|
|
1363
|
+
msg.modelUsed && /* @__PURE__ */ jsx6("span", { className: "font-mono normal-case", children: msg.modelUsed }),
|
|
1364
|
+
formatTokensPerSecond(msg) && /* @__PURE__ */ jsx6("span", { children: formatTokensPerSecond(msg) }),
|
|
1365
|
+
formatModelCost(msg, models) && /* @__PURE__ */ jsx6("span", { children: formatModelCost(msg, models) })
|
|
1256
1366
|
] }),
|
|
1257
|
-
reasoning && /* @__PURE__ */
|
|
1258
|
-
/* @__PURE__ */
|
|
1259
|
-
/* @__PURE__ */
|
|
1367
|
+
reasoning && /* @__PURE__ */ jsxs6("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !content, children: [
|
|
1368
|
+
/* @__PURE__ */ jsx6("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !content ? /* @__PURE__ */ jsx6("span", { className: "animate-pulse", children: "Thinking\u2026" }) : thinkMsRef.current != null ? `Thought for ${Math.max(1, Math.round(thinkMsRef.current / 1e3))}s` : "Thought process" }),
|
|
1369
|
+
/* @__PURE__ */ jsx6("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground", children: reasoning })
|
|
1260
1370
|
] }),
|
|
1261
|
-
/* @__PURE__ */
|
|
1262
|
-
|
|
1263
|
-
streaming && content && !msg.toolCalls?.length && /* @__PURE__ */
|
|
1371
|
+
/* @__PURE__ */ jsxs6("div", { className: "text-base leading-[1.75]", children: [
|
|
1372
|
+
body,
|
|
1373
|
+
streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx6("span", { className: "ml-0.5 inline-block h-[1.1em] w-[3px] translate-y-[2px] animate-pulse rounded-sm bg-foreground/70", "aria-hidden": true })
|
|
1264
1374
|
] }),
|
|
1265
|
-
msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */
|
|
1375
|
+
msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */ jsx6("div", { className: "mt-2 flex flex-col gap-1.5", children: msg.toolCalls.map((tc) => /* @__PURE__ */ jsx6(
|
|
1266
1376
|
ToolCallCard,
|
|
1267
1377
|
{
|
|
1268
1378
|
call: tc,
|
|
@@ -1276,21 +1386,40 @@ function AssistantMessage({
|
|
|
1276
1386
|
renderExtras?.(msg)
|
|
1277
1387
|
] });
|
|
1278
1388
|
}
|
|
1389
|
+
var AssistantMessage = memo(AssistantMessageImpl);
|
|
1279
1390
|
function ThinkingRow({ agentLabel }) {
|
|
1280
|
-
const [seconds, setSeconds] =
|
|
1391
|
+
const [seconds, setSeconds] = useState6(0);
|
|
1281
1392
|
useEffect5(() => {
|
|
1282
1393
|
const id = setInterval(() => setSeconds((s) => s + 1), 1e3);
|
|
1283
1394
|
return () => clearInterval(id);
|
|
1284
1395
|
}, []);
|
|
1285
|
-
return /* @__PURE__ */
|
|
1286
|
-
/* @__PURE__ */
|
|
1287
|
-
/* @__PURE__ */
|
|
1288
|
-
/* @__PURE__ */
|
|
1396
|
+
return /* @__PURE__ */ jsxs6("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
|
|
1397
|
+
/* @__PURE__ */ jsx6("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
|
|
1398
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
|
|
1399
|
+
/* @__PURE__ */ jsx6("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx6("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
|
|
1289
1400
|
"Thinking",
|
|
1290
1401
|
seconds >= 3 ? ` \xB7 ${seconds}s` : "..."
|
|
1291
1402
|
] })
|
|
1292
1403
|
] });
|
|
1293
1404
|
}
|
|
1405
|
+
function StreamErrorRow({ message, onRetry }) {
|
|
1406
|
+
return /* @__PURE__ */ jsx6("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs6("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: [
|
|
1407
|
+
/* @__PURE__ */ jsxs6("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: [
|
|
1408
|
+
/* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "9" }),
|
|
1409
|
+
/* @__PURE__ */ jsx6("path", { d: "M12 8v4m0 4h.01" })
|
|
1410
|
+
] }),
|
|
1411
|
+
/* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 break-words", children: message }),
|
|
1412
|
+
onRetry && /* @__PURE__ */ jsx6(
|
|
1413
|
+
"button",
|
|
1414
|
+
{
|
|
1415
|
+
type: "button",
|
|
1416
|
+
onClick: onRetry,
|
|
1417
|
+
className: `shrink-0 rounded border border-destructive/40 bg-card px-2 py-0.5 text-[11px] font-medium text-destructive transition hover:bg-destructive/10 ${POPOVER_OPTION_FOCUS}`,
|
|
1418
|
+
children: "Retry"
|
|
1419
|
+
}
|
|
1420
|
+
)
|
|
1421
|
+
] }) });
|
|
1422
|
+
}
|
|
1294
1423
|
function ChatMessages({
|
|
1295
1424
|
messages,
|
|
1296
1425
|
models = [],
|
|
@@ -1301,16 +1430,23 @@ function ChatMessages({
|
|
|
1301
1430
|
loading,
|
|
1302
1431
|
approval,
|
|
1303
1432
|
onToolCallClick,
|
|
1304
|
-
toolRenderers
|
|
1433
|
+
toolRenderers,
|
|
1434
|
+
error,
|
|
1435
|
+
onRetry,
|
|
1436
|
+
renderEmpty
|
|
1305
1437
|
}) {
|
|
1306
|
-
const renderBody =
|
|
1438
|
+
const renderBody = useMemo3(
|
|
1439
|
+
() => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx6("p", { className: "whitespace-pre-wrap", children: content })),
|
|
1440
|
+
[renderMarkdown]
|
|
1441
|
+
);
|
|
1307
1442
|
const lastIsUser = messages[messages.length - 1]?.role === "user";
|
|
1308
|
-
return /* @__PURE__ */
|
|
1443
|
+
if (messages.length === 0 && !loading && !error && renderEmpty) return /* @__PURE__ */ jsx6(Fragment3, { children: renderEmpty() });
|
|
1444
|
+
return /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
1309
1445
|
messages.map(
|
|
1310
|
-
(msg) => msg.role === "user" ? /* @__PURE__ */
|
|
1311
|
-
/* @__PURE__ */
|
|
1312
|
-
/* @__PURE__ */
|
|
1313
|
-
] }) }, msg.id) : /* @__PURE__ */
|
|
1446
|
+
(msg) => msg.role === "user" ? /* @__PURE__ */ jsx6("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs6("div", { className: "ml-auto w-fit max-w-[85%]", children: [
|
|
1447
|
+
/* @__PURE__ */ jsx6("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
|
|
1448
|
+
/* @__PURE__ */ jsx6("div", { className: "rounded-2xl rounded-tr-md bg-primary/10 px-4 py-2.5 text-base leading-relaxed", children: /* @__PURE__ */ jsx6("p", { className: "whitespace-pre-wrap", children: msg.content }) })
|
|
1449
|
+
] }) }, msg.id) : /* @__PURE__ */ jsx6(
|
|
1314
1450
|
AssistantMessage,
|
|
1315
1451
|
{
|
|
1316
1452
|
msg,
|
|
@@ -1326,7 +1462,8 @@ function ChatMessages({
|
|
|
1326
1462
|
msg.id
|
|
1327
1463
|
)
|
|
1328
1464
|
),
|
|
1329
|
-
loading && lastIsUser && /* @__PURE__ */
|
|
1465
|
+
loading && lastIsUser && /* @__PURE__ */ jsx6(ThinkingRow, { agentLabel }),
|
|
1466
|
+
error && !loading && /* @__PURE__ */ jsx6(StreamErrorRow, { message: error, onRetry })
|
|
1330
1467
|
] });
|
|
1331
1468
|
}
|
|
1332
1469
|
export {
|
|
@@ -1351,6 +1488,8 @@ export {
|
|
|
1351
1488
|
nextRevealCount,
|
|
1352
1489
|
pendingApprovalOf,
|
|
1353
1490
|
streamChatTurn,
|
|
1491
|
+
usePending,
|
|
1492
|
+
usePopover,
|
|
1354
1493
|
useSandboxTerminalConnection,
|
|
1355
1494
|
useSmoothText,
|
|
1356
1495
|
waterfallLayout
|