@optilogic/chat 1.0.0-beta.1 → 1.0.0-beta.10
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 +235 -0
- package/dist/index.cjs +725 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +319 -6
- package/dist/index.d.ts +319 -6
- package/dist/index.js +708 -25
- package/dist/index.js.map +1 -1
- package/package.json +15 -9
- package/src/components/agent-response/AgentResponse.tsx +76 -5
- package/src/components/agent-response/components/ActivityIndicators.tsx +36 -4
- package/src/components/agent-response/components/HITLSection.tsx +95 -0
- package/src/components/agent-response/components/MetadataRow.tsx +21 -6
- package/src/components/agent-response/components/ThinkingSection.tsx +101 -9
- package/src/components/agent-response/components/TruncatedMessage.tsx +52 -0
- package/src/components/agent-response/components/index.ts +6 -0
- package/src/components/agent-response/hooks/useAgentResponseAccumulator.ts +41 -0
- package/src/components/agent-response/index.ts +7 -0
- package/src/components/agent-response/types.ts +54 -1
- package/src/components/hitl-interactions/HITLInteractionRecord.tsx +139 -0
- package/src/components/hitl-interactions/HITLQuestionPanel.tsx +263 -0
- package/src/components/hitl-interactions/index.ts +18 -0
- package/src/components/user-prompt/UserPrompt.tsx +60 -0
- package/src/components/user-prompt/index.ts +1 -0
- package/src/components/user-prompt-input/UserPromptInput.tsx +326 -0
- package/src/components/user-prompt-input/index.ts +2 -0
- package/src/components/user-prompt-input/types.ts +52 -0
- package/src/index.ts +28 -0
package/dist/index.js
CHANGED
|
@@ -1,15 +1,36 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { useState, useCallback,
|
|
3
|
-
import { cn, Popover, PopoverTrigger, PopoverContent, LoadingSpinner } from '@optilogic/core';
|
|
4
|
-
import { Wrench, Book, HardDrive, Check, Copy, ThumbsUp, ThumbsDown,
|
|
1
|
+
import * as React11 from 'react';
|
|
2
|
+
import { useState, useCallback, useRef, useEffect, useMemo } from 'react';
|
|
3
|
+
import { cn, Popover, PopoverTrigger, PopoverContent, Button, Textarea, IconButton, LoadingSpinner } from '@optilogic/core';
|
|
4
|
+
import { Activity, Wrench, Book, HardDrive, Check, Copy, ThumbsUp, ThumbsDown, ChevronDown, ChevronRight, MessageCircleQuestion, Square, Loader2, Send, ChevronUp } from 'lucide-react';
|
|
5
5
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
6
|
+
import { SlateEditor, Text } from '@optilogic/editor';
|
|
6
7
|
|
|
7
8
|
// src/components/agent-response/AgentResponse.tsx
|
|
8
|
-
var ActivityIndicators =
|
|
9
|
-
({ toolCalls, knowledge, memory, className, ...props }, ref) => {
|
|
10
|
-
const hasAnyActivity = toolCalls.length > 0 || knowledge.length > 0 || memory.length > 0;
|
|
9
|
+
var ActivityIndicators = React11.forwardRef(
|
|
10
|
+
({ toolCalls, knowledge, memory, statusUpdates = [], className, ...props }, ref) => {
|
|
11
|
+
const hasAnyActivity = toolCalls.length > 0 || knowledge.length > 0 || memory.length > 0 || statusUpdates.length > 0;
|
|
11
12
|
if (!hasAnyActivity) return null;
|
|
12
13
|
return /* @__PURE__ */ jsxs("div", { ref, className: cn("flex items-center gap-2", className), ...props, children: [
|
|
14
|
+
statusUpdates.length > 0 && /* @__PURE__ */ jsxs(Popover, { children: [
|
|
15
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
16
|
+
"button",
|
|
17
|
+
{
|
|
18
|
+
className: "flex items-center gap-1 text-muted-foreground hover:text-foreground transition-colors",
|
|
19
|
+
onClick: (e) => e.stopPropagation(),
|
|
20
|
+
children: [
|
|
21
|
+
/* @__PURE__ */ jsx(Activity, { className: "w-3.5 h-3.5" }),
|
|
22
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs", children: statusUpdates.length })
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
) }),
|
|
26
|
+
/* @__PURE__ */ jsx(PopoverContent, { className: "w-80", children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
27
|
+
/* @__PURE__ */ jsx("h4", { className: "font-medium text-sm", children: "Status Updates" }),
|
|
28
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2 max-h-60 overflow-auto", children: statusUpdates.map((item) => /* @__PURE__ */ jsxs("div", { className: "p-2 bg-muted rounded text-xs", children: [
|
|
29
|
+
item.agent && /* @__PURE__ */ jsx("div", { className: "font-medium text-muted-foreground", children: item.agent }),
|
|
30
|
+
/* @__PURE__ */ jsx("div", { className: item.agent ? "mt-1" : "", children: item.message })
|
|
31
|
+
] }, item.id)) })
|
|
32
|
+
] }) })
|
|
33
|
+
] }),
|
|
13
34
|
toolCalls.length > 0 && /* @__PURE__ */ jsxs(Popover, { children: [
|
|
14
35
|
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
15
36
|
"button",
|
|
@@ -104,7 +125,7 @@ function formatTotalTime(seconds) {
|
|
|
104
125
|
const minutes = seconds / 60;
|
|
105
126
|
return `${minutes.toFixed(1)}m`;
|
|
106
127
|
}
|
|
107
|
-
var MetadataRow =
|
|
128
|
+
var MetadataRow = React11.forwardRef(
|
|
108
129
|
({
|
|
109
130
|
hasThinking,
|
|
110
131
|
isExpanded,
|
|
@@ -112,6 +133,8 @@ var MetadataRow = React.forwardRef(
|
|
|
112
133
|
toolCalls,
|
|
113
134
|
knowledge,
|
|
114
135
|
memory,
|
|
136
|
+
statusUpdates = [],
|
|
137
|
+
statusContent,
|
|
115
138
|
status,
|
|
116
139
|
elapsedTime,
|
|
117
140
|
className,
|
|
@@ -119,7 +142,7 @@ var MetadataRow = React.forwardRef(
|
|
|
119
142
|
}, ref) => {
|
|
120
143
|
const isProcessing = status === "processing";
|
|
121
144
|
const isComplete = status === "complete";
|
|
122
|
-
const hasActivity = toolCalls.length > 0 || knowledge.length > 0 || memory.length > 0;
|
|
145
|
+
const hasActivity = toolCalls.length > 0 || knowledge.length > 0 || memory.length > 0 || statusUpdates.length > 0;
|
|
123
146
|
const renderLeftContent = () => {
|
|
124
147
|
if (hasThinking) {
|
|
125
148
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
@@ -136,7 +159,7 @@ var MetadataRow = React.forwardRef(
|
|
|
136
159
|
return null;
|
|
137
160
|
};
|
|
138
161
|
const leftContent = renderLeftContent();
|
|
139
|
-
if (!leftContent && !hasActivity) {
|
|
162
|
+
if (!leftContent && !hasActivity && !statusContent) {
|
|
140
163
|
return null;
|
|
141
164
|
}
|
|
142
165
|
return /* @__PURE__ */ jsxs(
|
|
@@ -150,16 +173,18 @@ var MetadataRow = React.forwardRef(
|
|
|
150
173
|
"button",
|
|
151
174
|
{
|
|
152
175
|
onClick: onToggle,
|
|
153
|
-
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",
|
|
176
|
+
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",
|
|
154
177
|
children: leftContent
|
|
155
178
|
}
|
|
156
|
-
) : /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5", children: leftContent }),
|
|
179
|
+
) : /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 shrink-0", children: leftContent }),
|
|
180
|
+
statusContent && /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0 mx-2", children: statusContent }),
|
|
157
181
|
/* @__PURE__ */ jsx(
|
|
158
182
|
ActivityIndicators,
|
|
159
183
|
{
|
|
160
184
|
toolCalls,
|
|
161
185
|
knowledge,
|
|
162
|
-
memory
|
|
186
|
+
memory,
|
|
187
|
+
statusUpdates
|
|
163
188
|
}
|
|
164
189
|
)
|
|
165
190
|
]
|
|
@@ -168,24 +193,61 @@ var MetadataRow = React.forwardRef(
|
|
|
168
193
|
}
|
|
169
194
|
);
|
|
170
195
|
MetadataRow.displayName = "MetadataRow";
|
|
171
|
-
var
|
|
172
|
-
|
|
173
|
-
|
|
196
|
+
var ThinkingStepItem = ({ step, renderMarkdown }) => {
|
|
197
|
+
const [isCollapsed, setIsCollapsed] = useState(step.isCollapsed ?? false);
|
|
198
|
+
const toggleCollapse = useCallback(() => {
|
|
199
|
+
setIsCollapsed((prev) => !prev);
|
|
200
|
+
}, []);
|
|
201
|
+
const indentPadding = step.depth * 16;
|
|
202
|
+
return /* @__PURE__ */ jsxs("div", { className: "border-b border-border/50 last:border-b-0", children: [
|
|
203
|
+
/* @__PURE__ */ jsxs(
|
|
204
|
+
"button",
|
|
205
|
+
{
|
|
206
|
+
onClick: toggleCollapse,
|
|
207
|
+
className: "w-full flex items-center gap-1.5 py-1.5 px-2 hover:bg-muted/50 transition-colors text-left",
|
|
208
|
+
style: { paddingLeft: `${indentPadding + 8}px` },
|
|
209
|
+
children: [
|
|
210
|
+
isCollapsed ? /* @__PURE__ */ jsx(ChevronRight, { className: "w-3 h-3 text-muted-foreground flex-shrink-0" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "w-3 h-3 text-muted-foreground flex-shrink-0" }),
|
|
211
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-foreground/80", children: step.label })
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
),
|
|
215
|
+
!isCollapsed && /* @__PURE__ */ jsx(
|
|
216
|
+
"div",
|
|
217
|
+
{
|
|
218
|
+
className: "pb-2 px-2",
|
|
219
|
+
style: { paddingLeft: `${indentPadding + 28}px` },
|
|
220
|
+
children: renderMarkdown ? /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: renderMarkdown(step.content) }) : /* @__PURE__ */ jsx("pre", { className: "text-xs text-muted-foreground whitespace-pre-wrap font-mono", children: step.content })
|
|
221
|
+
}
|
|
222
|
+
)
|
|
223
|
+
] });
|
|
224
|
+
};
|
|
225
|
+
var ThinkingSection = React11.forwardRef(
|
|
226
|
+
({ content, isExpanded, renderMarkdown, className, ...props }, ref) => {
|
|
227
|
+
if (!isExpanded || !content || Array.isArray(content) && content.length === 0) {
|
|
174
228
|
return null;
|
|
175
229
|
}
|
|
230
|
+
const isStructured = Array.isArray(content);
|
|
176
231
|
return /* @__PURE__ */ jsx(
|
|
177
232
|
"div",
|
|
178
233
|
{
|
|
179
234
|
ref,
|
|
180
235
|
className: cn("px-3 pb-3 border-t border-border", className),
|
|
181
236
|
...props,
|
|
182
|
-
children: /* @__PURE__ */ jsx("div", { className: "mt-2 max-h-[200px] overflow-y-auto", children: /* @__PURE__ */ jsx("
|
|
237
|
+
children: /* @__PURE__ */ jsx("div", { className: "mt-2 max-h-[200px] overflow-y-auto", children: isStructured ? /* @__PURE__ */ jsx("div", { className: "space-y-0", children: content.map((step) => /* @__PURE__ */ jsx(
|
|
238
|
+
ThinkingStepItem,
|
|
239
|
+
{
|
|
240
|
+
step,
|
|
241
|
+
renderMarkdown
|
|
242
|
+
},
|
|
243
|
+
step.id
|
|
244
|
+
)) }) : renderMarkdown ? /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: renderMarkdown(content) }) : /* @__PURE__ */ jsx("pre", { className: "text-xs text-muted-foreground whitespace-pre-wrap font-mono", children: content }) })
|
|
183
245
|
}
|
|
184
246
|
);
|
|
185
247
|
}
|
|
186
248
|
);
|
|
187
249
|
ThinkingSection.displayName = "ThinkingSection";
|
|
188
|
-
var ActionBar =
|
|
250
|
+
var ActionBar = React11.forwardRef(
|
|
189
251
|
({
|
|
190
252
|
response,
|
|
191
253
|
isVisible,
|
|
@@ -274,6 +336,313 @@ var ActionBar = React.forwardRef(
|
|
|
274
336
|
}
|
|
275
337
|
);
|
|
276
338
|
ActionBar.displayName = "ActionBar";
|
|
339
|
+
function buildResponseString(questions, selectedOptions, freeformText) {
|
|
340
|
+
const parts = [];
|
|
341
|
+
for (const q of questions) {
|
|
342
|
+
const answer = selectedOptions[q];
|
|
343
|
+
if (answer) {
|
|
344
|
+
parts.push(`Q: ${q}
|
|
345
|
+
A: ${answer}`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
const trimmed = freeformText.trim();
|
|
349
|
+
if (trimmed) {
|
|
350
|
+
parts.push(`Additional context: ${trimmed}`);
|
|
351
|
+
}
|
|
352
|
+
return parts.join("\n\n");
|
|
353
|
+
}
|
|
354
|
+
var HITLQuestionPanel = React11.forwardRef(({ question, onSubmit, onStop, className, ...props }, ref) => {
|
|
355
|
+
const [freeformText, setFreeformText] = useState("");
|
|
356
|
+
const [selectedOptions, setSelectedOptions] = useState({});
|
|
357
|
+
const hasTimeout = question.timeoutSeconds != null;
|
|
358
|
+
const [secondsLeft, setSecondsLeft] = useState(
|
|
359
|
+
() => hasTimeout ? Math.max(
|
|
360
|
+
0,
|
|
361
|
+
Math.round(
|
|
362
|
+
question.timeoutSeconds - (Date.now() - question.receivedAt) / 1e3
|
|
363
|
+
)
|
|
364
|
+
) : Infinity
|
|
365
|
+
);
|
|
366
|
+
const textareaRef = useRef(null);
|
|
367
|
+
useEffect(() => {
|
|
368
|
+
textareaRef.current?.focus();
|
|
369
|
+
}, []);
|
|
370
|
+
useEffect(() => {
|
|
371
|
+
if (!hasTimeout) return;
|
|
372
|
+
const interval = setInterval(() => {
|
|
373
|
+
const remaining = Math.max(
|
|
374
|
+
0,
|
|
375
|
+
Math.round(
|
|
376
|
+
question.timeoutSeconds - (Date.now() - question.receivedAt) / 1e3
|
|
377
|
+
)
|
|
378
|
+
);
|
|
379
|
+
setSecondsLeft(remaining);
|
|
380
|
+
if (remaining <= 0) clearInterval(interval);
|
|
381
|
+
}, 1e3);
|
|
382
|
+
return () => clearInterval(interval);
|
|
383
|
+
}, [hasTimeout, question.timeoutSeconds, question.receivedAt]);
|
|
384
|
+
const timedOut = hasTimeout && secondsLeft <= 0;
|
|
385
|
+
const questionsWithOptions = useMemo(
|
|
386
|
+
() => question.questions.filter((q) => question.options?.[q]?.length),
|
|
387
|
+
[question.questions, question.options]
|
|
388
|
+
);
|
|
389
|
+
const allOptionsSelected = questionsWithOptions.length > 0 && questionsWithOptions.every((q) => selectedOptions[q]);
|
|
390
|
+
const hasFreeformText = freeformText.trim().length > 0;
|
|
391
|
+
const canSubmit = !timedOut && (allOptionsSelected || hasFreeformText);
|
|
392
|
+
const handleOptionClick = useCallback(
|
|
393
|
+
(questionText, option) => {
|
|
394
|
+
if (timedOut) return;
|
|
395
|
+
setSelectedOptions((prev) => {
|
|
396
|
+
if (prev[questionText] === option) {
|
|
397
|
+
const next = { ...prev };
|
|
398
|
+
delete next[questionText];
|
|
399
|
+
return next;
|
|
400
|
+
}
|
|
401
|
+
return { ...prev, [questionText]: option };
|
|
402
|
+
});
|
|
403
|
+
},
|
|
404
|
+
[timedOut]
|
|
405
|
+
);
|
|
406
|
+
const handleSubmit = useCallback(() => {
|
|
407
|
+
if (!canSubmit) return;
|
|
408
|
+
const combined = buildResponseString(
|
|
409
|
+
question.questions,
|
|
410
|
+
selectedOptions,
|
|
411
|
+
freeformText
|
|
412
|
+
);
|
|
413
|
+
onSubmit(combined);
|
|
414
|
+
}, [canSubmit, question.questions, selectedOptions, freeformText, onSubmit]);
|
|
415
|
+
const handleKeyDown = useCallback(
|
|
416
|
+
(e) => {
|
|
417
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
418
|
+
e.preventDefault();
|
|
419
|
+
handleSubmit();
|
|
420
|
+
}
|
|
421
|
+
},
|
|
422
|
+
[handleSubmit]
|
|
423
|
+
);
|
|
424
|
+
const formatTime2 = (s) => {
|
|
425
|
+
const m = Math.floor(s / 60);
|
|
426
|
+
const sec = s % 60;
|
|
427
|
+
return `${m}:${sec.toString().padStart(2, "0")}`;
|
|
428
|
+
};
|
|
429
|
+
return /* @__PURE__ */ jsxs(
|
|
430
|
+
"div",
|
|
431
|
+
{
|
|
432
|
+
ref,
|
|
433
|
+
className: cn(
|
|
434
|
+
"rounded-lg border border-border bg-muted p-4 space-y-3",
|
|
435
|
+
className
|
|
436
|
+
),
|
|
437
|
+
...props,
|
|
438
|
+
children: [
|
|
439
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
440
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: question.reason }) }),
|
|
441
|
+
hasTimeout && /* @__PURE__ */ jsx(
|
|
442
|
+
"span",
|
|
443
|
+
{
|
|
444
|
+
className: cn(
|
|
445
|
+
"text-xs font-mono whitespace-nowrap",
|
|
446
|
+
secondsLeft <= 30 ? "text-destructive" : "text-muted-foreground"
|
|
447
|
+
),
|
|
448
|
+
children: timedOut ? "Timed out" : formatTime2(secondsLeft)
|
|
449
|
+
}
|
|
450
|
+
)
|
|
451
|
+
] }),
|
|
452
|
+
question.context && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground bg-background rounded p-2 border border-border max-h-24 overflow-y-auto", children: /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap font-mono", children: question.context }) }),
|
|
453
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-3", children: question.questions.map((q, i) => /* @__PURE__ */ jsxs("div", { children: [
|
|
454
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-foreground", children: q }),
|
|
455
|
+
question.options?.[q] && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 mt-1.5", children: question.options[q].map((option, j) => {
|
|
456
|
+
const isSelected = selectedOptions[q] === option;
|
|
457
|
+
return /* @__PURE__ */ jsx(
|
|
458
|
+
Button,
|
|
459
|
+
{
|
|
460
|
+
variant: isSelected ? "primary" : "outline",
|
|
461
|
+
size: "sm",
|
|
462
|
+
onClick: () => handleOptionClick(q, option),
|
|
463
|
+
disabled: timedOut,
|
|
464
|
+
children: option
|
|
465
|
+
},
|
|
466
|
+
j
|
|
467
|
+
);
|
|
468
|
+
}) })
|
|
469
|
+
] }, i)) }),
|
|
470
|
+
/* @__PURE__ */ jsx(
|
|
471
|
+
Textarea,
|
|
472
|
+
{
|
|
473
|
+
ref: textareaRef,
|
|
474
|
+
value: freeformText,
|
|
475
|
+
onChange: (e) => setFreeformText(e.target.value),
|
|
476
|
+
onKeyDown: handleKeyDown,
|
|
477
|
+
disabled: timedOut,
|
|
478
|
+
placeholder: "Add additional context or type a full response...",
|
|
479
|
+
rows: 2,
|
|
480
|
+
className: "resize-none"
|
|
481
|
+
}
|
|
482
|
+
),
|
|
483
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
484
|
+
/* @__PURE__ */ jsx(
|
|
485
|
+
Button,
|
|
486
|
+
{
|
|
487
|
+
variant: "ghost",
|
|
488
|
+
size: "sm",
|
|
489
|
+
onClick: onStop,
|
|
490
|
+
className: "text-destructive hover:text-destructive hover:bg-destructive/10",
|
|
491
|
+
children: "Stop agent"
|
|
492
|
+
}
|
|
493
|
+
),
|
|
494
|
+
/* @__PURE__ */ jsx(
|
|
495
|
+
Button,
|
|
496
|
+
{
|
|
497
|
+
variant: "primary",
|
|
498
|
+
size: "sm",
|
|
499
|
+
onClick: handleSubmit,
|
|
500
|
+
disabled: !canSubmit,
|
|
501
|
+
children: "Send response"
|
|
502
|
+
}
|
|
503
|
+
)
|
|
504
|
+
] })
|
|
505
|
+
]
|
|
506
|
+
}
|
|
507
|
+
);
|
|
508
|
+
});
|
|
509
|
+
HITLQuestionPanel.displayName = "HITLQuestionPanel";
|
|
510
|
+
function parseResponse(response) {
|
|
511
|
+
const answers = {};
|
|
512
|
+
let additionalContext = null;
|
|
513
|
+
const blocks = response.split("\n\n");
|
|
514
|
+
for (const block of blocks) {
|
|
515
|
+
const qaMatch = block.match(/^Q: (.+)\nA: (.+)$/s);
|
|
516
|
+
if (qaMatch) {
|
|
517
|
+
answers[qaMatch[1].trim()] = qaMatch[2].trim();
|
|
518
|
+
} else if (block.startsWith("Additional context: ")) {
|
|
519
|
+
additionalContext = block.slice("Additional context: ".length).trim();
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
return { answers, additionalContext };
|
|
523
|
+
}
|
|
524
|
+
var HITLInteractionRecord = React11.forwardRef(({ interaction, className, ...props }, ref) => {
|
|
525
|
+
const { question, response, respondedAt } = interaction;
|
|
526
|
+
const timestamp = new Date(respondedAt).toLocaleTimeString([], {
|
|
527
|
+
hour: "2-digit",
|
|
528
|
+
minute: "2-digit"
|
|
529
|
+
});
|
|
530
|
+
const { answers, additionalContext } = useMemo(
|
|
531
|
+
() => parseResponse(response),
|
|
532
|
+
[response]
|
|
533
|
+
);
|
|
534
|
+
const hasParsedAnswers = Object.keys(answers).length > 0;
|
|
535
|
+
return /* @__PURE__ */ jsxs(
|
|
536
|
+
"div",
|
|
537
|
+
{
|
|
538
|
+
ref,
|
|
539
|
+
className: cn(
|
|
540
|
+
"rounded-lg border border-border bg-muted p-3 space-y-2 text-sm",
|
|
541
|
+
className
|
|
542
|
+
),
|
|
543
|
+
...props,
|
|
544
|
+
children: [
|
|
545
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
546
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-muted-foreground", children: "Clarifying Question" }),
|
|
547
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: timestamp })
|
|
548
|
+
] }),
|
|
549
|
+
/* @__PURE__ */ jsx("p", { className: "text-foreground font-medium", children: question.reason }),
|
|
550
|
+
question.context && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground bg-background rounded p-2 border border-border", children: /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap font-mono", children: question.context }) }),
|
|
551
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: question.questions.map((q, i) => /* @__PURE__ */ jsxs("div", { children: [
|
|
552
|
+
/* @__PURE__ */ jsx("p", { className: "text-foreground", children: q }),
|
|
553
|
+
question.options?.[q] && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground ml-2", children: [
|
|
554
|
+
"Options: ",
|
|
555
|
+
question.options[q].join(", ")
|
|
556
|
+
] }),
|
|
557
|
+
hasParsedAnswers && answers[q] && /* @__PURE__ */ jsxs("p", { className: "text-xs text-foreground ml-2 mt-0.5 bg-background rounded px-2 py-1 border border-border", children: [
|
|
558
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Answer: " }),
|
|
559
|
+
answers[q]
|
|
560
|
+
] })
|
|
561
|
+
] }, i)) }),
|
|
562
|
+
hasParsedAnswers && additionalContext && /* @__PURE__ */ jsxs("div", { className: "border-t border-border pt-2", children: [
|
|
563
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-xs", children: "Additional context:" }),
|
|
564
|
+
/* @__PURE__ */ jsx("p", { className: "text-foreground mt-0.5", children: additionalContext })
|
|
565
|
+
] }),
|
|
566
|
+
!hasParsedAnswers && /* @__PURE__ */ jsxs("div", { className: "border-t border-border pt-2", children: [
|
|
567
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-xs", children: "Response:" }),
|
|
568
|
+
/* @__PURE__ */ jsx("p", { className: "text-foreground mt-0.5", children: response })
|
|
569
|
+
] })
|
|
570
|
+
]
|
|
571
|
+
}
|
|
572
|
+
);
|
|
573
|
+
});
|
|
574
|
+
HITLInteractionRecord.displayName = "HITLInteractionRecord";
|
|
575
|
+
var HITLSection = React11.forwardRef(
|
|
576
|
+
({
|
|
577
|
+
interactions,
|
|
578
|
+
defaultExpanded = false,
|
|
579
|
+
isExpanded: controlledExpanded,
|
|
580
|
+
onExpandedChange,
|
|
581
|
+
className,
|
|
582
|
+
...props
|
|
583
|
+
}, ref) => {
|
|
584
|
+
const [uncontrolledExpanded, setUncontrolledExpanded] = useState(defaultExpanded);
|
|
585
|
+
const isControlled = controlledExpanded !== void 0;
|
|
586
|
+
const isExpanded = isControlled ? controlledExpanded : uncontrolledExpanded;
|
|
587
|
+
const toggleExpanded = useCallback(() => {
|
|
588
|
+
const newValue = !isExpanded;
|
|
589
|
+
if (isControlled) {
|
|
590
|
+
onExpandedChange?.(newValue);
|
|
591
|
+
} else {
|
|
592
|
+
setUncontrolledExpanded(newValue);
|
|
593
|
+
}
|
|
594
|
+
}, [isExpanded, isControlled, onExpandedChange]);
|
|
595
|
+
if (!interactions || interactions.length === 0) {
|
|
596
|
+
return null;
|
|
597
|
+
}
|
|
598
|
+
return /* @__PURE__ */ jsxs(
|
|
599
|
+
"div",
|
|
600
|
+
{
|
|
601
|
+
ref,
|
|
602
|
+
className: cn("border-t border-border", className),
|
|
603
|
+
...props,
|
|
604
|
+
children: [
|
|
605
|
+
/* @__PURE__ */ jsxs(
|
|
606
|
+
"button",
|
|
607
|
+
{
|
|
608
|
+
onClick: toggleExpanded,
|
|
609
|
+
className: "w-full flex items-center gap-2 py-2 px-3 hover:bg-muted/50 transition-colors text-left",
|
|
610
|
+
children: [
|
|
611
|
+
isExpanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "w-3.5 h-3.5 text-muted-foreground flex-shrink-0" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "w-3.5 h-3.5 text-muted-foreground flex-shrink-0" }),
|
|
612
|
+
/* @__PURE__ */ jsx(MessageCircleQuestion, { className: "w-3.5 h-3.5 text-muted-foreground flex-shrink-0" }),
|
|
613
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-foreground/80", children: [
|
|
614
|
+
"Clarifying Questions (",
|
|
615
|
+
interactions.length,
|
|
616
|
+
")"
|
|
617
|
+
] })
|
|
618
|
+
]
|
|
619
|
+
}
|
|
620
|
+
),
|
|
621
|
+
isExpanded && /* @__PURE__ */ jsx("div", { className: "px-3 pb-3 space-y-2", children: interactions.map((interaction, i) => /* @__PURE__ */ jsx(HITLInteractionRecord, { interaction }, i)) })
|
|
622
|
+
]
|
|
623
|
+
}
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
);
|
|
627
|
+
HITLSection.displayName = "HITLSection";
|
|
628
|
+
var TruncatedMessage = React11.forwardRef(
|
|
629
|
+
({ message, className, ...props }, ref) => {
|
|
630
|
+
return /* @__PURE__ */ jsx(
|
|
631
|
+
"div",
|
|
632
|
+
{
|
|
633
|
+
ref,
|
|
634
|
+
className: cn(
|
|
635
|
+
"text-xs text-muted-foreground truncate min-w-0",
|
|
636
|
+
className
|
|
637
|
+
),
|
|
638
|
+
title: message,
|
|
639
|
+
...props,
|
|
640
|
+
children: message
|
|
641
|
+
}
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
);
|
|
645
|
+
TruncatedMessage.displayName = "TruncatedMessage";
|
|
277
646
|
function useThinkingTimer({
|
|
278
647
|
startTime,
|
|
279
648
|
endTime,
|
|
@@ -308,6 +677,7 @@ var initialAgentResponseState = {
|
|
|
308
677
|
toolCalls: [],
|
|
309
678
|
knowledge: [],
|
|
310
679
|
memory: [],
|
|
680
|
+
statusUpdates: [],
|
|
311
681
|
response: "",
|
|
312
682
|
thinkingStartTime: null,
|
|
313
683
|
responseCompleteTime: null,
|
|
@@ -342,6 +712,23 @@ function useAgentResponseAccumulator(options) {
|
|
|
342
712
|
}
|
|
343
713
|
return { ...prev, status: newStatus };
|
|
344
714
|
case "thinking": {
|
|
715
|
+
if (payload.thinkingStep) {
|
|
716
|
+
const newStep = {
|
|
717
|
+
id: payload.thinkingStep.id || `step-${Date.now()}`,
|
|
718
|
+
label: payload.thinkingStep.label,
|
|
719
|
+
content: payload.thinkingStep.content,
|
|
720
|
+
depth: payload.thinkingStep.depth ?? 0,
|
|
721
|
+
isCollapsed: payload.thinkingStep.isCollapsed
|
|
722
|
+
};
|
|
723
|
+
const thinkingStartTime2 = prev.thinkingStartTime ?? Date.now();
|
|
724
|
+
return {
|
|
725
|
+
...prev,
|
|
726
|
+
status: newStatus,
|
|
727
|
+
thinkingSteps: [...prev.thinkingSteps || [], newStep],
|
|
728
|
+
thinkingStartTime: thinkingStartTime2,
|
|
729
|
+
firstMessageTime
|
|
730
|
+
};
|
|
731
|
+
}
|
|
345
732
|
const newThinking = payload.message || payload.content || "";
|
|
346
733
|
const separator = prev.thinking && newThinking ? "\n\n" : "";
|
|
347
734
|
const thinkingStartTime = prev.thinkingStartTime ?? (newThinking ? Date.now() : null);
|
|
@@ -415,6 +802,24 @@ function useAgentResponseAccumulator(options) {
|
|
|
415
802
|
responseCompleteTime: Date.now(),
|
|
416
803
|
firstMessageTime: prev.firstMessageTime ?? Date.now()
|
|
417
804
|
};
|
|
805
|
+
case "status_update": {
|
|
806
|
+
const statusMessage = payload.message || payload.statusUpdate?.message;
|
|
807
|
+
if (statusMessage) {
|
|
808
|
+
const newStatusItem = {
|
|
809
|
+
id: payload.statusUpdate?.id || `status-${Date.now()}`,
|
|
810
|
+
message: statusMessage,
|
|
811
|
+
agent: payload.statusUpdate?.agent,
|
|
812
|
+
timestamp: Date.now()
|
|
813
|
+
};
|
|
814
|
+
return {
|
|
815
|
+
...prev,
|
|
816
|
+
status: newStatus,
|
|
817
|
+
statusUpdates: [...prev.statusUpdates, newStatusItem],
|
|
818
|
+
firstMessageTime
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
return { ...prev, status: newStatus, firstMessageTime };
|
|
822
|
+
}
|
|
418
823
|
default:
|
|
419
824
|
return { ...prev, status: newStatus, firstMessageTime };
|
|
420
825
|
}
|
|
@@ -427,7 +832,7 @@ function useAgentResponseAccumulator(options) {
|
|
|
427
832
|
}, []);
|
|
428
833
|
return { state, handleMessage, reset };
|
|
429
834
|
}
|
|
430
|
-
var AgentResponse =
|
|
835
|
+
var AgentResponse = React11.forwardRef(
|
|
431
836
|
({
|
|
432
837
|
state,
|
|
433
838
|
id,
|
|
@@ -439,7 +844,11 @@ var AgentResponse = React.forwardRef(
|
|
|
439
844
|
thinkingExpanded: controlledThinkingExpanded,
|
|
440
845
|
onThinkingExpandedChange,
|
|
441
846
|
actionsVisible = "hover",
|
|
847
|
+
hitlInteractions,
|
|
848
|
+
defaultHITLExpanded = false,
|
|
849
|
+
statusContent,
|
|
442
850
|
renderMarkdown,
|
|
851
|
+
renderThinkingMarkdown,
|
|
443
852
|
className,
|
|
444
853
|
...props
|
|
445
854
|
}, ref) => {
|
|
@@ -464,8 +873,10 @@ var AgentResponse = React.forwardRef(
|
|
|
464
873
|
if (!state.firstMessageTime || !state.responseCompleteTime) return 0;
|
|
465
874
|
return (state.responseCompleteTime - state.firstMessageTime) / 1e3;
|
|
466
875
|
}, [state.firstMessageTime, state.responseCompleteTime]);
|
|
467
|
-
const
|
|
468
|
-
const
|
|
876
|
+
const hasThinkingContent = !!state.thinking || state.thinkingSteps && state.thinkingSteps.length > 0 || false;
|
|
877
|
+
const hasHITLInteractions = hitlInteractions && hitlInteractions.length > 0;
|
|
878
|
+
const hasAnyContent = hasThinkingContent || state.toolCalls.length > 0 || state.knowledge.length > 0 || state.memory.length > 0 || state.statusUpdates.length > 0 || hasHITLInteractions || state.response;
|
|
879
|
+
const showMetadataRow = hasThinkingContent || state.toolCalls.length > 0 || state.knowledge.length > 0 || state.memory.length > 0 || state.statusUpdates.length > 0 || state.status === "processing";
|
|
469
880
|
const showActionBar = state.status === "complete" && state.response;
|
|
470
881
|
const isActionBarVisible = actionsVisible === true || actionsVisible === "hover" && isHovered;
|
|
471
882
|
if (!hasAnyContent) {
|
|
@@ -485,12 +896,14 @@ var AgentResponse = React.forwardRef(
|
|
|
485
896
|
/* @__PURE__ */ jsx(
|
|
486
897
|
MetadataRow,
|
|
487
898
|
{
|
|
488
|
-
hasThinking:
|
|
899
|
+
hasThinking: hasThinkingContent,
|
|
489
900
|
isExpanded: thinkingExpanded,
|
|
490
901
|
onToggle: toggleThinking,
|
|
491
902
|
toolCalls: state.toolCalls,
|
|
492
903
|
knowledge: state.knowledge,
|
|
493
904
|
memory: state.memory,
|
|
905
|
+
statusUpdates: state.statusUpdates,
|
|
906
|
+
statusContent,
|
|
494
907
|
status: state.status,
|
|
495
908
|
elapsedTime
|
|
496
909
|
}
|
|
@@ -498,11 +911,19 @@ var AgentResponse = React.forwardRef(
|
|
|
498
911
|
/* @__PURE__ */ jsx(
|
|
499
912
|
ThinkingSection,
|
|
500
913
|
{
|
|
501
|
-
content: state.thinking,
|
|
502
|
-
isExpanded: thinkingExpanded
|
|
914
|
+
content: state.thinkingSteps && state.thinkingSteps.length > 0 ? state.thinkingSteps : state.thinking,
|
|
915
|
+
isExpanded: thinkingExpanded,
|
|
916
|
+
renderMarkdown: renderThinkingMarkdown
|
|
503
917
|
}
|
|
504
918
|
)
|
|
505
919
|
] }),
|
|
920
|
+
hasHITLInteractions && /* @__PURE__ */ jsx(
|
|
921
|
+
HITLSection,
|
|
922
|
+
{
|
|
923
|
+
interactions: hitlInteractions,
|
|
924
|
+
defaultExpanded: defaultHITLExpanded
|
|
925
|
+
}
|
|
926
|
+
),
|
|
506
927
|
state.response && /* @__PURE__ */ jsx(
|
|
507
928
|
"div",
|
|
508
929
|
{
|
|
@@ -531,7 +952,269 @@ var AgentResponse = React.forwardRef(
|
|
|
531
952
|
}
|
|
532
953
|
);
|
|
533
954
|
AgentResponse.displayName = "AgentResponse";
|
|
955
|
+
var UserPrompt = React11.forwardRef(
|
|
956
|
+
({ content, timestamp, className, ...props }, ref) => {
|
|
957
|
+
return /* @__PURE__ */ jsxs(
|
|
958
|
+
"div",
|
|
959
|
+
{
|
|
960
|
+
ref,
|
|
961
|
+
className: cn(
|
|
962
|
+
"w-fit max-w-[80%] rounded-lg px-4 pt-3.5 pb-3",
|
|
963
|
+
"bg-secondary text-secondary-foreground",
|
|
964
|
+
className
|
|
965
|
+
),
|
|
966
|
+
...props,
|
|
967
|
+
children: [
|
|
968
|
+
/* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap", children: content }),
|
|
969
|
+
timestamp && /* @__PURE__ */ jsx("p", { className: "text-xs text-secondary-foreground/70 mt-1", children: timestamp.toLocaleTimeString([], {
|
|
970
|
+
hour: "2-digit",
|
|
971
|
+
minute: "2-digit"
|
|
972
|
+
}) })
|
|
973
|
+
]
|
|
974
|
+
}
|
|
975
|
+
);
|
|
976
|
+
}
|
|
977
|
+
);
|
|
978
|
+
UserPrompt.displayName = "UserPrompt";
|
|
979
|
+
function createCodeBlockDecorate(entry) {
|
|
980
|
+
const [node, path] = entry;
|
|
981
|
+
const ranges = [];
|
|
982
|
+
if (!Text.isText(node)) {
|
|
983
|
+
return ranges;
|
|
984
|
+
}
|
|
985
|
+
const { text } = node;
|
|
986
|
+
const backtickPositions = [];
|
|
987
|
+
let searchStart = 0;
|
|
988
|
+
while (true) {
|
|
989
|
+
const pos = text.indexOf("```", searchStart);
|
|
990
|
+
if (pos === -1) break;
|
|
991
|
+
backtickPositions.push(pos);
|
|
992
|
+
searchStart = pos + 3;
|
|
993
|
+
}
|
|
994
|
+
let i = 0;
|
|
995
|
+
while (i < backtickPositions.length) {
|
|
996
|
+
const openPos = backtickPositions[i];
|
|
997
|
+
const closePos = backtickPositions[i + 1];
|
|
998
|
+
ranges.push({
|
|
999
|
+
anchor: { path, offset: openPos },
|
|
1000
|
+
focus: { path, offset: openPos + 3 },
|
|
1001
|
+
codeDelimiter: true
|
|
1002
|
+
});
|
|
1003
|
+
if (closePos !== void 0) {
|
|
1004
|
+
if (closePos > openPos + 3) {
|
|
1005
|
+
ranges.push({
|
|
1006
|
+
anchor: { path, offset: openPos + 3 },
|
|
1007
|
+
focus: { path, offset: closePos },
|
|
1008
|
+
codeBlock: true
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
ranges.push({
|
|
1012
|
+
anchor: { path, offset: closePos },
|
|
1013
|
+
focus: { path, offset: closePos + 3 },
|
|
1014
|
+
codeDelimiter: true
|
|
1015
|
+
});
|
|
1016
|
+
i += 2;
|
|
1017
|
+
} else {
|
|
1018
|
+
if (text.length > openPos + 3) {
|
|
1019
|
+
ranges.push({
|
|
1020
|
+
anchor: { path, offset: openPos + 3 },
|
|
1021
|
+
focus: { path, offset: text.length },
|
|
1022
|
+
codeBlock: true
|
|
1023
|
+
});
|
|
1024
|
+
}
|
|
1025
|
+
i += 1;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
return ranges;
|
|
1029
|
+
}
|
|
1030
|
+
function CodeBlockLeaf({ attributes, children, leaf }) {
|
|
1031
|
+
const leafAny = leaf;
|
|
1032
|
+
if (leafAny.codeBlock) {
|
|
1033
|
+
return /* @__PURE__ */ jsx(
|
|
1034
|
+
"span",
|
|
1035
|
+
{
|
|
1036
|
+
...attributes,
|
|
1037
|
+
className: "bg-muted/50 text-muted-foreground font-mono text-sm rounded px-1",
|
|
1038
|
+
children
|
|
1039
|
+
}
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
1042
|
+
if (leafAny.codeDelimiter) {
|
|
1043
|
+
return /* @__PURE__ */ jsx(
|
|
1044
|
+
"span",
|
|
1045
|
+
{
|
|
1046
|
+
...attributes,
|
|
1047
|
+
className: "text-muted-foreground/50 font-mono text-sm",
|
|
1048
|
+
children
|
|
1049
|
+
}
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
1052
|
+
return /* @__PURE__ */ jsx("span", { ...attributes, children });
|
|
1053
|
+
}
|
|
1054
|
+
var UserPromptInput = React11.forwardRef(
|
|
1055
|
+
({
|
|
1056
|
+
value = "",
|
|
1057
|
+
onChange,
|
|
1058
|
+
onSubmit,
|
|
1059
|
+
clearOnSubmit = true,
|
|
1060
|
+
placeholder = "Type your message...",
|
|
1061
|
+
disabled = false,
|
|
1062
|
+
isSubmitting = false,
|
|
1063
|
+
onStop,
|
|
1064
|
+
disableWhileSubmitting = true,
|
|
1065
|
+
autoFocus = false,
|
|
1066
|
+
refocusAfterSubmit = false,
|
|
1067
|
+
onReady,
|
|
1068
|
+
minRows = 1,
|
|
1069
|
+
maxRows = 6,
|
|
1070
|
+
renderActions,
|
|
1071
|
+
enableTags = false,
|
|
1072
|
+
onTagCreate,
|
|
1073
|
+
onTagDelete,
|
|
1074
|
+
className,
|
|
1075
|
+
...props
|
|
1076
|
+
}, ref) => {
|
|
1077
|
+
const editorRef = React11.useRef(null);
|
|
1078
|
+
const [internalValue, setInternalValue] = React11.useState(value);
|
|
1079
|
+
const prevIsSubmitting = React11.useRef(isSubmitting);
|
|
1080
|
+
const hasEmittedReady = React11.useRef(false);
|
|
1081
|
+
React11.useEffect(() => {
|
|
1082
|
+
setInternalValue(value);
|
|
1083
|
+
}, [value]);
|
|
1084
|
+
React11.useEffect(() => {
|
|
1085
|
+
if (autoFocus) {
|
|
1086
|
+
requestAnimationFrame(() => {
|
|
1087
|
+
requestAnimationFrame(() => {
|
|
1088
|
+
editorRef.current?.focus();
|
|
1089
|
+
});
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
}, [autoFocus]);
|
|
1093
|
+
React11.useEffect(() => {
|
|
1094
|
+
if (!hasEmittedReady.current && onReady) {
|
|
1095
|
+
requestAnimationFrame(() => {
|
|
1096
|
+
requestAnimationFrame(() => {
|
|
1097
|
+
hasEmittedReady.current = true;
|
|
1098
|
+
onReady();
|
|
1099
|
+
});
|
|
1100
|
+
});
|
|
1101
|
+
}
|
|
1102
|
+
}, [onReady]);
|
|
1103
|
+
React11.useEffect(() => {
|
|
1104
|
+
if (refocusAfterSubmit && prevIsSubmitting.current && !isSubmitting) {
|
|
1105
|
+
requestAnimationFrame(() => {
|
|
1106
|
+
editorRef.current?.focus();
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
1109
|
+
prevIsSubmitting.current = isSubmitting;
|
|
1110
|
+
}, [isSubmitting, refocusAfterSubmit]);
|
|
1111
|
+
React11.useImperativeHandle(
|
|
1112
|
+
ref,
|
|
1113
|
+
() => ({
|
|
1114
|
+
focus: () => {
|
|
1115
|
+
try {
|
|
1116
|
+
editorRef.current?.focus();
|
|
1117
|
+
} catch {
|
|
1118
|
+
requestAnimationFrame(() => {
|
|
1119
|
+
requestAnimationFrame(() => {
|
|
1120
|
+
editorRef.current?.focus();
|
|
1121
|
+
});
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
},
|
|
1125
|
+
clear: () => {
|
|
1126
|
+
editorRef.current?.clear();
|
|
1127
|
+
setInternalValue("");
|
|
1128
|
+
},
|
|
1129
|
+
getText: () => editorRef.current?.getText() ?? "",
|
|
1130
|
+
insertText: (text) => editorRef.current?.insertText(text)
|
|
1131
|
+
}),
|
|
1132
|
+
[]
|
|
1133
|
+
);
|
|
1134
|
+
const handleChange = React11.useCallback(
|
|
1135
|
+
(newValue) => {
|
|
1136
|
+
setInternalValue(newValue);
|
|
1137
|
+
onChange?.(newValue);
|
|
1138
|
+
},
|
|
1139
|
+
[onChange]
|
|
1140
|
+
);
|
|
1141
|
+
const handleSubmit = React11.useCallback(
|
|
1142
|
+
(text) => {
|
|
1143
|
+
if (disabled || isSubmitting) return;
|
|
1144
|
+
if (!text.trim()) return;
|
|
1145
|
+
onSubmit?.(text.trim());
|
|
1146
|
+
if (clearOnSubmit) {
|
|
1147
|
+
editorRef.current?.clear();
|
|
1148
|
+
setInternalValue("");
|
|
1149
|
+
}
|
|
1150
|
+
},
|
|
1151
|
+
[disabled, isSubmitting, onSubmit, clearOnSubmit]
|
|
1152
|
+
);
|
|
1153
|
+
const handleSendClick = React11.useCallback(() => {
|
|
1154
|
+
const text = editorRef.current?.getText() ?? "";
|
|
1155
|
+
handleSubmit(text);
|
|
1156
|
+
}, [handleSubmit]);
|
|
1157
|
+
const hasContent = internalValue.trim().length > 0;
|
|
1158
|
+
const canSubmit = hasContent && !disabled && !isSubmitting;
|
|
1159
|
+
return /* @__PURE__ */ jsxs(
|
|
1160
|
+
"div",
|
|
1161
|
+
{
|
|
1162
|
+
className: cn(
|
|
1163
|
+
"rounded-lg border border-input bg-background",
|
|
1164
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
1165
|
+
className
|
|
1166
|
+
),
|
|
1167
|
+
...props,
|
|
1168
|
+
children: [
|
|
1169
|
+
/* @__PURE__ */ jsx("div", { className: "pl-2 pr-0 pt-1 pb-1", children: /* @__PURE__ */ jsx(
|
|
1170
|
+
SlateEditor,
|
|
1171
|
+
{
|
|
1172
|
+
ref: editorRef,
|
|
1173
|
+
value: internalValue,
|
|
1174
|
+
onChange: handleChange,
|
|
1175
|
+
onSubmit: handleSubmit,
|
|
1176
|
+
clearOnSubmit: false,
|
|
1177
|
+
placeholder,
|
|
1178
|
+
disabled: disabled || disableWhileSubmitting && isSubmitting,
|
|
1179
|
+
enableTags,
|
|
1180
|
+
onTagCreate,
|
|
1181
|
+
onTagDelete,
|
|
1182
|
+
minRows,
|
|
1183
|
+
maxRows,
|
|
1184
|
+
decorate: createCodeBlockDecorate,
|
|
1185
|
+
renderLeaf: CodeBlockLeaf
|
|
1186
|
+
}
|
|
1187
|
+
) }),
|
|
1188
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between pl-2 pr-1 pb-1 pt-1", children: [
|
|
1189
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: renderActions?.() }),
|
|
1190
|
+
isSubmitting && onStop ? /* @__PURE__ */ jsx(
|
|
1191
|
+
IconButton,
|
|
1192
|
+
{
|
|
1193
|
+
icon: /* @__PURE__ */ jsx(Square, {}),
|
|
1194
|
+
variant: "filled",
|
|
1195
|
+
size: "sm",
|
|
1196
|
+
"aria-label": "Stop",
|
|
1197
|
+
onClick: onStop
|
|
1198
|
+
}
|
|
1199
|
+
) : /* @__PURE__ */ jsx(
|
|
1200
|
+
IconButton,
|
|
1201
|
+
{
|
|
1202
|
+
icon: isSubmitting ? /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) : /* @__PURE__ */ jsx(Send, {}),
|
|
1203
|
+
variant: "filled",
|
|
1204
|
+
size: "sm",
|
|
1205
|
+
"aria-label": isSubmitting ? "Sending..." : "Send message",
|
|
1206
|
+
disabled: !canSubmit,
|
|
1207
|
+
onClick: handleSendClick
|
|
1208
|
+
}
|
|
1209
|
+
)
|
|
1210
|
+
] })
|
|
1211
|
+
]
|
|
1212
|
+
}
|
|
1213
|
+
);
|
|
1214
|
+
}
|
|
1215
|
+
);
|
|
1216
|
+
UserPromptInput.displayName = "UserPromptInput";
|
|
534
1217
|
|
|
535
|
-
export { ActionBar, ActivityIndicators, AgentResponse, MetadataRow, ThinkingSection, formatTime, formatTotalTime, initialAgentResponseState, useAgentResponseAccumulator, useThinkingTimer };
|
|
1218
|
+
export { ActionBar, ActivityIndicators, AgentResponse, HITLInteractionRecord, HITLQuestionPanel, HITLSection, MetadataRow, ThinkingSection, TruncatedMessage, UserPrompt, UserPromptInput, buildResponseString, formatTime, formatTotalTime, initialAgentResponseState, useAgentResponseAccumulator, useThinkingTimer };
|
|
536
1219
|
//# sourceMappingURL=index.js.map
|
|
537
1220
|
//# sourceMappingURL=index.js.map
|