@tangle-network/agent-app 0.43.23 → 0.43.25
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/app-auth/index.d.ts +163 -0
- package/dist/app-auth/index.js +166 -0
- package/dist/app-auth/index.js.map +1 -0
- package/dist/assets/index.d.ts +2 -2
- package/dist/assistant/index.d.ts +1 -0
- package/dist/assistant/index.js +2 -1
- package/dist/assistant/index.js.map +1 -1
- package/dist/chat-store/index.d.ts +193 -0
- package/dist/chat-store/index.js +194 -0
- package/dist/chat-store/index.js.map +1 -0
- package/dist/chunk-4H77LX3V.js +38 -0
- package/dist/chunk-4H77LX3V.js.map +1 -0
- package/dist/chunk-4TXDD6P2.js +163 -0
- package/dist/chunk-4TXDD6P2.js.map +1 -0
- package/dist/chunk-AVBANQ67.js +295 -0
- package/dist/chunk-AVBANQ67.js.map +1 -0
- package/dist/{chunk-UKYZ4O2O.js → chunk-JJGZ54EB.js} +64 -5
- package/dist/chunk-JJGZ54EB.js.map +1 -0
- package/dist/{chunk-VMY4TKMN.js → chunk-PEPXQTJ3.js} +921 -432
- package/dist/chunk-PEPXQTJ3.js.map +1 -0
- package/dist/chunk-U7DLCPJ6.js +203 -0
- package/dist/chunk-U7DLCPJ6.js.map +1 -0
- package/dist/{chunk-SAOAAA3S.js → chunk-UHXQ3KNX.js} +1 -22
- package/dist/chunk-UHXQ3KNX.js.map +1 -0
- package/dist/contract-DYbTzEDf.d.ts +122 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +172 -88
- package/dist/interactions/index.d.ts +141 -0
- package/dist/interactions/index.js +59 -0
- package/dist/interactions/index.js.map +1 -0
- package/dist/parts-BeRnK54I.d.ts +185 -0
- package/dist/platform/index.d.ts +2 -270
- package/dist/platform/index.js +12 -278
- package/dist/platform/index.js.map +1 -1
- package/dist/preset-cloudflare/index.d.ts +0 -10
- package/dist/preset-cloudflare/index.js +1 -1
- package/dist/profile/index.d.ts +33 -2
- package/dist/profile/index.js +37 -1
- package/dist/profile/index.js.map +1 -1
- package/dist/sandbox/index.d.ts +61 -5
- package/dist/sandbox/index.js +13 -1
- package/dist/sso-Df4wtL8D.d.ts +270 -0
- package/dist/teams/index.js +9 -9
- package/dist/teams/invitations-api.js +3 -3
- package/dist/web-react/index.d.ts +206 -96
- package/dist/web-react/index.js +68 -22
- package/package.json +21 -2
- package/dist/chunk-SAOAAA3S.js.map +0 -1
- package/dist/chunk-UKYZ4O2O.js.map +0 -1
- package/dist/chunk-VMY4TKMN.js.map +0 -1
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
stepActivityFlowTrace
|
|
3
3
|
} from "./chunk-2QI7XV2T.js";
|
|
4
|
+
import {
|
|
5
|
+
cancelStatusFor,
|
|
6
|
+
fieldAcceptsFreeText,
|
|
7
|
+
interactionFromWireRequest,
|
|
8
|
+
isTerminalInteractionStatus,
|
|
9
|
+
parseInteractionRequest,
|
|
10
|
+
questionInteractionContentSignature
|
|
11
|
+
} from "./chunk-4TXDD6P2.js";
|
|
4
12
|
import {
|
|
5
13
|
snapHarnessToModel,
|
|
6
14
|
snapModelToHarness
|
|
7
15
|
} from "./chunk-E7QYOOON.js";
|
|
8
16
|
|
|
9
17
|
// src/web-react/index.tsx
|
|
10
|
-
import { useEffect as useEffect5, useMemo as
|
|
18
|
+
import { useEffect as useEffect5, useMemo as useMemo6, useRef as useRef6, useState as useState9, memo } from "react";
|
|
11
19
|
|
|
12
20
|
// src/web-react/smooth-text.ts
|
|
13
21
|
import { useEffect, useRef, useState } from "react";
|
|
@@ -364,145 +372,6 @@ function BrandMark({ size = 24, className }) {
|
|
|
364
372
|
return /* @__PURE__ */ jsx3(Suspense, { fallback: /* @__PURE__ */ jsx3(MarkSpacer, { size, className }), children: /* @__PURE__ */ jsx3(LazyKnot, { size, className }) });
|
|
365
373
|
}
|
|
366
374
|
|
|
367
|
-
// src/web-react/chat-interactions.ts
|
|
368
|
-
import {
|
|
369
|
-
InteractionRequestSchema
|
|
370
|
-
} from "@tangle-network/agent-interface";
|
|
371
|
-
var INTERACTION_EVENT = "interaction";
|
|
372
|
-
var INTERACTION_CANCEL_EVENT = "interaction.cancel";
|
|
373
|
-
var INTERACTION_RESOLVED_EVENT = "interaction.resolved";
|
|
374
|
-
var RENDERABLE_INTERACTION_KINDS = /* @__PURE__ */ new Set(["question", "plan"]);
|
|
375
|
-
function isRenderableInteractionKind(kind) {
|
|
376
|
-
return RENDERABLE_INTERACTION_KINDS.has(kind);
|
|
377
|
-
}
|
|
378
|
-
function isSafeInteractionFieldKey(key) {
|
|
379
|
-
return /^[A-Za-z0-9_-]+$/.test(key) && key !== "__proto__" && key !== "constructor" && key !== "prototype";
|
|
380
|
-
}
|
|
381
|
-
function isTerminalInteractionStatus(status) {
|
|
382
|
-
return status !== "pending";
|
|
383
|
-
}
|
|
384
|
-
function canTransitionInteractionStatus(from, to) {
|
|
385
|
-
return from === "pending" && to !== from;
|
|
386
|
-
}
|
|
387
|
-
function cancelStatusFor(reason) {
|
|
388
|
-
return reason === "timeout" ? "expired" : "cancelled";
|
|
389
|
-
}
|
|
390
|
-
function stableValue(value) {
|
|
391
|
-
if (Array.isArray(value)) return value.map(stableValue);
|
|
392
|
-
if (!value || typeof value !== "object") return value;
|
|
393
|
-
return Object.fromEntries(
|
|
394
|
-
Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, nested]) => [key, stableValue(nested)])
|
|
395
|
-
);
|
|
396
|
-
}
|
|
397
|
-
function normalizedInteractionText(value) {
|
|
398
|
-
return (value ?? "").replace(/\s+/g, " ").trim();
|
|
399
|
-
}
|
|
400
|
-
function questionInteractionContentSignature(interaction) {
|
|
401
|
-
if (interaction.kind !== "question") return null;
|
|
402
|
-
return JSON.stringify(stableValue({
|
|
403
|
-
kind: interaction.kind,
|
|
404
|
-
title: normalizedInteractionText(interaction.title),
|
|
405
|
-
body: normalizedInteractionText(interaction.body),
|
|
406
|
-
fields: interaction.fields
|
|
407
|
-
}));
|
|
408
|
-
}
|
|
409
|
-
function dedupeQuestionInteractionsByContent(interactions) {
|
|
410
|
-
const seen = /* @__PURE__ */ new Set();
|
|
411
|
-
return interactions.filter((interaction) => {
|
|
412
|
-
const signature = questionInteractionContentSignature(interaction);
|
|
413
|
-
if (!signature) return true;
|
|
414
|
-
if (seen.has(signature)) return false;
|
|
415
|
-
seen.add(signature);
|
|
416
|
-
return true;
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
function parseInteractionRequest(data) {
|
|
420
|
-
const request = data?.request;
|
|
421
|
-
if (!request || typeof request !== "object") {
|
|
422
|
-
return { succeeded: false, error: "interaction event carried no request object" };
|
|
423
|
-
}
|
|
424
|
-
const validation = InteractionRequestSchema.safeParse(request);
|
|
425
|
-
if (!validation.success) {
|
|
426
|
-
return { succeeded: false, error: `malformed interaction request: ${validation.error.message}` };
|
|
427
|
-
}
|
|
428
|
-
return { succeeded: true, value: request };
|
|
429
|
-
}
|
|
430
|
-
function parseInteractionCancel(data) {
|
|
431
|
-
const id = typeof data?.id === "string" && data.id ? data.id : null;
|
|
432
|
-
if (!id) return { succeeded: false, error: "interaction.cancel event carried no id" };
|
|
433
|
-
const reason = typeof data?.reason === "string" && data.reason ? data.reason : void 0;
|
|
434
|
-
return { succeeded: true, value: { id, ...reason ? { reason } : {} } };
|
|
435
|
-
}
|
|
436
|
-
function fieldAcceptsFreeText(field) {
|
|
437
|
-
if (field.type === "text") return true;
|
|
438
|
-
if (field.type === "select") return field.allowCustom === true;
|
|
439
|
-
return false;
|
|
440
|
-
}
|
|
441
|
-
function composerAnswerDeliveries(pending) {
|
|
442
|
-
const deliveries = [];
|
|
443
|
-
for (const interaction of pending) {
|
|
444
|
-
if (interaction.kind !== "question") continue;
|
|
445
|
-
const field = interaction.fields.find(fieldAcceptsFreeText) ?? interaction.fields[0];
|
|
446
|
-
if (!field) continue;
|
|
447
|
-
deliveries.push({ interactionId: interaction.id, field });
|
|
448
|
-
}
|
|
449
|
-
return deliveries;
|
|
450
|
-
}
|
|
451
|
-
function composerAnswerData(field, text) {
|
|
452
|
-
return { [field.name]: field.type === "select" ? [text] : text };
|
|
453
|
-
}
|
|
454
|
-
function interactionPartKey(id) {
|
|
455
|
-
return `interaction:${id}`;
|
|
456
|
-
}
|
|
457
|
-
function noticePartKey(id) {
|
|
458
|
-
return `notice:${id}`;
|
|
459
|
-
}
|
|
460
|
-
function noticePart(noticeKind, id, text) {
|
|
461
|
-
return { type: "notice", id, noticeKind, text };
|
|
462
|
-
}
|
|
463
|
-
function interactionFromWireRequest(request) {
|
|
464
|
-
return {
|
|
465
|
-
id: request.id,
|
|
466
|
-
kind: request.kind,
|
|
467
|
-
title: request.title,
|
|
468
|
-
...request.body ? { body: request.body } : {},
|
|
469
|
-
fields: request.answerSpec.fields,
|
|
470
|
-
status: "pending"
|
|
471
|
-
};
|
|
472
|
-
}
|
|
473
|
-
function interactionToPersistedPart(request, status, cancelReason) {
|
|
474
|
-
return {
|
|
475
|
-
type: "interaction",
|
|
476
|
-
id: request.id,
|
|
477
|
-
kind: request.kind,
|
|
478
|
-
title: request.title,
|
|
479
|
-
...request.body ? { body: request.body } : {},
|
|
480
|
-
answerSpec: { fields: request.answerSpec.fields },
|
|
481
|
-
status,
|
|
482
|
-
...cancelReason ? { cancelReason } : {}
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
function persistedPartToInteraction(part) {
|
|
486
|
-
if (String(part.type ?? "") !== "interaction") return null;
|
|
487
|
-
const id = typeof part.id === "string" && part.id ? part.id : null;
|
|
488
|
-
const kind = typeof part.kind === "string" && part.kind ? part.kind : null;
|
|
489
|
-
const title = typeof part.title === "string" ? part.title : "";
|
|
490
|
-
const answerSpec = part.answerSpec;
|
|
491
|
-
const fields = Array.isArray(answerSpec?.fields) ? answerSpec.fields : null;
|
|
492
|
-
const status = part.status;
|
|
493
|
-
const validStatus = status && ["pending", "answered", "declined", "cancelled", "expired"].includes(status);
|
|
494
|
-
if (!id || !kind || !fields || !validStatus) return null;
|
|
495
|
-
return {
|
|
496
|
-
id,
|
|
497
|
-
kind,
|
|
498
|
-
title,
|
|
499
|
-
...typeof part.body === "string" && part.body ? { body: part.body } : {},
|
|
500
|
-
fields,
|
|
501
|
-
status,
|
|
502
|
-
...typeof part.cancelReason === "string" && part.cancelReason ? { cancelReason: part.cancelReason } : {}
|
|
503
|
-
};
|
|
504
|
-
}
|
|
505
|
-
|
|
506
375
|
// src/web-react/chat-stream.ts
|
|
507
376
|
function dispatchChatStreamLine(line, cb) {
|
|
508
377
|
let receivedContent = false;
|
|
@@ -578,9 +447,19 @@ function dispatchChatStreamLine(line, cb) {
|
|
|
578
447
|
}
|
|
579
448
|
break;
|
|
580
449
|
}
|
|
581
|
-
case "error":
|
|
582
|
-
|
|
450
|
+
case "error": {
|
|
451
|
+
const message = String(evt.details ?? evt.error ?? "Unknown stream error");
|
|
452
|
+
if (cb.onErrorEvent) {
|
|
453
|
+
cb.onErrorEvent(message);
|
|
454
|
+
} else {
|
|
455
|
+
console.error("[chat-stream] unhandled stream error event:", message);
|
|
456
|
+
cb.onText?.(`
|
|
457
|
+
|
|
458
|
+
The agent hit an error and this turn stopped: ${message}`);
|
|
459
|
+
receivedContent = true;
|
|
460
|
+
}
|
|
583
461
|
break;
|
|
462
|
+
}
|
|
584
463
|
default:
|
|
585
464
|
break;
|
|
586
465
|
}
|
|
@@ -914,9 +793,618 @@ function ChatComposer({
|
|
|
914
793
|
);
|
|
915
794
|
}
|
|
916
795
|
|
|
917
|
-
// src/web-react/
|
|
918
|
-
|
|
796
|
+
// src/web-react/interaction-card-support.ts
|
|
797
|
+
function interactionStatusLabels(labels) {
|
|
798
|
+
return { cancelled: "Withdrawn", expired: "Expired", ...labels };
|
|
799
|
+
}
|
|
800
|
+
function interactionTerminalNotes(noun, extra) {
|
|
801
|
+
return {
|
|
802
|
+
expired: `This ${noun} expired \u2014 send a new message to continue.`,
|
|
803
|
+
cancelled: `The agent withdrew this ${noun}.`,
|
|
804
|
+
...extra
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
function fieldAnswer(field, values) {
|
|
808
|
+
const value = values[field.name] ?? {};
|
|
809
|
+
if (field.type === "select") {
|
|
810
|
+
const custom = field.allowCustom === true ? value.custom?.trim() : void 0;
|
|
811
|
+
const chosen = [...value.selected ?? [], ...custom ? [custom] : []];
|
|
812
|
+
if (field.multi !== true && custom) return [custom];
|
|
813
|
+
return chosen.length > 0 ? chosen : null;
|
|
814
|
+
}
|
|
815
|
+
if (field.type === "number") {
|
|
816
|
+
const parsed = Number(value.text);
|
|
817
|
+
return value.text?.trim() && Number.isFinite(parsed) ? parsed : null;
|
|
818
|
+
}
|
|
819
|
+
if (field.type === "boolean") return value.selected ? value.selected[0] === "true" : null;
|
|
820
|
+
const text = value.text?.trim();
|
|
821
|
+
return text ? text : null;
|
|
822
|
+
}
|
|
823
|
+
function buildAnswerData(fields, values) {
|
|
824
|
+
const data = {};
|
|
825
|
+
for (const field of fields) {
|
|
826
|
+
const answer = fieldAnswer(field, values);
|
|
827
|
+
if (answer === null) {
|
|
828
|
+
if (field.required === false) continue;
|
|
829
|
+
return null;
|
|
830
|
+
}
|
|
831
|
+
data[field.name] = answer;
|
|
832
|
+
}
|
|
833
|
+
return data;
|
|
834
|
+
}
|
|
835
|
+
function isLateAnswerableStatus(status) {
|
|
836
|
+
return status === "expired" || status === "cancelled";
|
|
837
|
+
}
|
|
838
|
+
function hasSecretField(fields) {
|
|
839
|
+
return fields.some((field) => field.type === "secret");
|
|
840
|
+
}
|
|
841
|
+
function optionLabel(field, value) {
|
|
842
|
+
return field.options.find((option) => option.value === value)?.label ?? value;
|
|
843
|
+
}
|
|
844
|
+
function answerText(field, answer) {
|
|
845
|
+
if (field.type === "select" && Array.isArray(answer)) {
|
|
846
|
+
return answer.map((value) => optionLabel(field, value)).join(", ");
|
|
847
|
+
}
|
|
848
|
+
if (field.type === "boolean") return answer === true ? "Yes" : "No";
|
|
849
|
+
if (field.type === "secret") return "[secret omitted]";
|
|
850
|
+
return String(answer);
|
|
851
|
+
}
|
|
852
|
+
function lateAnswerMessage(interaction, data) {
|
|
853
|
+
const title = interaction.title.trim() || "the earlier question";
|
|
854
|
+
const body = interaction.body?.trim();
|
|
855
|
+
const answers = interaction.fields.map((field) => {
|
|
856
|
+
const answer = data[field.name];
|
|
857
|
+
if (answer === void 0) return null;
|
|
858
|
+
return { label: field.label.trim(), text: answerText(field, answer).trim() };
|
|
859
|
+
}).filter((item) => !!item && item.text.length > 0);
|
|
860
|
+
const only = answers.length === 1 ? answers[0] : void 0;
|
|
861
|
+
const answerSummary = only ? only.text : answers.map((item) => `${item.label || "Answer"}: ${item.text}`).join("\n");
|
|
862
|
+
return [
|
|
863
|
+
`Regarding your earlier question: "${title}"`,
|
|
864
|
+
body ? `Context: ${body}` : null,
|
|
865
|
+
`My answer: ${answerSummary}`
|
|
866
|
+
].filter((line) => !!line).join("\n");
|
|
867
|
+
}
|
|
868
|
+
var INTERACTION_SUBMIT_TIMEOUT_MS = 3e4;
|
|
869
|
+
var INTERACTION_SUBMIT_TIMEOUT_MESSAGE = "Could not reach the agent. Try again.";
|
|
870
|
+
async function responseErrorMessage(res) {
|
|
871
|
+
const text = await res.text().catch(() => "");
|
|
872
|
+
if (text) {
|
|
873
|
+
try {
|
|
874
|
+
const parsed = JSON.parse(text);
|
|
875
|
+
const message = typeof parsed.error === "string" && parsed.error.trim() ? parsed.error : typeof parsed.message === "string" && parsed.message.trim() ? parsed.message : null;
|
|
876
|
+
if (message) return { ...typeof parsed.code === "string" ? { code: parsed.code } : {}, message };
|
|
877
|
+
} catch {
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
return { message: `Answer failed (${res.status})` };
|
|
881
|
+
}
|
|
882
|
+
function createInteractionAnswerSubmitter(options) {
|
|
883
|
+
const timeoutMs = options.timeoutMs ?? INTERACTION_SUBMIT_TIMEOUT_MS;
|
|
884
|
+
return async (submission) => {
|
|
885
|
+
const doFetch = options.fetchImpl ?? fetch;
|
|
886
|
+
const url = typeof options.url === "function" ? options.url(submission) : options.url;
|
|
887
|
+
const extra = typeof options.body === "function" ? options.body(submission) : options.body ?? {};
|
|
888
|
+
const controller = new AbortController();
|
|
889
|
+
const timer = setTimeout(() => controller.abort(INTERACTION_SUBMIT_TIMEOUT_MESSAGE), timeoutMs);
|
|
890
|
+
try {
|
|
891
|
+
const res = await doFetch(url, {
|
|
892
|
+
method: "POST",
|
|
893
|
+
headers: { "Content-Type": "application/json" },
|
|
894
|
+
signal: controller.signal,
|
|
895
|
+
body: JSON.stringify({
|
|
896
|
+
...extra,
|
|
897
|
+
id: submission.id,
|
|
898
|
+
outcome: submission.outcome,
|
|
899
|
+
...submission.data ? { data: submission.data } : {}
|
|
900
|
+
})
|
|
901
|
+
});
|
|
902
|
+
if (res.ok) return { ok: true };
|
|
903
|
+
const failure = await responseErrorMessage(res);
|
|
904
|
+
return { ok: false, expired: res.status === 410, message: failure.message };
|
|
905
|
+
} catch (err) {
|
|
906
|
+
if (controller.signal.aborted) {
|
|
907
|
+
return { ok: false, expired: false, message: INTERACTION_SUBMIT_TIMEOUT_MESSAGE };
|
|
908
|
+
}
|
|
909
|
+
return { ok: false, expired: false, message: err instanceof Error ? err.message : "Failed to submit the answer" };
|
|
910
|
+
} finally {
|
|
911
|
+
clearTimeout(timer);
|
|
912
|
+
}
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// src/web-react/interaction-question-card.tsx
|
|
917
|
+
import { useMemo as useMemo2, useRef as useRef4, useState as useState4 } from "react";
|
|
919
918
|
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
919
|
+
function CheckGlyph({ className }) {
|
|
920
|
+
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: "M20 6 9 17l-5-5" }) });
|
|
921
|
+
}
|
|
922
|
+
var BADGE_VARIANT_CLASSES = {
|
|
923
|
+
outline: "border-border text-foreground",
|
|
924
|
+
default: "border-transparent bg-primary text-primary-foreground",
|
|
925
|
+
destructive: "border-transparent bg-destructive/15 text-destructive"
|
|
926
|
+
};
|
|
927
|
+
function InteractionBadge({ variant, children }) {
|
|
928
|
+
return /* @__PURE__ */ jsx5("span", { className: `inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium ${BADGE_VARIANT_CLASSES[variant]}`, children });
|
|
929
|
+
}
|
|
930
|
+
function InteractionActionButton({
|
|
931
|
+
variant = "primary",
|
|
932
|
+
onClick,
|
|
933
|
+
disabled,
|
|
934
|
+
children
|
|
935
|
+
}) {
|
|
936
|
+
const variantClasses = variant === "primary" ? "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90" : "border border-border bg-transparent text-foreground hover:bg-accent/40";
|
|
937
|
+
return /* @__PURE__ */ jsx5(
|
|
938
|
+
"button",
|
|
939
|
+
{
|
|
940
|
+
type: "button",
|
|
941
|
+
onClick,
|
|
942
|
+
disabled,
|
|
943
|
+
className: `inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium transition disabled:cursor-not-allowed disabled:opacity-40 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring ${variantClasses}`,
|
|
944
|
+
children
|
|
945
|
+
}
|
|
946
|
+
);
|
|
947
|
+
}
|
|
948
|
+
var FIELD_INPUT_CLASSES = "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground outline-none focus:border-primary disabled:opacity-50";
|
|
949
|
+
function QuestionOptionList({
|
|
950
|
+
groupName,
|
|
951
|
+
idPrefix,
|
|
952
|
+
options,
|
|
953
|
+
multi,
|
|
954
|
+
selectedValues,
|
|
955
|
+
disabled,
|
|
956
|
+
onToggle
|
|
957
|
+
}) {
|
|
958
|
+
return /* @__PURE__ */ jsx5(Fragment3, { children: options.map((option, optionIndex) => {
|
|
959
|
+
const inputId = `${idPrefix}-${optionIndex}`;
|
|
960
|
+
const checked = selectedValues.includes(option.value);
|
|
961
|
+
return /* @__PURE__ */ jsxs4("label", { htmlFor: inputId, className: "flex cursor-pointer gap-2 rounded-lg border border-border/70 p-3 transition-colors hover:bg-muted/50", children: [
|
|
962
|
+
/* @__PURE__ */ jsx5(
|
|
963
|
+
"input",
|
|
964
|
+
{
|
|
965
|
+
id: inputId,
|
|
966
|
+
type: multi ? "checkbox" : "radio",
|
|
967
|
+
name: groupName,
|
|
968
|
+
value: option.value,
|
|
969
|
+
checked,
|
|
970
|
+
disabled,
|
|
971
|
+
onChange: () => onToggle(option.value),
|
|
972
|
+
"aria-labelledby": `${inputId}-label`,
|
|
973
|
+
"aria-describedby": option.description ? `${inputId}-description` : void 0,
|
|
974
|
+
className: "mt-0.5 h-4 w-4 shrink-0 accent-primary"
|
|
975
|
+
}
|
|
976
|
+
),
|
|
977
|
+
/* @__PURE__ */ jsxs4("span", { className: "min-w-0", children: [
|
|
978
|
+
/* @__PURE__ */ jsx5("span", { id: `${inputId}-label`, className: "block text-sm font-medium leading-5 text-foreground", children: option.label }),
|
|
979
|
+
option.description && /* @__PURE__ */ jsx5("span", { id: `${inputId}-description`, className: "mt-0.5 block text-xs leading-5 text-muted-foreground", children: option.description })
|
|
980
|
+
] })
|
|
981
|
+
] }, `${option.value}-${optionIndex}`);
|
|
982
|
+
}) });
|
|
983
|
+
}
|
|
984
|
+
function selectField(field) {
|
|
985
|
+
return field.type === "select" ? field : null;
|
|
986
|
+
}
|
|
987
|
+
function valuesWithSelected(values, field, optionValue) {
|
|
988
|
+
const current = values[field.name]?.selected ?? [];
|
|
989
|
+
let selected = [optionValue];
|
|
990
|
+
if (field.multi === true) {
|
|
991
|
+
selected = current.includes(optionValue) ? current.filter((item) => item !== optionValue) : [...current, optionValue];
|
|
992
|
+
}
|
|
993
|
+
return { ...values, [field.name]: { ...values[field.name], selected } };
|
|
994
|
+
}
|
|
995
|
+
var STATUS_LABELS = interactionStatusLabels({
|
|
996
|
+
pending: "Waiting for your answer",
|
|
997
|
+
answered: "Answered",
|
|
998
|
+
declined: "Declined"
|
|
999
|
+
});
|
|
1000
|
+
var TERMINAL_NOTES = interactionTerminalNotes("question", {
|
|
1001
|
+
expired: "The original run ended. Answer now to send a new message with this context.",
|
|
1002
|
+
cancelled: "The agent withdrew this question. Answer now to send a new message with this context."
|
|
1003
|
+
});
|
|
1004
|
+
function InteractionQuestionCard({
|
|
1005
|
+
interaction,
|
|
1006
|
+
canWrite,
|
|
1007
|
+
submitAnswer,
|
|
1008
|
+
onResolved,
|
|
1009
|
+
onLateAnswer,
|
|
1010
|
+
className
|
|
1011
|
+
}) {
|
|
1012
|
+
const [values, setValues] = useState4({});
|
|
1013
|
+
const [submitting, setSubmitting] = useState4(false);
|
|
1014
|
+
const [localStatus, setLocalStatus] = useState4(null);
|
|
1015
|
+
const [lateAnswerSent, setLateAnswerSent] = useState4(false);
|
|
1016
|
+
const [error, setError] = useState4(null);
|
|
1017
|
+
const submitInFlightRef = useRef4(false);
|
|
1018
|
+
const status = isTerminalInteractionStatus(interaction.status) ? interaction.status : localStatus ?? interaction.status;
|
|
1019
|
+
const answered = status === "answered";
|
|
1020
|
+
const lateAnswerable = isLateAnswerableStatus(status) && onLateAnswer !== void 0;
|
|
1021
|
+
const secretLateAnswerBlocked = lateAnswerable && hasSecretField(interaction.fields);
|
|
1022
|
+
const canLateAnswer = canWrite && lateAnswerable && !lateAnswerSent && !secretLateAnswerBlocked;
|
|
1023
|
+
const disabled = !canWrite || status !== "pending" && !canLateAnswer || submitting;
|
|
1024
|
+
const answerData = useMemo2(() => buildAnswerData(interaction.fields, values), [interaction.fields, values]);
|
|
1025
|
+
const setFieldValue = (name, patch) => {
|
|
1026
|
+
setValues((prev) => ({ ...prev, [name]: { ...prev[name], ...patch } }));
|
|
1027
|
+
};
|
|
1028
|
+
const toggleSelected = (field, optionValue) => {
|
|
1029
|
+
setValues((prev) => valuesWithSelected(prev, field, optionValue));
|
|
1030
|
+
};
|
|
1031
|
+
async function submitLateAnswer() {
|
|
1032
|
+
if (submitInFlightRef.current || !canLateAnswer || !onLateAnswer) return;
|
|
1033
|
+
const data = buildAnswerData(interaction.fields, values);
|
|
1034
|
+
if (!data) return;
|
|
1035
|
+
submitInFlightRef.current = true;
|
|
1036
|
+
setSubmitting(true);
|
|
1037
|
+
setError(null);
|
|
1038
|
+
let accepted;
|
|
1039
|
+
try {
|
|
1040
|
+
accepted = await onLateAnswer(lateAnswerMessage(interaction, data));
|
|
1041
|
+
} catch {
|
|
1042
|
+
accepted = false;
|
|
1043
|
+
} finally {
|
|
1044
|
+
submitInFlightRef.current = false;
|
|
1045
|
+
setSubmitting(false);
|
|
1046
|
+
}
|
|
1047
|
+
if (accepted === false) {
|
|
1048
|
+
setError("The new message was not sent. Try again from this card.");
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
setLateAnswerSent(true);
|
|
1052
|
+
}
|
|
1053
|
+
async function submit() {
|
|
1054
|
+
if (lateAnswerable) {
|
|
1055
|
+
await submitLateAnswer();
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
if (submitInFlightRef.current || disabled || !answerData) return;
|
|
1059
|
+
submitInFlightRef.current = true;
|
|
1060
|
+
setSubmitting(true);
|
|
1061
|
+
setError(null);
|
|
1062
|
+
try {
|
|
1063
|
+
const result = await submitAnswer({ id: interaction.id, outcome: "accepted", data: answerData });
|
|
1064
|
+
if (result.ok) {
|
|
1065
|
+
setLocalStatus("answered");
|
|
1066
|
+
onResolved?.(interaction.id, "answered");
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
if (result.expired) {
|
|
1070
|
+
setLocalStatus("expired");
|
|
1071
|
+
onResolved?.(interaction.id, "expired");
|
|
1072
|
+
return;
|
|
1073
|
+
}
|
|
1074
|
+
setError(result.message);
|
|
1075
|
+
} finally {
|
|
1076
|
+
submitInFlightRef.current = false;
|
|
1077
|
+
setSubmitting(false);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
const terminalNote = secretLateAnswerBlocked ? "This question asked for a secret, so it cannot be sent as a new chat message. Ask the agent to request it again." : TERMINAL_NOTES[status];
|
|
1081
|
+
const showSubmitButton = status === "pending" || canWrite && lateAnswerable && !lateAnswerSent;
|
|
1082
|
+
let submitLabel = "Submit answer";
|
|
1083
|
+
if (lateAnswerable) {
|
|
1084
|
+
submitLabel = submitting ? "Sending\u2026" : "Send as new message";
|
|
1085
|
+
} else if (submitting) {
|
|
1086
|
+
submitLabel = "Submitting\u2026";
|
|
1087
|
+
}
|
|
1088
|
+
return /* @__PURE__ */ jsxs4("div", { className: `rounded-xl border border-border bg-card p-4 shadow-sm ${className ?? ""}`, children: [
|
|
1089
|
+
/* @__PURE__ */ jsxs4("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-2", children: [
|
|
1090
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
1091
|
+
/* @__PURE__ */ jsx5(InteractionBadge, { variant: "outline", children: "Question" }),
|
|
1092
|
+
/* @__PURE__ */ jsx5(InteractionBadge, { variant: answered ? "default" : status === "expired" || status === "declined" ? "destructive" : "outline", children: STATUS_LABELS[status] })
|
|
1093
|
+
] }),
|
|
1094
|
+
/* @__PURE__ */ jsx5("span", { className: "text-xs text-muted-foreground", children: "The agent asked for input" })
|
|
1095
|
+
] }),
|
|
1096
|
+
interaction.title.trim() && interaction.fields.every((field) => field.label !== interaction.title) && /* @__PURE__ */ jsx5("p", { className: "mb-3 text-sm font-medium leading-5 text-foreground", children: interaction.title }),
|
|
1097
|
+
interaction.body && /* @__PURE__ */ jsx5("p", { className: "mb-3 text-sm leading-5 text-muted-foreground", children: interaction.body }),
|
|
1098
|
+
/* @__PURE__ */ jsx5("div", { className: "space-y-4", children: interaction.fields.map((field) => {
|
|
1099
|
+
const value = values[field.name] ?? {};
|
|
1100
|
+
const select = selectField(field);
|
|
1101
|
+
return /* @__PURE__ */ jsxs4("fieldset", { className: "space-y-2", children: [
|
|
1102
|
+
/* @__PURE__ */ jsx5("p", { className: "text-sm font-medium leading-5 text-foreground", children: field.label }),
|
|
1103
|
+
select ? /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
|
|
1104
|
+
/* @__PURE__ */ jsx5(
|
|
1105
|
+
QuestionOptionList,
|
|
1106
|
+
{
|
|
1107
|
+
groupName: `${interaction.id}-${field.name}`,
|
|
1108
|
+
idPrefix: `${interaction.id}-${field.name}`,
|
|
1109
|
+
options: select.options,
|
|
1110
|
+
multi: select.multi === true,
|
|
1111
|
+
selectedValues: value.selected ?? [],
|
|
1112
|
+
disabled,
|
|
1113
|
+
onToggle: (optionValue) => toggleSelected(select, optionValue)
|
|
1114
|
+
}
|
|
1115
|
+
),
|
|
1116
|
+
select.allowCustom === true && /* @__PURE__ */ jsx5(
|
|
1117
|
+
"input",
|
|
1118
|
+
{
|
|
1119
|
+
type: "text",
|
|
1120
|
+
value: value.custom ?? "",
|
|
1121
|
+
disabled,
|
|
1122
|
+
onChange: (event) => setFieldValue(field.name, { custom: event.target.value }),
|
|
1123
|
+
placeholder: "Other \u2014 type your own answer",
|
|
1124
|
+
"aria-label": `Custom answer for ${field.label}`,
|
|
1125
|
+
className: FIELD_INPUT_CLASSES
|
|
1126
|
+
}
|
|
1127
|
+
)
|
|
1128
|
+
] }) : field.type === "boolean" ? /* @__PURE__ */ jsx5("div", { className: "flex gap-4", children: ["true", "false"].map((boolValue) => /* @__PURE__ */ jsxs4("label", { className: "flex cursor-pointer items-center gap-2 text-sm text-foreground", children: [
|
|
1129
|
+
/* @__PURE__ */ jsx5(
|
|
1130
|
+
"input",
|
|
1131
|
+
{
|
|
1132
|
+
type: "radio",
|
|
1133
|
+
name: `${interaction.id}-${field.name}`,
|
|
1134
|
+
value: boolValue,
|
|
1135
|
+
checked: (value.selected ?? [])[0] === boolValue,
|
|
1136
|
+
disabled,
|
|
1137
|
+
onChange: () => setFieldValue(field.name, { selected: [boolValue] }),
|
|
1138
|
+
className: "h-4 w-4 accent-primary"
|
|
1139
|
+
}
|
|
1140
|
+
),
|
|
1141
|
+
boolValue === "true" ? "Yes" : "No"
|
|
1142
|
+
] }, boolValue)) }) : field.type === "number" ? /* @__PURE__ */ jsx5(
|
|
1143
|
+
"input",
|
|
1144
|
+
{
|
|
1145
|
+
type: "number",
|
|
1146
|
+
value: value.text ?? "",
|
|
1147
|
+
disabled,
|
|
1148
|
+
"aria-label": field.label,
|
|
1149
|
+
onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
|
|
1150
|
+
className: FIELD_INPUT_CLASSES
|
|
1151
|
+
}
|
|
1152
|
+
) : field.type === "secret" ? /* @__PURE__ */ jsx5(
|
|
1153
|
+
"input",
|
|
1154
|
+
{
|
|
1155
|
+
type: "password",
|
|
1156
|
+
value: value.text ?? "",
|
|
1157
|
+
disabled,
|
|
1158
|
+
"aria-label": field.label,
|
|
1159
|
+
onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
|
|
1160
|
+
placeholder: field.placeholder,
|
|
1161
|
+
className: FIELD_INPUT_CLASSES
|
|
1162
|
+
}
|
|
1163
|
+
) : /* @__PURE__ */ jsx5(
|
|
1164
|
+
"textarea",
|
|
1165
|
+
{
|
|
1166
|
+
value: value.text ?? "",
|
|
1167
|
+
disabled,
|
|
1168
|
+
"aria-label": field.label,
|
|
1169
|
+
onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
|
|
1170
|
+
rows: 3,
|
|
1171
|
+
placeholder: field.type === "text" ? field.placeholder : void 0,
|
|
1172
|
+
className: FIELD_INPUT_CLASSES
|
|
1173
|
+
}
|
|
1174
|
+
)
|
|
1175
|
+
] }, field.name);
|
|
1176
|
+
}) }),
|
|
1177
|
+
error && /* @__PURE__ */ jsx5("p", { className: "mt-3 text-xs text-destructive", children: error }),
|
|
1178
|
+
terminalNote && /* @__PURE__ */ jsx5("p", { className: "mt-3 text-xs text-muted-foreground", children: terminalNote }),
|
|
1179
|
+
showSubmitButton && /* @__PURE__ */ jsx5("div", { className: "mt-4 flex items-center justify-end gap-2", children: /* @__PURE__ */ jsx5(InteractionActionButton, { onClick: () => void submit(), disabled: disabled || !answerData, children: submitLabel }) }),
|
|
1180
|
+
answered && /* @__PURE__ */ jsx5("div", { className: "mt-4 flex items-center justify-end", children: /* @__PURE__ */ jsxs4("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
|
|
1181
|
+
/* @__PURE__ */ jsx5(CheckGlyph, { className: "h-3 w-3" }),
|
|
1182
|
+
"Answered"
|
|
1183
|
+
] }) }),
|
|
1184
|
+
lateAnswerSent && /* @__PURE__ */ jsx5("div", { className: "mt-4 flex items-center justify-end", children: /* @__PURE__ */ jsxs4("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
|
|
1185
|
+
/* @__PURE__ */ jsx5(CheckGlyph, { className: "h-3 w-3" }),
|
|
1186
|
+
"Sent as new message"
|
|
1187
|
+
] }) })
|
|
1188
|
+
] });
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
// src/web-react/interaction-plan-card.tsx
|
|
1192
|
+
import { useMemo as useMemo3, useRef as useRef5, useState as useState5 } from "react";
|
|
1193
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1194
|
+
function CheckGlyph2({ className }) {
|
|
1195
|
+
return /* @__PURE__ */ jsx6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx6("path", { d: "M20 6 9 17l-5-5" }) });
|
|
1196
|
+
}
|
|
1197
|
+
function ChevronDownGlyph({ className }) {
|
|
1198
|
+
return /* @__PURE__ */ jsx6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx6("path", { d: "m6 9 6 6 6-6" }) });
|
|
1199
|
+
}
|
|
1200
|
+
var STATUS_LABELS2 = interactionStatusLabels({
|
|
1201
|
+
pending: "Waiting for your approval",
|
|
1202
|
+
answered: "Approved",
|
|
1203
|
+
declined: "Rejected"
|
|
1204
|
+
});
|
|
1205
|
+
var TERMINAL_NOTES2 = interactionTerminalNotes("plan", {
|
|
1206
|
+
declined: "The agent was asked to revise the plan."
|
|
1207
|
+
});
|
|
1208
|
+
var COLLAPSED_MAX_HEIGHT = 320;
|
|
1209
|
+
function InteractionPlanCard({
|
|
1210
|
+
interaction,
|
|
1211
|
+
canWrite,
|
|
1212
|
+
submitAnswer,
|
|
1213
|
+
onResolved,
|
|
1214
|
+
renderMarkdown,
|
|
1215
|
+
className
|
|
1216
|
+
}) {
|
|
1217
|
+
const [values, setValues] = useState5({});
|
|
1218
|
+
const [expanded, setExpanded] = useState5(false);
|
|
1219
|
+
const [submitting, setSubmitting] = useState5(null);
|
|
1220
|
+
const [localStatus, setLocalStatus] = useState5(null);
|
|
1221
|
+
const [error, setError] = useState5(null);
|
|
1222
|
+
const submitInFlightRef = useRef5(false);
|
|
1223
|
+
const status = isTerminalInteractionStatus(interaction.status) ? interaction.status : localStatus ?? interaction.status;
|
|
1224
|
+
const disabled = !canWrite || status !== "pending" || submitting !== null;
|
|
1225
|
+
const approveData = useMemo3(() => buildAnswerData(interaction.fields, values), [interaction.fields, values]);
|
|
1226
|
+
const rejectData = useMemo3(() => {
|
|
1227
|
+
const data = {};
|
|
1228
|
+
for (const field of interaction.fields) {
|
|
1229
|
+
const answer = fieldAnswer(field, values);
|
|
1230
|
+
if (answer !== null) data[field.name] = answer;
|
|
1231
|
+
}
|
|
1232
|
+
return data;
|
|
1233
|
+
}, [interaction.fields, values]);
|
|
1234
|
+
async function submit(outcome) {
|
|
1235
|
+
const data = outcome === "accepted" ? approveData : rejectData;
|
|
1236
|
+
if (submitInFlightRef.current || disabled || data === null) return;
|
|
1237
|
+
submitInFlightRef.current = true;
|
|
1238
|
+
setSubmitting(outcome === "accepted" ? "approve" : "reject");
|
|
1239
|
+
setError(null);
|
|
1240
|
+
try {
|
|
1241
|
+
const result = await submitAnswer({ id: interaction.id, outcome, data });
|
|
1242
|
+
if (result.ok) {
|
|
1243
|
+
const resolved = outcome === "accepted" ? "answered" : "declined";
|
|
1244
|
+
setLocalStatus(resolved);
|
|
1245
|
+
onResolved?.(interaction.id, resolved);
|
|
1246
|
+
return;
|
|
1247
|
+
}
|
|
1248
|
+
if (result.expired) {
|
|
1249
|
+
setLocalStatus("expired");
|
|
1250
|
+
onResolved?.(interaction.id, "expired");
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
setError(result.message);
|
|
1254
|
+
} finally {
|
|
1255
|
+
submitInFlightRef.current = false;
|
|
1256
|
+
setSubmitting(null);
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
const terminalNote = TERMINAL_NOTES2[status];
|
|
1260
|
+
const approved = status === "answered";
|
|
1261
|
+
return /* @__PURE__ */ jsxs5("div", { className: `rounded-xl border border-border bg-card p-4 shadow-sm ${className ?? ""}`, children: [
|
|
1262
|
+
/* @__PURE__ */ jsxs5("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-2", children: [
|
|
1263
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
1264
|
+
/* @__PURE__ */ jsx6(InteractionBadge, { variant: "outline", children: "Plan" }),
|
|
1265
|
+
/* @__PURE__ */ jsx6(InteractionBadge, { variant: approved ? "default" : status === "expired" || status === "declined" ? "destructive" : "outline", children: STATUS_LABELS2[status] })
|
|
1266
|
+
] }),
|
|
1267
|
+
/* @__PURE__ */ jsx6("span", { className: "text-xs text-muted-foreground", children: "The agent proposed a plan" })
|
|
1268
|
+
] }),
|
|
1269
|
+
interaction.title.trim() && /* @__PURE__ */ jsx6("p", { className: "mb-3 text-sm font-medium leading-5 text-foreground", children: interaction.title }),
|
|
1270
|
+
interaction.body && /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
|
|
1271
|
+
/* @__PURE__ */ jsx6(
|
|
1272
|
+
"div",
|
|
1273
|
+
{
|
|
1274
|
+
className: "overflow-hidden text-sm text-foreground",
|
|
1275
|
+
style: expanded ? void 0 : { maxHeight: COLLAPSED_MAX_HEIGHT },
|
|
1276
|
+
children: renderMarkdown ? renderMarkdown(interaction.body) : /* @__PURE__ */ jsx6("p", { className: "whitespace-pre-wrap leading-5", children: interaction.body })
|
|
1277
|
+
}
|
|
1278
|
+
),
|
|
1279
|
+
!expanded && /* @__PURE__ */ jsx6("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-card to-transparent" }),
|
|
1280
|
+
/* @__PURE__ */ jsxs5(
|
|
1281
|
+
"button",
|
|
1282
|
+
{
|
|
1283
|
+
type: "button",
|
|
1284
|
+
onClick: () => setExpanded((prev) => !prev),
|
|
1285
|
+
className: "mt-1 inline-flex items-center gap-1 text-xs text-muted-foreground transition hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1286
|
+
children: [
|
|
1287
|
+
/* @__PURE__ */ jsx6(ChevronDownGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
|
|
1288
|
+
expanded ? "Collapse plan" : "Show full plan"
|
|
1289
|
+
]
|
|
1290
|
+
}
|
|
1291
|
+
)
|
|
1292
|
+
] }),
|
|
1293
|
+
interaction.fields.length > 0 && /* @__PURE__ */ jsx6("div", { className: "mt-3 space-y-4", children: interaction.fields.map((field) => /* @__PURE__ */ jsxs5("fieldset", { className: "space-y-2", children: [
|
|
1294
|
+
/* @__PURE__ */ jsx6("p", { className: "text-sm font-medium leading-5 text-foreground", children: field.label }),
|
|
1295
|
+
fieldAcceptsFreeText(field) ? /* @__PURE__ */ jsx6(
|
|
1296
|
+
"textarea",
|
|
1297
|
+
{
|
|
1298
|
+
value: values[field.name]?.text ?? "",
|
|
1299
|
+
disabled,
|
|
1300
|
+
"aria-label": field.label,
|
|
1301
|
+
onChange: (event) => setValues((prev) => ({ ...prev, [field.name]: { ...prev[field.name], text: event.target.value } })),
|
|
1302
|
+
rows: 2,
|
|
1303
|
+
placeholder: field.type === "text" ? field.placeholder ?? "Optional feedback for the agent" : void 0,
|
|
1304
|
+
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground outline-none focus:border-primary disabled:opacity-50"
|
|
1305
|
+
}
|
|
1306
|
+
) : /* @__PURE__ */ jsx6(
|
|
1307
|
+
"input",
|
|
1308
|
+
{
|
|
1309
|
+
type: "text",
|
|
1310
|
+
value: values[field.name]?.text ?? "",
|
|
1311
|
+
disabled,
|
|
1312
|
+
"aria-label": field.label,
|
|
1313
|
+
onChange: (event) => setValues((prev) => ({ ...prev, [field.name]: { ...prev[field.name], text: event.target.value } })),
|
|
1314
|
+
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground outline-none focus:border-primary disabled:opacity-50"
|
|
1315
|
+
}
|
|
1316
|
+
)
|
|
1317
|
+
] }, field.name)) }),
|
|
1318
|
+
error && /* @__PURE__ */ jsx6("p", { className: "mt-3 text-xs text-destructive", children: error }),
|
|
1319
|
+
terminalNote && /* @__PURE__ */ jsx6("p", { className: "mt-3 text-xs text-muted-foreground", children: terminalNote }),
|
|
1320
|
+
status === "pending" && /* @__PURE__ */ jsxs5("div", { className: "mt-4 flex items-center justify-end gap-2", children: [
|
|
1321
|
+
/* @__PURE__ */ jsx6(InteractionActionButton, { variant: "outline", onClick: () => void submit("declined"), disabled, children: submitting === "reject" ? "Sending\u2026" : "Request changes" }),
|
|
1322
|
+
/* @__PURE__ */ jsx6(InteractionActionButton, { onClick: () => void submit("accepted"), disabled: disabled || approveData === null, children: submitting === "approve" ? "Approving\u2026" : "Approve plan" })
|
|
1323
|
+
] }),
|
|
1324
|
+
approved && /* @__PURE__ */ jsx6("div", { className: "mt-4 flex items-center justify-end", children: /* @__PURE__ */ jsxs5("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
|
|
1325
|
+
/* @__PURE__ */ jsx6(CheckGlyph2, { className: "h-3 w-3" }),
|
|
1326
|
+
"Approved"
|
|
1327
|
+
] }) })
|
|
1328
|
+
] });
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
// src/web-react/use-chat-interactions.ts
|
|
1332
|
+
import { useCallback as useCallback2, useMemo as useMemo4, useState as useState6 } from "react";
|
|
1333
|
+
function hasPendingContentDuplicate(list, interaction) {
|
|
1334
|
+
if (interaction.status !== "pending") return false;
|
|
1335
|
+
const signature = questionInteractionContentSignature(interaction);
|
|
1336
|
+
if (!signature) return false;
|
|
1337
|
+
return list.some((item) => item.id !== interaction.id && item.status === "pending" && questionInteractionContentSignature(item) === signature);
|
|
1338
|
+
}
|
|
1339
|
+
function upsertChatInteraction(list, interaction) {
|
|
1340
|
+
const index = list.findIndex((item) => item.id === interaction.id);
|
|
1341
|
+
if (index === -1) {
|
|
1342
|
+
if (hasPendingContentDuplicate(list, interaction)) return list;
|
|
1343
|
+
return [...list, interaction];
|
|
1344
|
+
}
|
|
1345
|
+
const existing = list[index];
|
|
1346
|
+
if (!existing || isTerminalInteractionStatus(existing.status)) return list;
|
|
1347
|
+
const next = [...list];
|
|
1348
|
+
next[index] = interaction;
|
|
1349
|
+
return next;
|
|
1350
|
+
}
|
|
1351
|
+
function cancelChatInteraction(list, cancel) {
|
|
1352
|
+
const index = list.findIndex((item) => item.id === cancel.id);
|
|
1353
|
+
const existing = list[index];
|
|
1354
|
+
if (!existing || existing.status !== "pending") return list;
|
|
1355
|
+
const next = [...list];
|
|
1356
|
+
next[index] = {
|
|
1357
|
+
...existing,
|
|
1358
|
+
status: cancelStatusFor(cancel.reason),
|
|
1359
|
+
...cancel.reason ? { cancelReason: cancel.reason } : {}
|
|
1360
|
+
};
|
|
1361
|
+
return next;
|
|
1362
|
+
}
|
|
1363
|
+
function resolveChatInteraction(list, id, status) {
|
|
1364
|
+
const index = list.findIndex((item) => item.id === id);
|
|
1365
|
+
const existing = list[index];
|
|
1366
|
+
if (!existing || existing.status !== "pending") return list;
|
|
1367
|
+
const next = [...list];
|
|
1368
|
+
next[index] = { ...existing, status };
|
|
1369
|
+
return next;
|
|
1370
|
+
}
|
|
1371
|
+
function terminalizePendingChatInteractions(list, status) {
|
|
1372
|
+
if (!list.some((item) => item.status === "pending")) return list;
|
|
1373
|
+
return list.map((item) => item.status === "pending" ? { ...item, status } : item);
|
|
1374
|
+
}
|
|
1375
|
+
function restoreChatInteractions(list, outstanding) {
|
|
1376
|
+
const outstandingIds = new Set(outstanding.map((request) => request.id));
|
|
1377
|
+
let next = list.map((item) => item.status === "pending" && !outstandingIds.has(item.id) ? { ...item, status: "answered" } : item);
|
|
1378
|
+
for (const request of outstanding) {
|
|
1379
|
+
next = upsertChatInteraction(next, interactionFromWireRequest(request));
|
|
1380
|
+
}
|
|
1381
|
+
return next;
|
|
1382
|
+
}
|
|
1383
|
+
function useChatInteractions() {
|
|
1384
|
+
const [interactions, setInteractions] = useState6([]);
|
|
1385
|
+
const upsert = useCallback2((interaction) => {
|
|
1386
|
+
setInteractions((prev) => upsertChatInteraction(prev, interaction));
|
|
1387
|
+
}, []);
|
|
1388
|
+
const applyCancel = useCallback2((cancel) => {
|
|
1389
|
+
setInteractions((prev) => cancelChatInteraction(prev, cancel));
|
|
1390
|
+
}, []);
|
|
1391
|
+
const markResolved = useCallback2((id, status) => {
|
|
1392
|
+
setInteractions((prev) => resolveChatInteraction(prev, id, status));
|
|
1393
|
+
}, []);
|
|
1394
|
+
const restore = useCallback2((outstanding) => {
|
|
1395
|
+
setInteractions((prev) => restoreChatInteractions(prev, outstanding));
|
|
1396
|
+
}, []);
|
|
1397
|
+
const terminalizePending = useCallback2((status) => {
|
|
1398
|
+
setInteractions((prev) => terminalizePendingChatInteractions(prev, status));
|
|
1399
|
+
}, []);
|
|
1400
|
+
const reset = useCallback2(() => setInteractions([]), []);
|
|
1401
|
+
const pending = useMemo4(() => interactions.filter((item) => item.status === "pending"), [interactions]);
|
|
1402
|
+
return { interactions, pending, upsert, applyCancel, markResolved, restore, terminalizePending, reset };
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
// src/web-react/mission-activity.tsx
|
|
1406
|
+
import { useCallback as useCallback3, useEffect as useEffect4, useState as useState7 } from "react";
|
|
1407
|
+
import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
920
1408
|
var LIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "running"]);
|
|
921
1409
|
var OK_STATUSES = /* @__PURE__ */ new Set(["completed", "done", "succeeded"]);
|
|
922
1410
|
var ERROR_STATUSES = /* @__PURE__ */ new Set(["failed", "error", "cancelled", "aborted"]);
|
|
@@ -963,20 +1451,20 @@ function waterfallLayout(trace) {
|
|
|
963
1451
|
});
|
|
964
1452
|
}
|
|
965
1453
|
function ChevronGlyph({ className }) {
|
|
966
|
-
return /* @__PURE__ */
|
|
1454
|
+
return /* @__PURE__ */ jsx7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx7("path", { d: "m6 9 6 6 6-6" }) });
|
|
967
1455
|
}
|
|
968
1456
|
function RefreshGlyph({ className }) {
|
|
969
|
-
return /* @__PURE__ */
|
|
1457
|
+
return /* @__PURE__ */ jsx7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx7("path", { d: "M21 12a9 9 0 1 1-2.64-6.36M21 3v6h-6" }) });
|
|
970
1458
|
}
|
|
971
1459
|
function CopyGlyph({ className }) {
|
|
972
|
-
return /* @__PURE__ */
|
|
973
|
-
/* @__PURE__ */
|
|
974
|
-
/* @__PURE__ */
|
|
1460
|
+
return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
1461
|
+
/* @__PURE__ */ jsx7("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
|
|
1462
|
+
/* @__PURE__ */ jsx7("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
975
1463
|
] });
|
|
976
1464
|
}
|
|
977
1465
|
function TraceIdCopy({ traceId }) {
|
|
978
|
-
const [copied, setCopied] =
|
|
979
|
-
const copy =
|
|
1466
|
+
const [copied, setCopied] = useState7(false);
|
|
1467
|
+
const copy = useCallback3(() => {
|
|
980
1468
|
void navigator.clipboard?.writeText(traceId).then(
|
|
981
1469
|
() => {
|
|
982
1470
|
setCopied(true);
|
|
@@ -986,7 +1474,7 @@ function TraceIdCopy({ traceId }) {
|
|
|
986
1474
|
}
|
|
987
1475
|
);
|
|
988
1476
|
}, [traceId]);
|
|
989
|
-
return /* @__PURE__ */
|
|
1477
|
+
return /* @__PURE__ */ jsxs6(
|
|
990
1478
|
"button",
|
|
991
1479
|
{
|
|
992
1480
|
type: "button",
|
|
@@ -995,23 +1483,23 @@ function TraceIdCopy({ traceId }) {
|
|
|
995
1483
|
"aria-label": "Copy trace id",
|
|
996
1484
|
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",
|
|
997
1485
|
children: [
|
|
998
|
-
/* @__PURE__ */
|
|
999
|
-
/* @__PURE__ */
|
|
1000
|
-
copied && /* @__PURE__ */
|
|
1486
|
+
/* @__PURE__ */ jsx7("span", { className: "truncate", children: traceId }),
|
|
1487
|
+
/* @__PURE__ */ jsx7(CopyGlyph, { className: "h-3 w-3 shrink-0" }),
|
|
1488
|
+
copied && /* @__PURE__ */ jsx7("span", { className: "shrink-0 not-italic text-success", children: "copied" })
|
|
1001
1489
|
]
|
|
1002
1490
|
}
|
|
1003
1491
|
);
|
|
1004
1492
|
}
|
|
1005
1493
|
function StatusDot({ tone }) {
|
|
1006
|
-
return /* @__PURE__ */
|
|
1007
|
-
/* @__PURE__ */
|
|
1494
|
+
return /* @__PURE__ */ jsxs6("span", { className: "inline-flex items-center", children: [
|
|
1495
|
+
/* @__PURE__ */ jsx7(
|
|
1008
1496
|
"span",
|
|
1009
1497
|
{
|
|
1010
1498
|
"aria-hidden": true,
|
|
1011
1499
|
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"}`
|
|
1012
1500
|
}
|
|
1013
1501
|
),
|
|
1014
|
-
/* @__PURE__ */
|
|
1502
|
+
/* @__PURE__ */ jsx7("span", { className: "sr-only", children: tone })
|
|
1015
1503
|
] });
|
|
1016
1504
|
}
|
|
1017
1505
|
var BAR_CLASS = {
|
|
@@ -1023,19 +1511,19 @@ function FlowWaterfall({ trace }) {
|
|
|
1023
1511
|
const rows = waterfallLayout(trace);
|
|
1024
1512
|
if (rows.length === 0) return null;
|
|
1025
1513
|
const cost = formatActivityCost(trace.costUsd);
|
|
1026
|
-
return /* @__PURE__ */
|
|
1027
|
-
rows.map((row, i) => /* @__PURE__ */
|
|
1028
|
-
/* @__PURE__ */
|
|
1029
|
-
/* @__PURE__ */
|
|
1514
|
+
return /* @__PURE__ */ jsxs6("div", { className: "space-y-1", children: [
|
|
1515
|
+
rows.map((row, i) => /* @__PURE__ */ jsxs6("div", { className: "grid grid-cols-[minmax(0,2fr)_minmax(0,3fr)_auto] items-center gap-2", children: [
|
|
1516
|
+
/* @__PURE__ */ jsx7("span", { className: "truncate font-mono text-[11px] text-muted-foreground", title: row.name, children: row.name }),
|
|
1517
|
+
/* @__PURE__ */ jsx7("div", { className: "relative h-2 rounded-sm bg-muted/40", children: /* @__PURE__ */ jsx7(
|
|
1030
1518
|
"div",
|
|
1031
1519
|
{
|
|
1032
1520
|
className: `absolute inset-y-0 rounded-sm ${row.ok ? BAR_CLASS[row.kind] : "bg-destructive/80"} ${row.approx ? "opacity-70" : ""}`,
|
|
1033
1521
|
style: { left: `${row.offsetPct}%`, width: `${row.widthPct}%` }
|
|
1034
1522
|
}
|
|
1035
1523
|
) }),
|
|
1036
|
-
/* @__PURE__ */
|
|
1524
|
+
/* @__PURE__ */ jsx7("span", { className: "shrink-0 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: row.durationLabel })
|
|
1037
1525
|
] }, i)),
|
|
1038
|
-
/* @__PURE__ */
|
|
1526
|
+
/* @__PURE__ */ jsxs6("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
|
|
1039
1527
|
(trace.totalMs / 1e3).toFixed(1),
|
|
1040
1528
|
"s",
|
|
1041
1529
|
cost ? ` \xB7 ${cost}` : ""
|
|
@@ -1043,43 +1531,43 @@ function FlowWaterfall({ trace }) {
|
|
|
1043
1531
|
] });
|
|
1044
1532
|
}
|
|
1045
1533
|
function MissionActivityLane({ activity, startedAt, nowMs }) {
|
|
1046
|
-
const [expanded, setExpanded] =
|
|
1534
|
+
const [expanded, setExpanded] = useState7(false);
|
|
1047
1535
|
if (activity.length === 0) return null;
|
|
1048
|
-
return /* @__PURE__ */
|
|
1536
|
+
return /* @__PURE__ */ jsxs6("div", { className: "mt-1 border-l border-border/50 pl-3", children: [
|
|
1049
1537
|
activity.map((run) => {
|
|
1050
1538
|
const tone = activityTone(run.status);
|
|
1051
1539
|
const cost = formatActivityCost(run.costUsd);
|
|
1052
1540
|
const duration = formatActivityDuration(run.durationMs);
|
|
1053
|
-
return /* @__PURE__ */
|
|
1054
|
-
/* @__PURE__ */
|
|
1055
|
-
/* @__PURE__ */
|
|
1056
|
-
/* @__PURE__ */
|
|
1057
|
-
/* @__PURE__ */
|
|
1541
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
|
|
1542
|
+
/* @__PURE__ */ jsx7(StatusDot, { tone }),
|
|
1543
|
+
/* @__PURE__ */ jsxs6("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
1544
|
+
/* @__PURE__ */ jsx7("span", { className: "font-medium", children: run.tool }),
|
|
1545
|
+
/* @__PURE__ */ jsxs6("span", { className: "text-muted-foreground", children: [
|
|
1058
1546
|
" \u2014 ",
|
|
1059
1547
|
run.detail
|
|
1060
1548
|
] })
|
|
1061
1549
|
] }),
|
|
1062
|
-
tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */
|
|
1063
|
-
/* @__PURE__ */
|
|
1064
|
-
tone !== "live" && tone !== "ok" && /* @__PURE__ */
|
|
1065
|
-
cost && /* @__PURE__ */
|
|
1066
|
-
duration && /* @__PURE__ */
|
|
1550
|
+
tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */ jsx7("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 ") }),
|
|
1551
|
+
/* @__PURE__ */ jsxs6("span", { className: "flex shrink-0 items-center gap-1.5 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: [
|
|
1552
|
+
tone !== "live" && tone !== "ok" && /* @__PURE__ */ jsx7("span", { children: run.status }),
|
|
1553
|
+
cost && /* @__PURE__ */ jsx7("span", { children: cost }),
|
|
1554
|
+
duration && /* @__PURE__ */ jsx7("span", { children: duration })
|
|
1067
1555
|
] })
|
|
1068
1556
|
] }, run.taskId);
|
|
1069
1557
|
}),
|
|
1070
|
-
/* @__PURE__ */
|
|
1558
|
+
/* @__PURE__ */ jsxs6(
|
|
1071
1559
|
"button",
|
|
1072
1560
|
{
|
|
1073
1561
|
type: "button",
|
|
1074
1562
|
onClick: () => setExpanded((v) => !v),
|
|
1075
1563
|
className: "flex items-center gap-1 py-0.5 text-[10px] font-medium text-muted-foreground/70 transition hover:text-foreground",
|
|
1076
1564
|
children: [
|
|
1077
|
-
/* @__PURE__ */
|
|
1565
|
+
/* @__PURE__ */ jsx7(ChevronGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
|
|
1078
1566
|
"timeline"
|
|
1079
1567
|
]
|
|
1080
1568
|
}
|
|
1081
1569
|
),
|
|
1082
|
-
expanded && /* @__PURE__ */
|
|
1570
|
+
expanded && /* @__PURE__ */ jsx7("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx7(
|
|
1083
1571
|
FlowWaterfall,
|
|
1084
1572
|
{
|
|
1085
1573
|
trace: stepActivityFlowTrace(activity, {
|
|
@@ -1094,45 +1582,45 @@ function ActivityRow({
|
|
|
1094
1582
|
record,
|
|
1095
1583
|
renderMissionRef
|
|
1096
1584
|
}) {
|
|
1097
|
-
const [open, setOpen] =
|
|
1585
|
+
const [open, setOpen] = useState7(false);
|
|
1098
1586
|
const tone = activityTone(record.status);
|
|
1099
1587
|
const cost = formatActivityCost(record.costUsd);
|
|
1100
1588
|
const duration = formatActivityDuration(record.durationMs);
|
|
1101
|
-
return /* @__PURE__ */
|
|
1102
|
-
/* @__PURE__ */
|
|
1103
|
-
/* @__PURE__ */
|
|
1104
|
-
/* @__PURE__ */
|
|
1105
|
-
/* @__PURE__ */
|
|
1106
|
-
/* @__PURE__ */
|
|
1589
|
+
return /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-border/60 bg-card", children: [
|
|
1590
|
+
/* @__PURE__ */ jsxs6("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: [
|
|
1591
|
+
/* @__PURE__ */ jsx7(StatusDot, { tone }),
|
|
1592
|
+
/* @__PURE__ */ jsxs6("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
1593
|
+
/* @__PURE__ */ jsx7("span", { className: "font-medium", children: record.tool }),
|
|
1594
|
+
/* @__PURE__ */ jsxs6("span", { className: "text-muted-foreground", children: [
|
|
1107
1595
|
" \u2014 ",
|
|
1108
1596
|
record.detail
|
|
1109
1597
|
] })
|
|
1110
1598
|
] }),
|
|
1111
|
-
tone === "live" && (record.iteration !== void 0 || record.phase !== void 0) && /* @__PURE__ */
|
|
1112
|
-
/* @__PURE__ */
|
|
1599
|
+
tone === "live" && (record.iteration !== void 0 || record.phase !== void 0) && /* @__PURE__ */ jsx7("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 ") }),
|
|
1600
|
+
/* @__PURE__ */ jsx7(
|
|
1113
1601
|
"span",
|
|
1114
1602
|
{
|
|
1115
1603
|
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"}`,
|
|
1116
1604
|
children: record.status
|
|
1117
1605
|
}
|
|
1118
1606
|
),
|
|
1119
|
-
cost && /* @__PURE__ */
|
|
1120
|
-
/* @__PURE__ */
|
|
1607
|
+
cost && /* @__PURE__ */ jsx7("span", { className: "shrink-0 font-mono text-[11px] tabular-nums text-muted-foreground", children: cost }),
|
|
1608
|
+
/* @__PURE__ */ jsx7(ChevronGlyph, { className: `h-3 w-3 shrink-0 text-muted-foreground transition-transform ${open ? "rotate-180" : ""}` })
|
|
1121
1609
|
] }),
|
|
1122
|
-
open && /* @__PURE__ */
|
|
1123
|
-
record.durationMs !== void 0 && /* @__PURE__ */
|
|
1124
|
-
/* @__PURE__ */
|
|
1125
|
-
/* @__PURE__ */
|
|
1126
|
-
/* @__PURE__ */
|
|
1127
|
-
/* @__PURE__ */
|
|
1128
|
-
/* @__PURE__ */
|
|
1129
|
-
duration && /* @__PURE__ */
|
|
1130
|
-
/* @__PURE__ */
|
|
1131
|
-
/* @__PURE__ */
|
|
1610
|
+
open && /* @__PURE__ */ jsxs6("div", { className: "space-y-2.5 border-t border-border/40 px-3 py-2.5", children: [
|
|
1611
|
+
record.durationMs !== void 0 && /* @__PURE__ */ jsx7("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx7(FlowWaterfall, { trace: stepActivityFlowTrace([record]) }) }),
|
|
1612
|
+
/* @__PURE__ */ jsxs6("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 font-mono text-[11px]", children: [
|
|
1613
|
+
/* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground/60", children: "task" }),
|
|
1614
|
+
/* @__PURE__ */ jsx7("dd", { className: "truncate text-muted-foreground", children: record.taskId }),
|
|
1615
|
+
/* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground/60", children: "started" }),
|
|
1616
|
+
/* @__PURE__ */ jsx7("dd", { className: "text-muted-foreground", children: new Date(record.startedAt).toLocaleString() }),
|
|
1617
|
+
duration && /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1618
|
+
/* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground/60", children: "duration" }),
|
|
1619
|
+
/* @__PURE__ */ jsx7("dd", { className: "text-muted-foreground", children: duration })
|
|
1132
1620
|
] }),
|
|
1133
|
-
record.traceId && /* @__PURE__ */
|
|
1134
|
-
/* @__PURE__ */
|
|
1135
|
-
/* @__PURE__ */
|
|
1621
|
+
record.traceId && /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1622
|
+
/* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground/60", children: "trace" }),
|
|
1623
|
+
/* @__PURE__ */ jsx7("dd", { className: "min-w-0", children: /* @__PURE__ */ jsx7(TraceIdCopy, { traceId: record.traceId }) })
|
|
1136
1624
|
] })
|
|
1137
1625
|
] }),
|
|
1138
1626
|
record.missionRef && renderMissionRef?.(record.missionRef, record)
|
|
@@ -1140,11 +1628,11 @@ function ActivityRow({
|
|
|
1140
1628
|
] });
|
|
1141
1629
|
}
|
|
1142
1630
|
function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent activity", emptyLabel = "No agent runs yet." }) {
|
|
1143
|
-
const [rows, setRows] =
|
|
1144
|
-
const [cursor, setCursor] =
|
|
1145
|
-
const [loading, setLoading] =
|
|
1146
|
-
const [error, setError] =
|
|
1147
|
-
const load =
|
|
1631
|
+
const [rows, setRows] = useState7([]);
|
|
1632
|
+
const [cursor, setCursor] = useState7(void 0);
|
|
1633
|
+
const [loading, setLoading] = useState7(false);
|
|
1634
|
+
const [error, setError] = useState7(null);
|
|
1635
|
+
const load = useCallback3(
|
|
1148
1636
|
async (from) => {
|
|
1149
1637
|
setLoading(true);
|
|
1150
1638
|
setError(null);
|
|
@@ -1163,10 +1651,10 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
|
|
|
1163
1651
|
useEffect4(() => {
|
|
1164
1652
|
void load();
|
|
1165
1653
|
}, [load]);
|
|
1166
|
-
return /* @__PURE__ */
|
|
1167
|
-
/* @__PURE__ */
|
|
1168
|
-
/* @__PURE__ */
|
|
1169
|
-
/* @__PURE__ */
|
|
1654
|
+
return /* @__PURE__ */ jsxs6("div", { className: "space-y-2", children: [
|
|
1655
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
1656
|
+
/* @__PURE__ */ jsx7("h2", { className: "flex-1 text-sm font-semibold", children: title }),
|
|
1657
|
+
/* @__PURE__ */ jsx7(
|
|
1170
1658
|
"button",
|
|
1171
1659
|
{
|
|
1172
1660
|
type: "button",
|
|
@@ -1174,14 +1662,14 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
|
|
|
1174
1662
|
disabled: loading,
|
|
1175
1663
|
"aria-label": "Refresh",
|
|
1176
1664
|
className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground disabled:opacity-50",
|
|
1177
|
-
children: /* @__PURE__ */
|
|
1665
|
+
children: /* @__PURE__ */ jsx7(RefreshGlyph, { className: `h-3.5 w-3.5 ${loading ? "animate-spin" : ""}` })
|
|
1178
1666
|
}
|
|
1179
1667
|
)
|
|
1180
1668
|
] }),
|
|
1181
|
-
error && /* @__PURE__ */
|
|
1182
|
-
!error && rows.length === 0 && !loading && /* @__PURE__ */
|
|
1183
|
-
/* @__PURE__ */
|
|
1184
|
-
cursor && /* @__PURE__ */
|
|
1669
|
+
error && /* @__PURE__ */ jsx7("p", { role: "alert", className: "rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: error }),
|
|
1670
|
+
!error && rows.length === 0 && !loading && /* @__PURE__ */ jsx7("p", { className: "px-1 text-sm text-muted-foreground", children: emptyLabel }),
|
|
1671
|
+
/* @__PURE__ */ jsx7("div", { className: "space-y-1.5", children: rows.map((record) => /* @__PURE__ */ jsx7(ActivityRow, { record, renderMissionRef }, record.taskId)) }),
|
|
1672
|
+
cursor && /* @__PURE__ */ jsx7(
|
|
1185
1673
|
"button",
|
|
1186
1674
|
{
|
|
1187
1675
|
type: "button",
|
|
@@ -1195,9 +1683,9 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
|
|
|
1195
1683
|
}
|
|
1196
1684
|
|
|
1197
1685
|
// src/web-react/seat-paywall.tsx
|
|
1198
|
-
import { jsx as
|
|
1199
|
-
function
|
|
1200
|
-
return /* @__PURE__ */
|
|
1686
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1687
|
+
function CheckGlyph3() {
|
|
1688
|
+
return /* @__PURE__ */ jsx8(
|
|
1201
1689
|
"svg",
|
|
1202
1690
|
{
|
|
1203
1691
|
className: "h-4 w-4 shrink-0 text-primary",
|
|
@@ -1208,14 +1696,14 @@ function CheckGlyph() {
|
|
|
1208
1696
|
strokeLinecap: "round",
|
|
1209
1697
|
strokeLinejoin: "round",
|
|
1210
1698
|
"aria-hidden": true,
|
|
1211
|
-
children: /* @__PURE__ */
|
|
1699
|
+
children: /* @__PURE__ */ jsx8("path", { d: "M20 6 9 17l-5-5" })
|
|
1212
1700
|
}
|
|
1213
1701
|
);
|
|
1214
1702
|
}
|
|
1215
1703
|
function Benefit({ children }) {
|
|
1216
|
-
return /* @__PURE__ */
|
|
1217
|
-
/* @__PURE__ */
|
|
1218
|
-
/* @__PURE__ */
|
|
1704
|
+
return /* @__PURE__ */ jsxs7("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
|
|
1705
|
+
/* @__PURE__ */ jsx8("span", { className: "mt-0.5", children: /* @__PURE__ */ jsx8(CheckGlyph3, {}) }),
|
|
1706
|
+
/* @__PURE__ */ jsx8("span", { children })
|
|
1219
1707
|
] });
|
|
1220
1708
|
}
|
|
1221
1709
|
function SeatPaywall({
|
|
@@ -1229,30 +1717,30 @@ function SeatPaywall({
|
|
|
1229
1717
|
footnote
|
|
1230
1718
|
}) {
|
|
1231
1719
|
const { pending, run } = usePending();
|
|
1232
|
-
return /* @__PURE__ */
|
|
1233
|
-
/* @__PURE__ */
|
|
1234
|
-
/* @__PURE__ */
|
|
1720
|
+
return /* @__PURE__ */ jsx8("div", { className: "flex min-h-[60vh] w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxs7("div", { className: "w-full max-w-md rounded-2xl border border-border bg-card p-8 shadow-sm", children: [
|
|
1721
|
+
/* @__PURE__ */ jsx8("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: product }),
|
|
1722
|
+
/* @__PURE__ */ jsxs7("h1", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: [
|
|
1235
1723
|
"Unlock ",
|
|
1236
1724
|
product
|
|
1237
1725
|
] }),
|
|
1238
|
-
tagline && /* @__PURE__ */
|
|
1239
|
-
/* @__PURE__ */
|
|
1240
|
-
/* @__PURE__ */
|
|
1726
|
+
tagline && /* @__PURE__ */ jsx8("p", { className: "mt-2 text-sm text-muted-foreground", children: tagline }),
|
|
1727
|
+
/* @__PURE__ */ jsxs7("div", { className: "mt-6 flex items-baseline gap-1.5", children: [
|
|
1728
|
+
/* @__PURE__ */ jsxs7("span", { className: "text-3xl font-semibold text-foreground", children: [
|
|
1241
1729
|
"$",
|
|
1242
1730
|
priceUsd
|
|
1243
1731
|
] }),
|
|
1244
|
-
/* @__PURE__ */
|
|
1732
|
+
/* @__PURE__ */ jsx8("span", { className: "text-sm text-muted-foreground", children: "/mo" })
|
|
1245
1733
|
] }),
|
|
1246
|
-
/* @__PURE__ */
|
|
1734
|
+
/* @__PURE__ */ jsxs7("p", { className: "mt-1 text-sm text-muted-foreground", children: [
|
|
1247
1735
|
"Includes $",
|
|
1248
1736
|
includedUsageUsd,
|
|
1249
1737
|
"/mo of AI usage"
|
|
1250
1738
|
] }),
|
|
1251
|
-
/* @__PURE__ */
|
|
1739
|
+
/* @__PURE__ */ jsx8("ul", { className: "mt-6 space-y-2.5", children: (benefits ?? [
|
|
1252
1740
|
`Full access to ${product}`,
|
|
1253
1741
|
`$${includedUsageUsd}/mo of AI usage included, every month`
|
|
1254
|
-
]).map((benefit, i) => /* @__PURE__ */
|
|
1255
|
-
/* @__PURE__ */
|
|
1742
|
+
]).map((benefit, i) => /* @__PURE__ */ jsx8(Benefit, { children: benefit }, i)) }),
|
|
1743
|
+
/* @__PURE__ */ jsx8(
|
|
1256
1744
|
"button",
|
|
1257
1745
|
{
|
|
1258
1746
|
type: "button",
|
|
@@ -1262,13 +1750,13 @@ function SeatPaywall({
|
|
|
1262
1750
|
children: pending ? "Opening checkout\u2026" : ctaLabel ?? `Unlock ${product}`
|
|
1263
1751
|
}
|
|
1264
1752
|
),
|
|
1265
|
-
footnote && /* @__PURE__ */
|
|
1753
|
+
footnote && /* @__PURE__ */ jsx8("p", { className: "mt-3 text-center text-xs text-muted-foreground/70", children: footnote })
|
|
1266
1754
|
] }) });
|
|
1267
1755
|
}
|
|
1268
1756
|
|
|
1269
1757
|
// src/web-react/agent-session-controls.tsx
|
|
1270
|
-
import { useMemo as
|
|
1271
|
-
import { jsx as
|
|
1758
|
+
import { useMemo as useMemo5, useState as useState8 } from "react";
|
|
1759
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1272
1760
|
var HARNESS_LABELS = {
|
|
1273
1761
|
opencode: "OpenCode (any model)",
|
|
1274
1762
|
"claude-code": "Claude Code (Anthropic)",
|
|
@@ -1288,12 +1776,12 @@ function harnessLabel(h) {
|
|
|
1288
1776
|
return HARNESS_LABELS[h] ?? h;
|
|
1289
1777
|
}
|
|
1290
1778
|
function ChevronDown2({ className }) {
|
|
1291
|
-
return /* @__PURE__ */
|
|
1779
|
+
return /* @__PURE__ */ jsx9("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx9("path", { d: "m6 9 6 6 6-6" }) });
|
|
1292
1780
|
}
|
|
1293
1781
|
function GearGlyph({ className }) {
|
|
1294
|
-
return /* @__PURE__ */
|
|
1295
|
-
/* @__PURE__ */
|
|
1296
|
-
/* @__PURE__ */
|
|
1782
|
+
return /* @__PURE__ */ jsxs8("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
1783
|
+
/* @__PURE__ */ jsx9("circle", { cx: "12", cy: "12", r: "3" }),
|
|
1784
|
+
/* @__PURE__ */ jsx9("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" })
|
|
1297
1785
|
] });
|
|
1298
1786
|
}
|
|
1299
1787
|
var FOCUS_RING = "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background";
|
|
@@ -1302,11 +1790,11 @@ function HarnessPicker({
|
|
|
1302
1790
|
onChange,
|
|
1303
1791
|
available
|
|
1304
1792
|
}) {
|
|
1305
|
-
const [open, setOpen] =
|
|
1793
|
+
const [open, setOpen] = useState8(false);
|
|
1306
1794
|
const { containerRef, triggerProps } = usePopover(open, setOpen);
|
|
1307
1795
|
const options = available ?? Object.keys(HARNESS_LABELS);
|
|
1308
|
-
return /* @__PURE__ */
|
|
1309
|
-
/* @__PURE__ */
|
|
1796
|
+
return /* @__PURE__ */ jsxs8("div", { ref: containerRef, className: "relative inline-flex", children: [
|
|
1797
|
+
/* @__PURE__ */ jsxs8(
|
|
1310
1798
|
"button",
|
|
1311
1799
|
{
|
|
1312
1800
|
type: "button",
|
|
@@ -1315,12 +1803,12 @@ function HarnessPicker({
|
|
|
1315
1803
|
title: "Agent backend",
|
|
1316
1804
|
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}`,
|
|
1317
1805
|
children: [
|
|
1318
|
-
/* @__PURE__ */
|
|
1319
|
-
/* @__PURE__ */
|
|
1806
|
+
/* @__PURE__ */ jsx9("span", { className: "truncate", children: harnessLabel(value) }),
|
|
1807
|
+
/* @__PURE__ */ jsx9(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
1320
1808
|
]
|
|
1321
1809
|
}
|
|
1322
1810
|
),
|
|
1323
|
-
open && /* @__PURE__ */
|
|
1811
|
+
open && /* @__PURE__ */ jsx9("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__ */ jsx9(
|
|
1324
1812
|
"button",
|
|
1325
1813
|
{
|
|
1326
1814
|
type: "button",
|
|
@@ -1339,7 +1827,7 @@ function HarnessPicker({
|
|
|
1339
1827
|
}
|
|
1340
1828
|
function useCoherentHandlers(props) {
|
|
1341
1829
|
const { model, models, harness, onModelChange, onHarnessChange } = props;
|
|
1342
|
-
const canonicalIds =
|
|
1830
|
+
const canonicalIds = useMemo5(() => models.map((m) => m.id), [models]);
|
|
1343
1831
|
const onModel = (next) => {
|
|
1344
1832
|
onModelChange(next);
|
|
1345
1833
|
const nextHarness = snapHarnessToModel(harness, next);
|
|
@@ -1367,11 +1855,11 @@ function AgentSessionControls(props) {
|
|
|
1367
1855
|
className
|
|
1368
1856
|
} = props;
|
|
1369
1857
|
const { onModel, onHarness } = useCoherentHandlers(props);
|
|
1370
|
-
const [open, setOpen] =
|
|
1858
|
+
const [open, setOpen] = useState8(false);
|
|
1371
1859
|
const { containerRef: popoverRef, triggerProps } = usePopover(open, setOpen);
|
|
1372
1860
|
const selectedModel = models.find((m) => m.id === model);
|
|
1373
1861
|
const showEffort = selectedModel?.supportsReasoning ?? true;
|
|
1374
|
-
const modelPicker = /* @__PURE__ */
|
|
1862
|
+
const modelPicker = /* @__PURE__ */ jsx9(
|
|
1375
1863
|
ModelPicker,
|
|
1376
1864
|
{
|
|
1377
1865
|
value: model,
|
|
@@ -1382,17 +1870,17 @@ function AgentSessionControls(props) {
|
|
|
1382
1870
|
}
|
|
1383
1871
|
);
|
|
1384
1872
|
if (layout === "inline") {
|
|
1385
|
-
return /* @__PURE__ */
|
|
1873
|
+
return /* @__PURE__ */ jsxs8("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
|
|
1386
1874
|
modelPicker,
|
|
1387
|
-
showHarness && /* @__PURE__ */
|
|
1388
|
-
showEffort && /* @__PURE__ */
|
|
1875
|
+
showHarness && /* @__PURE__ */ jsx9(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
|
|
1876
|
+
showEffort && /* @__PURE__ */ jsx9(EffortPicker, { value: effort, onChange: onEffortChange })
|
|
1389
1877
|
] });
|
|
1390
1878
|
}
|
|
1391
1879
|
const hasAdvanced = showHarness || showEffort;
|
|
1392
|
-
return /* @__PURE__ */
|
|
1880
|
+
return /* @__PURE__ */ jsxs8("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
|
|
1393
1881
|
modelPicker,
|
|
1394
|
-
hasAdvanced && /* @__PURE__ */
|
|
1395
|
-
/* @__PURE__ */
|
|
1882
|
+
hasAdvanced && /* @__PURE__ */ jsxs8("div", { ref: popoverRef, className: "relative inline-flex", children: [
|
|
1883
|
+
/* @__PURE__ */ jsx9(
|
|
1396
1884
|
"button",
|
|
1397
1885
|
{
|
|
1398
1886
|
type: "button",
|
|
@@ -1401,19 +1889,19 @@ function AgentSessionControls(props) {
|
|
|
1401
1889
|
title: "Model settings \u2014 pick the agent backend and how hard it thinks",
|
|
1402
1890
|
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}`,
|
|
1403
1891
|
"data-state": open ? "open" : "closed",
|
|
1404
|
-
children: /* @__PURE__ */
|
|
1892
|
+
children: /* @__PURE__ */ jsx9(GearGlyph, { className: "h-4 w-4" })
|
|
1405
1893
|
}
|
|
1406
1894
|
),
|
|
1407
|
-
open && /* @__PURE__ */
|
|
1408
|
-
showHarness && /* @__PURE__ */
|
|
1409
|
-
/* @__PURE__ */
|
|
1410
|
-
/* @__PURE__ */
|
|
1411
|
-
/* @__PURE__ */
|
|
1895
|
+
open && /* @__PURE__ */ jsxs8("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: [
|
|
1896
|
+
showHarness && /* @__PURE__ */ jsxs8("div", { className: "space-y-1.5", children: [
|
|
1897
|
+
/* @__PURE__ */ jsx9("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
|
|
1898
|
+
/* @__PURE__ */ jsx9(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
|
|
1899
|
+
/* @__PURE__ */ jsx9("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "The engine that runs the agent. Switching it keeps your model choice compatible." })
|
|
1412
1900
|
] }),
|
|
1413
|
-
showEffort && /* @__PURE__ */
|
|
1414
|
-
/* @__PURE__ */
|
|
1415
|
-
/* @__PURE__ */
|
|
1416
|
-
/* @__PURE__ */
|
|
1901
|
+
showEffort && /* @__PURE__ */ jsxs8("div", { className: "space-y-1.5", children: [
|
|
1902
|
+
/* @__PURE__ */ jsx9("p", { className: "text-xs font-medium text-foreground", children: "Thinking" }),
|
|
1903
|
+
/* @__PURE__ */ jsx9(EffortPicker, { value: effort, onChange: onEffortChange, label: "" }),
|
|
1904
|
+
/* @__PURE__ */ jsx9("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "How hard the agent thinks before answering. Higher is slower but more thorough." })
|
|
1417
1905
|
] })
|
|
1418
1906
|
] })
|
|
1419
1907
|
] })
|
|
@@ -1421,7 +1909,7 @@ function AgentSessionControls(props) {
|
|
|
1421
1909
|
}
|
|
1422
1910
|
|
|
1423
1911
|
// src/web-react/index.tsx
|
|
1424
|
-
import { Fragment as
|
|
1912
|
+
import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1425
1913
|
function formatModelCost(msg, models) {
|
|
1426
1914
|
if (msg.promptTokens == null && msg.completionTokens == null) return null;
|
|
1427
1915
|
const pricing = models.find((m) => m.id === msg.modelUsed)?.pricing;
|
|
@@ -1435,41 +1923,41 @@ function formatTokensPerSecond(msg) {
|
|
|
1435
1923
|
return `${Math.round(msg.completionTokens / (msg.durationMs / 1e3))} tok/s`;
|
|
1436
1924
|
}
|
|
1437
1925
|
function RunDrillIn({ run, onClose }) {
|
|
1438
|
-
return /* @__PURE__ */
|
|
1439
|
-
/* @__PURE__ */
|
|
1440
|
-
/* @__PURE__ */
|
|
1926
|
+
return /* @__PURE__ */ jsxs9("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: [
|
|
1927
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
|
|
1928
|
+
/* @__PURE__ */ jsx10(
|
|
1441
1929
|
"span",
|
|
1442
1930
|
{
|
|
1443
1931
|
className: `h-2 w-2 shrink-0 rounded-full ${run.status === "running" ? "bg-warning" : run.status === "error" ? "bg-destructive" : "bg-success"}`
|
|
1444
1932
|
}
|
|
1445
1933
|
),
|
|
1446
|
-
/* @__PURE__ */
|
|
1447
|
-
/* @__PURE__ */
|
|
1448
|
-
/* @__PURE__ */
|
|
1934
|
+
/* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
|
|
1935
|
+
/* @__PURE__ */ jsx10("p", { className: "truncate text-sm font-semibold", children: run.title }),
|
|
1936
|
+
/* @__PURE__ */ jsx10("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
|
|
1449
1937
|
] }),
|
|
1450
|
-
/* @__PURE__ */
|
|
1938
|
+
/* @__PURE__ */ jsx10(
|
|
1451
1939
|
"button",
|
|
1452
1940
|
{
|
|
1453
1941
|
type: "button",
|
|
1454
1942
|
onClick: onClose,
|
|
1455
1943
|
"aria-label": "Close",
|
|
1456
1944
|
className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground",
|
|
1457
|
-
children: /* @__PURE__ */
|
|
1945
|
+
children: /* @__PURE__ */ jsx10("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx10("path", { d: "M18 6 6 18M6 6l12 12" }) })
|
|
1458
1946
|
}
|
|
1459
1947
|
)
|
|
1460
1948
|
] }),
|
|
1461
|
-
/* @__PURE__ */
|
|
1462
|
-
run.steps.length === 0 && /* @__PURE__ */
|
|
1463
|
-
run.steps.map((step, i) => /* @__PURE__ */
|
|
1464
|
-
/* @__PURE__ */
|
|
1465
|
-
/* @__PURE__ */
|
|
1466
|
-
/* @__PURE__ */
|
|
1467
|
-
/* @__PURE__ */
|
|
1949
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
|
|
1950
|
+
run.steps.length === 0 && /* @__PURE__ */ jsx10("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
|
|
1951
|
+
run.steps.map((step, i) => /* @__PURE__ */ jsxs9("div", { className: "rounded-lg border border-border/60 bg-background", children: [
|
|
1952
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
|
|
1953
|
+
/* @__PURE__ */ jsx10("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
|
|
1954
|
+
/* @__PURE__ */ jsx10("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
|
|
1955
|
+
/* @__PURE__ */ jsx10("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
|
|
1468
1956
|
] }),
|
|
1469
|
-
step.detail && /* @__PURE__ */
|
|
1957
|
+
step.detail && /* @__PURE__ */ jsx10("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 })
|
|
1470
1958
|
] }, i))
|
|
1471
1959
|
] }),
|
|
1472
|
-
/* @__PURE__ */
|
|
1960
|
+
/* @__PURE__ */ jsx10("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." })
|
|
1473
1961
|
] });
|
|
1474
1962
|
}
|
|
1475
1963
|
function pendingApprovalOf(call) {
|
|
@@ -1483,20 +1971,20 @@ function ChatEmptyState({
|
|
|
1483
1971
|
subline = "Describe the outcome you want. The agent works through it step by step, and pauses for your approval before anything irreversible.",
|
|
1484
1972
|
doors
|
|
1485
1973
|
}) {
|
|
1486
|
-
return /* @__PURE__ */
|
|
1487
|
-
/* @__PURE__ */
|
|
1488
|
-
/* @__PURE__ */
|
|
1489
|
-
/* @__PURE__ */
|
|
1490
|
-
subline && /* @__PURE__ */
|
|
1491
|
-
doors && doors.length > 0 && /* @__PURE__ */
|
|
1974
|
+
return /* @__PURE__ */ jsxs9("div", { className: "mx-auto flex w-full max-w-2xl flex-col items-center px-6 py-12 text-center sm:py-20", children: [
|
|
1975
|
+
/* @__PURE__ */ jsx10("span", { className: "mb-5 inline-flex h-14 w-14 items-center justify-center rounded-2xl bg-primary/10 ring-1 ring-primary/15", children: /* @__PURE__ */ jsx10(BrandMark, { size: 32, className: "shrink-0" }) }),
|
|
1976
|
+
/* @__PURE__ */ jsx10("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: productName }),
|
|
1977
|
+
/* @__PURE__ */ jsx10("h2", { className: "mt-1.5 text-balance text-2xl font-semibold leading-tight text-foreground sm:text-[28px]", children: headline }),
|
|
1978
|
+
subline && /* @__PURE__ */ jsx10("p", { className: "mt-3 max-w-md text-[15px] leading-relaxed text-muted-foreground", children: subline }),
|
|
1979
|
+
doors && doors.length > 0 && /* @__PURE__ */ jsx10("div", { className: "mt-7 grid w-full gap-2.5 sm:grid-cols-3", children: doors.slice(0, 3).map((door, i) => /* @__PURE__ */ jsxs9(
|
|
1492
1980
|
"button",
|
|
1493
1981
|
{
|
|
1494
1982
|
type: "button",
|
|
1495
1983
|
onClick: door.onSelect,
|
|
1496
1984
|
className: "group flex min-h-[44px] flex-col items-start rounded-xl border border-border bg-card px-4 py-3 text-left transition hover:border-primary/40 hover:bg-accent/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
1497
1985
|
children: [
|
|
1498
|
-
/* @__PURE__ */
|
|
1499
|
-
door.description && /* @__PURE__ */
|
|
1986
|
+
/* @__PURE__ */ jsx10("span", { className: "text-sm font-semibold text-foreground", children: door.label }),
|
|
1987
|
+
door.description && /* @__PURE__ */ jsx10("span", { className: "mt-0.5 text-[12px] leading-snug text-muted-foreground", children: door.description })
|
|
1500
1988
|
]
|
|
1501
1989
|
},
|
|
1502
1990
|
i
|
|
@@ -1505,26 +1993,26 @@ function ChatEmptyState({
|
|
|
1505
1993
|
}
|
|
1506
1994
|
function ToolGlyph({ name, className }) {
|
|
1507
1995
|
if (name.startsWith("sandbox_")) {
|
|
1508
|
-
return /* @__PURE__ */
|
|
1509
|
-
/* @__PURE__ */
|
|
1510
|
-
/* @__PURE__ */
|
|
1996
|
+
return /* @__PURE__ */ jsxs9("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
1997
|
+
/* @__PURE__ */ jsx10("polyline", { points: "4 17 10 11 4 5" }),
|
|
1998
|
+
/* @__PURE__ */ jsx10("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
|
|
1511
1999
|
] });
|
|
1512
2000
|
}
|
|
1513
2001
|
if (name === "submit_proposal") {
|
|
1514
|
-
return /* @__PURE__ */
|
|
1515
|
-
/* @__PURE__ */
|
|
1516
|
-
/* @__PURE__ */
|
|
2002
|
+
return /* @__PURE__ */ jsxs9("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
2003
|
+
/* @__PURE__ */ jsx10("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
2004
|
+
/* @__PURE__ */ jsx10("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
|
|
1517
2005
|
] });
|
|
1518
2006
|
}
|
|
1519
2007
|
if (name === "schedule_followup") {
|
|
1520
|
-
return /* @__PURE__ */
|
|
1521
|
-
/* @__PURE__ */
|
|
1522
|
-
/* @__PURE__ */
|
|
2008
|
+
return /* @__PURE__ */ jsxs9("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
|
|
2009
|
+
/* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "9" }),
|
|
2010
|
+
/* @__PURE__ */ jsx10("path", { d: "M12 7v5l3 3" })
|
|
1523
2011
|
] });
|
|
1524
2012
|
}
|
|
1525
|
-
return /* @__PURE__ */
|
|
1526
|
-
/* @__PURE__ */
|
|
1527
|
-
/* @__PURE__ */
|
|
2013
|
+
return /* @__PURE__ */ jsxs9("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
2014
|
+
/* @__PURE__ */ jsx10("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
|
|
2015
|
+
/* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "4" })
|
|
1528
2016
|
] });
|
|
1529
2017
|
}
|
|
1530
2018
|
function toolOutcomeOf(call) {
|
|
@@ -1591,36 +2079,36 @@ function truncate(v, max = 240) {
|
|
|
1591
2079
|
function KvRows({ data }) {
|
|
1592
2080
|
const entries = Object.entries(data).filter(([, v]) => v !== void 0 && v !== null && v !== "");
|
|
1593
2081
|
if (!entries.length) return null;
|
|
1594
|
-
return /* @__PURE__ */
|
|
1595
|
-
/* @__PURE__ */
|
|
1596
|
-
/* @__PURE__ */
|
|
2082
|
+
return /* @__PURE__ */ jsx10("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs9("div", { className: "contents", children: [
|
|
2083
|
+
/* @__PURE__ */ jsx10("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
|
|
2084
|
+
/* @__PURE__ */ jsx10("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
|
|
1597
2085
|
] }, k)) });
|
|
1598
2086
|
}
|
|
1599
2087
|
function ShellDetail({ call }) {
|
|
1600
2088
|
const outcome = toolOutcomeOf(call);
|
|
1601
2089
|
const r = outcome?.result ?? {};
|
|
1602
|
-
return /* @__PURE__ */
|
|
1603
|
-
/* @__PURE__ */
|
|
1604
|
-
/* @__PURE__ */
|
|
1605
|
-
/* @__PURE__ */
|
|
1606
|
-
r.exitCode != null && /* @__PURE__ */
|
|
2090
|
+
return /* @__PURE__ */ jsxs9("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
|
|
2091
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
|
|
2092
|
+
/* @__PURE__ */ jsx10("span", { className: "select-none text-zinc-500", children: "$" }),
|
|
2093
|
+
/* @__PURE__ */ jsx10("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
|
|
2094
|
+
r.exitCode != null && /* @__PURE__ */ jsxs9("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
|
|
1607
2095
|
"exit ",
|
|
1608
2096
|
r.exitCode
|
|
1609
2097
|
] })
|
|
1610
2098
|
] }),
|
|
1611
|
-
/* @__PURE__ */
|
|
2099
|
+
/* @__PURE__ */ jsx10("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)" })
|
|
1612
2100
|
] });
|
|
1613
2101
|
}
|
|
1614
2102
|
function DefaultToolDetail({ call }) {
|
|
1615
2103
|
const outcome = toolOutcomeOf(call);
|
|
1616
|
-
return /* @__PURE__ */
|
|
1617
|
-
call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */
|
|
1618
|
-
/* @__PURE__ */
|
|
1619
|
-
/* @__PURE__ */
|
|
2104
|
+
return /* @__PURE__ */ jsxs9("div", { className: "space-y-2", children: [
|
|
2105
|
+
call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs9("div", { children: [
|
|
2106
|
+
/* @__PURE__ */ jsx10("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
|
|
2107
|
+
/* @__PURE__ */ jsx10(KvRows, { data: call.args })
|
|
1620
2108
|
] }),
|
|
1621
|
-
outcome && /* @__PURE__ */
|
|
1622
|
-
/* @__PURE__ */
|
|
1623
|
-
outcome.ok === false ? /* @__PURE__ */
|
|
2109
|
+
outcome && /* @__PURE__ */ jsxs9("div", { children: [
|
|
2110
|
+
/* @__PURE__ */ jsx10("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: outcome.ok === false ? "Failed" : "Result" }),
|
|
2111
|
+
outcome.ok === false ? /* @__PURE__ */ jsx10("p", { className: "text-xs text-destructive", children: outcome.message ?? "Tool failed" }) : outcome.result && typeof outcome.result === "object" ? /* @__PURE__ */ jsx10(KvRows, { data: outcome.result }) : /* @__PURE__ */ jsx10("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(outcome.result) })
|
|
1624
2112
|
] })
|
|
1625
2113
|
] });
|
|
1626
2114
|
}
|
|
@@ -1631,23 +2119,23 @@ function ProposalCard({
|
|
|
1631
2119
|
approval,
|
|
1632
2120
|
renderers
|
|
1633
2121
|
}) {
|
|
1634
|
-
const [expanded, setExpanded] =
|
|
2122
|
+
const [expanded, setExpanded] = useState9(false);
|
|
1635
2123
|
const { summary, meta } = proposalPreview(call);
|
|
1636
2124
|
const custom = renderers?.[call.name]?.(call, message);
|
|
1637
2125
|
const { pending: deciding, run: decide } = usePending();
|
|
1638
|
-
return /* @__PURE__ */
|
|
1639
|
-
/* @__PURE__ */
|
|
1640
|
-
/* @__PURE__ */
|
|
1641
|
-
/* @__PURE__ */
|
|
1642
|
-
/* @__PURE__ */
|
|
1643
|
-
/* @__PURE__ */
|
|
1644
|
-
summary && /* @__PURE__ */
|
|
1645
|
-
meta.length > 0 && /* @__PURE__ */
|
|
2126
|
+
return /* @__PURE__ */ jsxs9("div", { className: "w-full max-w-full rounded-xl border border-warning/50 bg-warning/[0.06] text-sm shadow-sm ring-1 ring-warning/10", children: [
|
|
2127
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-2.5 px-4 pt-3.5", children: [
|
|
2128
|
+
/* @__PURE__ */ jsx10("span", { className: "mt-0.5 inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-warning/15 text-warning", children: /* @__PURE__ */ jsx10(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
|
|
2129
|
+
/* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
|
|
2130
|
+
/* @__PURE__ */ jsx10("p", { className: "text-[10px] font-semibold uppercase tracking-wider text-warning-foreground", children: "Needs your approval" }),
|
|
2131
|
+
/* @__PURE__ */ jsx10("p", { className: "mt-0.5 text-[15px] font-semibold leading-snug text-foreground", children: friendlyToolTitle(call) }),
|
|
2132
|
+
summary && /* @__PURE__ */ jsx10("p", { className: "mt-1 text-[13px] leading-relaxed text-muted-foreground", children: summary }),
|
|
2133
|
+
meta.length > 0 && /* @__PURE__ */ jsx10("div", { className: "mt-1.5 flex flex-wrap items-center gap-1.5", children: meta.map((m, i) => /* @__PURE__ */ jsx10("span", { className: "rounded-full bg-muted/60 px-2 py-0.5 text-[11px] font-medium text-muted-foreground", children: m }, i)) })
|
|
1646
2134
|
] })
|
|
1647
2135
|
] }),
|
|
1648
|
-
/* @__PURE__ */
|
|
1649
|
-
approval ? /* @__PURE__ */
|
|
1650
|
-
/* @__PURE__ */
|
|
2136
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-2 px-4 pb-3.5 pt-3", children: [
|
|
2137
|
+
approval ? /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
2138
|
+
/* @__PURE__ */ jsx10(
|
|
1651
2139
|
"button",
|
|
1652
2140
|
{
|
|
1653
2141
|
type: "button",
|
|
@@ -1657,7 +2145,7 @@ function ProposalCard({
|
|
|
1657
2145
|
children: "Approve & run"
|
|
1658
2146
|
}
|
|
1659
2147
|
),
|
|
1660
|
-
/* @__PURE__ */
|
|
2148
|
+
/* @__PURE__ */ jsx10(
|
|
1661
2149
|
"button",
|
|
1662
2150
|
{
|
|
1663
2151
|
type: "button",
|
|
@@ -1667,8 +2155,8 @@ function ProposalCard({
|
|
|
1667
2155
|
children: "Reject"
|
|
1668
2156
|
}
|
|
1669
2157
|
)
|
|
1670
|
-
] }) : /* @__PURE__ */
|
|
1671
|
-
/* @__PURE__ */
|
|
2158
|
+
] }) : /* @__PURE__ */ jsx10("span", { className: "text-[12px] font-medium text-muted-foreground", children: "Awaiting approval\u2026" }),
|
|
2159
|
+
/* @__PURE__ */ jsxs9(
|
|
1672
2160
|
"button",
|
|
1673
2161
|
{
|
|
1674
2162
|
type: "button",
|
|
@@ -1677,23 +2165,23 @@ function ProposalCard({
|
|
|
1677
2165
|
className: "ml-auto inline-flex items-center gap-1 rounded text-[12px] font-medium text-muted-foreground transition hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1678
2166
|
children: [
|
|
1679
2167
|
expanded ? "Hide details" : "View details",
|
|
1680
|
-
/* @__PURE__ */
|
|
2168
|
+
/* @__PURE__ */ jsx10(ChevronDown, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` })
|
|
1681
2169
|
]
|
|
1682
2170
|
}
|
|
1683
2171
|
)
|
|
1684
2172
|
] }),
|
|
1685
|
-
expanded && /* @__PURE__ */
|
|
2173
|
+
expanded && /* @__PURE__ */ jsx10("div", { className: "border-t border-warning/20 px-4 py-3 text-xs", children: custom ?? /* @__PURE__ */ jsx10(DefaultToolDetail, { call }) })
|
|
1686
2174
|
] });
|
|
1687
2175
|
}
|
|
1688
2176
|
function FollowupCard({ call }) {
|
|
1689
2177
|
const a = call.args ?? {};
|
|
1690
2178
|
const when = typeof a.when === "string" ? a.when : typeof a.at === "string" ? a.at : typeof a.schedule === "string" ? a.schedule : null;
|
|
1691
|
-
return /* @__PURE__ */
|
|
1692
|
-
/* @__PURE__ */
|
|
1693
|
-
/* @__PURE__ */
|
|
1694
|
-
/* @__PURE__ */
|
|
2179
|
+
return /* @__PURE__ */ jsxs9("div", { className: "w-fit min-w-[260px] max-w-full rounded-lg border border-border/60 border-l-2 border-l-primary/60 bg-muted/20 px-3 py-2 text-sm", children: [
|
|
2180
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
2181
|
+
/* @__PURE__ */ jsx10(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-primary/80" }),
|
|
2182
|
+
/* @__PURE__ */ jsx10("span", { className: "min-w-0 flex-1 truncate font-medium text-foreground", children: friendlyToolTitle(call) })
|
|
1695
2183
|
] }),
|
|
1696
|
-
when && /* @__PURE__ */
|
|
2184
|
+
when && /* @__PURE__ */ jsx10("p", { className: "mt-0.5 pl-[22px] text-[12px] text-muted-foreground", children: when })
|
|
1697
2185
|
] });
|
|
1698
2186
|
}
|
|
1699
2187
|
function ToolCallCard({
|
|
@@ -1703,13 +2191,13 @@ function ToolCallCard({
|
|
|
1703
2191
|
onOpenRun,
|
|
1704
2192
|
renderers
|
|
1705
2193
|
}) {
|
|
1706
|
-
const [expanded, setExpanded] =
|
|
2194
|
+
const [expanded, setExpanded] = useState9(false);
|
|
1707
2195
|
const pending = call.status === "done" ? pendingApprovalOf(call) : null;
|
|
1708
2196
|
const kind = blockKindOf(call);
|
|
1709
2197
|
const failed = call.status === "error" || toolOutcomeOf(call)?.ok === false;
|
|
1710
2198
|
const custom = renderers?.[call.name]?.(call, message);
|
|
1711
2199
|
if (pending) {
|
|
1712
|
-
return /* @__PURE__ */
|
|
2200
|
+
return /* @__PURE__ */ jsx10(
|
|
1713
2201
|
ProposalCard,
|
|
1714
2202
|
{
|
|
1715
2203
|
call,
|
|
@@ -1721,16 +2209,16 @@ function ToolCallCard({
|
|
|
1721
2209
|
);
|
|
1722
2210
|
}
|
|
1723
2211
|
if (kind === "followup" && !failed) {
|
|
1724
|
-
return /* @__PURE__ */
|
|
2212
|
+
return /* @__PURE__ */ jsx10(FollowupCard, { call });
|
|
1725
2213
|
}
|
|
1726
2214
|
const isCommand = kind === "command";
|
|
1727
|
-
return /* @__PURE__ */
|
|
2215
|
+
return /* @__PURE__ */ jsxs9(
|
|
1728
2216
|
"div",
|
|
1729
2217
|
{
|
|
1730
2218
|
className: `w-fit min-w-[280px] max-w-full rounded-lg border text-xs transition ${failed ? "border-destructive/40 bg-destructive/5" : "border-border/60 bg-muted/20"}`,
|
|
1731
2219
|
children: [
|
|
1732
|
-
/* @__PURE__ */
|
|
1733
|
-
/* @__PURE__ */
|
|
2220
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
|
|
2221
|
+
/* @__PURE__ */ jsxs9(
|
|
1734
2222
|
"button",
|
|
1735
2223
|
{
|
|
1736
2224
|
type: "button",
|
|
@@ -1738,14 +2226,14 @@ function ToolCallCard({
|
|
|
1738
2226
|
"aria-expanded": expanded,
|
|
1739
2227
|
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",
|
|
1740
2228
|
children: [
|
|
1741
|
-
/* @__PURE__ */
|
|
2229
|
+
/* @__PURE__ */ jsx10(
|
|
1742
2230
|
"span",
|
|
1743
2231
|
{
|
|
1744
2232
|
className: `h-2 w-2 shrink-0 rounded-full ${call.status === "running" ? "animate-pulse bg-warning" : failed ? "bg-destructive" : "bg-success"}`
|
|
1745
2233
|
}
|
|
1746
2234
|
),
|
|
1747
|
-
/* @__PURE__ */
|
|
1748
|
-
/* @__PURE__ */
|
|
2235
|
+
/* @__PURE__ */ jsx10(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
2236
|
+
/* @__PURE__ */ jsx10(
|
|
1749
2237
|
"span",
|
|
1750
2238
|
{
|
|
1751
2239
|
className: `min-w-0 flex-1 truncate ${isCommand ? "font-mono text-[12px] tracking-tight text-foreground/90" : "font-medium"}`,
|
|
@@ -1755,8 +2243,8 @@ function ToolCallCard({
|
|
|
1755
2243
|
]
|
|
1756
2244
|
}
|
|
1757
2245
|
),
|
|
1758
|
-
/* @__PURE__ */
|
|
1759
|
-
/* @__PURE__ */
|
|
2246
|
+
/* @__PURE__ */ jsx10("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : failed ? "failed" : "done" }),
|
|
2247
|
+
/* @__PURE__ */ jsx10(
|
|
1760
2248
|
"button",
|
|
1761
2249
|
{
|
|
1762
2250
|
type: "button",
|
|
@@ -1764,13 +2252,13 @@ function ToolCallCard({
|
|
|
1764
2252
|
"aria-label": expanded ? "Collapse details" : "Expand details",
|
|
1765
2253
|
"aria-expanded": expanded,
|
|
1766
2254
|
className: "shrink-0 rounded p-0.5 focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1767
|
-
children: /* @__PURE__ */
|
|
2255
|
+
children: /* @__PURE__ */ jsx10(ChevronDown, { className: `h-3 w-3 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
|
|
1768
2256
|
}
|
|
1769
2257
|
)
|
|
1770
2258
|
] }),
|
|
1771
|
-
expanded && /* @__PURE__ */
|
|
1772
|
-
custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */
|
|
1773
|
-
onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */
|
|
2259
|
+
expanded && /* @__PURE__ */ jsxs9("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
|
|
2260
|
+
custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx10(ShellDetail, { call }) : /* @__PURE__ */ jsx10(DefaultToolDetail, { call })),
|
|
2261
|
+
onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx10(
|
|
1774
2262
|
"button",
|
|
1775
2263
|
{
|
|
1776
2264
|
type: "button",
|
|
@@ -1785,7 +2273,7 @@ function ToolCallCard({
|
|
|
1785
2273
|
);
|
|
1786
2274
|
}
|
|
1787
2275
|
function StreamingCaret() {
|
|
1788
|
-
return /* @__PURE__ */
|
|
2276
|
+
return /* @__PURE__ */ jsx10(
|
|
1789
2277
|
"span",
|
|
1790
2278
|
{
|
|
1791
2279
|
className: "ml-0.5 inline-block h-[1.1em] w-[3px] translate-y-[2px] animate-pulse rounded-sm bg-foreground/70",
|
|
@@ -1800,11 +2288,11 @@ function SegmentText({
|
|
|
1800
2288
|
renderBody
|
|
1801
2289
|
}) {
|
|
1802
2290
|
const text = useSmoothText(content, streaming);
|
|
1803
|
-
const body =
|
|
2291
|
+
const body = useMemo6(() => renderBody(text), [renderBody, text]);
|
|
1804
2292
|
if (!content.trim() && !showCaret) return null;
|
|
1805
|
-
return /* @__PURE__ */
|
|
2293
|
+
return /* @__PURE__ */ jsxs9("div", { className: "text-base leading-[1.75]", children: [
|
|
1806
2294
|
body,
|
|
1807
|
-
showCaret && /* @__PURE__ */
|
|
2295
|
+
showCaret && /* @__PURE__ */ jsx10(StreamingCaret, {})
|
|
1808
2296
|
] });
|
|
1809
2297
|
}
|
|
1810
2298
|
var COLLAPSE_TOOL_RUN_AT = 3;
|
|
@@ -1827,7 +2315,7 @@ function SegmentedBody({
|
|
|
1827
2315
|
const leftoverToolCalls = (msg.toolCalls ?? []).filter(
|
|
1828
2316
|
(tc) => !segmentToolIds.has(tc.id)
|
|
1829
2317
|
);
|
|
1830
|
-
const renderToolCard = (call) => /* @__PURE__ */
|
|
2318
|
+
const renderToolCard = (call) => /* @__PURE__ */ jsx10(
|
|
1831
2319
|
ToolCallCard,
|
|
1832
2320
|
{
|
|
1833
2321
|
call,
|
|
@@ -1850,9 +2338,9 @@ function SegmentedBody({
|
|
|
1850
2338
|
else groups.push({ kind: "tools", index: i, calls: [seg.call] });
|
|
1851
2339
|
}
|
|
1852
2340
|
}
|
|
1853
|
-
return /* @__PURE__ */
|
|
2341
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-2", children: [
|
|
1854
2342
|
groups.map(
|
|
1855
|
-
(g) => g.kind === "text" ? /* @__PURE__ */
|
|
2343
|
+
(g) => g.kind === "text" ? /* @__PURE__ */ jsx10(
|
|
1856
2344
|
SegmentText,
|
|
1857
2345
|
{
|
|
1858
2346
|
content: g.content,
|
|
@@ -1861,24 +2349,24 @@ function SegmentedBody({
|
|
|
1861
2349
|
renderBody
|
|
1862
2350
|
},
|
|
1863
2351
|
`text-${g.index}`
|
|
1864
|
-
) : !streaming && g.calls.length >= COLLAPSE_TOOL_RUN_AT && !g.calls.some(isImportantTool) ? /* @__PURE__ */
|
|
2352
|
+
) : !streaming && g.calls.length >= COLLAPSE_TOOL_RUN_AT && !g.calls.some(isImportantTool) ? /* @__PURE__ */ jsxs9(
|
|
1865
2353
|
"details",
|
|
1866
2354
|
{
|
|
1867
2355
|
className: "rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2",
|
|
1868
2356
|
children: [
|
|
1869
|
-
/* @__PURE__ */
|
|
2357
|
+
/* @__PURE__ */ jsxs9("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: [
|
|
1870
2358
|
"Worked through ",
|
|
1871
2359
|
g.calls.length,
|
|
1872
2360
|
" steps"
|
|
1873
2361
|
] }),
|
|
1874
|
-
/* @__PURE__ */
|
|
2362
|
+
/* @__PURE__ */ jsx10("div", { className: "mt-2 flex flex-col gap-2", children: g.calls.map(renderToolCard) })
|
|
1875
2363
|
]
|
|
1876
2364
|
},
|
|
1877
2365
|
`tools-${g.index}`
|
|
1878
|
-
) : /* @__PURE__ */
|
|
2366
|
+
) : /* @__PURE__ */ jsx10("div", { className: "flex flex-col gap-2", children: g.calls.map(renderToolCard) }, `tools-${g.index}`)
|
|
1879
2367
|
),
|
|
1880
2368
|
leftoverToolCalls.map(renderToolCard),
|
|
1881
|
-
streaming && segments[lastIndex]?.kind === "tool" && /* @__PURE__ */
|
|
2369
|
+
streaming && segments[lastIndex]?.kind === "tool" && /* @__PURE__ */ jsx10(StreamingCaret, {})
|
|
1882
2370
|
] });
|
|
1883
2371
|
}
|
|
1884
2372
|
function AssistantMessageImpl({
|
|
@@ -1894,12 +2382,12 @@ function AssistantMessageImpl({
|
|
|
1894
2382
|
}) {
|
|
1895
2383
|
const content = useSmoothText(msg.content, streaming);
|
|
1896
2384
|
const reasoning = useSmoothText(msg.reasoning ?? "", streaming);
|
|
1897
|
-
const body =
|
|
2385
|
+
const body = useMemo6(() => renderBody(content), [renderBody, content]);
|
|
1898
2386
|
const segments = msg.segments;
|
|
1899
2387
|
const hasAnswerText = content !== "" || (segments?.some((s) => s.kind === "text" && s.content.trim() !== "") ?? false);
|
|
1900
|
-
const reasoningScrollRef =
|
|
1901
|
-
const thinkStartRef =
|
|
1902
|
-
const thinkMsRef =
|
|
2388
|
+
const reasoningScrollRef = useRef6(null);
|
|
2389
|
+
const thinkStartRef = useRef6(null);
|
|
2390
|
+
const thinkMsRef = useRef6(null);
|
|
1903
2391
|
if (streaming && reasoning && !hasAnswerText && thinkStartRef.current === null) {
|
|
1904
2392
|
thinkStartRef.current = performance.now();
|
|
1905
2393
|
}
|
|
@@ -1913,21 +2401,21 @@ function AssistantMessageImpl({
|
|
|
1913
2401
|
const thinkingSeconds = useThinkingSeconds(
|
|
1914
2402
|
streaming && !!reasoning && !hasAnswerText
|
|
1915
2403
|
);
|
|
1916
|
-
return /* @__PURE__ */
|
|
1917
|
-
/* @__PURE__ */
|
|
1918
|
-
/* @__PURE__ */
|
|
1919
|
-
msg.modelUsed && /* @__PURE__ */
|
|
1920
|
-
formatTokensPerSecond(msg) && /* @__PURE__ */
|
|
1921
|
-
formatModelCost(msg, models) && /* @__PURE__ */
|
|
2404
|
+
return /* @__PURE__ */ jsxs9("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
|
|
2405
|
+
/* @__PURE__ */ jsxs9("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
|
|
2406
|
+
/* @__PURE__ */ jsx10("span", { className: "font-semibold uppercase", children: agentLabel }),
|
|
2407
|
+
msg.modelUsed && /* @__PURE__ */ jsx10("span", { className: "font-mono normal-case", children: msg.modelUsed }),
|
|
2408
|
+
formatTokensPerSecond(msg) && /* @__PURE__ */ jsx10("span", { children: formatTokensPerSecond(msg) }),
|
|
2409
|
+
formatModelCost(msg, models) && /* @__PURE__ */ jsx10("span", { children: formatModelCost(msg, models) })
|
|
1922
2410
|
] }),
|
|
1923
|
-
reasoning && /* @__PURE__ */
|
|
1924
|
-
/* @__PURE__ */
|
|
2411
|
+
reasoning && /* @__PURE__ */ jsxs9("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !hasAnswerText, children: [
|
|
2412
|
+
/* @__PURE__ */ jsx10("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !hasAnswerText ? /* @__PURE__ */ jsxs9("span", { className: "animate-pulse", children: [
|
|
1925
2413
|
"Thinking",
|
|
1926
2414
|
thinkingSeconds >= 3 ? ` \xB7 ${thinkingSeconds}s` : "\u2026"
|
|
1927
2415
|
] }) : thinkMsRef.current != null ? `Thought for ${Math.max(1, Math.round(thinkMsRef.current / 1e3))}s` : "Thought process" }),
|
|
1928
|
-
/* @__PURE__ */
|
|
2416
|
+
/* @__PURE__ */ jsx10("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground", children: reasoning })
|
|
1929
2417
|
] }),
|
|
1930
|
-
segments && segments.length > 0 ? /* @__PURE__ */
|
|
2418
|
+
segments && segments.length > 0 ? /* @__PURE__ */ jsx10(
|
|
1931
2419
|
SegmentedBody,
|
|
1932
2420
|
{
|
|
1933
2421
|
segments,
|
|
@@ -1938,12 +2426,12 @@ function AssistantMessageImpl({
|
|
|
1938
2426
|
onToolCallClick,
|
|
1939
2427
|
toolRenderers
|
|
1940
2428
|
}
|
|
1941
|
-
) : /* @__PURE__ */
|
|
1942
|
-
/* @__PURE__ */
|
|
2429
|
+
) : /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
2430
|
+
/* @__PURE__ */ jsxs9("div", { className: "text-base leading-[1.75]", children: [
|
|
1943
2431
|
body,
|
|
1944
|
-
streaming && content && !msg.toolCalls?.length && /* @__PURE__ */
|
|
2432
|
+
streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx10(StreamingCaret, {})
|
|
1945
2433
|
] }),
|
|
1946
|
-
msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */
|
|
2434
|
+
msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */ jsx10("div", { className: "mt-2 flex flex-col gap-1.5", children: msg.toolCalls.map((tc) => /* @__PURE__ */ jsx10(
|
|
1947
2435
|
ToolCallCard,
|
|
1948
2436
|
{
|
|
1949
2437
|
call: tc,
|
|
@@ -1960,7 +2448,7 @@ function AssistantMessageImpl({
|
|
|
1960
2448
|
}
|
|
1961
2449
|
var AssistantMessage = memo(AssistantMessageImpl);
|
|
1962
2450
|
function useThinkingSeconds(active) {
|
|
1963
|
-
const [seconds, setSeconds] =
|
|
2451
|
+
const [seconds, setSeconds] = useState9(0);
|
|
1964
2452
|
useEffect5(() => {
|
|
1965
2453
|
if (!active) return;
|
|
1966
2454
|
setSeconds(0);
|
|
@@ -1971,23 +2459,23 @@ function useThinkingSeconds(active) {
|
|
|
1971
2459
|
}
|
|
1972
2460
|
function ThinkingRow({ agentLabel }) {
|
|
1973
2461
|
const seconds = useThinkingSeconds(true);
|
|
1974
|
-
return /* @__PURE__ */
|
|
1975
|
-
/* @__PURE__ */
|
|
1976
|
-
/* @__PURE__ */
|
|
1977
|
-
/* @__PURE__ */
|
|
2462
|
+
return /* @__PURE__ */ jsxs9("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
|
|
2463
|
+
/* @__PURE__ */ jsx10("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
|
|
2464
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
|
|
2465
|
+
/* @__PURE__ */ jsx10("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx10("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
|
|
1978
2466
|
"Thinking",
|
|
1979
2467
|
seconds >= 3 ? ` \xB7 ${seconds}s` : "..."
|
|
1980
2468
|
] })
|
|
1981
2469
|
] });
|
|
1982
2470
|
}
|
|
1983
2471
|
function StreamErrorRow({ message, onRetry }) {
|
|
1984
|
-
return /* @__PURE__ */
|
|
1985
|
-
/* @__PURE__ */
|
|
1986
|
-
/* @__PURE__ */
|
|
1987
|
-
/* @__PURE__ */
|
|
2472
|
+
return /* @__PURE__ */ jsx10("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs9("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: [
|
|
2473
|
+
/* @__PURE__ */ jsxs9("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: [
|
|
2474
|
+
/* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "9" }),
|
|
2475
|
+
/* @__PURE__ */ jsx10("path", { d: "M12 8v4m0 4h.01" })
|
|
1988
2476
|
] }),
|
|
1989
|
-
/* @__PURE__ */
|
|
1990
|
-
onRetry && /* @__PURE__ */
|
|
2477
|
+
/* @__PURE__ */ jsx10("span", { className: "min-w-0 flex-1 break-words", children: message }),
|
|
2478
|
+
onRetry && /* @__PURE__ */ jsx10(
|
|
1991
2479
|
"button",
|
|
1992
2480
|
{
|
|
1993
2481
|
type: "button",
|
|
@@ -2015,25 +2503,25 @@ function ChatMessages({
|
|
|
2015
2503
|
emptyState,
|
|
2016
2504
|
header
|
|
2017
2505
|
}) {
|
|
2018
|
-
const renderBody =
|
|
2019
|
-
() => renderMarkdown ?? ((content) => /* @__PURE__ */
|
|
2506
|
+
const renderBody = useMemo6(
|
|
2507
|
+
() => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx10("p", { className: "whitespace-pre-wrap", children: content })),
|
|
2020
2508
|
[renderMarkdown]
|
|
2021
2509
|
);
|
|
2022
2510
|
const lastIsUser = messages[messages.length - 1]?.role === "user";
|
|
2023
2511
|
if (messages.length === 0 && !loading && !error) {
|
|
2024
|
-
const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */
|
|
2025
|
-
return /* @__PURE__ */
|
|
2512
|
+
const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */ jsx10(ChatEmptyState, { ...emptyState });
|
|
2513
|
+
return /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
2026
2514
|
header,
|
|
2027
2515
|
empty
|
|
2028
2516
|
] });
|
|
2029
2517
|
}
|
|
2030
|
-
return /* @__PURE__ */
|
|
2518
|
+
return /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
2031
2519
|
header,
|
|
2032
2520
|
messages.map(
|
|
2033
|
-
(msg) => msg.role === "user" ? /* @__PURE__ */
|
|
2034
|
-
/* @__PURE__ */
|
|
2035
|
-
/* @__PURE__ */
|
|
2036
|
-
] }) }, msg.id) : /* @__PURE__ */
|
|
2521
|
+
(msg) => msg.role === "user" ? /* @__PURE__ */ jsx10("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs9("div", { className: "ml-auto w-fit max-w-[85%]", children: [
|
|
2522
|
+
/* @__PURE__ */ jsx10("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
|
|
2523
|
+
/* @__PURE__ */ jsx10("div", { className: "rounded-2xl rounded-tr-md bg-primary/10 px-4 py-2.5 text-base leading-relaxed", children: /* @__PURE__ */ jsx10("p", { className: "whitespace-pre-wrap", children: msg.content }) })
|
|
2524
|
+
] }) }, msg.id) : /* @__PURE__ */ jsx10(
|
|
2037
2525
|
AssistantMessage,
|
|
2038
2526
|
{
|
|
2039
2527
|
msg,
|
|
@@ -2049,8 +2537,8 @@ function ChatMessages({
|
|
|
2049
2537
|
msg.id
|
|
2050
2538
|
)
|
|
2051
2539
|
),
|
|
2052
|
-
loading && lastIsUser && /* @__PURE__ */
|
|
2053
|
-
error && !loading && /* @__PURE__ */
|
|
2540
|
+
loading && lastIsUser && /* @__PURE__ */ jsx10(ThinkingRow, { agentLabel }),
|
|
2541
|
+
error && !loading && /* @__PURE__ */ jsx10(StreamErrorRow, { message: error, onRetry })
|
|
2054
2542
|
] });
|
|
2055
2543
|
}
|
|
2056
2544
|
|
|
@@ -2063,31 +2551,32 @@ export {
|
|
|
2063
2551
|
ModelPicker,
|
|
2064
2552
|
DEFAULT_EFFORT_LEVELS,
|
|
2065
2553
|
EffortPicker,
|
|
2066
|
-
INTERACTION_EVENT,
|
|
2067
|
-
INTERACTION_CANCEL_EVENT,
|
|
2068
|
-
INTERACTION_RESOLVED_EVENT,
|
|
2069
|
-
isRenderableInteractionKind,
|
|
2070
|
-
isSafeInteractionFieldKey,
|
|
2071
|
-
isTerminalInteractionStatus,
|
|
2072
|
-
canTransitionInteractionStatus,
|
|
2073
|
-
cancelStatusFor,
|
|
2074
|
-
questionInteractionContentSignature,
|
|
2075
|
-
dedupeQuestionInteractionsByContent,
|
|
2076
|
-
parseInteractionRequest,
|
|
2077
|
-
parseInteractionCancel,
|
|
2078
|
-
fieldAcceptsFreeText,
|
|
2079
|
-
composerAnswerDeliveries,
|
|
2080
|
-
composerAnswerData,
|
|
2081
|
-
interactionPartKey,
|
|
2082
|
-
noticePartKey,
|
|
2083
|
-
noticePart,
|
|
2084
|
-
interactionFromWireRequest,
|
|
2085
|
-
interactionToPersistedPart,
|
|
2086
|
-
persistedPartToInteraction,
|
|
2087
2554
|
dispatchChatStreamLine,
|
|
2088
2555
|
consumeChatStream,
|
|
2089
2556
|
streamChatTurn,
|
|
2090
2557
|
ChatComposer,
|
|
2558
|
+
interactionStatusLabels,
|
|
2559
|
+
interactionTerminalNotes,
|
|
2560
|
+
fieldAnswer,
|
|
2561
|
+
buildAnswerData,
|
|
2562
|
+
isLateAnswerableStatus,
|
|
2563
|
+
hasSecretField,
|
|
2564
|
+
lateAnswerMessage,
|
|
2565
|
+
INTERACTION_SUBMIT_TIMEOUT_MS,
|
|
2566
|
+
INTERACTION_SUBMIT_TIMEOUT_MESSAGE,
|
|
2567
|
+
responseErrorMessage,
|
|
2568
|
+
createInteractionAnswerSubmitter,
|
|
2569
|
+
InteractionBadge,
|
|
2570
|
+
InteractionActionButton,
|
|
2571
|
+
QuestionOptionList,
|
|
2572
|
+
InteractionQuestionCard,
|
|
2573
|
+
InteractionPlanCard,
|
|
2574
|
+
upsertChatInteraction,
|
|
2575
|
+
cancelChatInteraction,
|
|
2576
|
+
resolveChatInteraction,
|
|
2577
|
+
terminalizePendingChatInteractions,
|
|
2578
|
+
restoreChatInteractions,
|
|
2579
|
+
useChatInteractions,
|
|
2091
2580
|
activityTone,
|
|
2092
2581
|
formatActivityCost,
|
|
2093
2582
|
formatActivityDuration,
|
|
@@ -2106,4 +2595,4 @@ export {
|
|
|
2106
2595
|
useThinkingSeconds,
|
|
2107
2596
|
ChatMessages
|
|
2108
2597
|
};
|
|
2109
|
-
//# sourceMappingURL=chunk-
|
|
2598
|
+
//# sourceMappingURL=chunk-PEPXQTJ3.js.map
|