@invergent/agent-chat-react 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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.js
CHANGED
|
@@ -885,9 +885,9 @@ var defaultGetThinkingMessage = (isStreaming, duration) => {
|
|
|
885
885
|
return /* @__PURE__ */ jsx(Shimmer, { duration: 1, children: "Thinking..." });
|
|
886
886
|
}
|
|
887
887
|
if (duration === void 0) {
|
|
888
|
-
return /* @__PURE__ */ jsx("p", { className: "text-foreground", children: "Thought for a few seconds" });
|
|
888
|
+
return /* @__PURE__ */ jsx("p", { className: "text-muted-foreground italic", children: "Thought for a few seconds" });
|
|
889
889
|
}
|
|
890
|
-
return /* @__PURE__ */ jsxs("p", { className: "text-foreground", children: [
|
|
890
|
+
return /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground italic", children: [
|
|
891
891
|
"Thought for ",
|
|
892
892
|
duration,
|
|
893
893
|
" seconds"
|
|
@@ -6580,6 +6580,59 @@ function useSmoothStream(target, isStreaming) {
|
|
|
6580
6580
|
}, [isActive]);
|
|
6581
6581
|
return displayedLen >= target.length ? target : target.slice(0, displayedLen);
|
|
6582
6582
|
}
|
|
6583
|
+
|
|
6584
|
+
// src/lib/next-action.ts
|
|
6585
|
+
var _NEXT_ACTION_RE = /<next_action([^>]*)>([\s\S]*?)<\/next_action>\s*/gi;
|
|
6586
|
+
var _ATTR_RE = /(\w+)="([^"]*)"/g;
|
|
6587
|
+
var _VALID_COMPLEXITY = /* @__PURE__ */ new Set([
|
|
6588
|
+
"low",
|
|
6589
|
+
"medium",
|
|
6590
|
+
"high"
|
|
6591
|
+
]);
|
|
6592
|
+
var _VALID_SUMMARY = /* @__PURE__ */ new Set([
|
|
6593
|
+
"show",
|
|
6594
|
+
"hide"
|
|
6595
|
+
]);
|
|
6596
|
+
function _parseAttrs(rawAttrs) {
|
|
6597
|
+
const out = {};
|
|
6598
|
+
for (const m of rawAttrs.matchAll(_ATTR_RE)) {
|
|
6599
|
+
out[m[1].toLowerCase()] = m[2];
|
|
6600
|
+
}
|
|
6601
|
+
return out;
|
|
6602
|
+
}
|
|
6603
|
+
function _inferNarration(text) {
|
|
6604
|
+
if (!text) return null;
|
|
6605
|
+
const head = text.trimStart().split(/\n\s*\n/, 1)[0].slice(0, 240);
|
|
6606
|
+
const endMatch = /([.!?])(\s|$)/.exec(head);
|
|
6607
|
+
const firstSentence = (endMatch ? head.slice(0, endMatch.index + 1) : head).trim();
|
|
6608
|
+
if (!firstSentence || firstSentence.length > 200) return null;
|
|
6609
|
+
return firstSentence;
|
|
6610
|
+
}
|
|
6611
|
+
function stripAndParseNextAction(text) {
|
|
6612
|
+
if (!text) {
|
|
6613
|
+
return { cleaned: text ?? "", action: null, inferredNarration: null };
|
|
6614
|
+
}
|
|
6615
|
+
let last = null;
|
|
6616
|
+
const matches = Array.from(text.matchAll(_NEXT_ACTION_RE));
|
|
6617
|
+
if (matches.length === 0) {
|
|
6618
|
+
return {
|
|
6619
|
+
cleaned: text,
|
|
6620
|
+
action: null,
|
|
6621
|
+
inferredNarration: _inferNarration(text)
|
|
6622
|
+
};
|
|
6623
|
+
}
|
|
6624
|
+
for (const match of matches) {
|
|
6625
|
+
const attrs = _parseAttrs(match[1] ?? "");
|
|
6626
|
+
const rawComplexity = (attrs["complexity"] ?? "").trim().toLowerCase();
|
|
6627
|
+
const complexity = _VALID_COMPLEXITY.has(rawComplexity) ? rawComplexity : "medium";
|
|
6628
|
+
const rawSummary = (attrs["summary"] ?? "").trim().toLowerCase();
|
|
6629
|
+
const summary = _VALID_SUMMARY.has(rawSummary) ? rawSummary : "hide";
|
|
6630
|
+
const body = (match[2] ?? "").trim() || "done";
|
|
6631
|
+
last = { complexity, summary, body };
|
|
6632
|
+
}
|
|
6633
|
+
const cleaned = text.replace(_NEXT_ACTION_RE, "").trimEnd();
|
|
6634
|
+
return { cleaned, action: last, inferredNarration: null };
|
|
6635
|
+
}
|
|
6583
6636
|
var Artifact = ({ className, ...props }) => /* @__PURE__ */ jsx(
|
|
6584
6637
|
"div",
|
|
6585
6638
|
{
|
|
@@ -6705,12 +6758,21 @@ var EXPANDED_HEIGHT_PX = 800;
|
|
|
6705
6758
|
var MIN_ZOOM = 0.5;
|
|
6706
6759
|
var MAX_ZOOM = 2;
|
|
6707
6760
|
var ZOOM_STEP = 0.1;
|
|
6761
|
+
var SAFETY_STYLE_PREAMBLE = "<style>html,body{max-height:100vh}canvas{max-height:80vh!important}</style>";
|
|
6762
|
+
function injectSafetyStyle(html) {
|
|
6763
|
+
const headCloseIdx = html.search(/<\/head\s*>/i);
|
|
6764
|
+
if (headCloseIdx >= 0) {
|
|
6765
|
+
return html.slice(0, headCloseIdx) + SAFETY_STYLE_PREAMBLE + html.slice(headCloseIdx);
|
|
6766
|
+
}
|
|
6767
|
+
return SAFETY_STYLE_PREAMBLE + html;
|
|
6768
|
+
}
|
|
6708
6769
|
function ArtifactHtml({
|
|
6709
6770
|
spec,
|
|
6710
6771
|
fill = false
|
|
6711
6772
|
}) {
|
|
6712
6773
|
const [expanded, setExpanded] = useState(false);
|
|
6713
6774
|
const [zoom, setZoom] = useState(1);
|
|
6775
|
+
const safeSrcdoc = useMemo(() => injectSafetyStyle(spec.html), [spec.html]);
|
|
6714
6776
|
const viewportHeight = expanded ? EXPANDED_HEIGHT_PX : DEFAULT_HEIGHT_PX;
|
|
6715
6777
|
const clamp = (v) => Math.round(Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, v)) * 100) / 100;
|
|
6716
6778
|
return /* @__PURE__ */ jsxs(
|
|
@@ -6730,7 +6792,7 @@ function ArtifactHtml({
|
|
|
6730
6792
|
"iframe",
|
|
6731
6793
|
{
|
|
6732
6794
|
title: "artifact-html",
|
|
6733
|
-
srcDoc:
|
|
6795
|
+
srcDoc: safeSrcdoc,
|
|
6734
6796
|
sandbox: "allow-scripts",
|
|
6735
6797
|
className: cn("border-0", fill && "h-full w-full"),
|
|
6736
6798
|
style: fill ? { zoom } : {
|
|
@@ -7824,16 +7886,6 @@ function TurnSummaryCard({
|
|
|
7824
7886
|
}) })
|
|
7825
7887
|
] });
|
|
7826
7888
|
}
|
|
7827
|
-
function TurnSummaryPending() {
|
|
7828
|
-
return /* @__PURE__ */ jsxs("div", { className: "mt-3 rounded border border-border bg-muted/50 px-3 py-2 text-sm", children: [
|
|
7829
|
-
/* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-semibold uppercase tracking-wide", children: "Summary" }),
|
|
7830
|
-
/* @__PURE__ */ jsx(Shimmer, { duration: 3, spread: 3, className: "mb-2 text-sm", children: "Summarizing conversation..." }),
|
|
7831
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
7832
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-3/4" }),
|
|
7833
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-2/3" })
|
|
7834
|
-
] })
|
|
7835
|
-
] });
|
|
7836
|
-
}
|
|
7837
7889
|
function ArtifactRow({
|
|
7838
7890
|
artifact,
|
|
7839
7891
|
sessionId,
|
|
@@ -7896,6 +7948,7 @@ function ArtifactRow({
|
|
|
7896
7948
|
}
|
|
7897
7949
|
) });
|
|
7898
7950
|
}
|
|
7951
|
+
var WORKING_ON_IT_DELAY_MS = 250;
|
|
7899
7952
|
function messageToEntries(msg, isLast, artifactFallbacks) {
|
|
7900
7953
|
if (msg.role === "system") {
|
|
7901
7954
|
if (msg.systemKind === "skill_invoked") {
|
|
@@ -7926,16 +7979,23 @@ function messageToEntries(msg, isLast, artifactFallbacks) {
|
|
|
7926
7979
|
const hasToolCalls = !!(msg.toolCalls && msg.toolCalls.length > 0);
|
|
7927
7980
|
const hasContent = !!(msg.content && msg.content !== msg.reasoning);
|
|
7928
7981
|
const isStreaming = msg.status === "streaming" && isLast;
|
|
7929
|
-
const effectiveReasoning = hasToolCalls && hasContent ? msg.reasoning ? msg.reasoning + "\n" + msg.content : msg.content : msg.reasoning;
|
|
7930
7982
|
const effectiveHasContent = hasContent && !hasToolCalls;
|
|
7931
|
-
if (
|
|
7983
|
+
if (msg.reasoning) {
|
|
7932
7984
|
entries.push({
|
|
7933
7985
|
kind: "reasoning",
|
|
7934
7986
|
key: `${msg.id}-reasoning`,
|
|
7935
|
-
reasoning:
|
|
7987
|
+
reasoning: msg.reasoning,
|
|
7936
7988
|
isStreaming: isStreaming && !effectiveHasContent && !hasToolCalls
|
|
7937
7989
|
});
|
|
7938
7990
|
}
|
|
7991
|
+
if (hasContent && hasToolCalls) {
|
|
7992
|
+
entries.push({
|
|
7993
|
+
kind: "narration",
|
|
7994
|
+
key: `${msg.id}-narration`,
|
|
7995
|
+
text: msg.content,
|
|
7996
|
+
isStreaming: isStreaming && !effectiveHasContent
|
|
7997
|
+
});
|
|
7998
|
+
}
|
|
7939
7999
|
if (hasToolCalls) {
|
|
7940
8000
|
for (const tc of msg.toolCalls) {
|
|
7941
8001
|
if (tc.toolName === "create_artifact") {
|
|
@@ -7966,12 +8026,6 @@ function messageToEntries(msg, isLast, artifactFallbacks) {
|
|
|
7966
8026
|
msg
|
|
7967
8027
|
});
|
|
7968
8028
|
}
|
|
7969
|
-
const hasRunningTool = hasToolCalls && msg.toolCalls.some(
|
|
7970
|
-
(tc) => tc.status === "running"
|
|
7971
|
-
);
|
|
7972
|
-
if (isStreaming && !effectiveHasContent && !hasRunningTool) {
|
|
7973
|
-
entries.push({ kind: "thinking", key: `${msg.id}-thinking` });
|
|
7974
|
-
}
|
|
7975
8029
|
return entries;
|
|
7976
8030
|
}
|
|
7977
8031
|
function groupBrowserActivityEntries(entries) {
|
|
@@ -8083,7 +8137,10 @@ function OrphanSystemMarker({
|
|
|
8083
8137
|
return /* @__PURE__ */ jsxs("div", { className: "my-2 flex items-center gap-2 px-4 text-xs text-foreground/60 ", children: [
|
|
8084
8138
|
/* @__PURE__ */ jsx("span", { className: "size-2 rounded-full bg-emerald-500" }),
|
|
8085
8139
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
8086
|
-
/* @__PURE__ */
|
|
8140
|
+
/* @__PURE__ */ jsxs("span", { className: "font-semibold text-foreground", children: [
|
|
8141
|
+
"Running skill",
|
|
8142
|
+
" "
|
|
8143
|
+
] }),
|
|
8087
8144
|
/* @__PURE__ */ jsx("span", { className: "text-foreground/60 truncate", children: skill })
|
|
8088
8145
|
] })
|
|
8089
8146
|
] });
|
|
@@ -8198,6 +8255,9 @@ function TimelineEntryItem({
|
|
|
8198
8255
|
if (entry.kind === "text") {
|
|
8199
8256
|
return /* @__PURE__ */ jsx(TextEntry, { entry, step });
|
|
8200
8257
|
}
|
|
8258
|
+
if (entry.kind === "narration") {
|
|
8259
|
+
return /* @__PURE__ */ jsx(NarrationEntry, { entry, step });
|
|
8260
|
+
}
|
|
8201
8261
|
if (entry.kind === "skill_invoked") {
|
|
8202
8262
|
return /* @__PURE__ */ jsxs(TimelineItem, { step, children: [
|
|
8203
8263
|
/* @__PURE__ */ jsxs(TimelineHeader, { children: [
|
|
@@ -8256,18 +8316,35 @@ function ReasoningEntry({
|
|
|
8256
8316
|
] }) })
|
|
8257
8317
|
] });
|
|
8258
8318
|
}
|
|
8319
|
+
function NarrationEntry({
|
|
8320
|
+
entry,
|
|
8321
|
+
step
|
|
8322
|
+
}) {
|
|
8323
|
+
const text = useSmoothStream(entry.text, entry.isStreaming);
|
|
8324
|
+
const { action, inferredNarration } = stripAndParseNextAction(text);
|
|
8325
|
+
const line = action ? action.body.trim().toLowerCase() === "done" ? null : action.body : inferredNarration;
|
|
8326
|
+
if (!line) return null;
|
|
8327
|
+
return /* @__PURE__ */ jsxs(TimelineItem, { step, children: [
|
|
8328
|
+
/* @__PURE__ */ jsxs(TimelineHeader, { children: [
|
|
8329
|
+
/* @__PURE__ */ jsx(TimelineSeparator, { style: { backgroundColor: "var(--color-border)" } }),
|
|
8330
|
+
/* @__PURE__ */ jsx(TimelineIndicator, { className: "size-2 border-none bg-foreground/30" })
|
|
8331
|
+
] }),
|
|
8332
|
+
/* @__PURE__ */ jsx(TimelineContent, { children: /* @__PURE__ */ jsx("p", { children: line }) })
|
|
8333
|
+
] });
|
|
8334
|
+
}
|
|
8259
8335
|
function TextEntry({
|
|
8260
8336
|
entry,
|
|
8261
8337
|
step
|
|
8262
8338
|
}) {
|
|
8263
8339
|
const content = useSmoothStream(entry.content, entry.isStreaming);
|
|
8340
|
+
const { cleaned } = stripAndParseNextAction(content);
|
|
8264
8341
|
return /* @__PURE__ */ jsxs(TimelineItem, { step, children: [
|
|
8265
8342
|
/* @__PURE__ */ jsxs(TimelineHeader, { children: [
|
|
8266
8343
|
/* @__PURE__ */ jsx(TimelineSeparator, { style: { backgroundColor: "var(--color-border)" } }),
|
|
8267
8344
|
/* @__PURE__ */ jsx(TimelineIndicator, { className: "size-2 border-none bg-foreground/40" })
|
|
8268
8345
|
] }),
|
|
8269
8346
|
/* @__PURE__ */ jsxs(TimelineContent, { children: [
|
|
8270
|
-
/* @__PURE__ */ jsx(MessageResponse, { children:
|
|
8347
|
+
/* @__PURE__ */ jsx(MessageResponse, { children: cleaned }),
|
|
8271
8348
|
entry.isFinalTurnText && entry.msg.status === "complete" && /* @__PURE__ */ jsx(TurnFeedback, { msg: entry.msg })
|
|
8272
8349
|
] })
|
|
8273
8350
|
] });
|
|
@@ -8279,8 +8356,9 @@ function SimpleFinalAnswer({
|
|
|
8279
8356
|
}) {
|
|
8280
8357
|
const content = useSmoothStream(text, isStreaming);
|
|
8281
8358
|
const revealComplete = content.length >= text.length;
|
|
8359
|
+
const { cleaned } = stripAndParseNextAction(content);
|
|
8282
8360
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
8283
|
-
/* @__PURE__ */ jsx(MessageResponse, { children:
|
|
8361
|
+
/* @__PURE__ */ jsx(MessageResponse, { children: cleaned }),
|
|
8284
8362
|
tail?.status === "complete" && revealComplete && /* @__PURE__ */ jsx(TurnFeedback, { msg: tail })
|
|
8285
8363
|
] });
|
|
8286
8364
|
}
|
|
@@ -8573,7 +8651,7 @@ function IterationGroup({
|
|
|
8573
8651
|
if (!label) {
|
|
8574
8652
|
return null;
|
|
8575
8653
|
}
|
|
8576
|
-
const labelTone = summary ? "text-foreground
|
|
8654
|
+
const labelTone = summary ? "text-muted-foreground italic" : "text-muted-foreground";
|
|
8577
8655
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
8578
8656
|
/* @__PURE__ */ jsxs(
|
|
8579
8657
|
"button",
|
|
@@ -8659,10 +8737,7 @@ function deriveFileArtifactsFromMessages(messages) {
|
|
|
8659
8737
|
}
|
|
8660
8738
|
function SimpleAssistantGroup({
|
|
8661
8739
|
messages,
|
|
8662
|
-
lastGlobalIndex,
|
|
8663
|
-
totalMessages,
|
|
8664
8740
|
isRunning,
|
|
8665
|
-
terminal,
|
|
8666
8741
|
sessionId,
|
|
8667
8742
|
artifactFallbacks,
|
|
8668
8743
|
onFileSelect,
|
|
@@ -8673,16 +8748,15 @@ function SimpleAssistantGroup({
|
|
|
8673
8748
|
const tailHasTools = !!(tail?.toolCalls && tail.toolCalls.length > 0);
|
|
8674
8749
|
const tailIsTextOnly = !!tail && !tailHasTools;
|
|
8675
8750
|
const finalText = tailIsTextOnly && tail.content ? tail.content : "";
|
|
8676
|
-
const isTailGroup = lastGlobalIndex === totalMessages - 1;
|
|
8677
|
-
const tailRendersOwnShimmer = !!tail && isIterationLive(tail) && !tailIsTextOnly;
|
|
8678
|
-
const showThinkingShim = isTailGroup && isRunning && !tailRendersOwnShimmer;
|
|
8679
8751
|
const showErrorInfo = !!tail && tail.status === "error" && !!tail.errorInfo;
|
|
8680
8752
|
const turnComplete = !isRunning && tail?.status === "complete";
|
|
8753
|
+
const summaryPref = finalText !== null ? stripAndParseNextAction(finalText).action?.summary ?? "hide" : "hide";
|
|
8681
8754
|
const effectiveTurnSummary = (() => {
|
|
8682
8755
|
const fromHarness = tail?.turnSummary;
|
|
8683
8756
|
if (fromHarness && fromHarness.artifacts.length > 0) {
|
|
8684
8757
|
return fromHarness;
|
|
8685
8758
|
}
|
|
8759
|
+
if (summaryPref === "hide") return null;
|
|
8686
8760
|
if (!turnComplete) return fromHarness;
|
|
8687
8761
|
const derived = deriveFileArtifactsFromMessages(messages);
|
|
8688
8762
|
if (derived.length === 0) return fromHarness;
|
|
@@ -8706,17 +8780,22 @@ function SimpleAssistantGroup({
|
|
|
8706
8780
|
message.id
|
|
8707
8781
|
);
|
|
8708
8782
|
}
|
|
8709
|
-
if (message === tail && tailIsTextOnly) return null;
|
|
8710
|
-
|
|
8711
|
-
|
|
8712
|
-
|
|
8713
|
-
|
|
8714
|
-
|
|
8715
|
-
|
|
8716
|
-
|
|
8717
|
-
|
|
8718
|
-
|
|
8719
|
-
|
|
8783
|
+
if (message === tail && tailIsTextOnly && finalText) return null;
|
|
8784
|
+
const rawContent = (message.content ?? "").trim();
|
|
8785
|
+
const { action, inferredNarration } = stripAndParseNextAction(rawContent);
|
|
8786
|
+
const narrationLine = action ? action.body.trim().toLowerCase() === "done" ? null : action.body : inferredNarration;
|
|
8787
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
8788
|
+
narrationLine && /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground", children: narrationLine }),
|
|
8789
|
+
/* @__PURE__ */ jsx(
|
|
8790
|
+
IterationGroup,
|
|
8791
|
+
{
|
|
8792
|
+
message,
|
|
8793
|
+
sessionId,
|
|
8794
|
+
artifactFallbacks,
|
|
8795
|
+
onFileSelect
|
|
8796
|
+
}
|
|
8797
|
+
)
|
|
8798
|
+
] }, message.id);
|
|
8720
8799
|
}) }),
|
|
8721
8800
|
finalText && /* @__PURE__ */ jsx(
|
|
8722
8801
|
SimpleFinalAnswer,
|
|
@@ -8726,8 +8805,7 @@ function SimpleAssistantGroup({
|
|
|
8726
8805
|
tail
|
|
8727
8806
|
}
|
|
8728
8807
|
),
|
|
8729
|
-
|
|
8730
|
-
effectiveTurnSummary ? /* @__PURE__ */ jsx(
|
|
8808
|
+
effectiveTurnSummary && /* @__PURE__ */ jsx(
|
|
8731
8809
|
TurnSummaryCard,
|
|
8732
8810
|
{
|
|
8733
8811
|
summary: effectiveTurnSummary,
|
|
@@ -8735,16 +8813,6 @@ function SimpleAssistantGroup({
|
|
|
8735
8813
|
messages,
|
|
8736
8814
|
onFileSelect
|
|
8737
8815
|
}
|
|
8738
|
-
) : (
|
|
8739
|
-
// The harness summarizer runs after the last assistant
|
|
8740
|
-
// response and before ``session.complete``. Show a pending
|
|
8741
|
-
// placeholder during that window so users aren't surprised
|
|
8742
|
-
// when the Summary card pops in. Gated on ``!terminal``
|
|
8743
|
-
// rather than ``isRunning`` because the text-only final
|
|
8744
|
-
// ``llm.response`` already flips ``isRunning`` to false —
|
|
8745
|
-
// the summarizer then runs in the gap before
|
|
8746
|
-
// ``session.complete`` (which is what sets ``terminal``).
|
|
8747
|
-
isTailGroup && !terminal && !!finalText && tail?.status === "complete" && /* @__PURE__ */ jsx(TurnSummaryPending, {})
|
|
8748
8816
|
),
|
|
8749
8817
|
showErrorInfo && /* @__PURE__ */ jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsx(ErrorMessage, { errorInfo: tail.errorInfo, onRetry }) })
|
|
8750
8818
|
] }) });
|
|
@@ -8754,7 +8822,6 @@ function AssistantGroup({
|
|
|
8754
8822
|
lastGlobalIndex,
|
|
8755
8823
|
totalMessages,
|
|
8756
8824
|
isRunning,
|
|
8757
|
-
terminal,
|
|
8758
8825
|
sessionId,
|
|
8759
8826
|
artifactFallbacks,
|
|
8760
8827
|
onFileSelect,
|
|
@@ -8766,10 +8833,7 @@ function AssistantGroup({
|
|
|
8766
8833
|
SimpleAssistantGroup,
|
|
8767
8834
|
{
|
|
8768
8835
|
messages,
|
|
8769
|
-
lastGlobalIndex,
|
|
8770
|
-
totalMessages,
|
|
8771
8836
|
isRunning,
|
|
8772
|
-
terminal,
|
|
8773
8837
|
sessionId,
|
|
8774
8838
|
artifactFallbacks,
|
|
8775
8839
|
onFileSelect,
|
|
@@ -8791,15 +8855,6 @@ function AssistantGroup({
|
|
|
8791
8855
|
break;
|
|
8792
8856
|
}
|
|
8793
8857
|
}
|
|
8794
|
-
const isTailGroup = lastGlobalIndex === totalMessages - 1;
|
|
8795
|
-
const lastEntry = entries[entries.length - 1];
|
|
8796
|
-
const hasRunningTool = entries.some(
|
|
8797
|
-
(e) => e.kind === "tool" && e.tc.status === "running"
|
|
8798
|
-
);
|
|
8799
|
-
const tailMsg = messages[messages.length - 1];
|
|
8800
|
-
if (isTailGroup && isRunning && !hasRunningTool && lastEntry?.kind !== "thinking") {
|
|
8801
|
-
entries.push({ kind: "thinking", key: `${tailMsg.id}-tail-thinking` });
|
|
8802
|
-
}
|
|
8803
8858
|
const tail = messages[messages.length - 1];
|
|
8804
8859
|
const showErrorInfo = tail && tail.role === "assistant" && tail.status === "error" && !!tail.errorInfo;
|
|
8805
8860
|
return /* @__PURE__ */ jsx(Message, { from: "assistant", children: /* @__PURE__ */ jsxs(MessageContent, { children: [
|
|
@@ -8847,11 +8902,30 @@ function RetryBanner({ indicator }) {
|
|
|
8847
8902
|
}
|
|
8848
8903
|
);
|
|
8849
8904
|
}
|
|
8905
|
+
function WorkingOnItIndicator() {
|
|
8906
|
+
return /* @__PURE__ */ jsx(Message, { from: "assistant", children: /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(Shimmer, { duration: 3, spread: 3, className: "text-sm", children: "Working on it..." }) }) });
|
|
8907
|
+
}
|
|
8908
|
+
function useDelayedRunningIndicator(isRunning) {
|
|
8909
|
+
const [visible, setVisible] = useState(isRunning);
|
|
8910
|
+
useEffect(() => {
|
|
8911
|
+
if (!isRunning) {
|
|
8912
|
+
setVisible(false);
|
|
8913
|
+
return;
|
|
8914
|
+
}
|
|
8915
|
+
if (visible) return;
|
|
8916
|
+
const timeout = window.setTimeout(() => {
|
|
8917
|
+
setVisible(true);
|
|
8918
|
+
}, WORKING_ON_IT_DELAY_MS);
|
|
8919
|
+
return () => {
|
|
8920
|
+
window.clearTimeout(timeout);
|
|
8921
|
+
};
|
|
8922
|
+
}, [isRunning, visible]);
|
|
8923
|
+
return visible;
|
|
8924
|
+
}
|
|
8850
8925
|
function ChatThread({
|
|
8851
8926
|
sessionId,
|
|
8852
8927
|
messages,
|
|
8853
8928
|
isRunning,
|
|
8854
|
-
terminal,
|
|
8855
8929
|
isLoadingHistory = false,
|
|
8856
8930
|
onSend,
|
|
8857
8931
|
onStop,
|
|
@@ -8872,6 +8946,7 @@ function ChatThread({
|
|
|
8872
8946
|
onViewModeChange
|
|
8873
8947
|
}) {
|
|
8874
8948
|
const groups = useMemo(() => groupMessages(messages), [messages]);
|
|
8949
|
+
const showWorkingOnIt = useDelayedRunningIndicator(isRunning);
|
|
8875
8950
|
const artifactFallbacks = useMemo(() => {
|
|
8876
8951
|
const fallbacks = {};
|
|
8877
8952
|
const createArtifactToolCallIds = [];
|
|
@@ -8905,7 +8980,7 @@ function ChatThread({
|
|
|
8905
8980
|
}
|
|
8906
8981
|
return null;
|
|
8907
8982
|
}, [messages]);
|
|
8908
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden bg-background text-
|
|
8983
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden bg-background text-base", children: [
|
|
8909
8984
|
/* @__PURE__ */ jsxs(Conversation, { className: "relative flex-1 min-h-0", children: [
|
|
8910
8985
|
/* @__PURE__ */ jsx(ConversationContent, { className: "mx-auto w-full max-w-4xl", children: messages.length === 0 && isLoadingHistory ? /* @__PURE__ */ jsx(
|
|
8911
8986
|
ConversationEmptyState,
|
|
@@ -8959,7 +9034,6 @@ function ChatThread({
|
|
|
8959
9034
|
lastGlobalIndex: group.lastGlobalIndex,
|
|
8960
9035
|
totalMessages: messages.length,
|
|
8961
9036
|
isRunning,
|
|
8962
|
-
terminal,
|
|
8963
9037
|
sessionId,
|
|
8964
9038
|
artifactFallbacks,
|
|
8965
9039
|
onFileSelect,
|
|
@@ -8969,7 +9043,7 @@ function ChatThread({
|
|
|
8969
9043
|
group.messages[0].id
|
|
8970
9044
|
);
|
|
8971
9045
|
}),
|
|
8972
|
-
|
|
9046
|
+
showWorkingOnIt && /* @__PURE__ */ jsx(WorkingOnItIndicator, {})
|
|
8973
9047
|
] }) }),
|
|
8974
9048
|
/* @__PURE__ */ jsx(ConversationScrollButton, {})
|
|
8975
9049
|
] }),
|
|
@@ -9753,6 +9827,9 @@ function applyAgentChatEvent(state, event) {
|
|
|
9753
9827
|
sessionDone: state.sessionDone || event.type === "session.done"
|
|
9754
9828
|
};
|
|
9755
9829
|
nextState = applyRetryIndicator(nextState, event);
|
|
9830
|
+
if (state.terminal && isPostTerminalLiveEvent(event.type)) {
|
|
9831
|
+
return nextState;
|
|
9832
|
+
}
|
|
9756
9833
|
switch (event.type) {
|
|
9757
9834
|
case "user.message":
|
|
9758
9835
|
return withMessages(
|
|
@@ -9895,6 +9972,9 @@ function applyAgentChatEvent(state, event) {
|
|
|
9895
9972
|
return applyTurnSummary(nextState, event);
|
|
9896
9973
|
}
|
|
9897
9974
|
}
|
|
9975
|
+
function isPostTerminalLiveEvent(type) {
|
|
9976
|
+
return type === "harness.wake" || type === "llm.request" || type === "session.resume" || type === "llm.delta" || type === "llm.response" || type === "llm.thinking" || type === "tool.call";
|
|
9977
|
+
}
|
|
9898
9978
|
function applyRetryIndicator(state, event) {
|
|
9899
9979
|
switch (event.type) {
|
|
9900
9980
|
case "harness.wake":
|
|
@@ -10083,30 +10163,18 @@ function applyLlmResponse(state, event) {
|
|
|
10083
10163
|
);
|
|
10084
10164
|
if (state.hadDeltas && idx >= 0 && !hasUserAfter) {
|
|
10085
10165
|
const current = messages[idx];
|
|
10086
|
-
|
|
10087
|
-
|
|
10088
|
-
|
|
10089
|
-
|
|
10090
|
-
|
|
10091
|
-
|
|
10092
|
-
|
|
10093
|
-
turnId: turnId ?? current.turnId,
|
|
10094
|
-
iterationIndex: iterationIndex ?? current.iterationIndex
|
|
10095
|
-
};
|
|
10096
|
-
} else {
|
|
10097
|
-
messages[idx] = {
|
|
10098
|
-
...current,
|
|
10099
|
-
status: "complete",
|
|
10100
|
-
llmResponseEventId: event.eventId,
|
|
10101
|
-
turnId: turnId ?? current.turnId,
|
|
10102
|
-
iterationIndex: iterationIndex ?? current.iterationIndex
|
|
10103
|
-
};
|
|
10104
|
-
}
|
|
10166
|
+
messages[idx] = {
|
|
10167
|
+
...current,
|
|
10168
|
+
status: hasToolCalls ? "streaming" : "complete",
|
|
10169
|
+
llmResponseEventId: event.eventId,
|
|
10170
|
+
turnId: turnId ?? current.turnId,
|
|
10171
|
+
iterationIndex: iterationIndex ?? current.iterationIndex
|
|
10172
|
+
};
|
|
10105
10173
|
} else if (matchesExistingToolTurn && idx >= 0) {
|
|
10106
10174
|
const current = messages[idx];
|
|
10107
10175
|
messages[idx] = {
|
|
10108
10176
|
...current,
|
|
10109
|
-
|
|
10177
|
+
content: responseContent ? appendText(current.content, responseContent) : current.content,
|
|
10110
10178
|
status: "streaming",
|
|
10111
10179
|
llmResponseEventId: event.eventId,
|
|
10112
10180
|
turnId: turnId ?? current.turnId,
|
|
@@ -10116,8 +10184,8 @@ function applyLlmResponse(state, event) {
|
|
|
10116
10184
|
messages.push({
|
|
10117
10185
|
id: `evt-${event.eventId}`,
|
|
10118
10186
|
role: "assistant",
|
|
10119
|
-
content:
|
|
10120
|
-
reasoning:
|
|
10187
|
+
content: responseContent,
|
|
10188
|
+
reasoning: void 0,
|
|
10121
10189
|
createdAt: /* @__PURE__ */ new Date(),
|
|
10122
10190
|
status: hasToolCalls ? "streaming" : "complete",
|
|
10123
10191
|
llmResponseEventId: event.eventId,
|
|
@@ -10126,25 +10194,14 @@ function applyLlmResponse(state, event) {
|
|
|
10126
10194
|
});
|
|
10127
10195
|
} else {
|
|
10128
10196
|
const current = messages[idx];
|
|
10129
|
-
|
|
10130
|
-
|
|
10131
|
-
|
|
10132
|
-
|
|
10133
|
-
|
|
10134
|
-
|
|
10135
|
-
|
|
10136
|
-
|
|
10137
|
-
};
|
|
10138
|
-
} else {
|
|
10139
|
-
messages[idx] = {
|
|
10140
|
-
...current,
|
|
10141
|
-
content: responseContent || current.content,
|
|
10142
|
-
status: hasToolCalls ? "streaming" : "complete",
|
|
10143
|
-
llmResponseEventId: event.eventId,
|
|
10144
|
-
turnId: turnId ?? current.turnId,
|
|
10145
|
-
iterationIndex: iterationIndex ?? current.iterationIndex
|
|
10146
|
-
};
|
|
10147
|
-
}
|
|
10197
|
+
messages[idx] = {
|
|
10198
|
+
...current,
|
|
10199
|
+
content: responseContent || current.content,
|
|
10200
|
+
status: hasToolCalls ? "streaming" : "complete",
|
|
10201
|
+
llmResponseEventId: event.eventId,
|
|
10202
|
+
turnId: turnId ?? current.turnId,
|
|
10203
|
+
iterationIndex: iterationIndex ?? current.iterationIndex
|
|
10204
|
+
};
|
|
10148
10205
|
}
|
|
10149
10206
|
const inputTokens = numberValue(event.data.input_tokens);
|
|
10150
10207
|
const outputTokens = numberValue(event.data.output_tokens);
|
|
@@ -13511,7 +13568,7 @@ function TreeNodeRow({
|
|
|
13511
13568
|
type: "button",
|
|
13512
13569
|
className: cn(
|
|
13513
13570
|
"p-2 md:p-1 rounded hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none transition-all",
|
|
13514
|
-
deletingSessionId === entry.id ? "opacity-100" : "opacity-
|
|
13571
|
+
deletingSessionId === entry.id ? "opacity-100" : "opacity-60 md:opacity-50 md:group-hover:opacity-100 md:focus-visible:opacity-100"
|
|
13515
13572
|
),
|
|
13516
13573
|
onClick: (e) => {
|
|
13517
13574
|
e.stopPropagation();
|