@tangle-network/agent-app 0.10.1 → 0.11.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/README.md +10 -0
- package/dist/agent-activity-C8ZG0F0M.d.ts +43 -0
- package/dist/chunk-5RT6KY4G.js +190 -0
- package/dist/chunk-5RT6KY4G.js.map +1 -0
- package/dist/chunk-AFDROJ64.js +218 -0
- package/dist/chunk-AFDROJ64.js.map +1 -0
- package/dist/{chunk-UIWB2F6N.js → chunk-UDXMR3AD.js} +80 -24
- package/dist/chunk-UDXMR3AD.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +31 -1
- package/dist/missions/index.d.ts +38 -5
- package/dist/missions/index.js +3 -1
- package/dist/trace/index.d.ts +137 -1
- package/dist/trace/index.js +24 -138
- package/dist/trace/index.js.map +1 -1
- package/dist/web-react/index.d.ts +79 -1
- package/dist/web-react/index.js +386 -133
- package/dist/web-react/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-UIWB2F6N.js.map +0 -1
package/dist/web-react/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
stepActivityFlowTrace
|
|
3
|
+
} from "../chunk-AFDROJ64.js";
|
|
4
|
+
|
|
1
5
|
// src/web-react/index.tsx
|
|
2
|
-
import { useEffect as
|
|
6
|
+
import { useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState3 } from "react";
|
|
3
7
|
|
|
4
8
|
// src/web-react/provider-logo.tsx
|
|
5
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -206,23 +210,264 @@ async function streamChatTurn(opts) {
|
|
|
206
210
|
}
|
|
207
211
|
}
|
|
208
212
|
|
|
209
|
-
// src/web-react/
|
|
213
|
+
// src/web-react/mission-activity.tsx
|
|
214
|
+
import { useCallback, useEffect as useEffect2, useState as useState2 } from "react";
|
|
210
215
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
211
|
-
|
|
216
|
+
var LIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "running"]);
|
|
217
|
+
var OK_STATUSES = /* @__PURE__ */ new Set(["completed", "done", "succeeded"]);
|
|
218
|
+
var ERROR_STATUSES = /* @__PURE__ */ new Set(["failed", "error", "cancelled", "aborted"]);
|
|
219
|
+
function activityTone(status) {
|
|
220
|
+
const s = status.toLowerCase();
|
|
221
|
+
if (LIVE_STATUSES.has(s)) return "live";
|
|
222
|
+
if (OK_STATUSES.has(s)) return "ok";
|
|
223
|
+
if (ERROR_STATUSES.has(s)) return "error";
|
|
224
|
+
return "neutral";
|
|
225
|
+
}
|
|
226
|
+
function formatActivityCost(costUsd) {
|
|
227
|
+
if (costUsd === void 0 || !isFinite(costUsd) || costUsd <= 0) return null;
|
|
228
|
+
return costUsd < 0.01 ? `$${costUsd.toFixed(4)}` : `$${costUsd.toFixed(2)}`;
|
|
229
|
+
}
|
|
230
|
+
function formatActivityDuration(durationMs) {
|
|
231
|
+
if (durationMs === void 0 || !isFinite(durationMs) || durationMs < 0) return null;
|
|
232
|
+
const totalSeconds = Math.round(durationMs / 1e3);
|
|
233
|
+
if (totalSeconds < 60) return `${totalSeconds}s`;
|
|
234
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
235
|
+
const seconds = totalSeconds % 60;
|
|
236
|
+
if (minutes < 60) return `${minutes}m ${String(seconds).padStart(2, "0")}s`;
|
|
237
|
+
return `${Math.floor(minutes / 60)}h ${String(minutes % 60).padStart(2, "0")}m`;
|
|
238
|
+
}
|
|
239
|
+
function mergeActivityPages(existing, incoming) {
|
|
240
|
+
const byTask = /* @__PURE__ */ new Map();
|
|
241
|
+
for (const row of existing) byTask.set(row.taskId, row);
|
|
242
|
+
for (const row of incoming) byTask.set(row.taskId, row);
|
|
243
|
+
return [...byTask.values()].sort((a, b) => Date.parse(b.startedAt) - Date.parse(a.startedAt));
|
|
244
|
+
}
|
|
245
|
+
function waterfallLayout(trace) {
|
|
246
|
+
const total = trace.totalMs > 0 ? trace.totalMs : 1;
|
|
247
|
+
return [...trace.spans].sort((a, b) => a.startMs - b.startMs).map((span) => {
|
|
248
|
+
const meta = span.meta ?? {};
|
|
249
|
+
const failed = meta.ok === false || typeof meta.status === "string" && activityTone(meta.status) === "error";
|
|
250
|
+
return {
|
|
251
|
+
name: span.name,
|
|
252
|
+
kind: span.kind,
|
|
253
|
+
offsetPct: Math.max(0, Math.min(100, span.startMs / total * 100)),
|
|
254
|
+
widthPct: Math.max(0.5, Math.min(100, (span.endMs - span.startMs) / total * 100)),
|
|
255
|
+
durationLabel: `${((span.endMs - span.startMs) / 1e3).toFixed(1)}s${span.approx ? "~" : ""}`,
|
|
256
|
+
approx: span.approx === true,
|
|
257
|
+
ok: !failed
|
|
258
|
+
};
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
function ChevronGlyph({ className }) {
|
|
212
262
|
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" }) });
|
|
213
263
|
}
|
|
264
|
+
function RefreshGlyph({ className }) {
|
|
265
|
+
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: "M21 12a9 9 0 1 1-2.64-6.36M21 3v6h-6" }) });
|
|
266
|
+
}
|
|
267
|
+
function StatusDot({ tone }) {
|
|
268
|
+
return /* @__PURE__ */ jsx2(
|
|
269
|
+
"span",
|
|
270
|
+
{
|
|
271
|
+
className: `h-2 w-2 shrink-0 rounded-full ${tone === "live" ? "animate-pulse bg-yellow-500" : tone === "ok" ? "bg-green-500" : tone === "error" ? "bg-red-500" : "bg-muted-foreground/40"}`
|
|
272
|
+
}
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
var BAR_CLASS = {
|
|
276
|
+
pipeline: "bg-muted-foreground/30",
|
|
277
|
+
model: "bg-primary/60",
|
|
278
|
+
tool: "bg-primary"
|
|
279
|
+
};
|
|
280
|
+
function FlowWaterfall({ trace }) {
|
|
281
|
+
const rows = waterfallLayout(trace);
|
|
282
|
+
if (rows.length === 0) return null;
|
|
283
|
+
const cost = formatActivityCost(trace.costUsd);
|
|
284
|
+
return /* @__PURE__ */ jsxs2("div", { className: "space-y-1", children: [
|
|
285
|
+
rows.map((row, i) => /* @__PURE__ */ jsxs2("div", { className: "grid grid-cols-[minmax(0,2fr)_minmax(0,3fr)_auto] items-center gap-2", children: [
|
|
286
|
+
/* @__PURE__ */ jsx2("span", { className: "truncate font-mono text-[11px] text-muted-foreground", title: row.name, children: row.name }),
|
|
287
|
+
/* @__PURE__ */ jsx2("div", { className: "relative h-2 rounded-sm bg-muted/40", children: /* @__PURE__ */ jsx2(
|
|
288
|
+
"div",
|
|
289
|
+
{
|
|
290
|
+
className: `absolute inset-y-0 rounded-sm ${row.ok ? BAR_CLASS[row.kind] : "bg-red-500/80"} ${row.approx ? "opacity-70" : ""}`,
|
|
291
|
+
style: { left: `${row.offsetPct}%`, width: `${row.widthPct}%` }
|
|
292
|
+
}
|
|
293
|
+
) }),
|
|
294
|
+
/* @__PURE__ */ jsx2("span", { className: "shrink-0 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: row.durationLabel })
|
|
295
|
+
] }, i)),
|
|
296
|
+
/* @__PURE__ */ jsxs2("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
|
|
297
|
+
(trace.totalMs / 1e3).toFixed(1),
|
|
298
|
+
"s",
|
|
299
|
+
cost ? ` \xB7 ${cost}` : ""
|
|
300
|
+
] })
|
|
301
|
+
] });
|
|
302
|
+
}
|
|
303
|
+
function MissionActivityLane({ activity, startedAt, nowMs }) {
|
|
304
|
+
const [expanded, setExpanded] = useState2(false);
|
|
305
|
+
if (activity.length === 0) return null;
|
|
306
|
+
return /* @__PURE__ */ jsxs2("div", { className: "mt-1 border-l border-border/50 pl-3", children: [
|
|
307
|
+
activity.map((run) => {
|
|
308
|
+
const tone = activityTone(run.status);
|
|
309
|
+
const cost = formatActivityCost(run.costUsd);
|
|
310
|
+
const duration = formatActivityDuration(run.durationMs);
|
|
311
|
+
return /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
|
|
312
|
+
/* @__PURE__ */ jsx2(StatusDot, { tone }),
|
|
313
|
+
/* @__PURE__ */ jsxs2("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
314
|
+
/* @__PURE__ */ jsx2("span", { className: "font-medium", children: run.tool }),
|
|
315
|
+
/* @__PURE__ */ jsxs2("span", { className: "text-muted-foreground", children: [
|
|
316
|
+
" \u2014 ",
|
|
317
|
+
run.detail
|
|
318
|
+
] })
|
|
319
|
+
] }),
|
|
320
|
+
tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */ jsx2("span", { className: "shrink-0 rounded-full bg-yellow-500/10 px-1.5 py-0.5 font-mono text-[10px] text-yellow-700 dark:text-yellow-400", children: [run.iteration !== void 0 ? `iter ${run.iteration}` : null, run.phase ?? null].filter(Boolean).join(" \xB7 ") }),
|
|
321
|
+
/* @__PURE__ */ jsxs2("span", { className: "flex shrink-0 items-center gap-1.5 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: [
|
|
322
|
+
tone !== "live" && tone !== "ok" && /* @__PURE__ */ jsx2("span", { children: run.status }),
|
|
323
|
+
cost && /* @__PURE__ */ jsx2("span", { children: cost }),
|
|
324
|
+
duration && /* @__PURE__ */ jsx2("span", { children: duration })
|
|
325
|
+
] })
|
|
326
|
+
] }, run.taskId);
|
|
327
|
+
}),
|
|
328
|
+
/* @__PURE__ */ jsxs2(
|
|
329
|
+
"button",
|
|
330
|
+
{
|
|
331
|
+
type: "button",
|
|
332
|
+
onClick: () => setExpanded((v) => !v),
|
|
333
|
+
className: "flex items-center gap-1 py-0.5 text-[10px] font-medium text-muted-foreground/70 transition hover:text-foreground",
|
|
334
|
+
children: [
|
|
335
|
+
/* @__PURE__ */ jsx2(ChevronGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
|
|
336
|
+
"timeline"
|
|
337
|
+
]
|
|
338
|
+
}
|
|
339
|
+
),
|
|
340
|
+
expanded && /* @__PURE__ */ jsx2("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx2(
|
|
341
|
+
FlowWaterfall,
|
|
342
|
+
{
|
|
343
|
+
trace: stepActivityFlowTrace(activity, {
|
|
344
|
+
...startedAt !== void 0 ? { startedAt } : {},
|
|
345
|
+
...nowMs !== void 0 ? { nowMs } : {}
|
|
346
|
+
})
|
|
347
|
+
}
|
|
348
|
+
) })
|
|
349
|
+
] });
|
|
350
|
+
}
|
|
351
|
+
function ActivityRow({
|
|
352
|
+
record,
|
|
353
|
+
renderMissionRef
|
|
354
|
+
}) {
|
|
355
|
+
const [open, setOpen] = useState2(false);
|
|
356
|
+
const tone = activityTone(record.status);
|
|
357
|
+
const cost = formatActivityCost(record.costUsd);
|
|
358
|
+
const duration = formatActivityDuration(record.durationMs);
|
|
359
|
+
return /* @__PURE__ */ jsxs2("div", { className: "rounded-lg border border-border/60 bg-card", children: [
|
|
360
|
+
/* @__PURE__ */ jsxs2("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: [
|
|
361
|
+
/* @__PURE__ */ jsx2(StatusDot, { tone }),
|
|
362
|
+
/* @__PURE__ */ jsxs2("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
363
|
+
/* @__PURE__ */ jsx2("span", { className: "font-medium", children: record.tool }),
|
|
364
|
+
/* @__PURE__ */ jsxs2("span", { className: "text-muted-foreground", children: [
|
|
365
|
+
" \u2014 ",
|
|
366
|
+
record.detail
|
|
367
|
+
] })
|
|
368
|
+
] }),
|
|
369
|
+
tone === "live" && (record.iteration !== void 0 || record.phase !== void 0) && /* @__PURE__ */ jsx2("span", { className: "shrink-0 rounded-full bg-yellow-500/10 px-2 py-0.5 font-mono text-[10px] text-yellow-700 dark:text-yellow-400", children: [record.iteration !== void 0 ? `iter ${record.iteration}` : null, record.phase ?? null].filter(Boolean).join(" \xB7 ") }),
|
|
370
|
+
/* @__PURE__ */ jsx2(
|
|
371
|
+
"span",
|
|
372
|
+
{
|
|
373
|
+
className: `shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium ${tone === "ok" ? "bg-green-500/10 text-green-700 dark:text-green-400" : tone === "error" ? "bg-red-500/10 text-red-700 dark:text-red-400" : tone === "live" ? "bg-yellow-500/10 text-yellow-700 dark:text-yellow-400" : "bg-muted/60 text-muted-foreground"}`,
|
|
374
|
+
children: record.status
|
|
375
|
+
}
|
|
376
|
+
),
|
|
377
|
+
cost && /* @__PURE__ */ jsx2("span", { className: "shrink-0 font-mono text-[11px] tabular-nums text-muted-foreground", children: cost }),
|
|
378
|
+
/* @__PURE__ */ jsx2(ChevronGlyph, { className: `h-3 w-3 shrink-0 text-muted-foreground transition-transform ${open ? "rotate-180" : ""}` })
|
|
379
|
+
] }),
|
|
380
|
+
open && /* @__PURE__ */ jsxs2("div", { className: "space-y-1.5 border-t border-border/40 px-3 py-2.5", children: [
|
|
381
|
+
/* @__PURE__ */ jsxs2("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 font-mono text-[11px]", children: [
|
|
382
|
+
/* @__PURE__ */ jsx2("dt", { className: "text-muted-foreground/60", children: "task" }),
|
|
383
|
+
/* @__PURE__ */ jsx2("dd", { className: "truncate text-muted-foreground", children: record.taskId }),
|
|
384
|
+
/* @__PURE__ */ jsx2("dt", { className: "text-muted-foreground/60", children: "started" }),
|
|
385
|
+
/* @__PURE__ */ jsx2("dd", { className: "text-muted-foreground", children: new Date(record.startedAt).toLocaleString() }),
|
|
386
|
+
duration && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
387
|
+
/* @__PURE__ */ jsx2("dt", { className: "text-muted-foreground/60", children: "duration" }),
|
|
388
|
+
/* @__PURE__ */ jsx2("dd", { className: "text-muted-foreground", children: duration })
|
|
389
|
+
] }),
|
|
390
|
+
record.traceId && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
391
|
+
/* @__PURE__ */ jsx2("dt", { className: "text-muted-foreground/60", children: "trace" }),
|
|
392
|
+
/* @__PURE__ */ jsx2("dd", { className: "truncate text-muted-foreground", children: record.traceId })
|
|
393
|
+
] })
|
|
394
|
+
] }),
|
|
395
|
+
record.missionRef && renderMissionRef?.(record.missionRef, record)
|
|
396
|
+
] })
|
|
397
|
+
] });
|
|
398
|
+
}
|
|
399
|
+
function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent activity", emptyLabel = "No agent runs yet." }) {
|
|
400
|
+
const [rows, setRows] = useState2([]);
|
|
401
|
+
const [cursor, setCursor] = useState2(void 0);
|
|
402
|
+
const [loading, setLoading] = useState2(false);
|
|
403
|
+
const [error, setError] = useState2(null);
|
|
404
|
+
const load = useCallback(
|
|
405
|
+
async (from) => {
|
|
406
|
+
setLoading(true);
|
|
407
|
+
setError(null);
|
|
408
|
+
try {
|
|
409
|
+
const page = await fetchActivity(from);
|
|
410
|
+
setRows((prev) => mergeActivityPages(from === void 0 ? [] : prev, page.items));
|
|
411
|
+
setCursor(page.nextCursor);
|
|
412
|
+
} catch (e) {
|
|
413
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
414
|
+
} finally {
|
|
415
|
+
setLoading(false);
|
|
416
|
+
}
|
|
417
|
+
},
|
|
418
|
+
[fetchActivity]
|
|
419
|
+
);
|
|
420
|
+
useEffect2(() => {
|
|
421
|
+
void load();
|
|
422
|
+
}, [load]);
|
|
423
|
+
return /* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
|
|
424
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
|
|
425
|
+
/* @__PURE__ */ jsx2("h2", { className: "flex-1 text-sm font-semibold", children: title }),
|
|
426
|
+
/* @__PURE__ */ jsx2(
|
|
427
|
+
"button",
|
|
428
|
+
{
|
|
429
|
+
type: "button",
|
|
430
|
+
onClick: () => void load(),
|
|
431
|
+
disabled: loading,
|
|
432
|
+
"aria-label": "Refresh",
|
|
433
|
+
className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground disabled:opacity-50",
|
|
434
|
+
children: /* @__PURE__ */ jsx2(RefreshGlyph, { className: `h-3.5 w-3.5 ${loading ? "animate-spin" : ""}` })
|
|
435
|
+
}
|
|
436
|
+
)
|
|
437
|
+
] }),
|
|
438
|
+
error && /* @__PURE__ */ jsx2("p", { className: "rounded-md border border-red-300/60 bg-red-500/5 px-3 py-2 text-xs text-red-600", children: error }),
|
|
439
|
+
!error && rows.length === 0 && !loading && /* @__PURE__ */ jsx2("p", { className: "px-1 text-sm text-muted-foreground", children: emptyLabel }),
|
|
440
|
+
/* @__PURE__ */ jsx2("div", { className: "space-y-1.5", children: rows.map((record) => /* @__PURE__ */ jsx2(ActivityRow, { record, renderMissionRef }, record.taskId)) }),
|
|
441
|
+
cursor && /* @__PURE__ */ jsx2(
|
|
442
|
+
"button",
|
|
443
|
+
{
|
|
444
|
+
type: "button",
|
|
445
|
+
onClick: () => void load(cursor),
|
|
446
|
+
disabled: loading,
|
|
447
|
+
className: "w-full rounded-md border border-border bg-card px-3 py-1.5 text-xs font-medium text-muted-foreground transition hover:bg-accent/30 disabled:opacity-50",
|
|
448
|
+
children: "Older runs"
|
|
449
|
+
}
|
|
450
|
+
)
|
|
451
|
+
] });
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// src/web-react/index.tsx
|
|
455
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
456
|
+
function ChevronDown({ className }) {
|
|
457
|
+
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" }) });
|
|
458
|
+
}
|
|
214
459
|
function SearchGlyph({ className }) {
|
|
215
|
-
return /* @__PURE__ */
|
|
216
|
-
/* @__PURE__ */
|
|
217
|
-
/* @__PURE__ */
|
|
460
|
+
return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
461
|
+
/* @__PURE__ */ jsx3("circle", { cx: "11", cy: "11", r: "8" }),
|
|
462
|
+
/* @__PURE__ */ jsx3("path", { d: "m21 21-4.3-4.3" })
|
|
218
463
|
] });
|
|
219
464
|
}
|
|
220
465
|
function SparkleGlyph({ className }) {
|
|
221
|
-
return /* @__PURE__ */
|
|
466
|
+
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: "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" }) });
|
|
222
467
|
}
|
|
223
468
|
function useClickOutside(onOutside) {
|
|
224
469
|
const ref = useRef2(null);
|
|
225
|
-
|
|
470
|
+
useEffect3(() => {
|
|
226
471
|
function handler(e) {
|
|
227
472
|
if (ref.current && !ref.current.contains(e.target)) onOutside();
|
|
228
473
|
}
|
|
@@ -257,7 +502,7 @@ function formatContext(len) {
|
|
|
257
502
|
return `${len} ctx`;
|
|
258
503
|
}
|
|
259
504
|
function SectionHeader({ children }) {
|
|
260
|
-
return /* @__PURE__ */
|
|
505
|
+
return /* @__PURE__ */ jsx3("div", { className: "px-3 pb-1 pt-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground/70", children });
|
|
261
506
|
}
|
|
262
507
|
function ModelRow({
|
|
263
508
|
model,
|
|
@@ -267,30 +512,30 @@ function ModelRow({
|
|
|
267
512
|
}) {
|
|
268
513
|
const price = formatPrice(model.pricing?.prompt);
|
|
269
514
|
const ctx = formatContext(model.contextLength);
|
|
270
|
-
return /* @__PURE__ */
|
|
515
|
+
return /* @__PURE__ */ jsxs3(
|
|
271
516
|
"button",
|
|
272
517
|
{
|
|
273
518
|
type: "button",
|
|
274
519
|
onClick: onSelect,
|
|
275
520
|
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"}`,
|
|
276
521
|
children: [
|
|
277
|
-
renderProviderBadge ? renderProviderBadge(model.provider) : /* @__PURE__ */
|
|
278
|
-
/* @__PURE__ */
|
|
279
|
-
!model.supportsTools && /* @__PURE__ */
|
|
280
|
-
/* @__PURE__ */
|
|
281
|
-
ctx && /* @__PURE__ */
|
|
282
|
-
price && /* @__PURE__ */
|
|
522
|
+
renderProviderBadge ? renderProviderBadge(model.provider) : /* @__PURE__ */ jsx3(ProviderLogo, { provider: model.provider, size: 16 }),
|
|
523
|
+
/* @__PURE__ */ jsx3("span", { className: "truncate", children: model.name }),
|
|
524
|
+
!model.supportsTools && /* @__PURE__ */ jsx3("span", { className: "shrink-0 rounded bg-muted/60 px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground", children: "no tools" }),
|
|
525
|
+
/* @__PURE__ */ jsxs3("span", { className: "ml-auto flex shrink-0 items-center gap-2 text-xs text-muted-foreground", children: [
|
|
526
|
+
ctx && /* @__PURE__ */ jsx3("span", { children: ctx }),
|
|
527
|
+
price && /* @__PURE__ */ jsx3("span", { children: price })
|
|
283
528
|
] })
|
|
284
529
|
]
|
|
285
530
|
}
|
|
286
531
|
);
|
|
287
532
|
}
|
|
288
533
|
function ModelPicker({ value, onChange, models, loading, renderProviderBadge, recommendedLabel = "Recommended" }) {
|
|
289
|
-
const [open, setOpen] =
|
|
290
|
-
const [query, setQuery] =
|
|
534
|
+
const [open, setOpen] = useState3(false);
|
|
535
|
+
const [query, setQuery] = useState3("");
|
|
291
536
|
const containerRef = useClickOutside(() => setOpen(false));
|
|
292
537
|
const inputRef = useRef2(null);
|
|
293
|
-
|
|
538
|
+
useEffect3(() => {
|
|
294
539
|
if (open) inputRef.current?.focus();
|
|
295
540
|
}, [open]);
|
|
296
541
|
const selected = models.find((m) => m.id === value);
|
|
@@ -317,24 +562,24 @@ function ModelPicker({ value, onChange, models, loading, renderProviderBadge, re
|
|
|
317
562
|
setOpen(false);
|
|
318
563
|
setQuery("");
|
|
319
564
|
};
|
|
320
|
-
return /* @__PURE__ */
|
|
321
|
-
/* @__PURE__ */
|
|
565
|
+
return /* @__PURE__ */ jsxs3("div", { ref: containerRef, className: "relative inline-flex", children: [
|
|
566
|
+
/* @__PURE__ */ jsxs3(
|
|
322
567
|
"button",
|
|
323
568
|
{
|
|
324
569
|
type: "button",
|
|
325
570
|
onClick: () => setOpen((v) => !v),
|
|
326
571
|
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",
|
|
327
572
|
children: [
|
|
328
|
-
selected ? renderProviderBadge ? renderProviderBadge(selected.provider) : /* @__PURE__ */
|
|
329
|
-
/* @__PURE__ */
|
|
330
|
-
/* @__PURE__ */
|
|
573
|
+
selected ? renderProviderBadge ? renderProviderBadge(selected.provider) : /* @__PURE__ */ jsx3(ProviderLogo, { provider: selected.provider, size: 16 }) : /* @__PURE__ */ jsx3(SparkleGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
574
|
+
/* @__PURE__ */ jsx3("span", { className: "max-w-[160px] truncate", children: selected?.name ?? value }),
|
|
575
|
+
/* @__PURE__ */ jsx3(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
331
576
|
]
|
|
332
577
|
}
|
|
333
578
|
),
|
|
334
|
-
open && /* @__PURE__ */
|
|
335
|
-
/* @__PURE__ */
|
|
336
|
-
/* @__PURE__ */
|
|
337
|
-
/* @__PURE__ */
|
|
579
|
+
open && /* @__PURE__ */ jsxs3("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: [
|
|
580
|
+
/* @__PURE__ */ jsx3("div", { className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 rounded-lg border border-border bg-background px-3 py-2", children: [
|
|
581
|
+
/* @__PURE__ */ jsx3(SearchGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
582
|
+
/* @__PURE__ */ jsx3(
|
|
338
583
|
"input",
|
|
339
584
|
{
|
|
340
585
|
ref: inputRef,
|
|
@@ -346,20 +591,20 @@ function ModelPicker({ value, onChange, models, loading, renderProviderBadge, re
|
|
|
346
591
|
}
|
|
347
592
|
)
|
|
348
593
|
] }) }),
|
|
349
|
-
/* @__PURE__ */
|
|
350
|
-
loading && /* @__PURE__ */
|
|
351
|
-
!loading && filtered && /* @__PURE__ */
|
|
352
|
-
filtered.length === 0 && /* @__PURE__ */
|
|
353
|
-
filtered.map((m) => /* @__PURE__ */
|
|
594
|
+
/* @__PURE__ */ jsxs3("div", { className: "max-h-[400px] overflow-y-auto p-1 pb-2", children: [
|
|
595
|
+
loading && /* @__PURE__ */ jsx3("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "Loading models..." }),
|
|
596
|
+
!loading && filtered && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
597
|
+
filtered.length === 0 && /* @__PURE__ */ jsx3("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "No models match your search" }),
|
|
598
|
+
filtered.map((m) => /* @__PURE__ */ jsx3(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
|
|
354
599
|
] }),
|
|
355
|
-
!loading && !filtered && /* @__PURE__ */
|
|
356
|
-
sections.recommended.length > 0 && /* @__PURE__ */
|
|
357
|
-
/* @__PURE__ */
|
|
358
|
-
sections.recommended.map((m) => /* @__PURE__ */
|
|
600
|
+
!loading && !filtered && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
601
|
+
sections.recommended.length > 0 && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
602
|
+
/* @__PURE__ */ jsx3(SectionHeader, { children: recommendedLabel }),
|
|
603
|
+
sections.recommended.map((m) => /* @__PURE__ */ jsx3(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
|
|
359
604
|
] }),
|
|
360
|
-
sections.byProvider.map((g) => /* @__PURE__ */
|
|
361
|
-
/* @__PURE__ */
|
|
362
|
-
g.items.map((m) => /* @__PURE__ */
|
|
605
|
+
sections.byProvider.map((g) => /* @__PURE__ */ jsxs3("div", { children: [
|
|
606
|
+
/* @__PURE__ */ jsx3(SectionHeader, { children: g.provider }),
|
|
607
|
+
g.items.map((m) => /* @__PURE__ */ jsx3(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
|
|
363
608
|
] }, g.provider))
|
|
364
609
|
] })
|
|
365
610
|
] })
|
|
@@ -373,11 +618,11 @@ var EFFORT_LEVELS = [
|
|
|
373
618
|
{ id: "high", label: "High" }
|
|
374
619
|
];
|
|
375
620
|
function EffortPicker({ value, onChange }) {
|
|
376
|
-
const [open, setOpen] =
|
|
621
|
+
const [open, setOpen] = useState3(false);
|
|
377
622
|
const containerRef = useClickOutside(() => setOpen(false));
|
|
378
623
|
const selected = EFFORT_LEVELS.find((l) => l.id === value) ?? EFFORT_LEVELS[2];
|
|
379
|
-
return /* @__PURE__ */
|
|
380
|
-
/* @__PURE__ */
|
|
624
|
+
return /* @__PURE__ */ jsxs3("div", { ref: containerRef, className: "relative inline-flex", children: [
|
|
625
|
+
/* @__PURE__ */ jsxs3(
|
|
381
626
|
"button",
|
|
382
627
|
{
|
|
383
628
|
type: "button",
|
|
@@ -385,13 +630,13 @@ function EffortPicker({ value, onChange }) {
|
|
|
385
630
|
title: "Reasoning effort",
|
|
386
631
|
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",
|
|
387
632
|
children: [
|
|
388
|
-
/* @__PURE__ */
|
|
389
|
-
/* @__PURE__ */
|
|
390
|
-
/* @__PURE__ */
|
|
633
|
+
/* @__PURE__ */ jsx3(SparkleGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
634
|
+
/* @__PURE__ */ jsx3("span", { children: selected.label }),
|
|
635
|
+
/* @__PURE__ */ jsx3(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
391
636
|
]
|
|
392
637
|
}
|
|
393
638
|
),
|
|
394
|
-
open && /* @__PURE__ */
|
|
639
|
+
open && /* @__PURE__ */ jsx3("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__ */ jsx3(
|
|
395
640
|
"button",
|
|
396
641
|
{
|
|
397
642
|
type: "button",
|
|
@@ -407,41 +652,41 @@ function EffortPicker({ value, onChange }) {
|
|
|
407
652
|
] });
|
|
408
653
|
}
|
|
409
654
|
function RunDrillIn({ run, onClose }) {
|
|
410
|
-
return /* @__PURE__ */
|
|
411
|
-
/* @__PURE__ */
|
|
412
|
-
/* @__PURE__ */
|
|
655
|
+
return /* @__PURE__ */ jsxs3("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: [
|
|
656
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
|
|
657
|
+
/* @__PURE__ */ jsx3(
|
|
413
658
|
"span",
|
|
414
659
|
{
|
|
415
660
|
className: `h-2 w-2 shrink-0 rounded-full ${run.status === "running" ? "bg-yellow-500" : run.status === "error" ? "bg-red-500" : "bg-green-500"}`
|
|
416
661
|
}
|
|
417
662
|
),
|
|
418
|
-
/* @__PURE__ */
|
|
419
|
-
/* @__PURE__ */
|
|
420
|
-
/* @__PURE__ */
|
|
663
|
+
/* @__PURE__ */ jsxs3("div", { className: "min-w-0 flex-1", children: [
|
|
664
|
+
/* @__PURE__ */ jsx3("p", { className: "truncate text-sm font-semibold", children: run.title }),
|
|
665
|
+
/* @__PURE__ */ jsx3("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
|
|
421
666
|
] }),
|
|
422
|
-
/* @__PURE__ */
|
|
667
|
+
/* @__PURE__ */ jsx3(
|
|
423
668
|
"button",
|
|
424
669
|
{
|
|
425
670
|
type: "button",
|
|
426
671
|
onClick: onClose,
|
|
427
672
|
"aria-label": "Close",
|
|
428
673
|
className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground",
|
|
429
|
-
children: /* @__PURE__ */
|
|
674
|
+
children: /* @__PURE__ */ jsx3("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx3("path", { d: "M18 6 6 18M6 6l12 12" }) })
|
|
430
675
|
}
|
|
431
676
|
)
|
|
432
677
|
] }),
|
|
433
|
-
/* @__PURE__ */
|
|
434
|
-
run.steps.length === 0 && /* @__PURE__ */
|
|
435
|
-
run.steps.map((step, i) => /* @__PURE__ */
|
|
436
|
-
/* @__PURE__ */
|
|
437
|
-
/* @__PURE__ */
|
|
438
|
-
/* @__PURE__ */
|
|
439
|
-
/* @__PURE__ */
|
|
678
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
|
|
679
|
+
run.steps.length === 0 && /* @__PURE__ */ jsx3("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
|
|
680
|
+
run.steps.map((step, i) => /* @__PURE__ */ jsxs3("div", { className: "rounded-lg border border-border/60 bg-background", children: [
|
|
681
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
|
|
682
|
+
/* @__PURE__ */ jsx3("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-red-600" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
|
|
683
|
+
/* @__PURE__ */ jsx3("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
|
|
684
|
+
/* @__PURE__ */ jsx3("span", { className: "shrink-0 text-[10px] text-muted-foreground/60", children: new Date(step.at).toLocaleTimeString() })
|
|
440
685
|
] }),
|
|
441
|
-
step.detail && /* @__PURE__ */
|
|
686
|
+
step.detail && /* @__PURE__ */ jsx3("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 })
|
|
442
687
|
] }, i))
|
|
443
688
|
] }),
|
|
444
|
-
/* @__PURE__ */
|
|
689
|
+
/* @__PURE__ */ jsx3("p", { className: "border-t border-border px-4 py-2 text-[11px] text-muted-foreground/60", children: "Readonly drill-in. Follow up in the main chat." })
|
|
445
690
|
] });
|
|
446
691
|
}
|
|
447
692
|
function pendingApprovalOf(call) {
|
|
@@ -451,26 +696,26 @@ function pendingApprovalOf(call) {
|
|
|
451
696
|
}
|
|
452
697
|
function ToolGlyph({ name, className }) {
|
|
453
698
|
if (name.startsWith("sandbox_")) {
|
|
454
|
-
return /* @__PURE__ */
|
|
455
|
-
/* @__PURE__ */
|
|
456
|
-
/* @__PURE__ */
|
|
699
|
+
return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
700
|
+
/* @__PURE__ */ jsx3("polyline", { points: "4 17 10 11 4 5" }),
|
|
701
|
+
/* @__PURE__ */ jsx3("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
|
|
457
702
|
] });
|
|
458
703
|
}
|
|
459
704
|
if (name === "submit_proposal") {
|
|
460
|
-
return /* @__PURE__ */
|
|
461
|
-
/* @__PURE__ */
|
|
462
|
-
/* @__PURE__ */
|
|
705
|
+
return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
706
|
+
/* @__PURE__ */ jsx3("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
707
|
+
/* @__PURE__ */ jsx3("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
|
|
463
708
|
] });
|
|
464
709
|
}
|
|
465
710
|
if (name === "schedule_followup") {
|
|
466
|
-
return /* @__PURE__ */
|
|
467
|
-
/* @__PURE__ */
|
|
468
|
-
/* @__PURE__ */
|
|
711
|
+
return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
|
|
712
|
+
/* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "9" }),
|
|
713
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 7v5l3 3" })
|
|
469
714
|
] });
|
|
470
715
|
}
|
|
471
|
-
return /* @__PURE__ */
|
|
472
|
-
/* @__PURE__ */
|
|
473
|
-
/* @__PURE__ */
|
|
716
|
+
return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
717
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
|
|
718
|
+
/* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "4" })
|
|
474
719
|
] });
|
|
475
720
|
}
|
|
476
721
|
function toolOutcomeOf(call) {
|
|
@@ -504,36 +749,36 @@ function truncate(v, max = 240) {
|
|
|
504
749
|
function KvRows({ data }) {
|
|
505
750
|
const entries = Object.entries(data).filter(([, v]) => v !== void 0 && v !== null && v !== "");
|
|
506
751
|
if (!entries.length) return null;
|
|
507
|
-
return /* @__PURE__ */
|
|
508
|
-
/* @__PURE__ */
|
|
509
|
-
/* @__PURE__ */
|
|
752
|
+
return /* @__PURE__ */ jsx3("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs3("div", { className: "contents", children: [
|
|
753
|
+
/* @__PURE__ */ jsx3("dt", { className: "font-mono text-[11px] text-muted-foreground/70", children: k }),
|
|
754
|
+
/* @__PURE__ */ jsx3("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
|
|
510
755
|
] }, k)) });
|
|
511
756
|
}
|
|
512
757
|
function ShellDetail({ call }) {
|
|
513
758
|
const outcome = toolOutcomeOf(call);
|
|
514
759
|
const r = outcome?.result ?? {};
|
|
515
|
-
return /* @__PURE__ */
|
|
516
|
-
/* @__PURE__ */
|
|
517
|
-
/* @__PURE__ */
|
|
518
|
-
/* @__PURE__ */
|
|
519
|
-
r.exitCode != null && /* @__PURE__ */
|
|
760
|
+
return /* @__PURE__ */ jsxs3("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
|
|
761
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
|
|
762
|
+
/* @__PURE__ */ jsx3("span", { className: "select-none text-zinc-500", children: "$" }),
|
|
763
|
+
/* @__PURE__ */ jsx3("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
|
|
764
|
+
r.exitCode != null && /* @__PURE__ */ jsxs3("span", { className: r.exitCode === 0 ? "text-emerald-400" : "text-red-400", children: [
|
|
520
765
|
"exit ",
|
|
521
766
|
r.exitCode
|
|
522
767
|
] })
|
|
523
768
|
] }),
|
|
524
|
-
/* @__PURE__ */
|
|
769
|
+
/* @__PURE__ */ jsx3("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)" })
|
|
525
770
|
] });
|
|
526
771
|
}
|
|
527
772
|
function DefaultToolDetail({ call }) {
|
|
528
773
|
const outcome = toolOutcomeOf(call);
|
|
529
|
-
return /* @__PURE__ */
|
|
530
|
-
call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */
|
|
531
|
-
/* @__PURE__ */
|
|
532
|
-
/* @__PURE__ */
|
|
774
|
+
return /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
|
|
775
|
+
call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs3("div", { children: [
|
|
776
|
+
/* @__PURE__ */ jsx3("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground/50", children: "Called with" }),
|
|
777
|
+
/* @__PURE__ */ jsx3(KvRows, { data: call.args })
|
|
533
778
|
] }),
|
|
534
|
-
outcome && /* @__PURE__ */
|
|
535
|
-
/* @__PURE__ */
|
|
536
|
-
outcome.ok === false ? /* @__PURE__ */
|
|
779
|
+
outcome && /* @__PURE__ */ jsxs3("div", { children: [
|
|
780
|
+
/* @__PURE__ */ jsx3("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground/50", children: outcome.ok === false ? "Failed" : "Result" }),
|
|
781
|
+
outcome.ok === false ? /* @__PURE__ */ jsx3("p", { className: "text-xs text-red-600", children: outcome.message ?? "Tool failed" }) : outcome.result && typeof outcome.result === "object" ? /* @__PURE__ */ jsx3(KvRows, { data: outcome.result }) : /* @__PURE__ */ jsx3("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(outcome.result) })
|
|
537
782
|
] })
|
|
538
783
|
] });
|
|
539
784
|
}
|
|
@@ -544,32 +789,32 @@ function ToolCallCard({
|
|
|
544
789
|
onOpenRun,
|
|
545
790
|
renderers
|
|
546
791
|
}) {
|
|
547
|
-
const [expanded, setExpanded] =
|
|
792
|
+
const [expanded, setExpanded] = useState3(false);
|
|
548
793
|
const pending = call.status === "done" ? pendingApprovalOf(call) : null;
|
|
549
794
|
const failed = call.status === "error" || toolOutcomeOf(call)?.ok === false;
|
|
550
795
|
const custom = renderers?.[call.name]?.(call, message);
|
|
551
|
-
return /* @__PURE__ */
|
|
796
|
+
return /* @__PURE__ */ jsxs3(
|
|
552
797
|
"div",
|
|
553
798
|
{
|
|
554
799
|
className: `w-fit min-w-[280px] max-w-full rounded-lg border text-xs transition ${pending ? "border-amber-300/60 bg-amber-500/5" : failed ? "border-red-300/60 bg-red-500/5" : "border-border/60 bg-muted/20"}`,
|
|
555
800
|
children: [
|
|
556
|
-
/* @__PURE__ */
|
|
801
|
+
/* @__PURE__ */ jsxs3(
|
|
557
802
|
"button",
|
|
558
803
|
{
|
|
559
804
|
type: "button",
|
|
560
805
|
onClick: () => setExpanded((v) => !v),
|
|
561
806
|
className: "flex w-full items-center gap-2 px-3 py-2 text-left",
|
|
562
807
|
children: [
|
|
563
|
-
/* @__PURE__ */
|
|
808
|
+
/* @__PURE__ */ jsx3(
|
|
564
809
|
"span",
|
|
565
810
|
{
|
|
566
811
|
className: `h-2 w-2 shrink-0 rounded-full ${call.status === "running" ? "animate-pulse bg-yellow-500" : pending ? "bg-amber-500" : failed ? "bg-red-500" : "bg-green-500"}`
|
|
567
812
|
}
|
|
568
813
|
),
|
|
569
|
-
/* @__PURE__ */
|
|
570
|
-
/* @__PURE__ */
|
|
571
|
-
pending && approval && /* @__PURE__ */
|
|
572
|
-
/* @__PURE__ */
|
|
814
|
+
/* @__PURE__ */ jsx3(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
815
|
+
/* @__PURE__ */ jsx3("span", { className: "min-w-0 flex-1 truncate font-medium", children: friendlyToolTitle(call) }),
|
|
816
|
+
pending && approval && /* @__PURE__ */ jsxs3("span", { className: "flex shrink-0 items-center gap-1", onClick: (e) => e.stopPropagation(), children: [
|
|
817
|
+
/* @__PURE__ */ jsx3(
|
|
573
818
|
"button",
|
|
574
819
|
{
|
|
575
820
|
type: "button",
|
|
@@ -578,7 +823,7 @@ function ToolCallCard({
|
|
|
578
823
|
children: "Approve"
|
|
579
824
|
}
|
|
580
825
|
),
|
|
581
|
-
/* @__PURE__ */
|
|
826
|
+
/* @__PURE__ */ jsx3(
|
|
582
827
|
"button",
|
|
583
828
|
{
|
|
584
829
|
type: "button",
|
|
@@ -588,14 +833,14 @@ function ToolCallCard({
|
|
|
588
833
|
}
|
|
589
834
|
)
|
|
590
835
|
] }),
|
|
591
|
-
/* @__PURE__ */
|
|
592
|
-
/* @__PURE__ */
|
|
836
|
+
/* @__PURE__ */ jsx3("span", { className: "shrink-0 text-[11px] text-muted-foreground/70", children: call.status === "running" ? "running\u2026" : pending ? "awaiting approval" : failed ? "failed" : "done" }),
|
|
837
|
+
/* @__PURE__ */ jsx3(ChevronDown, { className: `h-3 w-3 shrink-0 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
|
|
593
838
|
]
|
|
594
839
|
}
|
|
595
840
|
),
|
|
596
|
-
expanded && /* @__PURE__ */
|
|
597
|
-
custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */
|
|
598
|
-
onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */
|
|
841
|
+
expanded && /* @__PURE__ */ jsxs3("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
|
|
842
|
+
custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx3(ShellDetail, { call }) : /* @__PURE__ */ jsx3(DefaultToolDetail, { call })),
|
|
843
|
+
onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx3(
|
|
599
844
|
"button",
|
|
600
845
|
{
|
|
601
846
|
type: "button",
|
|
@@ -631,26 +876,26 @@ function AssistantMessage({
|
|
|
631
876
|
if (content && thinkStartRef.current !== null && thinkMsRef.current === null) {
|
|
632
877
|
thinkMsRef.current = performance.now() - thinkStartRef.current;
|
|
633
878
|
}
|
|
634
|
-
|
|
879
|
+
useEffect3(() => {
|
|
635
880
|
const el = reasoningScrollRef.current;
|
|
636
881
|
if (el && streaming && !content) el.scrollTop = el.scrollHeight;
|
|
637
882
|
}, [reasoning, streaming, content]);
|
|
638
|
-
return /* @__PURE__ */
|
|
639
|
-
/* @__PURE__ */
|
|
640
|
-
/* @__PURE__ */
|
|
641
|
-
msg.modelUsed && /* @__PURE__ */
|
|
642
|
-
formatTokensPerSecond(msg) && /* @__PURE__ */
|
|
643
|
-
formatModelCost(msg, models) && /* @__PURE__ */
|
|
883
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
|
|
884
|
+
/* @__PURE__ */ jsxs3("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground/60", children: [
|
|
885
|
+
/* @__PURE__ */ jsx3("span", { className: "font-semibold uppercase", children: agentLabel }),
|
|
886
|
+
msg.modelUsed && /* @__PURE__ */ jsx3("span", { className: "font-mono normal-case", children: msg.modelUsed }),
|
|
887
|
+
formatTokensPerSecond(msg) && /* @__PURE__ */ jsx3("span", { children: formatTokensPerSecond(msg) }),
|
|
888
|
+
formatModelCost(msg, models) && /* @__PURE__ */ jsx3("span", { children: formatModelCost(msg, models) })
|
|
644
889
|
] }),
|
|
645
|
-
reasoning && /* @__PURE__ */
|
|
646
|
-
/* @__PURE__ */
|
|
647
|
-
/* @__PURE__ */
|
|
890
|
+
reasoning && /* @__PURE__ */ jsxs3("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !content, children: [
|
|
891
|
+
/* @__PURE__ */ jsx3("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !content ? /* @__PURE__ */ jsx3("span", { className: "animate-pulse", children: "Thinking\u2026" }) : thinkMsRef.current != null ? `Thought for ${Math.max(1, Math.round(thinkMsRef.current / 1e3))}s` : "Thought process" }),
|
|
892
|
+
/* @__PURE__ */ jsx3("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground/70", children: reasoning })
|
|
648
893
|
] }),
|
|
649
|
-
/* @__PURE__ */
|
|
894
|
+
/* @__PURE__ */ jsxs3("div", { className: "text-base leading-[1.75]", children: [
|
|
650
895
|
renderBody(content),
|
|
651
|
-
streaming && content && !msg.toolCalls?.length && /* @__PURE__ */
|
|
896
|
+
streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx3("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 })
|
|
652
897
|
] }),
|
|
653
|
-
msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */
|
|
898
|
+
msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */ jsx3("div", { className: "mt-2 flex flex-col gap-1.5", children: msg.toolCalls.map((tc) => /* @__PURE__ */ jsx3(
|
|
654
899
|
ToolCallCard,
|
|
655
900
|
{
|
|
656
901
|
call: tc,
|
|
@@ -665,15 +910,15 @@ function AssistantMessage({
|
|
|
665
910
|
] });
|
|
666
911
|
}
|
|
667
912
|
function ThinkingRow({ agentLabel }) {
|
|
668
|
-
const [seconds, setSeconds] =
|
|
669
|
-
|
|
913
|
+
const [seconds, setSeconds] = useState3(0);
|
|
914
|
+
useEffect3(() => {
|
|
670
915
|
const id = setInterval(() => setSeconds((s) => s + 1), 1e3);
|
|
671
916
|
return () => clearInterval(id);
|
|
672
917
|
}, []);
|
|
673
|
-
return /* @__PURE__ */
|
|
674
|
-
/* @__PURE__ */
|
|
675
|
-
/* @__PURE__ */
|
|
676
|
-
/* @__PURE__ */
|
|
918
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
|
|
919
|
+
/* @__PURE__ */ jsx3("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground/60", children: agentLabel }),
|
|
920
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
|
|
921
|
+
/* @__PURE__ */ jsx3("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx3("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
|
|
677
922
|
"Thinking",
|
|
678
923
|
seconds >= 3 ? ` \xB7 ${seconds}s` : "..."
|
|
679
924
|
] })
|
|
@@ -691,14 +936,14 @@ function ChatMessages({
|
|
|
691
936
|
onToolCallClick,
|
|
692
937
|
toolRenderers
|
|
693
938
|
}) {
|
|
694
|
-
const renderBody = renderMarkdown ?? ((content) => /* @__PURE__ */
|
|
939
|
+
const renderBody = renderMarkdown ?? ((content) => /* @__PURE__ */ jsx3("p", { className: "whitespace-pre-wrap", children: content }));
|
|
695
940
|
const lastIsUser = messages[messages.length - 1]?.role === "user";
|
|
696
|
-
return /* @__PURE__ */
|
|
941
|
+
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
697
942
|
messages.map(
|
|
698
|
-
(msg) => msg.role === "user" ? /* @__PURE__ */
|
|
699
|
-
/* @__PURE__ */
|
|
700
|
-
/* @__PURE__ */
|
|
701
|
-
] }) }, msg.id) : /* @__PURE__ */
|
|
943
|
+
(msg) => msg.role === "user" ? /* @__PURE__ */ jsx3("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs3("div", { className: "ml-auto w-fit max-w-[85%]", children: [
|
|
944
|
+
/* @__PURE__ */ jsx3("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground/60", children: userLabel }),
|
|
945
|
+
/* @__PURE__ */ jsx3("div", { className: "rounded-2xl rounded-tr-md bg-primary/10 px-4 py-2.5 text-base leading-relaxed", children: /* @__PURE__ */ jsx3("p", { className: "whitespace-pre-wrap", children: msg.content }) })
|
|
946
|
+
] }) }, msg.id) : /* @__PURE__ */ jsx3(
|
|
702
947
|
AssistantMessage,
|
|
703
948
|
{
|
|
704
949
|
msg,
|
|
@@ -714,22 +959,30 @@ function ChatMessages({
|
|
|
714
959
|
msg.id
|
|
715
960
|
)
|
|
716
961
|
),
|
|
717
|
-
loading && lastIsUser && /* @__PURE__ */
|
|
962
|
+
loading && lastIsUser && /* @__PURE__ */ jsx3(ThinkingRow, { agentLabel })
|
|
718
963
|
] });
|
|
719
964
|
}
|
|
720
965
|
export {
|
|
966
|
+
AgentActivityPanel,
|
|
721
967
|
ChatMessages,
|
|
722
968
|
EffortPicker,
|
|
969
|
+
FlowWaterfall,
|
|
970
|
+
MissionActivityLane,
|
|
723
971
|
ModelPicker,
|
|
724
972
|
ProviderLogo,
|
|
725
973
|
RunDrillIn,
|
|
974
|
+
activityTone,
|
|
726
975
|
consumeChatStream,
|
|
727
976
|
dispatchChatStreamLine,
|
|
977
|
+
formatActivityCost,
|
|
978
|
+
formatActivityDuration,
|
|
728
979
|
formatModelCost,
|
|
729
980
|
formatTokensPerSecond,
|
|
981
|
+
mergeActivityPages,
|
|
730
982
|
nextRevealCount,
|
|
731
983
|
pendingApprovalOf,
|
|
732
984
|
streamChatTurn,
|
|
733
|
-
useSmoothText
|
|
985
|
+
useSmoothText,
|
|
986
|
+
waterfallLayout
|
|
734
987
|
};
|
|
735
988
|
//# sourceMappingURL=index.js.map
|