@optilogic/chat 1.0.0-beta.9 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -0
- package/dist/index.cjs +709 -79
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +283 -4
- package/dist/index.d.ts +283 -4
- package/dist/index.js +674 -53
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/agent-response/AgentResponse.tsx +59 -13
- package/src/components/agent-response/components/MetadataRow.tsx +15 -4
- package/src/components/agent-response/components/TruncatedMessage.tsx +52 -0
- package/src/components/agent-response/components/index.ts +3 -0
- package/src/components/agent-response/hooks/useAgentResponseAccumulator.ts +65 -8
- package/src/components/agent-response/index.ts +19 -0
- package/src/components/agent-response/types.ts +61 -1
- package/src/components/agent-timeline/AgentTimeline.tsx +256 -0
- package/src/components/agent-timeline/TimelineAgentBlock.tsx +84 -0
- package/src/components/agent-timeline/TimelineItem.tsx +97 -0
- package/src/components/agent-timeline/index.ts +14 -0
- package/src/components/agent-timeline/types.ts +49 -0
- package/src/components/agent-timeline/utils.ts +189 -0
- package/src/components/hitl-interactions/HITLQuestionPanel.tsx +35 -21
- package/src/components/hitl-interactions/index.ts +1 -1
- package/src/components/inline-actions/ActionMarkdownRenderer.tsx +60 -0
- package/src/components/inline-actions/index.ts +18 -0
- package/src/components/inline-actions/parseResponseSegments.ts +66 -0
- package/src/components/inline-actions/prompts.ts +41 -0
- package/src/components/inline-actions/types.ts +57 -0
- package/src/components/user-prompt-input/UserPromptInput.tsx +13 -8
- package/src/components/user-prompt-input/types.ts +4 -0
- package/src/index.ts +29 -0
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React11 = require('react');
|
|
4
4
|
var core = require('@optilogic/core');
|
|
5
5
|
var lucideReact = require('lucide-react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -24,10 +24,10 @@ function _interopNamespace(e) {
|
|
|
24
24
|
return Object.freeze(n);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
var
|
|
27
|
+
var React11__namespace = /*#__PURE__*/_interopNamespace(React11);
|
|
28
28
|
|
|
29
29
|
// src/components/agent-response/AgentResponse.tsx
|
|
30
|
-
var ActivityIndicators =
|
|
30
|
+
var ActivityIndicators = React11__namespace.forwardRef(
|
|
31
31
|
({ toolCalls, knowledge, memory, statusUpdates = [], className, ...props }, ref) => {
|
|
32
32
|
const hasAnyActivity = toolCalls.length > 0 || knowledge.length > 0 || memory.length > 0 || statusUpdates.length > 0;
|
|
33
33
|
if (!hasAnyActivity) return null;
|
|
@@ -146,7 +146,7 @@ function formatTotalTime(seconds) {
|
|
|
146
146
|
const minutes = seconds / 60;
|
|
147
147
|
return `${minutes.toFixed(1)}m`;
|
|
148
148
|
}
|
|
149
|
-
var MetadataRow =
|
|
149
|
+
var MetadataRow = React11__namespace.forwardRef(
|
|
150
150
|
({
|
|
151
151
|
hasThinking,
|
|
152
152
|
isExpanded,
|
|
@@ -155,6 +155,7 @@ var MetadataRow = React10__namespace.forwardRef(
|
|
|
155
155
|
knowledge,
|
|
156
156
|
memory,
|
|
157
157
|
statusUpdates = [],
|
|
158
|
+
statusContent,
|
|
158
159
|
status,
|
|
159
160
|
elapsedTime,
|
|
160
161
|
className,
|
|
@@ -179,7 +180,7 @@ var MetadataRow = React10__namespace.forwardRef(
|
|
|
179
180
|
return null;
|
|
180
181
|
};
|
|
181
182
|
const leftContent = renderLeftContent();
|
|
182
|
-
if (!leftContent && !hasActivity) {
|
|
183
|
+
if (!leftContent && !hasActivity && !statusContent) {
|
|
183
184
|
return null;
|
|
184
185
|
}
|
|
185
186
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -193,10 +194,11 @@ var MetadataRow = React10__namespace.forwardRef(
|
|
|
193
194
|
"button",
|
|
194
195
|
{
|
|
195
196
|
onClick: onToggle,
|
|
196
|
-
className: "flex items-center gap-1.5 hover:bg-muted/50 -ml-1.5 pl-1.5 pr-2 py-0.5 rounded transition-colors",
|
|
197
|
+
className: "flex items-center gap-1.5 hover:bg-muted/50 -ml-1.5 pl-1.5 pr-2 py-0.5 rounded transition-colors shrink-0",
|
|
197
198
|
children: leftContent
|
|
198
199
|
}
|
|
199
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5", children: leftContent }),
|
|
200
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5 shrink-0", children: leftContent }),
|
|
201
|
+
statusContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0 mx-2", children: statusContent }),
|
|
200
202
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
201
203
|
ActivityIndicators,
|
|
202
204
|
{
|
|
@@ -213,8 +215,8 @@ var MetadataRow = React10__namespace.forwardRef(
|
|
|
213
215
|
);
|
|
214
216
|
MetadataRow.displayName = "MetadataRow";
|
|
215
217
|
var ThinkingStepItem = ({ step, renderMarkdown }) => {
|
|
216
|
-
const [isCollapsed, setIsCollapsed] =
|
|
217
|
-
const toggleCollapse =
|
|
218
|
+
const [isCollapsed, setIsCollapsed] = React11.useState(step.isCollapsed ?? false);
|
|
219
|
+
const toggleCollapse = React11.useCallback(() => {
|
|
218
220
|
setIsCollapsed((prev) => !prev);
|
|
219
221
|
}, []);
|
|
220
222
|
const indentPadding = step.depth * 16;
|
|
@@ -241,7 +243,7 @@ var ThinkingStepItem = ({ step, renderMarkdown }) => {
|
|
|
241
243
|
)
|
|
242
244
|
] });
|
|
243
245
|
};
|
|
244
|
-
var ThinkingSection =
|
|
246
|
+
var ThinkingSection = React11__namespace.forwardRef(
|
|
245
247
|
({ content, isExpanded, renderMarkdown, className, ...props }, ref) => {
|
|
246
248
|
if (!isExpanded || !content || Array.isArray(content) && content.length === 0) {
|
|
247
249
|
return null;
|
|
@@ -266,7 +268,7 @@ var ThinkingSection = React10__namespace.forwardRef(
|
|
|
266
268
|
}
|
|
267
269
|
);
|
|
268
270
|
ThinkingSection.displayName = "ThinkingSection";
|
|
269
|
-
var ActionBar =
|
|
271
|
+
var ActionBar = React11__namespace.forwardRef(
|
|
270
272
|
({
|
|
271
273
|
response,
|
|
272
274
|
isVisible,
|
|
@@ -277,8 +279,8 @@ var ActionBar = React10__namespace.forwardRef(
|
|
|
277
279
|
className,
|
|
278
280
|
...props
|
|
279
281
|
}, ref) => {
|
|
280
|
-
const [copied, setCopied] =
|
|
281
|
-
const handleCopy =
|
|
282
|
+
const [copied, setCopied] = React11.useState(false);
|
|
283
|
+
const handleCopy = React11.useCallback(async () => {
|
|
282
284
|
try {
|
|
283
285
|
await navigator.clipboard.writeText(response);
|
|
284
286
|
setCopied(true);
|
|
@@ -288,11 +290,11 @@ var ActionBar = React10__namespace.forwardRef(
|
|
|
288
290
|
console.error("Failed to copy response:", err);
|
|
289
291
|
}
|
|
290
292
|
}, [response, onResponseCopy]);
|
|
291
|
-
const handleThumbsUp =
|
|
293
|
+
const handleThumbsUp = React11.useCallback(() => {
|
|
292
294
|
const newValue = feedback === "up" ? null : "up";
|
|
293
295
|
onFeedbackChange?.(newValue);
|
|
294
296
|
}, [feedback, onFeedbackChange]);
|
|
295
|
-
const handleThumbsDown =
|
|
297
|
+
const handleThumbsDown = React11.useCallback(() => {
|
|
296
298
|
const newValue = feedback === "down" ? null : "down";
|
|
297
299
|
onFeedbackChange?.(newValue);
|
|
298
300
|
}, [feedback, onFeedbackChange]);
|
|
@@ -370,22 +372,24 @@ A: ${answer}`);
|
|
|
370
372
|
}
|
|
371
373
|
return parts.join("\n\n");
|
|
372
374
|
}
|
|
373
|
-
var HITLQuestionPanel =
|
|
374
|
-
const [freeformText, setFreeformText] =
|
|
375
|
-
const [selectedOptions, setSelectedOptions] =
|
|
376
|
-
const
|
|
377
|
-
|
|
375
|
+
var HITLQuestionPanel = React11__namespace.forwardRef(({ question, onSubmit, onStop, className, ...props }, ref) => {
|
|
376
|
+
const [freeformText, setFreeformText] = React11.useState("");
|
|
377
|
+
const [selectedOptions, setSelectedOptions] = React11.useState({});
|
|
378
|
+
const hasTimeout = question.timeoutSeconds != null;
|
|
379
|
+
const [secondsLeft, setSecondsLeft] = React11.useState(
|
|
380
|
+
() => hasTimeout ? Math.max(
|
|
378
381
|
0,
|
|
379
382
|
Math.round(
|
|
380
383
|
question.timeoutSeconds - (Date.now() - question.receivedAt) / 1e3
|
|
381
384
|
)
|
|
382
|
-
)
|
|
385
|
+
) : Infinity
|
|
383
386
|
);
|
|
384
|
-
const textareaRef =
|
|
385
|
-
|
|
387
|
+
const textareaRef = React11.useRef(null);
|
|
388
|
+
React11.useEffect(() => {
|
|
386
389
|
textareaRef.current?.focus();
|
|
387
390
|
}, []);
|
|
388
|
-
|
|
391
|
+
React11.useEffect(() => {
|
|
392
|
+
if (!hasTimeout) return;
|
|
389
393
|
const interval = setInterval(() => {
|
|
390
394
|
const remaining = Math.max(
|
|
391
395
|
0,
|
|
@@ -397,16 +401,16 @@ var HITLQuestionPanel = React10__namespace.forwardRef(({ question, onSubmit, onS
|
|
|
397
401
|
if (remaining <= 0) clearInterval(interval);
|
|
398
402
|
}, 1e3);
|
|
399
403
|
return () => clearInterval(interval);
|
|
400
|
-
}, [question.timeoutSeconds, question.receivedAt]);
|
|
401
|
-
const timedOut = secondsLeft <= 0;
|
|
402
|
-
const questionsWithOptions =
|
|
404
|
+
}, [hasTimeout, question.timeoutSeconds, question.receivedAt]);
|
|
405
|
+
const timedOut = hasTimeout && secondsLeft <= 0;
|
|
406
|
+
const questionsWithOptions = React11.useMemo(
|
|
403
407
|
() => question.questions.filter((q) => question.options?.[q]?.length),
|
|
404
408
|
[question.questions, question.options]
|
|
405
409
|
);
|
|
406
410
|
const allOptionsSelected = questionsWithOptions.length > 0 && questionsWithOptions.every((q) => selectedOptions[q]);
|
|
407
411
|
const hasFreeformText = freeformText.trim().length > 0;
|
|
408
412
|
const canSubmit = !timedOut && (allOptionsSelected || hasFreeformText);
|
|
409
|
-
const handleOptionClick =
|
|
413
|
+
const handleOptionClick = React11.useCallback(
|
|
410
414
|
(questionText, option) => {
|
|
411
415
|
if (timedOut) return;
|
|
412
416
|
setSelectedOptions((prev) => {
|
|
@@ -420,16 +424,16 @@ var HITLQuestionPanel = React10__namespace.forwardRef(({ question, onSubmit, onS
|
|
|
420
424
|
},
|
|
421
425
|
[timedOut]
|
|
422
426
|
);
|
|
423
|
-
const handleSubmit =
|
|
427
|
+
const handleSubmit = React11.useCallback(() => {
|
|
424
428
|
if (!canSubmit) return;
|
|
425
429
|
const combined = buildResponseString(
|
|
426
430
|
question.questions,
|
|
427
431
|
selectedOptions,
|
|
428
432
|
freeformText
|
|
429
433
|
);
|
|
430
|
-
onSubmit(combined);
|
|
434
|
+
onSubmit(combined, { selectedOptions, freeformText });
|
|
431
435
|
}, [canSubmit, question.questions, selectedOptions, freeformText, onSubmit]);
|
|
432
|
-
const handleKeyDown =
|
|
436
|
+
const handleKeyDown = React11.useCallback(
|
|
433
437
|
(e) => {
|
|
434
438
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
435
439
|
e.preventDefault();
|
|
@@ -455,7 +459,7 @@ var HITLQuestionPanel = React10__namespace.forwardRef(({ question, onSubmit, onS
|
|
|
455
459
|
children: [
|
|
456
460
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
457
461
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-foreground", children: question.reason }) }),
|
|
458
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
462
|
+
hasTimeout && /* @__PURE__ */ jsxRuntime.jsx(
|
|
459
463
|
"span",
|
|
460
464
|
{
|
|
461
465
|
className: core.cn(
|
|
@@ -538,13 +542,13 @@ function parseResponse(response) {
|
|
|
538
542
|
}
|
|
539
543
|
return { answers, additionalContext };
|
|
540
544
|
}
|
|
541
|
-
var HITLInteractionRecord =
|
|
545
|
+
var HITLInteractionRecord = React11__namespace.forwardRef(({ interaction, className, ...props }, ref) => {
|
|
542
546
|
const { question, response, respondedAt } = interaction;
|
|
543
547
|
const timestamp = new Date(respondedAt).toLocaleTimeString([], {
|
|
544
548
|
hour: "2-digit",
|
|
545
549
|
minute: "2-digit"
|
|
546
550
|
});
|
|
547
|
-
const { answers, additionalContext } =
|
|
551
|
+
const { answers, additionalContext } = React11.useMemo(
|
|
548
552
|
() => parseResponse(response),
|
|
549
553
|
[response]
|
|
550
554
|
);
|
|
@@ -589,7 +593,7 @@ var HITLInteractionRecord = React10__namespace.forwardRef(({ interaction, classN
|
|
|
589
593
|
);
|
|
590
594
|
});
|
|
591
595
|
HITLInteractionRecord.displayName = "HITLInteractionRecord";
|
|
592
|
-
var HITLSection =
|
|
596
|
+
var HITLSection = React11__namespace.forwardRef(
|
|
593
597
|
({
|
|
594
598
|
interactions,
|
|
595
599
|
defaultExpanded = false,
|
|
@@ -598,10 +602,10 @@ var HITLSection = React10__namespace.forwardRef(
|
|
|
598
602
|
className,
|
|
599
603
|
...props
|
|
600
604
|
}, ref) => {
|
|
601
|
-
const [uncontrolledExpanded, setUncontrolledExpanded] =
|
|
605
|
+
const [uncontrolledExpanded, setUncontrolledExpanded] = React11.useState(defaultExpanded);
|
|
602
606
|
const isControlled = controlledExpanded !== void 0;
|
|
603
607
|
const isExpanded = isControlled ? controlledExpanded : uncontrolledExpanded;
|
|
604
|
-
const toggleExpanded =
|
|
608
|
+
const toggleExpanded = React11.useCallback(() => {
|
|
605
609
|
const newValue = !isExpanded;
|
|
606
610
|
if (isControlled) {
|
|
607
611
|
onExpandedChange?.(newValue);
|
|
@@ -642,13 +646,31 @@ var HITLSection = React10__namespace.forwardRef(
|
|
|
642
646
|
}
|
|
643
647
|
);
|
|
644
648
|
HITLSection.displayName = "HITLSection";
|
|
649
|
+
var TruncatedMessage = React11__namespace.forwardRef(
|
|
650
|
+
({ message, className, ...props }, ref) => {
|
|
651
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
652
|
+
"div",
|
|
653
|
+
{
|
|
654
|
+
ref,
|
|
655
|
+
className: core.cn(
|
|
656
|
+
"text-xs text-muted-foreground truncate min-w-0",
|
|
657
|
+
className
|
|
658
|
+
),
|
|
659
|
+
title: message,
|
|
660
|
+
...props,
|
|
661
|
+
children: message
|
|
662
|
+
}
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
);
|
|
666
|
+
TruncatedMessage.displayName = "TruncatedMessage";
|
|
645
667
|
function useThinkingTimer({
|
|
646
668
|
startTime,
|
|
647
669
|
endTime,
|
|
648
670
|
status
|
|
649
671
|
}) {
|
|
650
|
-
const [elapsed, setElapsed] =
|
|
651
|
-
|
|
672
|
+
const [elapsed, setElapsed] = React11.useState(0);
|
|
673
|
+
React11.useEffect(() => {
|
|
652
674
|
if (!startTime) {
|
|
653
675
|
setElapsed(0);
|
|
654
676
|
return;
|
|
@@ -677,17 +699,157 @@ var initialAgentResponseState = {
|
|
|
677
699
|
knowledge: [],
|
|
678
700
|
memory: [],
|
|
679
701
|
statusUpdates: [],
|
|
702
|
+
potentialResponses: [],
|
|
703
|
+
customTimelineEntries: [],
|
|
680
704
|
response: "",
|
|
681
705
|
thinkingStartTime: null,
|
|
682
706
|
responseCompleteTime: null,
|
|
683
707
|
firstMessageTime: null
|
|
684
708
|
};
|
|
685
709
|
|
|
710
|
+
// src/components/agent-timeline/utils.ts
|
|
711
|
+
function buildTimelineEntries(state) {
|
|
712
|
+
const entries = [];
|
|
713
|
+
if (state.thinkingSteps) {
|
|
714
|
+
let idx = 0;
|
|
715
|
+
for (const step of state.thinkingSteps) {
|
|
716
|
+
entries.push({
|
|
717
|
+
id: `tl-think-${idx++}`,
|
|
718
|
+
type: "thinking",
|
|
719
|
+
agentName: step.agentName ?? null,
|
|
720
|
+
parentAgent: step.parentAgent ?? null,
|
|
721
|
+
depth: step.depth ?? 0,
|
|
722
|
+
content: step.content,
|
|
723
|
+
title: step.label,
|
|
724
|
+
timestamp: step.timestamp ?? 0
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
} else if (state.thinking) {
|
|
728
|
+
entries.push({
|
|
729
|
+
id: "tl-think-0",
|
|
730
|
+
type: "thinking",
|
|
731
|
+
agentName: null,
|
|
732
|
+
parentAgent: null,
|
|
733
|
+
depth: 0,
|
|
734
|
+
content: state.thinking,
|
|
735
|
+
title: null,
|
|
736
|
+
timestamp: state.thinkingStartTime ?? 0
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
let toolIdx = 0;
|
|
740
|
+
for (const tool of state.toolCalls) {
|
|
741
|
+
entries.push({
|
|
742
|
+
id: `tl-tool-${toolIdx++}`,
|
|
743
|
+
type: "tool_call",
|
|
744
|
+
agentName: tool.agentName ?? null,
|
|
745
|
+
parentAgent: tool.parentAgent ?? null,
|
|
746
|
+
depth: tool.depth ?? 0,
|
|
747
|
+
content: tool.name,
|
|
748
|
+
title: null,
|
|
749
|
+
timestamp: tool.timestamp
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
let knowIdx = 0;
|
|
753
|
+
for (const item of state.knowledge) {
|
|
754
|
+
entries.push({
|
|
755
|
+
id: `tl-know-${knowIdx++}`,
|
|
756
|
+
type: "knowledge",
|
|
757
|
+
agentName: item.agentName ?? null,
|
|
758
|
+
parentAgent: item.parentAgent ?? null,
|
|
759
|
+
depth: item.depth ?? 0,
|
|
760
|
+
content: item.content,
|
|
761
|
+
title: item.source,
|
|
762
|
+
timestamp: item.timestamp
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
let memIdx = 0;
|
|
766
|
+
for (const item of state.memory) {
|
|
767
|
+
entries.push({
|
|
768
|
+
id: `tl-mem-${memIdx++}`,
|
|
769
|
+
type: "memory",
|
|
770
|
+
agentName: item.agentName ?? null,
|
|
771
|
+
parentAgent: item.parentAgent ?? null,
|
|
772
|
+
depth: item.depth ?? 0,
|
|
773
|
+
content: item.content,
|
|
774
|
+
title: item.type,
|
|
775
|
+
timestamp: item.timestamp
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
let statIdx = 0;
|
|
779
|
+
for (const item of state.statusUpdates) {
|
|
780
|
+
entries.push({
|
|
781
|
+
id: `tl-stat-${statIdx++}`,
|
|
782
|
+
type: "status_update",
|
|
783
|
+
agentName: item.agentName ?? item.agent ?? null,
|
|
784
|
+
parentAgent: item.parentAgent ?? null,
|
|
785
|
+
depth: item.depth ?? 0,
|
|
786
|
+
content: item.message,
|
|
787
|
+
title: null,
|
|
788
|
+
timestamp: item.timestamp
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
if (state.potentialResponses) {
|
|
792
|
+
let respIdx = 0;
|
|
793
|
+
for (const resp of state.potentialResponses) {
|
|
794
|
+
entries.push({
|
|
795
|
+
id: `tl-resp-${respIdx++}`,
|
|
796
|
+
type: "ai_response",
|
|
797
|
+
agentName: resp.agentName ?? null,
|
|
798
|
+
parentAgent: resp.parentAgent ?? null,
|
|
799
|
+
depth: resp.depth ?? 0,
|
|
800
|
+
content: resp.content,
|
|
801
|
+
title: null,
|
|
802
|
+
timestamp: resp.timestamp
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
if (state.customTimelineEntries) {
|
|
807
|
+
entries.push(...state.customTimelineEntries);
|
|
808
|
+
}
|
|
809
|
+
entries.sort((a, b) => a.timestamp - b.timestamp);
|
|
810
|
+
return entries;
|
|
811
|
+
}
|
|
812
|
+
function groupIntoAgentRuns(entries) {
|
|
813
|
+
const runs = [];
|
|
814
|
+
let currentRun = null;
|
|
815
|
+
for (const entry of entries) {
|
|
816
|
+
const name = entry.agentName || "Agent";
|
|
817
|
+
if (!currentRun || currentRun.agentName !== name) {
|
|
818
|
+
currentRun = {
|
|
819
|
+
agentName: name,
|
|
820
|
+
parentAgent: entry.parentAgent,
|
|
821
|
+
depth: entry.depth,
|
|
822
|
+
entries: []
|
|
823
|
+
};
|
|
824
|
+
runs.push(currentRun);
|
|
825
|
+
}
|
|
826
|
+
currentRun.entries.push({ entry, count: 1 });
|
|
827
|
+
}
|
|
828
|
+
for (const run of runs) {
|
|
829
|
+
run.entries = deduplicateEntries(run.entries);
|
|
830
|
+
}
|
|
831
|
+
return runs;
|
|
832
|
+
}
|
|
833
|
+
function deduplicateEntries(entries) {
|
|
834
|
+
if (entries.length === 0) return [];
|
|
835
|
+
const result = [entries[0]];
|
|
836
|
+
for (let i = 1; i < entries.length; i++) {
|
|
837
|
+
const prev = result[result.length - 1];
|
|
838
|
+
const curr = entries[i];
|
|
839
|
+
if (prev.entry.type === curr.entry.type && prev.entry.content === curr.entry.content) {
|
|
840
|
+
prev.count += curr.count;
|
|
841
|
+
} else {
|
|
842
|
+
result.push({ ...curr });
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
return result;
|
|
846
|
+
}
|
|
847
|
+
|
|
686
848
|
// src/components/agent-response/hooks/useAgentResponseAccumulator.ts
|
|
687
849
|
function useAgentResponseAccumulator(options) {
|
|
688
|
-
const [state, setState] =
|
|
850
|
+
const [state, setState] = React11.useState(initialAgentResponseState);
|
|
689
851
|
const topic = options?.topic;
|
|
690
|
-
const handleMessage =
|
|
852
|
+
const handleMessage = React11.useCallback(
|
|
691
853
|
(message) => {
|
|
692
854
|
let payload;
|
|
693
855
|
if (topic) {
|
|
@@ -716,28 +878,44 @@ function useAgentResponseAccumulator(options) {
|
|
|
716
878
|
id: payload.thinkingStep.id || `step-${Date.now()}`,
|
|
717
879
|
label: payload.thinkingStep.label,
|
|
718
880
|
content: payload.thinkingStep.content,
|
|
719
|
-
depth: payload.thinkingStep.depth ?? 0,
|
|
720
|
-
isCollapsed: payload.thinkingStep.isCollapsed
|
|
881
|
+
depth: payload.thinkingStep.depth ?? payload.depth ?? 0,
|
|
882
|
+
isCollapsed: payload.thinkingStep.isCollapsed,
|
|
883
|
+
timestamp: Date.now(),
|
|
884
|
+
agentName: payload.agentName,
|
|
885
|
+
parentAgent: payload.parentAgent
|
|
721
886
|
};
|
|
722
887
|
const thinkingStartTime2 = prev.thinkingStartTime ?? Date.now();
|
|
723
|
-
|
|
888
|
+
const next2 = {
|
|
724
889
|
...prev,
|
|
725
890
|
status: newStatus,
|
|
726
891
|
thinkingSteps: [...prev.thinkingSteps || [], newStep],
|
|
727
892
|
thinkingStartTime: thinkingStartTime2,
|
|
728
893
|
firstMessageTime
|
|
729
894
|
};
|
|
895
|
+
return { ...next2, timelineEntries: buildTimelineEntries(next2) };
|
|
730
896
|
}
|
|
731
897
|
const newThinking = payload.message || payload.content || "";
|
|
732
898
|
const separator = prev.thinking && newThinking ? "\n\n" : "";
|
|
733
899
|
const thinkingStartTime = prev.thinkingStartTime ?? (newThinking ? Date.now() : null);
|
|
734
|
-
|
|
900
|
+
const prevSteps = prev.thinkingSteps || [];
|
|
901
|
+
const plainStep = {
|
|
902
|
+
id: `step-${prevSteps.length}`,
|
|
903
|
+
label: newThinking,
|
|
904
|
+
content: newThinking,
|
|
905
|
+
depth: payload.depth ?? 0,
|
|
906
|
+
timestamp: Date.now(),
|
|
907
|
+
agentName: payload.agentName,
|
|
908
|
+
parentAgent: payload.parentAgent
|
|
909
|
+
};
|
|
910
|
+
const next = {
|
|
735
911
|
...prev,
|
|
736
912
|
status: newStatus,
|
|
737
913
|
thinking: prev.thinking + separator + newThinking,
|
|
914
|
+
thinkingSteps: [...prevSteps, plainStep],
|
|
738
915
|
thinkingStartTime,
|
|
739
916
|
firstMessageTime
|
|
740
917
|
};
|
|
918
|
+
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
741
919
|
}
|
|
742
920
|
case "tool_call": {
|
|
743
921
|
const toolName = payload.message || payload.tool?.name;
|
|
@@ -746,14 +924,18 @@ function useAgentResponseAccumulator(options) {
|
|
|
746
924
|
id: payload.tool?.id || `tool-${Date.now()}`,
|
|
747
925
|
name: toolName,
|
|
748
926
|
arguments: payload.tool?.arguments,
|
|
749
|
-
timestamp: Date.now()
|
|
927
|
+
timestamp: Date.now(),
|
|
928
|
+
agentName: payload.agentName,
|
|
929
|
+
parentAgent: payload.parentAgent,
|
|
930
|
+
depth: payload.depth
|
|
750
931
|
};
|
|
751
|
-
|
|
932
|
+
const next = {
|
|
752
933
|
...prev,
|
|
753
934
|
status: newStatus,
|
|
754
935
|
toolCalls: [...prev.toolCalls, newToolCall],
|
|
755
936
|
firstMessageTime
|
|
756
937
|
};
|
|
938
|
+
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
757
939
|
}
|
|
758
940
|
return { ...prev, status: newStatus, firstMessageTime };
|
|
759
941
|
}
|
|
@@ -764,14 +946,18 @@ function useAgentResponseAccumulator(options) {
|
|
|
764
946
|
id: payload.knowledge?.id || `knowledge-${Date.now()}`,
|
|
765
947
|
source: payload.knowledge?.source || "unknown",
|
|
766
948
|
content: knowledgeContent,
|
|
767
|
-
timestamp: Date.now()
|
|
949
|
+
timestamp: Date.now(),
|
|
950
|
+
agentName: payload.agentName,
|
|
951
|
+
parentAgent: payload.parentAgent,
|
|
952
|
+
depth: payload.depth
|
|
768
953
|
};
|
|
769
|
-
|
|
954
|
+
const next = {
|
|
770
955
|
...prev,
|
|
771
956
|
status: newStatus,
|
|
772
957
|
knowledge: [...prev.knowledge, newKnowledge],
|
|
773
958
|
firstMessageTime
|
|
774
959
|
};
|
|
960
|
+
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
775
961
|
}
|
|
776
962
|
return { ...prev, status: newStatus, firstMessageTime };
|
|
777
963
|
}
|
|
@@ -782,14 +968,18 @@ function useAgentResponseAccumulator(options) {
|
|
|
782
968
|
id: payload.memory?.id || `memory-${Date.now()}`,
|
|
783
969
|
type: payload.memory?.type || "unknown",
|
|
784
970
|
content: memoryContent,
|
|
785
|
-
timestamp: Date.now()
|
|
971
|
+
timestamp: Date.now(),
|
|
972
|
+
agentName: payload.agentName,
|
|
973
|
+
parentAgent: payload.parentAgent,
|
|
974
|
+
depth: payload.depth
|
|
786
975
|
};
|
|
787
|
-
|
|
976
|
+
const next = {
|
|
788
977
|
...prev,
|
|
789
978
|
status: newStatus,
|
|
790
979
|
memory: [...prev.memory, newMemory],
|
|
791
980
|
firstMessageTime
|
|
792
981
|
};
|
|
982
|
+
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
793
983
|
}
|
|
794
984
|
return { ...prev, status: newStatus, firstMessageTime };
|
|
795
985
|
}
|
|
@@ -808,14 +998,39 @@ function useAgentResponseAccumulator(options) {
|
|
|
808
998
|
id: payload.statusUpdate?.id || `status-${Date.now()}`,
|
|
809
999
|
message: statusMessage,
|
|
810
1000
|
agent: payload.statusUpdate?.agent,
|
|
811
|
-
timestamp: Date.now()
|
|
1001
|
+
timestamp: Date.now(),
|
|
1002
|
+
agentName: payload.agentName,
|
|
1003
|
+
parentAgent: payload.parentAgent,
|
|
1004
|
+
depth: payload.depth
|
|
812
1005
|
};
|
|
813
|
-
|
|
1006
|
+
const next = {
|
|
814
1007
|
...prev,
|
|
815
1008
|
status: newStatus,
|
|
816
1009
|
statusUpdates: [...prev.statusUpdates, newStatusItem],
|
|
817
1010
|
firstMessageTime
|
|
818
1011
|
};
|
|
1012
|
+
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
1013
|
+
}
|
|
1014
|
+
return { ...prev, status: newStatus, firstMessageTime };
|
|
1015
|
+
}
|
|
1016
|
+
case "potential_response": {
|
|
1017
|
+
const respContent = payload.message || payload.content || "";
|
|
1018
|
+
if (respContent) {
|
|
1019
|
+
const newResp = {
|
|
1020
|
+
id: `resp-${Date.now()}`,
|
|
1021
|
+
content: respContent,
|
|
1022
|
+
timestamp: Date.now(),
|
|
1023
|
+
agentName: payload.agentName,
|
|
1024
|
+
parentAgent: payload.parentAgent,
|
|
1025
|
+
depth: payload.depth
|
|
1026
|
+
};
|
|
1027
|
+
const next = {
|
|
1028
|
+
...prev,
|
|
1029
|
+
status: newStatus,
|
|
1030
|
+
potentialResponses: [...prev.potentialResponses || [], newResp],
|
|
1031
|
+
firstMessageTime
|
|
1032
|
+
};
|
|
1033
|
+
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
819
1034
|
}
|
|
820
1035
|
return { ...prev, status: newStatus, firstMessageTime };
|
|
821
1036
|
}
|
|
@@ -826,12 +1041,293 @@ function useAgentResponseAccumulator(options) {
|
|
|
826
1041
|
},
|
|
827
1042
|
[topic]
|
|
828
1043
|
);
|
|
829
|
-
const reset =
|
|
1044
|
+
const reset = React11.useCallback(() => {
|
|
830
1045
|
setState(initialAgentResponseState);
|
|
831
1046
|
}, []);
|
|
832
1047
|
return { state, handleMessage, reset };
|
|
833
1048
|
}
|
|
834
|
-
var
|
|
1049
|
+
var ICON_MAP = {
|
|
1050
|
+
thinking: lucideReact.Brain,
|
|
1051
|
+
tool_call: lucideReact.Wrench,
|
|
1052
|
+
knowledge: lucideReact.BookOpen,
|
|
1053
|
+
memory: lucideReact.HardDrive,
|
|
1054
|
+
status_update: lucideReact.Activity,
|
|
1055
|
+
ai_response: lucideReact.MessageSquare,
|
|
1056
|
+
error: lucideReact.AlertCircle
|
|
1057
|
+
};
|
|
1058
|
+
function TimelineItem({
|
|
1059
|
+
displayEntry,
|
|
1060
|
+
renderMarkdown,
|
|
1061
|
+
isExpanded,
|
|
1062
|
+
onToggleExpanded
|
|
1063
|
+
}) {
|
|
1064
|
+
const { entry, count } = displayEntry;
|
|
1065
|
+
const Icon = ICON_MAP[entry.type] ?? lucideReact.Activity;
|
|
1066
|
+
const isLong = entry.content.length > 200 || entry.content.split("\n").length > 3;
|
|
1067
|
+
const canExpand = isLong || entry.type === "ai_response";
|
|
1068
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-1 flex items-start gap-2 group", children: [
|
|
1069
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-3.5 h-3.5 text-muted-foreground flex-shrink-0 mt-0.5" }),
|
|
1070
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: isExpanded && entry.type === "ai_response" && renderMarkdown ? (
|
|
1071
|
+
// Expanded AI response: rendered markdown
|
|
1072
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1073
|
+
renderMarkdown(entry.content),
|
|
1074
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1075
|
+
"button",
|
|
1076
|
+
{
|
|
1077
|
+
onClick: onToggleExpanded,
|
|
1078
|
+
className: "text-[10px] text-muted-foreground/70 hover:text-muted-foreground mt-1",
|
|
1079
|
+
children: "Show less"
|
|
1080
|
+
}
|
|
1081
|
+
)
|
|
1082
|
+
] })
|
|
1083
|
+
) : isExpanded ? (
|
|
1084
|
+
// Expanded non-AI: plain text
|
|
1085
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1086
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs text-muted-foreground whitespace-pre-wrap font-mono", children: entry.content }),
|
|
1087
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1088
|
+
"button",
|
|
1089
|
+
{
|
|
1090
|
+
onClick: onToggleExpanded,
|
|
1091
|
+
className: "text-[10px] text-muted-foreground/70 hover:text-muted-foreground mt-1",
|
|
1092
|
+
children: "Show less"
|
|
1093
|
+
}
|
|
1094
|
+
)
|
|
1095
|
+
] })
|
|
1096
|
+
) : (
|
|
1097
|
+
// Collapsed: truncated with optional expand
|
|
1098
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-1.5 min-w-0", children: [
|
|
1099
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1100
|
+
"div",
|
|
1101
|
+
{
|
|
1102
|
+
className: `text-xs text-muted-foreground min-w-0 ${canExpand ? "line-clamp-2 cursor-pointer hover:text-foreground/80" : ""}`,
|
|
1103
|
+
onClick: canExpand ? onToggleExpanded : void 0,
|
|
1104
|
+
children: entry.content
|
|
1105
|
+
}
|
|
1106
|
+
),
|
|
1107
|
+
count > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground/60 whitespace-nowrap flex-shrink-0", children: [
|
|
1108
|
+
"(x",
|
|
1109
|
+
count,
|
|
1110
|
+
")"
|
|
1111
|
+
] })
|
|
1112
|
+
] })
|
|
1113
|
+
) })
|
|
1114
|
+
] });
|
|
1115
|
+
}
|
|
1116
|
+
function TimelineAgentBlock({
|
|
1117
|
+
block,
|
|
1118
|
+
renderMarkdown,
|
|
1119
|
+
isSingleAgent,
|
|
1120
|
+
isCollapsed,
|
|
1121
|
+
onToggleCollapsed,
|
|
1122
|
+
expandedItems,
|
|
1123
|
+
onToggleItemExpanded
|
|
1124
|
+
}) {
|
|
1125
|
+
const indentPx = block.depth * 16;
|
|
1126
|
+
if (isSingleAgent && block.depth === 0) {
|
|
1127
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { paddingLeft: `${indentPx}px` }, children: block.entries.map((displayEntry, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1128
|
+
TimelineItem,
|
|
1129
|
+
{
|
|
1130
|
+
displayEntry,
|
|
1131
|
+
renderMarkdown,
|
|
1132
|
+
isExpanded: expandedItems.has(displayEntry.entry.id),
|
|
1133
|
+
onToggleExpanded: () => onToggleItemExpanded(displayEntry.entry.id)
|
|
1134
|
+
},
|
|
1135
|
+
displayEntry.entry.id + "-" + i
|
|
1136
|
+
)) });
|
|
1137
|
+
}
|
|
1138
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { paddingLeft: `${indentPx}px` }, children: [
|
|
1139
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1140
|
+
"button",
|
|
1141
|
+
{
|
|
1142
|
+
onClick: onToggleCollapsed,
|
|
1143
|
+
className: "w-full flex items-center gap-1.5 py-1 hover:bg-muted/50 -ml-1 pl-1 pr-2 rounded transition-colors text-left",
|
|
1144
|
+
children: [
|
|
1145
|
+
isCollapsed ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "w-3 h-3 text-muted-foreground flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "w-3 h-3 text-muted-foreground flex-shrink-0" }),
|
|
1146
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-foreground/80", children: block.agentName }),
|
|
1147
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground/60", children: [
|
|
1148
|
+
"(",
|
|
1149
|
+
block.entries.reduce((sum, e) => sum + e.count, 0),
|
|
1150
|
+
")"
|
|
1151
|
+
] })
|
|
1152
|
+
]
|
|
1153
|
+
}
|
|
1154
|
+
),
|
|
1155
|
+
!isCollapsed && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-4", children: block.entries.map((displayEntry, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1156
|
+
TimelineItem,
|
|
1157
|
+
{
|
|
1158
|
+
displayEntry,
|
|
1159
|
+
renderMarkdown,
|
|
1160
|
+
isExpanded: expandedItems.has(displayEntry.entry.id),
|
|
1161
|
+
onToggleExpanded: () => onToggleItemExpanded(displayEntry.entry.id)
|
|
1162
|
+
},
|
|
1163
|
+
displayEntry.entry.id + "-" + i
|
|
1164
|
+
)) })
|
|
1165
|
+
] });
|
|
1166
|
+
}
|
|
1167
|
+
function createTimelineUIState() {
|
|
1168
|
+
return {
|
|
1169
|
+
expandedItems: /* @__PURE__ */ new Set(),
|
|
1170
|
+
collapsedRuns: /* @__PURE__ */ new Set(),
|
|
1171
|
+
activeFilters: /* @__PURE__ */ new Set()
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
var TYPE_CONFIG = [
|
|
1175
|
+
{ type: "status_update", icon: lucideReact.Activity, label: "Status" },
|
|
1176
|
+
{ type: "thinking", icon: lucideReact.Brain, label: "Thinking" },
|
|
1177
|
+
{ type: "tool_call", icon: lucideReact.Wrench, label: "Tools" },
|
|
1178
|
+
{ type: "knowledge", icon: lucideReact.BookOpen, label: "Knowledge" },
|
|
1179
|
+
{ type: "memory", icon: lucideReact.HardDrive, label: "Memory" },
|
|
1180
|
+
{ type: "ai_response", icon: lucideReact.MessageSquare, label: "AI" },
|
|
1181
|
+
{ type: "error", icon: lucideReact.AlertCircle, label: "Errors" }
|
|
1182
|
+
];
|
|
1183
|
+
function AgentTimeline({ entries, renderMarkdown, uiState, maxHeight = "300px" }) {
|
|
1184
|
+
const containerRef = React11.useRef(null);
|
|
1185
|
+
const [renderTick, setRenderTick] = React11.useState(0);
|
|
1186
|
+
const forceRender = React11.useCallback(() => setRenderTick((t) => t + 1), []);
|
|
1187
|
+
const [internalExpandedItems] = React11.useState(() => /* @__PURE__ */ new Set());
|
|
1188
|
+
const [internalCollapsedRuns] = React11.useState(() => /* @__PURE__ */ new Set());
|
|
1189
|
+
const [internalActiveFilters] = React11.useState(() => /* @__PURE__ */ new Set());
|
|
1190
|
+
const expandedItems = uiState?.expandedItems ?? internalExpandedItems;
|
|
1191
|
+
const collapsedRuns = uiState?.collapsedRuns ?? internalCollapsedRuns;
|
|
1192
|
+
const activeFilters = uiState?.activeFilters ?? internalActiveFilters;
|
|
1193
|
+
const availableTypes = React11.useMemo(() => {
|
|
1194
|
+
const types = /* @__PURE__ */ new Set();
|
|
1195
|
+
for (const entry of entries) {
|
|
1196
|
+
types.add(entry.type);
|
|
1197
|
+
}
|
|
1198
|
+
return types;
|
|
1199
|
+
}, [entries]);
|
|
1200
|
+
const filteredEntries = React11.useMemo(
|
|
1201
|
+
() => activeFilters.size === 0 ? entries : entries.filter((e) => activeFilters.has(e.type)),
|
|
1202
|
+
[entries, activeFilters, renderTick]
|
|
1203
|
+
);
|
|
1204
|
+
const agentRuns = React11.useMemo(() => groupIntoAgentRuns(filteredEntries), [filteredEntries, renderTick]);
|
|
1205
|
+
const toggleFilter = React11.useCallback((type) => {
|
|
1206
|
+
if (activeFilters.has(type)) {
|
|
1207
|
+
activeFilters.delete(type);
|
|
1208
|
+
} else {
|
|
1209
|
+
activeFilters.add(type);
|
|
1210
|
+
}
|
|
1211
|
+
forceRender();
|
|
1212
|
+
}, [activeFilters, forceRender]);
|
|
1213
|
+
const clearFilters = React11.useCallback(() => {
|
|
1214
|
+
activeFilters.clear();
|
|
1215
|
+
forceRender();
|
|
1216
|
+
}, [activeFilters, forceRender]);
|
|
1217
|
+
const toggleItemExpanded = React11.useCallback((entryId) => {
|
|
1218
|
+
if (expandedItems.has(entryId)) {
|
|
1219
|
+
expandedItems.delete(entryId);
|
|
1220
|
+
} else {
|
|
1221
|
+
expandedItems.add(entryId);
|
|
1222
|
+
}
|
|
1223
|
+
forceRender();
|
|
1224
|
+
}, [expandedItems, forceRender]);
|
|
1225
|
+
const collapseAll = React11.useCallback(() => {
|
|
1226
|
+
collapsedRuns.clear();
|
|
1227
|
+
agentRuns.forEach((run, i) => {
|
|
1228
|
+
collapsedRuns.add(`${run.agentName}-${i}`);
|
|
1229
|
+
});
|
|
1230
|
+
expandedItems.clear();
|
|
1231
|
+
forceRender();
|
|
1232
|
+
}, [agentRuns, collapsedRuns, expandedItems, forceRender]);
|
|
1233
|
+
const expandAll = React11.useCallback(() => {
|
|
1234
|
+
collapsedRuns.clear();
|
|
1235
|
+
agentRuns.forEach((run, i) => {
|
|
1236
|
+
collapsedRuns.add(`${run.agentName}-${i}:expanded`);
|
|
1237
|
+
});
|
|
1238
|
+
forceRender();
|
|
1239
|
+
}, [agentRuns, collapsedRuns, forceRender]);
|
|
1240
|
+
if (entries.length === 0) return null;
|
|
1241
|
+
const isSingle = agentRuns.length === 1;
|
|
1242
|
+
const hasActiveFilter = activeFilters.size > 0;
|
|
1243
|
+
const scrollStyle = maxHeight !== "none" ? { maxHeight } : void 0;
|
|
1244
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1245
|
+
"div",
|
|
1246
|
+
{
|
|
1247
|
+
ref: containerRef,
|
|
1248
|
+
className: maxHeight !== "none" ? "overflow-y-auto" : "",
|
|
1249
|
+
style: scrollStyle,
|
|
1250
|
+
children: [
|
|
1251
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sticky top-0 z-10 bg-background flex items-center gap-1 py-1.5 mb-1 border-b border-border/50 flex-wrap pl-2", children: [
|
|
1252
|
+
TYPE_CONFIG.filter((tc) => availableTypes.has(tc.type)).map((tc) => {
|
|
1253
|
+
const isActive = activeFilters.has(tc.type);
|
|
1254
|
+
const count = entries.filter((e) => e.type === tc.type).length;
|
|
1255
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1256
|
+
"button",
|
|
1257
|
+
{
|
|
1258
|
+
onClick: () => toggleFilter(tc.type),
|
|
1259
|
+
className: `inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] transition-colors ${isActive ? "bg-accent text-accent-foreground ring-1 ring-accent-foreground/20" : "text-muted-foreground/60 hover:text-muted-foreground hover:bg-muted/50"}`,
|
|
1260
|
+
title: `${isActive ? "Hide" : "Show only"} ${tc.label}`,
|
|
1261
|
+
children: [
|
|
1262
|
+
/* @__PURE__ */ jsxRuntime.jsx(tc.icon, { className: "w-3 h-3" }),
|
|
1263
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: count })
|
|
1264
|
+
]
|
|
1265
|
+
},
|
|
1266
|
+
tc.type
|
|
1267
|
+
);
|
|
1268
|
+
}),
|
|
1269
|
+
hasActiveFilter && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1270
|
+
"button",
|
|
1271
|
+
{
|
|
1272
|
+
onClick: clearFilters,
|
|
1273
|
+
className: "text-[10px] text-muted-foreground/60 hover:text-muted-foreground px-1",
|
|
1274
|
+
children: "Clear"
|
|
1275
|
+
}
|
|
1276
|
+
),
|
|
1277
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
|
|
1278
|
+
!isSingle && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1279
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1280
|
+
"button",
|
|
1281
|
+
{
|
|
1282
|
+
onClick: collapseAll,
|
|
1283
|
+
className: "inline-flex items-center gap-0.5 text-[10px] text-muted-foreground/60 hover:text-muted-foreground px-1 py-0.5 rounded hover:bg-muted/50 transition-colors",
|
|
1284
|
+
title: "Collapse all",
|
|
1285
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsDownUp, { className: "w-3 h-3" })
|
|
1286
|
+
}
|
|
1287
|
+
),
|
|
1288
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1289
|
+
"button",
|
|
1290
|
+
{
|
|
1291
|
+
onClick: expandAll,
|
|
1292
|
+
className: "inline-flex items-center gap-0.5 text-[10px] text-muted-foreground/60 hover:text-muted-foreground px-1 py-0.5 rounded hover:bg-muted/50 transition-colors",
|
|
1293
|
+
title: "Expand all",
|
|
1294
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { className: "w-3 h-3" })
|
|
1295
|
+
}
|
|
1296
|
+
)
|
|
1297
|
+
] })
|
|
1298
|
+
] }),
|
|
1299
|
+
filteredEntries.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] text-muted-foreground/50 py-2 text-center", children: "No entries match the selected filters" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-0.5", children: agentRuns.map((run, i) => {
|
|
1300
|
+
const runKey = `${run.agentName}-${i}`;
|
|
1301
|
+
const defaultCollapsed = run.depth > 0;
|
|
1302
|
+
const isCollapsed = collapsedRuns.has(runKey) ? true : collapsedRuns.has(`${runKey}:expanded`) ? false : defaultCollapsed;
|
|
1303
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1304
|
+
TimelineAgentBlock,
|
|
1305
|
+
{
|
|
1306
|
+
block: run,
|
|
1307
|
+
renderMarkdown,
|
|
1308
|
+
isSingleAgent: isSingle,
|
|
1309
|
+
isCollapsed,
|
|
1310
|
+
onToggleCollapsed: () => {
|
|
1311
|
+
if (isCollapsed) {
|
|
1312
|
+
collapsedRuns.delete(runKey);
|
|
1313
|
+
collapsedRuns.add(`${runKey}:expanded`);
|
|
1314
|
+
} else {
|
|
1315
|
+
collapsedRuns.delete(`${runKey}:expanded`);
|
|
1316
|
+
collapsedRuns.add(runKey);
|
|
1317
|
+
}
|
|
1318
|
+
forceRender();
|
|
1319
|
+
},
|
|
1320
|
+
expandedItems,
|
|
1321
|
+
onToggleItemExpanded: toggleItemExpanded
|
|
1322
|
+
},
|
|
1323
|
+
runKey
|
|
1324
|
+
);
|
|
1325
|
+
}) })
|
|
1326
|
+
]
|
|
1327
|
+
}
|
|
1328
|
+
);
|
|
1329
|
+
}
|
|
1330
|
+
var AgentResponse = React11__namespace.forwardRef(
|
|
835
1331
|
({
|
|
836
1332
|
state,
|
|
837
1333
|
id,
|
|
@@ -845,15 +1341,18 @@ var AgentResponse = React10__namespace.forwardRef(
|
|
|
845
1341
|
actionsVisible = "hover",
|
|
846
1342
|
hitlInteractions,
|
|
847
1343
|
defaultHITLExpanded = false,
|
|
1344
|
+
statusContent,
|
|
848
1345
|
renderMarkdown,
|
|
849
1346
|
renderThinkingMarkdown,
|
|
1347
|
+
timelineMaxHeight,
|
|
850
1348
|
className,
|
|
851
1349
|
...props
|
|
852
1350
|
}, ref) => {
|
|
853
|
-
const
|
|
1351
|
+
const timelineUIStateRef = React11.useRef(createTimelineUIState());
|
|
1352
|
+
const [uncontrolledExpanded, setUncontrolledExpanded] = React11.useState(defaultThinkingExpanded);
|
|
854
1353
|
const isThinkingControlled = controlledThinkingExpanded !== void 0;
|
|
855
1354
|
const thinkingExpanded = isThinkingControlled ? controlledThinkingExpanded : uncontrolledExpanded;
|
|
856
|
-
const toggleThinking =
|
|
1355
|
+
const toggleThinking = React11.useCallback(() => {
|
|
857
1356
|
const newValue = !thinkingExpanded;
|
|
858
1357
|
if (isThinkingControlled) {
|
|
859
1358
|
onThinkingExpandedChange?.(newValue);
|
|
@@ -861,17 +1360,18 @@ var AgentResponse = React10__namespace.forwardRef(
|
|
|
861
1360
|
setUncontrolledExpanded(newValue);
|
|
862
1361
|
}
|
|
863
1362
|
}, [thinkingExpanded, isThinkingControlled, onThinkingExpandedChange]);
|
|
864
|
-
const [isHovered, setIsHovered] =
|
|
1363
|
+
const [isHovered, setIsHovered] = React11.useState(false);
|
|
865
1364
|
const elapsedTime = useThinkingTimer({
|
|
866
1365
|
startTime: state.thinkingStartTime,
|
|
867
1366
|
endTime: state.responseCompleteTime,
|
|
868
1367
|
status: state.status
|
|
869
1368
|
});
|
|
870
|
-
const totalTimeSeconds =
|
|
1369
|
+
const totalTimeSeconds = React11.useMemo(() => {
|
|
871
1370
|
if (!state.firstMessageTime || !state.responseCompleteTime) return 0;
|
|
872
1371
|
return (state.responseCompleteTime - state.firstMessageTime) / 1e3;
|
|
873
1372
|
}, [state.firstMessageTime, state.responseCompleteTime]);
|
|
874
|
-
const
|
|
1373
|
+
const hasTimelineEntries = !!(state.timelineEntries && state.timelineEntries.length > 0);
|
|
1374
|
+
const hasThinkingContent = !!state.thinking || state.thinkingSteps && state.thinkingSteps.length > 0 || hasTimelineEntries || false;
|
|
875
1375
|
const hasHITLInteractions = hitlInteractions && hitlInteractions.length > 0;
|
|
876
1376
|
const hasAnyContent = hasThinkingContent || state.toolCalls.length > 0 || state.knowledge.length > 0 || state.memory.length > 0 || state.statusUpdates.length > 0 || hasHITLInteractions || state.response;
|
|
877
1377
|
const showMetadataRow = hasThinkingContent || state.toolCalls.length > 0 || state.knowledge.length > 0 || state.memory.length > 0 || state.statusUpdates.length > 0 || state.status === "processing";
|
|
@@ -901,11 +1401,20 @@ var AgentResponse = React10__namespace.forwardRef(
|
|
|
901
1401
|
knowledge: state.knowledge,
|
|
902
1402
|
memory: state.memory,
|
|
903
1403
|
statusUpdates: state.statusUpdates,
|
|
1404
|
+
statusContent,
|
|
904
1405
|
status: state.status,
|
|
905
1406
|
elapsedTime
|
|
906
1407
|
}
|
|
907
1408
|
),
|
|
908
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1409
|
+
hasTimelineEntries ? thinkingExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pb-3 border-t border-border", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1410
|
+
AgentTimeline,
|
|
1411
|
+
{
|
|
1412
|
+
entries: state.timelineEntries,
|
|
1413
|
+
renderMarkdown: renderThinkingMarkdown,
|
|
1414
|
+
uiState: timelineUIStateRef.current,
|
|
1415
|
+
maxHeight: timelineMaxHeight
|
|
1416
|
+
}
|
|
1417
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
909
1418
|
ThinkingSection,
|
|
910
1419
|
{
|
|
911
1420
|
content: state.thinkingSteps && state.thinkingSteps.length > 0 ? state.thinkingSteps : state.thinking,
|
|
@@ -949,7 +1458,7 @@ var AgentResponse = React10__namespace.forwardRef(
|
|
|
949
1458
|
}
|
|
950
1459
|
);
|
|
951
1460
|
AgentResponse.displayName = "AgentResponse";
|
|
952
|
-
var UserPrompt =
|
|
1461
|
+
var UserPrompt = React11__namespace.forwardRef(
|
|
953
1462
|
({ content, timestamp, className, ...props }, ref) => {
|
|
954
1463
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
955
1464
|
"div",
|
|
@@ -1048,7 +1557,7 @@ function CodeBlockLeaf({ attributes, children, leaf }) {
|
|
|
1048
1557
|
}
|
|
1049
1558
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { ...attributes, children });
|
|
1050
1559
|
}
|
|
1051
|
-
var UserPromptInput =
|
|
1560
|
+
var UserPromptInput = React11__namespace.forwardRef(
|
|
1052
1561
|
({
|
|
1053
1562
|
value = "",
|
|
1054
1563
|
onChange,
|
|
@@ -1058,6 +1567,8 @@ var UserPromptInput = React10__namespace.forwardRef(
|
|
|
1058
1567
|
disabled = false,
|
|
1059
1568
|
isSubmitting = false,
|
|
1060
1569
|
onStop,
|
|
1570
|
+
stopTooltip,
|
|
1571
|
+
stopClassName,
|
|
1061
1572
|
disableWhileSubmitting = true,
|
|
1062
1573
|
autoFocus = false,
|
|
1063
1574
|
refocusAfterSubmit = false,
|
|
@@ -1071,14 +1582,14 @@ var UserPromptInput = React10__namespace.forwardRef(
|
|
|
1071
1582
|
className,
|
|
1072
1583
|
...props
|
|
1073
1584
|
}, ref) => {
|
|
1074
|
-
const editorRef =
|
|
1075
|
-
const [internalValue, setInternalValue] =
|
|
1076
|
-
const prevIsSubmitting =
|
|
1077
|
-
const hasEmittedReady =
|
|
1078
|
-
|
|
1585
|
+
const editorRef = React11__namespace.useRef(null);
|
|
1586
|
+
const [internalValue, setInternalValue] = React11__namespace.useState(value);
|
|
1587
|
+
const prevIsSubmitting = React11__namespace.useRef(isSubmitting);
|
|
1588
|
+
const hasEmittedReady = React11__namespace.useRef(false);
|
|
1589
|
+
React11__namespace.useEffect(() => {
|
|
1079
1590
|
setInternalValue(value);
|
|
1080
1591
|
}, [value]);
|
|
1081
|
-
|
|
1592
|
+
React11__namespace.useEffect(() => {
|
|
1082
1593
|
if (autoFocus) {
|
|
1083
1594
|
requestAnimationFrame(() => {
|
|
1084
1595
|
requestAnimationFrame(() => {
|
|
@@ -1087,7 +1598,7 @@ var UserPromptInput = React10__namespace.forwardRef(
|
|
|
1087
1598
|
});
|
|
1088
1599
|
}
|
|
1089
1600
|
}, [autoFocus]);
|
|
1090
|
-
|
|
1601
|
+
React11__namespace.useEffect(() => {
|
|
1091
1602
|
if (!hasEmittedReady.current && onReady) {
|
|
1092
1603
|
requestAnimationFrame(() => {
|
|
1093
1604
|
requestAnimationFrame(() => {
|
|
@@ -1097,7 +1608,7 @@ var UserPromptInput = React10__namespace.forwardRef(
|
|
|
1097
1608
|
});
|
|
1098
1609
|
}
|
|
1099
1610
|
}, [onReady]);
|
|
1100
|
-
|
|
1611
|
+
React11__namespace.useEffect(() => {
|
|
1101
1612
|
if (refocusAfterSubmit && prevIsSubmitting.current && !isSubmitting) {
|
|
1102
1613
|
requestAnimationFrame(() => {
|
|
1103
1614
|
editorRef.current?.focus();
|
|
@@ -1105,7 +1616,7 @@ var UserPromptInput = React10__namespace.forwardRef(
|
|
|
1105
1616
|
}
|
|
1106
1617
|
prevIsSubmitting.current = isSubmitting;
|
|
1107
1618
|
}, [isSubmitting, refocusAfterSubmit]);
|
|
1108
|
-
|
|
1619
|
+
React11__namespace.useImperativeHandle(
|
|
1109
1620
|
ref,
|
|
1110
1621
|
() => ({
|
|
1111
1622
|
focus: () => {
|
|
@@ -1128,14 +1639,14 @@ var UserPromptInput = React10__namespace.forwardRef(
|
|
|
1128
1639
|
}),
|
|
1129
1640
|
[]
|
|
1130
1641
|
);
|
|
1131
|
-
const handleChange =
|
|
1642
|
+
const handleChange = React11__namespace.useCallback(
|
|
1132
1643
|
(newValue) => {
|
|
1133
1644
|
setInternalValue(newValue);
|
|
1134
1645
|
onChange?.(newValue);
|
|
1135
1646
|
},
|
|
1136
1647
|
[onChange]
|
|
1137
1648
|
);
|
|
1138
|
-
const handleSubmit =
|
|
1649
|
+
const handleSubmit = React11__namespace.useCallback(
|
|
1139
1650
|
(text) => {
|
|
1140
1651
|
if (disabled || isSubmitting) return;
|
|
1141
1652
|
if (!text.trim()) return;
|
|
@@ -1147,7 +1658,7 @@ var UserPromptInput = React10__namespace.forwardRef(
|
|
|
1147
1658
|
},
|
|
1148
1659
|
[disabled, isSubmitting, onSubmit, clearOnSubmit]
|
|
1149
1660
|
);
|
|
1150
|
-
const handleSendClick =
|
|
1661
|
+
const handleSendClick = React11__namespace.useCallback(() => {
|
|
1151
1662
|
const text = editorRef.current?.getText() ?? "";
|
|
1152
1663
|
handleSubmit(text);
|
|
1153
1664
|
}, [handleSubmit]);
|
|
@@ -1184,16 +1695,17 @@ var UserPromptInput = React10__namespace.forwardRef(
|
|
|
1184
1695
|
) }),
|
|
1185
1696
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between pl-2 pr-1 pb-1 pt-1", children: [
|
|
1186
1697
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: renderActions?.() }),
|
|
1187
|
-
isSubmitting && onStop ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1698
|
+
isSubmitting && onStop ? /* @__PURE__ */ jsxRuntime.jsx(core.Tooltip, { content: stopTooltip, disabled: !stopTooltip, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1188
1699
|
core.IconButton,
|
|
1189
1700
|
{
|
|
1190
1701
|
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Square, {}),
|
|
1191
1702
|
variant: "filled",
|
|
1192
1703
|
size: "sm",
|
|
1193
|
-
"aria-label": "Stop",
|
|
1194
|
-
onClick: onStop
|
|
1704
|
+
"aria-label": stopTooltip || "Stop",
|
|
1705
|
+
onClick: onStop,
|
|
1706
|
+
className: stopClassName
|
|
1195
1707
|
}
|
|
1196
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1708
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1197
1709
|
core.IconButton,
|
|
1198
1710
|
{
|
|
1199
1711
|
icon: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, {}),
|
|
@@ -1212,20 +1724,138 @@ var UserPromptInput = React10__namespace.forwardRef(
|
|
|
1212
1724
|
);
|
|
1213
1725
|
UserPromptInput.displayName = "UserPromptInput";
|
|
1214
1726
|
|
|
1727
|
+
// src/components/inline-actions/parseResponseSegments.ts
|
|
1728
|
+
var ACTION_BLOCK_REGEX = /```json:action\s*\n([\s\S]*?)```/g;
|
|
1729
|
+
function parseResponseSegments(text) {
|
|
1730
|
+
if (!text) return [];
|
|
1731
|
+
const segments = [];
|
|
1732
|
+
let lastIndex = 0;
|
|
1733
|
+
ACTION_BLOCK_REGEX.lastIndex = 0;
|
|
1734
|
+
let match;
|
|
1735
|
+
while ((match = ACTION_BLOCK_REGEX.exec(text)) !== null) {
|
|
1736
|
+
const before = text.slice(lastIndex, match.index);
|
|
1737
|
+
if (before.trim()) {
|
|
1738
|
+
segments.push({ kind: "markdown", content: before });
|
|
1739
|
+
}
|
|
1740
|
+
const jsonContent = match[1].trim();
|
|
1741
|
+
let parsed = null;
|
|
1742
|
+
try {
|
|
1743
|
+
parsed = JSON.parse(jsonContent);
|
|
1744
|
+
} catch {
|
|
1745
|
+
}
|
|
1746
|
+
if (parsed && typeof parsed === "object" && typeof parsed.type === "string") {
|
|
1747
|
+
segments.push({
|
|
1748
|
+
kind: "action",
|
|
1749
|
+
actionType: parsed.type,
|
|
1750
|
+
payload: parsed
|
|
1751
|
+
});
|
|
1752
|
+
} else {
|
|
1753
|
+
const rawBlock = match[0];
|
|
1754
|
+
segments.push({ kind: "markdown", content: rawBlock });
|
|
1755
|
+
}
|
|
1756
|
+
lastIndex = match.index + match[0].length;
|
|
1757
|
+
}
|
|
1758
|
+
const trailing = text.slice(lastIndex);
|
|
1759
|
+
if (trailing.trim()) {
|
|
1760
|
+
segments.push({ kind: "markdown", content: trailing });
|
|
1761
|
+
}
|
|
1762
|
+
return segments;
|
|
1763
|
+
}
|
|
1764
|
+
function ActionMarkdownRenderer({
|
|
1765
|
+
content,
|
|
1766
|
+
registry,
|
|
1767
|
+
renderMarkdown,
|
|
1768
|
+
onAction,
|
|
1769
|
+
isLatest
|
|
1770
|
+
}) {
|
|
1771
|
+
const segments = React11.useMemo(() => parseResponseSegments(content), [content]);
|
|
1772
|
+
if (segments.length === 1 && segments[0].kind === "markdown") {
|
|
1773
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: renderMarkdown(segments[0].content) });
|
|
1774
|
+
}
|
|
1775
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: segments.map((segment, index) => {
|
|
1776
|
+
if (segment.kind === "markdown") {
|
|
1777
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderMarkdown(segment.content) }, `md-${index}`);
|
|
1778
|
+
}
|
|
1779
|
+
const Component = registry[segment.actionType];
|
|
1780
|
+
if (!Component) {
|
|
1781
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1782
|
+
"pre",
|
|
1783
|
+
{
|
|
1784
|
+
className: "my-4 p-4 rounded-lg border border-border bg-muted text-sm font-mono overflow-x-auto",
|
|
1785
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: JSON.stringify(segment.payload, null, 2) })
|
|
1786
|
+
},
|
|
1787
|
+
`action-fallback-${index}`
|
|
1788
|
+
);
|
|
1789
|
+
}
|
|
1790
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1791
|
+
Component,
|
|
1792
|
+
{
|
|
1793
|
+
payload: segment.payload,
|
|
1794
|
+
onAction,
|
|
1795
|
+
isLatest
|
|
1796
|
+
},
|
|
1797
|
+
`action-${segment.actionType}-${index}`
|
|
1798
|
+
);
|
|
1799
|
+
}) });
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
// src/components/inline-actions/prompts.ts
|
|
1803
|
+
var INLINE_ACTION_PROMPT = `
|
|
1804
|
+
<inline_actions>
|
|
1805
|
+
When your response should include interactive components (like query viewers,
|
|
1806
|
+
data tables, or executable actions), embed them as fenced code blocks using
|
|
1807
|
+
the \`json:action\` language tag:
|
|
1808
|
+
|
|
1809
|
+
\`\`\`json:action
|
|
1810
|
+
{
|
|
1811
|
+
"type": "action-type-here",
|
|
1812
|
+
...action-specific fields
|
|
1813
|
+
}
|
|
1814
|
+
\`\`\`
|
|
1815
|
+
|
|
1816
|
+
Rules:
|
|
1817
|
+
- Each block must contain valid JSON with a "type" field.
|
|
1818
|
+
- The "type" must match a registered action component on the frontend.
|
|
1819
|
+
- Multiple action blocks per response are allowed.
|
|
1820
|
+
- Surround action blocks with normal markdown text for user context.
|
|
1821
|
+
- The action block is rendered as an interactive component in the chat UI.
|
|
1822
|
+
- SQL strings inside JSON must be properly escaped (newlines as \\n, quotes as \\").
|
|
1823
|
+
|
|
1824
|
+
Available action types:
|
|
1825
|
+
|
|
1826
|
+
- "optimap-query": Displays SQL queries with a button to execute them and
|
|
1827
|
+
update the 3D globe map.
|
|
1828
|
+
Required fields:
|
|
1829
|
+
- type: "optimap-query"
|
|
1830
|
+
- locations_sql: string (the validated locations SQL query)
|
|
1831
|
+
- routes_sql: string (the validated routes SQL query)
|
|
1832
|
+
- database_name: string (the target database name)
|
|
1833
|
+
</inline_actions>
|
|
1834
|
+
`;
|
|
1835
|
+
|
|
1215
1836
|
exports.ActionBar = ActionBar;
|
|
1837
|
+
exports.ActionMarkdownRenderer = ActionMarkdownRenderer;
|
|
1216
1838
|
exports.ActivityIndicators = ActivityIndicators;
|
|
1217
1839
|
exports.AgentResponse = AgentResponse;
|
|
1840
|
+
exports.AgentTimeline = AgentTimeline;
|
|
1218
1841
|
exports.HITLInteractionRecord = HITLInteractionRecord;
|
|
1219
1842
|
exports.HITLQuestionPanel = HITLQuestionPanel;
|
|
1220
1843
|
exports.HITLSection = HITLSection;
|
|
1844
|
+
exports.INLINE_ACTION_PROMPT = INLINE_ACTION_PROMPT;
|
|
1221
1845
|
exports.MetadataRow = MetadataRow;
|
|
1222
1846
|
exports.ThinkingSection = ThinkingSection;
|
|
1847
|
+
exports.TruncatedMessage = TruncatedMessage;
|
|
1223
1848
|
exports.UserPrompt = UserPrompt;
|
|
1224
1849
|
exports.UserPromptInput = UserPromptInput;
|
|
1225
1850
|
exports.buildResponseString = buildResponseString;
|
|
1851
|
+
exports.buildTimelineEntries = buildTimelineEntries;
|
|
1852
|
+
exports.createTimelineUIState = createTimelineUIState;
|
|
1853
|
+
exports.deduplicateEntries = deduplicateEntries;
|
|
1226
1854
|
exports.formatTime = formatTime;
|
|
1227
1855
|
exports.formatTotalTime = formatTotalTime;
|
|
1856
|
+
exports.groupIntoAgentRuns = groupIntoAgentRuns;
|
|
1228
1857
|
exports.initialAgentResponseState = initialAgentResponseState;
|
|
1858
|
+
exports.parseResponseSegments = parseResponseSegments;
|
|
1229
1859
|
exports.useAgentResponseAccumulator = useAgentResponseAccumulator;
|
|
1230
1860
|
exports.useThinkingTimer = useThinkingTimer;
|
|
1231
1861
|
//# sourceMappingURL=index.cjs.map
|