@invergent/agent-chat-react 2.3.1 → 2.4.1
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/index.cjs +171 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +171 -114
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1090,9 +1090,9 @@ var defaultGetThinkingMessage = (isStreaming, duration) => {
|
|
|
1090
1090
|
return /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { duration: 1, children: "Thinking..." });
|
|
1091
1091
|
}
|
|
1092
1092
|
if (duration === void 0) {
|
|
1093
|
-
return /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-foreground", children: "Thought for a few seconds" });
|
|
1093
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground italic", children: "Thought for a few seconds" });
|
|
1094
1094
|
}
|
|
1095
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-foreground", children: [
|
|
1095
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-muted-foreground italic", children: [
|
|
1096
1096
|
"Thought for ",
|
|
1097
1097
|
duration,
|
|
1098
1098
|
" seconds"
|
|
@@ -6865,6 +6865,59 @@ function useSmoothStream(target, isStreaming) {
|
|
|
6865
6865
|
return displayedLen >= target.length ? target : target.slice(0, displayedLen);
|
|
6866
6866
|
}
|
|
6867
6867
|
|
|
6868
|
+
// src/lib/next-action.ts
|
|
6869
|
+
var _NEXT_ACTION_RE = /<next_action([^>]*)>([\s\S]*?)<\/next_action>\s*/gi;
|
|
6870
|
+
var _ATTR_RE = /(\w+)="([^"]*)"/g;
|
|
6871
|
+
var _VALID_COMPLEXITY = /* @__PURE__ */ new Set([
|
|
6872
|
+
"low",
|
|
6873
|
+
"medium",
|
|
6874
|
+
"high"
|
|
6875
|
+
]);
|
|
6876
|
+
var _VALID_SUMMARY = /* @__PURE__ */ new Set([
|
|
6877
|
+
"show",
|
|
6878
|
+
"hide"
|
|
6879
|
+
]);
|
|
6880
|
+
function _parseAttrs(rawAttrs) {
|
|
6881
|
+
const out = {};
|
|
6882
|
+
for (const m of rawAttrs.matchAll(_ATTR_RE)) {
|
|
6883
|
+
out[m[1].toLowerCase()] = m[2];
|
|
6884
|
+
}
|
|
6885
|
+
return out;
|
|
6886
|
+
}
|
|
6887
|
+
function _inferNarration(text) {
|
|
6888
|
+
if (!text) return null;
|
|
6889
|
+
const head = text.trimStart().split(/\n\s*\n/, 1)[0].slice(0, 240);
|
|
6890
|
+
const endMatch = /([.!?])(\s|$)/.exec(head);
|
|
6891
|
+
const firstSentence = (endMatch ? head.slice(0, endMatch.index + 1) : head).trim();
|
|
6892
|
+
if (!firstSentence || firstSentence.length > 200) return null;
|
|
6893
|
+
return firstSentence;
|
|
6894
|
+
}
|
|
6895
|
+
function stripAndParseNextAction(text) {
|
|
6896
|
+
if (!text) {
|
|
6897
|
+
return { cleaned: text ?? "", action: null, inferredNarration: null };
|
|
6898
|
+
}
|
|
6899
|
+
let last = null;
|
|
6900
|
+
const matches = Array.from(text.matchAll(_NEXT_ACTION_RE));
|
|
6901
|
+
if (matches.length === 0) {
|
|
6902
|
+
return {
|
|
6903
|
+
cleaned: text,
|
|
6904
|
+
action: null,
|
|
6905
|
+
inferredNarration: _inferNarration(text)
|
|
6906
|
+
};
|
|
6907
|
+
}
|
|
6908
|
+
for (const match of matches) {
|
|
6909
|
+
const attrs = _parseAttrs(match[1] ?? "");
|
|
6910
|
+
const rawComplexity = (attrs["complexity"] ?? "").trim().toLowerCase();
|
|
6911
|
+
const complexity = _VALID_COMPLEXITY.has(rawComplexity) ? rawComplexity : "medium";
|
|
6912
|
+
const rawSummary = (attrs["summary"] ?? "").trim().toLowerCase();
|
|
6913
|
+
const summary = _VALID_SUMMARY.has(rawSummary) ? rawSummary : "hide";
|
|
6914
|
+
const body = (match[2] ?? "").trim() || "done";
|
|
6915
|
+
last = { complexity, summary, body };
|
|
6916
|
+
}
|
|
6917
|
+
const cleaned = text.replace(_NEXT_ACTION_RE, "").trimEnd();
|
|
6918
|
+
return { cleaned, action: last, inferredNarration: null };
|
|
6919
|
+
}
|
|
6920
|
+
|
|
6868
6921
|
// src/components/ai-elements/artifact.tsx
|
|
6869
6922
|
init_utils();
|
|
6870
6923
|
var Artifact = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6995,12 +7048,21 @@ var EXPANDED_HEIGHT_PX = 800;
|
|
|
6995
7048
|
var MIN_ZOOM = 0.5;
|
|
6996
7049
|
var MAX_ZOOM = 2;
|
|
6997
7050
|
var ZOOM_STEP = 0.1;
|
|
7051
|
+
var SAFETY_STYLE_PREAMBLE = "<style>html,body{max-height:100vh}canvas{max-height:80vh!important}</style>";
|
|
7052
|
+
function injectSafetyStyle(html) {
|
|
7053
|
+
const headCloseIdx = html.search(/<\/head\s*>/i);
|
|
7054
|
+
if (headCloseIdx >= 0) {
|
|
7055
|
+
return html.slice(0, headCloseIdx) + SAFETY_STYLE_PREAMBLE + html.slice(headCloseIdx);
|
|
7056
|
+
}
|
|
7057
|
+
return SAFETY_STYLE_PREAMBLE + html;
|
|
7058
|
+
}
|
|
6998
7059
|
function ArtifactHtml({
|
|
6999
7060
|
spec,
|
|
7000
7061
|
fill = false
|
|
7001
7062
|
}) {
|
|
7002
7063
|
const [expanded, setExpanded] = react.useState(false);
|
|
7003
7064
|
const [zoom, setZoom] = react.useState(1);
|
|
7065
|
+
const safeSrcdoc = react.useMemo(() => injectSafetyStyle(spec.html), [spec.html]);
|
|
7004
7066
|
const viewportHeight = expanded ? EXPANDED_HEIGHT_PX : DEFAULT_HEIGHT_PX;
|
|
7005
7067
|
const clamp = (v) => Math.round(Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, v)) * 100) / 100;
|
|
7006
7068
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -7020,7 +7082,7 @@ function ArtifactHtml({
|
|
|
7020
7082
|
"iframe",
|
|
7021
7083
|
{
|
|
7022
7084
|
title: "artifact-html",
|
|
7023
|
-
srcDoc:
|
|
7085
|
+
srcDoc: safeSrcdoc,
|
|
7024
7086
|
sandbox: "allow-scripts",
|
|
7025
7087
|
className: cn("border-0", fill && "h-full w-full"),
|
|
7026
7088
|
style: fill ? { zoom } : {
|
|
@@ -8119,16 +8181,6 @@ function TurnSummaryCard({
|
|
|
8119
8181
|
}) })
|
|
8120
8182
|
] });
|
|
8121
8183
|
}
|
|
8122
|
-
function TurnSummaryPending() {
|
|
8123
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 rounded border border-border bg-muted/50 px-3 py-2 text-sm", children: [
|
|
8124
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 text-xs font-semibold uppercase tracking-wide", children: "Summary" }),
|
|
8125
|
-
/* @__PURE__ */ jsxRuntime.jsx(Shimmer, { duration: 3, spread: 3, className: "mb-2 text-sm", children: "Summarizing conversation..." }),
|
|
8126
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
8127
|
-
/* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-3 w-3/4" }),
|
|
8128
|
-
/* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-3 w-2/3" })
|
|
8129
|
-
] })
|
|
8130
|
-
] });
|
|
8131
|
-
}
|
|
8132
8184
|
function ArtifactRow({
|
|
8133
8185
|
artifact,
|
|
8134
8186
|
sessionId,
|
|
@@ -8194,6 +8246,7 @@ function ArtifactRow({
|
|
|
8194
8246
|
|
|
8195
8247
|
// src/components/chat/chat-thread.tsx
|
|
8196
8248
|
init_utils();
|
|
8249
|
+
var WORKING_ON_IT_DELAY_MS = 250;
|
|
8197
8250
|
function messageToEntries(msg, isLast, artifactFallbacks) {
|
|
8198
8251
|
if (msg.role === "system") {
|
|
8199
8252
|
if (msg.systemKind === "skill_invoked") {
|
|
@@ -8224,16 +8277,23 @@ function messageToEntries(msg, isLast, artifactFallbacks) {
|
|
|
8224
8277
|
const hasToolCalls = !!(msg.toolCalls && msg.toolCalls.length > 0);
|
|
8225
8278
|
const hasContent = !!(msg.content && msg.content !== msg.reasoning);
|
|
8226
8279
|
const isStreaming = msg.status === "streaming" && isLast;
|
|
8227
|
-
const effectiveReasoning = hasToolCalls && hasContent ? msg.reasoning ? msg.reasoning + "\n" + msg.content : msg.content : msg.reasoning;
|
|
8228
8280
|
const effectiveHasContent = hasContent && !hasToolCalls;
|
|
8229
|
-
if (
|
|
8281
|
+
if (msg.reasoning) {
|
|
8230
8282
|
entries.push({
|
|
8231
8283
|
kind: "reasoning",
|
|
8232
8284
|
key: `${msg.id}-reasoning`,
|
|
8233
|
-
reasoning:
|
|
8285
|
+
reasoning: msg.reasoning,
|
|
8234
8286
|
isStreaming: isStreaming && !effectiveHasContent && !hasToolCalls
|
|
8235
8287
|
});
|
|
8236
8288
|
}
|
|
8289
|
+
if (hasContent && hasToolCalls) {
|
|
8290
|
+
entries.push({
|
|
8291
|
+
kind: "narration",
|
|
8292
|
+
key: `${msg.id}-narration`,
|
|
8293
|
+
text: msg.content,
|
|
8294
|
+
isStreaming: isStreaming && !effectiveHasContent
|
|
8295
|
+
});
|
|
8296
|
+
}
|
|
8237
8297
|
if (hasToolCalls) {
|
|
8238
8298
|
for (const tc of msg.toolCalls) {
|
|
8239
8299
|
if (tc.toolName === "create_artifact") {
|
|
@@ -8264,12 +8324,6 @@ function messageToEntries(msg, isLast, artifactFallbacks) {
|
|
|
8264
8324
|
msg
|
|
8265
8325
|
});
|
|
8266
8326
|
}
|
|
8267
|
-
const hasRunningTool = hasToolCalls && msg.toolCalls.some(
|
|
8268
|
-
(tc) => tc.status === "running"
|
|
8269
|
-
);
|
|
8270
|
-
if (isStreaming && !effectiveHasContent && !hasRunningTool) {
|
|
8271
|
-
entries.push({ kind: "thinking", key: `${msg.id}-thinking` });
|
|
8272
|
-
}
|
|
8273
8327
|
return entries;
|
|
8274
8328
|
}
|
|
8275
8329
|
function groupBrowserActivityEntries(entries) {
|
|
@@ -8381,7 +8435,10 @@ function OrphanSystemMarker({
|
|
|
8381
8435
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-2 flex items-center gap-2 px-4 text-xs text-foreground/60 ", children: [
|
|
8382
8436
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-2 rounded-full bg-emerald-500" }),
|
|
8383
8437
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
8384
|
-
/* @__PURE__ */ jsxRuntime.
|
|
8438
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold text-foreground", children: [
|
|
8439
|
+
"Running skill",
|
|
8440
|
+
" "
|
|
8441
|
+
] }),
|
|
8385
8442
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground/60 truncate", children: skill })
|
|
8386
8443
|
] })
|
|
8387
8444
|
] });
|
|
@@ -8496,6 +8553,9 @@ function TimelineEntryItem({
|
|
|
8496
8553
|
if (entry.kind === "text") {
|
|
8497
8554
|
return /* @__PURE__ */ jsxRuntime.jsx(TextEntry, { entry, step });
|
|
8498
8555
|
}
|
|
8556
|
+
if (entry.kind === "narration") {
|
|
8557
|
+
return /* @__PURE__ */ jsxRuntime.jsx(NarrationEntry, { entry, step });
|
|
8558
|
+
}
|
|
8499
8559
|
if (entry.kind === "skill_invoked") {
|
|
8500
8560
|
return /* @__PURE__ */ jsxRuntime.jsxs(TimelineItem, { step, children: [
|
|
8501
8561
|
/* @__PURE__ */ jsxRuntime.jsxs(TimelineHeader, { children: [
|
|
@@ -8554,18 +8614,35 @@ function ReasoningEntry({
|
|
|
8554
8614
|
] }) })
|
|
8555
8615
|
] });
|
|
8556
8616
|
}
|
|
8617
|
+
function NarrationEntry({
|
|
8618
|
+
entry,
|
|
8619
|
+
step
|
|
8620
|
+
}) {
|
|
8621
|
+
const text = useSmoothStream(entry.text, entry.isStreaming);
|
|
8622
|
+
const { action, inferredNarration } = stripAndParseNextAction(text);
|
|
8623
|
+
const line = action ? action.body.trim().toLowerCase() === "done" ? null : action.body : inferredNarration;
|
|
8624
|
+
if (!line) return null;
|
|
8625
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(TimelineItem, { step, children: [
|
|
8626
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TimelineHeader, { children: [
|
|
8627
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimelineSeparator, { style: { backgroundColor: "var(--color-border)" } }),
|
|
8628
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimelineIndicator, { className: "size-2 border-none bg-foreground/30" })
|
|
8629
|
+
] }),
|
|
8630
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimelineContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: line }) })
|
|
8631
|
+
] });
|
|
8632
|
+
}
|
|
8557
8633
|
function TextEntry({
|
|
8558
8634
|
entry,
|
|
8559
8635
|
step
|
|
8560
8636
|
}) {
|
|
8561
8637
|
const content = useSmoothStream(entry.content, entry.isStreaming);
|
|
8638
|
+
const { cleaned } = stripAndParseNextAction(content);
|
|
8562
8639
|
return /* @__PURE__ */ jsxRuntime.jsxs(TimelineItem, { step, children: [
|
|
8563
8640
|
/* @__PURE__ */ jsxRuntime.jsxs(TimelineHeader, { children: [
|
|
8564
8641
|
/* @__PURE__ */ jsxRuntime.jsx(TimelineSeparator, { style: { backgroundColor: "var(--color-border)" } }),
|
|
8565
8642
|
/* @__PURE__ */ jsxRuntime.jsx(TimelineIndicator, { className: "size-2 border-none bg-foreground/40" })
|
|
8566
8643
|
] }),
|
|
8567
8644
|
/* @__PURE__ */ jsxRuntime.jsxs(TimelineContent, { children: [
|
|
8568
|
-
/* @__PURE__ */ jsxRuntime.jsx(MessageResponse, { children:
|
|
8645
|
+
/* @__PURE__ */ jsxRuntime.jsx(MessageResponse, { children: cleaned }),
|
|
8569
8646
|
entry.isFinalTurnText && entry.msg.status === "complete" && /* @__PURE__ */ jsxRuntime.jsx(TurnFeedback, { msg: entry.msg })
|
|
8570
8647
|
] })
|
|
8571
8648
|
] });
|
|
@@ -8577,8 +8654,9 @@ function SimpleFinalAnswer({
|
|
|
8577
8654
|
}) {
|
|
8578
8655
|
const content = useSmoothStream(text, isStreaming);
|
|
8579
8656
|
const revealComplete = content.length >= text.length;
|
|
8657
|
+
const { cleaned } = stripAndParseNextAction(content);
|
|
8580
8658
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
8581
|
-
/* @__PURE__ */ jsxRuntime.jsx(MessageResponse, { children:
|
|
8659
|
+
/* @__PURE__ */ jsxRuntime.jsx(MessageResponse, { children: cleaned }),
|
|
8582
8660
|
tail?.status === "complete" && revealComplete && /* @__PURE__ */ jsxRuntime.jsx(TurnFeedback, { msg: tail })
|
|
8583
8661
|
] });
|
|
8584
8662
|
}
|
|
@@ -8871,7 +8949,7 @@ function IterationGroup({
|
|
|
8871
8949
|
if (!label) {
|
|
8872
8950
|
return null;
|
|
8873
8951
|
}
|
|
8874
|
-
const labelTone = summary ? "text-foreground
|
|
8952
|
+
const labelTone = summary ? "text-muted-foreground italic" : "text-muted-foreground";
|
|
8875
8953
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
8876
8954
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
8877
8955
|
"button",
|
|
@@ -8957,10 +9035,7 @@ function deriveFileArtifactsFromMessages(messages) {
|
|
|
8957
9035
|
}
|
|
8958
9036
|
function SimpleAssistantGroup({
|
|
8959
9037
|
messages,
|
|
8960
|
-
lastGlobalIndex,
|
|
8961
|
-
totalMessages,
|
|
8962
9038
|
isRunning,
|
|
8963
|
-
terminal,
|
|
8964
9039
|
sessionId,
|
|
8965
9040
|
artifactFallbacks,
|
|
8966
9041
|
onFileSelect,
|
|
@@ -8971,16 +9046,15 @@ function SimpleAssistantGroup({
|
|
|
8971
9046
|
const tailHasTools = !!(tail?.toolCalls && tail.toolCalls.length > 0);
|
|
8972
9047
|
const tailIsTextOnly = !!tail && !tailHasTools;
|
|
8973
9048
|
const finalText = tailIsTextOnly && tail.content ? tail.content : "";
|
|
8974
|
-
const isTailGroup = lastGlobalIndex === totalMessages - 1;
|
|
8975
|
-
const tailRendersOwnShimmer = !!tail && isIterationLive(tail) && !tailIsTextOnly;
|
|
8976
|
-
const showThinkingShim = isTailGroup && isRunning && !tailRendersOwnShimmer;
|
|
8977
9049
|
const showErrorInfo = !!tail && tail.status === "error" && !!tail.errorInfo;
|
|
8978
9050
|
const turnComplete = !isRunning && tail?.status === "complete";
|
|
9051
|
+
const summaryPref = finalText !== null ? stripAndParseNextAction(finalText).action?.summary ?? "hide" : "hide";
|
|
8979
9052
|
const effectiveTurnSummary = (() => {
|
|
8980
9053
|
const fromHarness = tail?.turnSummary;
|
|
8981
9054
|
if (fromHarness && fromHarness.artifacts.length > 0) {
|
|
8982
9055
|
return fromHarness;
|
|
8983
9056
|
}
|
|
9057
|
+
if (summaryPref === "hide") return null;
|
|
8984
9058
|
if (!turnComplete) return fromHarness;
|
|
8985
9059
|
const derived = deriveFileArtifactsFromMessages(messages);
|
|
8986
9060
|
if (derived.length === 0) return fromHarness;
|
|
@@ -9004,17 +9078,22 @@ function SimpleAssistantGroup({
|
|
|
9004
9078
|
message.id
|
|
9005
9079
|
);
|
|
9006
9080
|
}
|
|
9007
|
-
if (message === tail && tailIsTextOnly) return null;
|
|
9008
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
|
|
9081
|
+
if (message === tail && tailIsTextOnly && finalText) return null;
|
|
9082
|
+
const rawContent = (message.content ?? "").trim();
|
|
9083
|
+
const { action, inferredNarration } = stripAndParseNextAction(rawContent);
|
|
9084
|
+
const narrationLine = action ? action.body.trim().toLowerCase() === "done" ? null : action.body : inferredNarration;
|
|
9085
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
9086
|
+
narrationLine && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground", children: narrationLine }),
|
|
9087
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9088
|
+
IterationGroup,
|
|
9089
|
+
{
|
|
9090
|
+
message,
|
|
9091
|
+
sessionId,
|
|
9092
|
+
artifactFallbacks,
|
|
9093
|
+
onFileSelect
|
|
9094
|
+
}
|
|
9095
|
+
)
|
|
9096
|
+
] }, message.id);
|
|
9018
9097
|
}) }),
|
|
9019
9098
|
finalText && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9020
9099
|
SimpleFinalAnswer,
|
|
@@ -9024,8 +9103,7 @@ function SimpleAssistantGroup({
|
|
|
9024
9103
|
tail
|
|
9025
9104
|
}
|
|
9026
9105
|
),
|
|
9027
|
-
|
|
9028
|
-
effectiveTurnSummary ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
9106
|
+
effectiveTurnSummary && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9029
9107
|
TurnSummaryCard,
|
|
9030
9108
|
{
|
|
9031
9109
|
summary: effectiveTurnSummary,
|
|
@@ -9033,16 +9111,6 @@ function SimpleAssistantGroup({
|
|
|
9033
9111
|
messages,
|
|
9034
9112
|
onFileSelect
|
|
9035
9113
|
}
|
|
9036
|
-
) : (
|
|
9037
|
-
// The harness summarizer runs after the last assistant
|
|
9038
|
-
// response and before ``session.complete``. Show a pending
|
|
9039
|
-
// placeholder during that window so users aren't surprised
|
|
9040
|
-
// when the Summary card pops in. Gated on ``!terminal``
|
|
9041
|
-
// rather than ``isRunning`` because the text-only final
|
|
9042
|
-
// ``llm.response`` already flips ``isRunning`` to false —
|
|
9043
|
-
// the summarizer then runs in the gap before
|
|
9044
|
-
// ``session.complete`` (which is what sets ``terminal``).
|
|
9045
|
-
isTailGroup && !terminal && !!finalText && tail?.status === "complete" && /* @__PURE__ */ jsxRuntime.jsx(TurnSummaryPending, {})
|
|
9046
9114
|
),
|
|
9047
9115
|
showErrorInfo && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage, { errorInfo: tail.errorInfo, onRetry }) })
|
|
9048
9116
|
] }) });
|
|
@@ -9052,7 +9120,6 @@ function AssistantGroup({
|
|
|
9052
9120
|
lastGlobalIndex,
|
|
9053
9121
|
totalMessages,
|
|
9054
9122
|
isRunning,
|
|
9055
|
-
terminal,
|
|
9056
9123
|
sessionId,
|
|
9057
9124
|
artifactFallbacks,
|
|
9058
9125
|
onFileSelect,
|
|
@@ -9064,10 +9131,7 @@ function AssistantGroup({
|
|
|
9064
9131
|
SimpleAssistantGroup,
|
|
9065
9132
|
{
|
|
9066
9133
|
messages,
|
|
9067
|
-
lastGlobalIndex,
|
|
9068
|
-
totalMessages,
|
|
9069
9134
|
isRunning,
|
|
9070
|
-
terminal,
|
|
9071
9135
|
sessionId,
|
|
9072
9136
|
artifactFallbacks,
|
|
9073
9137
|
onFileSelect,
|
|
@@ -9089,15 +9153,6 @@ function AssistantGroup({
|
|
|
9089
9153
|
break;
|
|
9090
9154
|
}
|
|
9091
9155
|
}
|
|
9092
|
-
const isTailGroup = lastGlobalIndex === totalMessages - 1;
|
|
9093
|
-
const lastEntry = entries[entries.length - 1];
|
|
9094
|
-
const hasRunningTool = entries.some(
|
|
9095
|
-
(e) => e.kind === "tool" && e.tc.status === "running"
|
|
9096
|
-
);
|
|
9097
|
-
const tailMsg = messages[messages.length - 1];
|
|
9098
|
-
if (isTailGroup && isRunning && !hasRunningTool && lastEntry?.kind !== "thinking") {
|
|
9099
|
-
entries.push({ kind: "thinking", key: `${tailMsg.id}-tail-thinking` });
|
|
9100
|
-
}
|
|
9101
9156
|
const tail = messages[messages.length - 1];
|
|
9102
9157
|
const showErrorInfo = tail && tail.role === "assistant" && tail.status === "error" && !!tail.errorInfo;
|
|
9103
9158
|
return /* @__PURE__ */ jsxRuntime.jsx(Message, { from: "assistant", children: /* @__PURE__ */ jsxRuntime.jsxs(MessageContent, { children: [
|
|
@@ -9145,11 +9200,30 @@ function RetryBanner({ indicator }) {
|
|
|
9145
9200
|
}
|
|
9146
9201
|
);
|
|
9147
9202
|
}
|
|
9203
|
+
function WorkingOnItIndicator() {
|
|
9204
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Message, { from: "assistant", children: /* @__PURE__ */ jsxRuntime.jsx(MessageContent, { children: /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { duration: 3, spread: 3, className: "text-sm", children: "Working on it..." }) }) });
|
|
9205
|
+
}
|
|
9206
|
+
function useDelayedRunningIndicator(isRunning) {
|
|
9207
|
+
const [visible, setVisible] = react.useState(isRunning);
|
|
9208
|
+
react.useEffect(() => {
|
|
9209
|
+
if (!isRunning) {
|
|
9210
|
+
setVisible(false);
|
|
9211
|
+
return;
|
|
9212
|
+
}
|
|
9213
|
+
if (visible) return;
|
|
9214
|
+
const timeout = window.setTimeout(() => {
|
|
9215
|
+
setVisible(true);
|
|
9216
|
+
}, WORKING_ON_IT_DELAY_MS);
|
|
9217
|
+
return () => {
|
|
9218
|
+
window.clearTimeout(timeout);
|
|
9219
|
+
};
|
|
9220
|
+
}, [isRunning, visible]);
|
|
9221
|
+
return visible;
|
|
9222
|
+
}
|
|
9148
9223
|
function ChatThread({
|
|
9149
9224
|
sessionId,
|
|
9150
9225
|
messages,
|
|
9151
9226
|
isRunning,
|
|
9152
|
-
terminal,
|
|
9153
9227
|
isLoadingHistory = false,
|
|
9154
9228
|
onSend,
|
|
9155
9229
|
onStop,
|
|
@@ -9170,6 +9244,7 @@ function ChatThread({
|
|
|
9170
9244
|
onViewModeChange
|
|
9171
9245
|
}) {
|
|
9172
9246
|
const groups = react.useMemo(() => groupMessages(messages), [messages]);
|
|
9247
|
+
const showWorkingOnIt = useDelayedRunningIndicator(isRunning);
|
|
9173
9248
|
const artifactFallbacks = react.useMemo(() => {
|
|
9174
9249
|
const fallbacks = {};
|
|
9175
9250
|
const createArtifactToolCallIds = [];
|
|
@@ -9203,7 +9278,7 @@ function ChatThread({
|
|
|
9203
9278
|
}
|
|
9204
9279
|
return null;
|
|
9205
9280
|
}, [messages]);
|
|
9206
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden bg-background text-
|
|
9281
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden bg-background text-base", children: [
|
|
9207
9282
|
/* @__PURE__ */ jsxRuntime.jsxs(Conversation, { className: "relative flex-1 min-h-0", children: [
|
|
9208
9283
|
/* @__PURE__ */ jsxRuntime.jsx(ConversationContent, { className: "mx-auto w-full max-w-4xl", children: messages.length === 0 && isLoadingHistory ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
9209
9284
|
ConversationEmptyState,
|
|
@@ -9257,7 +9332,6 @@ function ChatThread({
|
|
|
9257
9332
|
lastGlobalIndex: group.lastGlobalIndex,
|
|
9258
9333
|
totalMessages: messages.length,
|
|
9259
9334
|
isRunning,
|
|
9260
|
-
terminal,
|
|
9261
9335
|
sessionId,
|
|
9262
9336
|
artifactFallbacks,
|
|
9263
9337
|
onFileSelect,
|
|
@@ -9267,7 +9341,7 @@ function ChatThread({
|
|
|
9267
9341
|
group.messages[0].id
|
|
9268
9342
|
);
|
|
9269
9343
|
}),
|
|
9270
|
-
|
|
9344
|
+
showWorkingOnIt && /* @__PURE__ */ jsxRuntime.jsx(WorkingOnItIndicator, {})
|
|
9271
9345
|
] }) }),
|
|
9272
9346
|
/* @__PURE__ */ jsxRuntime.jsx(ConversationScrollButton, {})
|
|
9273
9347
|
] }),
|
|
@@ -10060,6 +10134,9 @@ function applyAgentChatEvent(state, event) {
|
|
|
10060
10134
|
sessionDone: state.sessionDone || event.type === "session.done"
|
|
10061
10135
|
};
|
|
10062
10136
|
nextState = applyRetryIndicator(nextState, event);
|
|
10137
|
+
if (state.terminal && isPostTerminalLiveEvent(event.type)) {
|
|
10138
|
+
return nextState;
|
|
10139
|
+
}
|
|
10063
10140
|
switch (event.type) {
|
|
10064
10141
|
case "user.message":
|
|
10065
10142
|
return withMessages(
|
|
@@ -10202,6 +10279,9 @@ function applyAgentChatEvent(state, event) {
|
|
|
10202
10279
|
return applyTurnSummary(nextState, event);
|
|
10203
10280
|
}
|
|
10204
10281
|
}
|
|
10282
|
+
function isPostTerminalLiveEvent(type) {
|
|
10283
|
+
return type === "harness.wake" || type === "llm.request" || type === "session.resume" || type === "llm.delta" || type === "llm.response" || type === "llm.thinking" || type === "tool.call";
|
|
10284
|
+
}
|
|
10205
10285
|
function applyRetryIndicator(state, event) {
|
|
10206
10286
|
switch (event.type) {
|
|
10207
10287
|
case "harness.wake":
|
|
@@ -10390,30 +10470,18 @@ function applyLlmResponse(state, event) {
|
|
|
10390
10470
|
);
|
|
10391
10471
|
if (state.hadDeltas && idx >= 0 && !hasUserAfter) {
|
|
10392
10472
|
const current = messages[idx];
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10398
|
-
|
|
10399
|
-
|
|
10400
|
-
turnId: turnId ?? current.turnId,
|
|
10401
|
-
iterationIndex: iterationIndex ?? current.iterationIndex
|
|
10402
|
-
};
|
|
10403
|
-
} else {
|
|
10404
|
-
messages[idx] = {
|
|
10405
|
-
...current,
|
|
10406
|
-
status: "complete",
|
|
10407
|
-
llmResponseEventId: event.eventId,
|
|
10408
|
-
turnId: turnId ?? current.turnId,
|
|
10409
|
-
iterationIndex: iterationIndex ?? current.iterationIndex
|
|
10410
|
-
};
|
|
10411
|
-
}
|
|
10473
|
+
messages[idx] = {
|
|
10474
|
+
...current,
|
|
10475
|
+
status: hasToolCalls ? "streaming" : "complete",
|
|
10476
|
+
llmResponseEventId: event.eventId,
|
|
10477
|
+
turnId: turnId ?? current.turnId,
|
|
10478
|
+
iterationIndex: iterationIndex ?? current.iterationIndex
|
|
10479
|
+
};
|
|
10412
10480
|
} else if (matchesExistingToolTurn && idx >= 0) {
|
|
10413
10481
|
const current = messages[idx];
|
|
10414
10482
|
messages[idx] = {
|
|
10415
10483
|
...current,
|
|
10416
|
-
|
|
10484
|
+
content: responseContent ? appendText(current.content, responseContent) : current.content,
|
|
10417
10485
|
status: "streaming",
|
|
10418
10486
|
llmResponseEventId: event.eventId,
|
|
10419
10487
|
turnId: turnId ?? current.turnId,
|
|
@@ -10423,8 +10491,8 @@ function applyLlmResponse(state, event) {
|
|
|
10423
10491
|
messages.push({
|
|
10424
10492
|
id: `evt-${event.eventId}`,
|
|
10425
10493
|
role: "assistant",
|
|
10426
|
-
content:
|
|
10427
|
-
reasoning:
|
|
10494
|
+
content: responseContent,
|
|
10495
|
+
reasoning: void 0,
|
|
10428
10496
|
createdAt: /* @__PURE__ */ new Date(),
|
|
10429
10497
|
status: hasToolCalls ? "streaming" : "complete",
|
|
10430
10498
|
llmResponseEventId: event.eventId,
|
|
@@ -10433,25 +10501,14 @@ function applyLlmResponse(state, event) {
|
|
|
10433
10501
|
});
|
|
10434
10502
|
} else {
|
|
10435
10503
|
const current = messages[idx];
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
|
|
10440
|
-
|
|
10441
|
-
|
|
10442
|
-
|
|
10443
|
-
|
|
10444
|
-
};
|
|
10445
|
-
} else {
|
|
10446
|
-
messages[idx] = {
|
|
10447
|
-
...current,
|
|
10448
|
-
content: responseContent || current.content,
|
|
10449
|
-
status: hasToolCalls ? "streaming" : "complete",
|
|
10450
|
-
llmResponseEventId: event.eventId,
|
|
10451
|
-
turnId: turnId ?? current.turnId,
|
|
10452
|
-
iterationIndex: iterationIndex ?? current.iterationIndex
|
|
10453
|
-
};
|
|
10454
|
-
}
|
|
10504
|
+
messages[idx] = {
|
|
10505
|
+
...current,
|
|
10506
|
+
content: responseContent || current.content,
|
|
10507
|
+
status: hasToolCalls ? "streaming" : "complete",
|
|
10508
|
+
llmResponseEventId: event.eventId,
|
|
10509
|
+
turnId: turnId ?? current.turnId,
|
|
10510
|
+
iterationIndex: iterationIndex ?? current.iterationIndex
|
|
10511
|
+
};
|
|
10455
10512
|
}
|
|
10456
10513
|
const inputTokens = numberValue(event.data.input_tokens);
|
|
10457
10514
|
const outputTokens = numberValue(event.data.output_tokens);
|
|
@@ -13825,7 +13882,7 @@ function TreeNodeRow({
|
|
|
13825
13882
|
type: "button",
|
|
13826
13883
|
className: cn(
|
|
13827
13884
|
"p-2 md:p-1 rounded hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none transition-all",
|
|
13828
|
-
deletingSessionId === entry.id ? "opacity-100" : "opacity-
|
|
13885
|
+
deletingSessionId === entry.id ? "opacity-100" : "opacity-60 md:opacity-50 md:group-hover:opacity-100 md:focus-visible:opacity-100"
|
|
13829
13886
|
),
|
|
13830
13887
|
onClick: (e) => {
|
|
13831
13888
|
e.stopPropagation();
|