@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.cjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
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');
|
|
7
|
+
var editor = require('@optilogic/editor');
|
|
7
8
|
|
|
8
9
|
function _interopNamespace(e) {
|
|
9
10
|
if (e && e.__esModule) return e;
|
|
@@ -23,14 +24,34 @@ function _interopNamespace(e) {
|
|
|
23
24
|
return Object.freeze(n);
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
var
|
|
27
|
+
var React11__namespace = /*#__PURE__*/_interopNamespace(React11);
|
|
27
28
|
|
|
28
29
|
// src/components/agent-response/AgentResponse.tsx
|
|
29
|
-
var ActivityIndicators =
|
|
30
|
-
({ toolCalls, knowledge, memory, className, ...props }, ref) => {
|
|
31
|
-
const hasAnyActivity = toolCalls.length > 0 || knowledge.length > 0 || memory.length > 0;
|
|
30
|
+
var ActivityIndicators = React11__namespace.forwardRef(
|
|
31
|
+
({ toolCalls, knowledge, memory, statusUpdates = [], className, ...props }, ref) => {
|
|
32
|
+
const hasAnyActivity = toolCalls.length > 0 || knowledge.length > 0 || memory.length > 0 || statusUpdates.length > 0;
|
|
32
33
|
if (!hasAnyActivity) return null;
|
|
33
34
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: core.cn("flex items-center gap-2", className), ...props, children: [
|
|
35
|
+
statusUpdates.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(core.Popover, { children: [
|
|
36
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
37
|
+
"button",
|
|
38
|
+
{
|
|
39
|
+
className: "flex items-center gap-1 text-muted-foreground hover:text-foreground transition-colors",
|
|
40
|
+
onClick: (e) => e.stopPropagation(),
|
|
41
|
+
children: [
|
|
42
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Activity, { className: "w-3.5 h-3.5" }),
|
|
43
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", children: statusUpdates.length })
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
) }),
|
|
47
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.PopoverContent, { className: "w-80", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
48
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-medium text-sm", children: "Status Updates" }),
|
|
49
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2 max-h-60 overflow-auto", children: statusUpdates.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 bg-muted rounded text-xs", children: [
|
|
50
|
+
item.agent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-muted-foreground", children: item.agent }),
|
|
51
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: item.agent ? "mt-1" : "", children: item.message })
|
|
52
|
+
] }, item.id)) })
|
|
53
|
+
] }) })
|
|
54
|
+
] }),
|
|
34
55
|
toolCalls.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(core.Popover, { children: [
|
|
35
56
|
/* @__PURE__ */ jsxRuntime.jsx(core.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
36
57
|
"button",
|
|
@@ -125,7 +146,7 @@ function formatTotalTime(seconds) {
|
|
|
125
146
|
const minutes = seconds / 60;
|
|
126
147
|
return `${minutes.toFixed(1)}m`;
|
|
127
148
|
}
|
|
128
|
-
var MetadataRow =
|
|
149
|
+
var MetadataRow = React11__namespace.forwardRef(
|
|
129
150
|
({
|
|
130
151
|
hasThinking,
|
|
131
152
|
isExpanded,
|
|
@@ -133,6 +154,8 @@ var MetadataRow = React__namespace.forwardRef(
|
|
|
133
154
|
toolCalls,
|
|
134
155
|
knowledge,
|
|
135
156
|
memory,
|
|
157
|
+
statusUpdates = [],
|
|
158
|
+
statusContent,
|
|
136
159
|
status,
|
|
137
160
|
elapsedTime,
|
|
138
161
|
className,
|
|
@@ -140,7 +163,7 @@ var MetadataRow = React__namespace.forwardRef(
|
|
|
140
163
|
}, ref) => {
|
|
141
164
|
const isProcessing = status === "processing";
|
|
142
165
|
const isComplete = status === "complete";
|
|
143
|
-
const hasActivity = toolCalls.length > 0 || knowledge.length > 0 || memory.length > 0;
|
|
166
|
+
const hasActivity = toolCalls.length > 0 || knowledge.length > 0 || memory.length > 0 || statusUpdates.length > 0;
|
|
144
167
|
const renderLeftContent = () => {
|
|
145
168
|
if (hasThinking) {
|
|
146
169
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
@@ -157,7 +180,7 @@ var MetadataRow = React__namespace.forwardRef(
|
|
|
157
180
|
return null;
|
|
158
181
|
};
|
|
159
182
|
const leftContent = renderLeftContent();
|
|
160
|
-
if (!leftContent && !hasActivity) {
|
|
183
|
+
if (!leftContent && !hasActivity && !statusContent) {
|
|
161
184
|
return null;
|
|
162
185
|
}
|
|
163
186
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -171,16 +194,18 @@ var MetadataRow = React__namespace.forwardRef(
|
|
|
171
194
|
"button",
|
|
172
195
|
{
|
|
173
196
|
onClick: onToggle,
|
|
174
|
-
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",
|
|
175
198
|
children: leftContent
|
|
176
199
|
}
|
|
177
|
-
) : /* @__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 }),
|
|
178
202
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
179
203
|
ActivityIndicators,
|
|
180
204
|
{
|
|
181
205
|
toolCalls,
|
|
182
206
|
knowledge,
|
|
183
|
-
memory
|
|
207
|
+
memory,
|
|
208
|
+
statusUpdates
|
|
184
209
|
}
|
|
185
210
|
)
|
|
186
211
|
]
|
|
@@ -189,24 +214,61 @@ var MetadataRow = React__namespace.forwardRef(
|
|
|
189
214
|
}
|
|
190
215
|
);
|
|
191
216
|
MetadataRow.displayName = "MetadataRow";
|
|
192
|
-
var
|
|
193
|
-
|
|
194
|
-
|
|
217
|
+
var ThinkingStepItem = ({ step, renderMarkdown }) => {
|
|
218
|
+
const [isCollapsed, setIsCollapsed] = React11.useState(step.isCollapsed ?? false);
|
|
219
|
+
const toggleCollapse = React11.useCallback(() => {
|
|
220
|
+
setIsCollapsed((prev) => !prev);
|
|
221
|
+
}, []);
|
|
222
|
+
const indentPadding = step.depth * 16;
|
|
223
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-border/50 last:border-b-0", children: [
|
|
224
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
225
|
+
"button",
|
|
226
|
+
{
|
|
227
|
+
onClick: toggleCollapse,
|
|
228
|
+
className: "w-full flex items-center gap-1.5 py-1.5 px-2 hover:bg-muted/50 transition-colors text-left",
|
|
229
|
+
style: { paddingLeft: `${indentPadding + 8}px` },
|
|
230
|
+
children: [
|
|
231
|
+
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" }),
|
|
232
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-foreground/80", children: step.label })
|
|
233
|
+
]
|
|
234
|
+
}
|
|
235
|
+
),
|
|
236
|
+
!isCollapsed && /* @__PURE__ */ jsxRuntime.jsx(
|
|
237
|
+
"div",
|
|
238
|
+
{
|
|
239
|
+
className: "pb-2 px-2",
|
|
240
|
+
style: { paddingLeft: `${indentPadding + 28}px` },
|
|
241
|
+
children: renderMarkdown ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: renderMarkdown(step.content) }) : /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs text-muted-foreground whitespace-pre-wrap font-mono", children: step.content })
|
|
242
|
+
}
|
|
243
|
+
)
|
|
244
|
+
] });
|
|
245
|
+
};
|
|
246
|
+
var ThinkingSection = React11__namespace.forwardRef(
|
|
247
|
+
({ content, isExpanded, renderMarkdown, className, ...props }, ref) => {
|
|
248
|
+
if (!isExpanded || !content || Array.isArray(content) && content.length === 0) {
|
|
195
249
|
return null;
|
|
196
250
|
}
|
|
251
|
+
const isStructured = Array.isArray(content);
|
|
197
252
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
198
253
|
"div",
|
|
199
254
|
{
|
|
200
255
|
ref,
|
|
201
256
|
className: core.cn("px-3 pb-3 border-t border-border", className),
|
|
202
257
|
...props,
|
|
203
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 max-h-[200px] overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx("
|
|
258
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 max-h-[200px] overflow-y-auto", children: isStructured ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-0", children: content.map((step) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
259
|
+
ThinkingStepItem,
|
|
260
|
+
{
|
|
261
|
+
step,
|
|
262
|
+
renderMarkdown
|
|
263
|
+
},
|
|
264
|
+
step.id
|
|
265
|
+
)) }) : renderMarkdown ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: renderMarkdown(content) }) : /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs text-muted-foreground whitespace-pre-wrap font-mono", children: content }) })
|
|
204
266
|
}
|
|
205
267
|
);
|
|
206
268
|
}
|
|
207
269
|
);
|
|
208
270
|
ThinkingSection.displayName = "ThinkingSection";
|
|
209
|
-
var ActionBar =
|
|
271
|
+
var ActionBar = React11__namespace.forwardRef(
|
|
210
272
|
({
|
|
211
273
|
response,
|
|
212
274
|
isVisible,
|
|
@@ -217,8 +279,8 @@ var ActionBar = React__namespace.forwardRef(
|
|
|
217
279
|
className,
|
|
218
280
|
...props
|
|
219
281
|
}, ref) => {
|
|
220
|
-
const [copied, setCopied] =
|
|
221
|
-
const handleCopy =
|
|
282
|
+
const [copied, setCopied] = React11.useState(false);
|
|
283
|
+
const handleCopy = React11.useCallback(async () => {
|
|
222
284
|
try {
|
|
223
285
|
await navigator.clipboard.writeText(response);
|
|
224
286
|
setCopied(true);
|
|
@@ -228,11 +290,11 @@ var ActionBar = React__namespace.forwardRef(
|
|
|
228
290
|
console.error("Failed to copy response:", err);
|
|
229
291
|
}
|
|
230
292
|
}, [response, onResponseCopy]);
|
|
231
|
-
const handleThumbsUp =
|
|
293
|
+
const handleThumbsUp = React11.useCallback(() => {
|
|
232
294
|
const newValue = feedback === "up" ? null : "up";
|
|
233
295
|
onFeedbackChange?.(newValue);
|
|
234
296
|
}, [feedback, onFeedbackChange]);
|
|
235
|
-
const handleThumbsDown =
|
|
297
|
+
const handleThumbsDown = React11.useCallback(() => {
|
|
236
298
|
const newValue = feedback === "down" ? null : "down";
|
|
237
299
|
onFeedbackChange?.(newValue);
|
|
238
300
|
}, [feedback, onFeedbackChange]);
|
|
@@ -295,13 +357,320 @@ var ActionBar = React__namespace.forwardRef(
|
|
|
295
357
|
}
|
|
296
358
|
);
|
|
297
359
|
ActionBar.displayName = "ActionBar";
|
|
360
|
+
function buildResponseString(questions, selectedOptions, freeformText) {
|
|
361
|
+
const parts = [];
|
|
362
|
+
for (const q of questions) {
|
|
363
|
+
const answer = selectedOptions[q];
|
|
364
|
+
if (answer) {
|
|
365
|
+
parts.push(`Q: ${q}
|
|
366
|
+
A: ${answer}`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
const trimmed = freeformText.trim();
|
|
370
|
+
if (trimmed) {
|
|
371
|
+
parts.push(`Additional context: ${trimmed}`);
|
|
372
|
+
}
|
|
373
|
+
return parts.join("\n\n");
|
|
374
|
+
}
|
|
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(
|
|
381
|
+
0,
|
|
382
|
+
Math.round(
|
|
383
|
+
question.timeoutSeconds - (Date.now() - question.receivedAt) / 1e3
|
|
384
|
+
)
|
|
385
|
+
) : Infinity
|
|
386
|
+
);
|
|
387
|
+
const textareaRef = React11.useRef(null);
|
|
388
|
+
React11.useEffect(() => {
|
|
389
|
+
textareaRef.current?.focus();
|
|
390
|
+
}, []);
|
|
391
|
+
React11.useEffect(() => {
|
|
392
|
+
if (!hasTimeout) return;
|
|
393
|
+
const interval = setInterval(() => {
|
|
394
|
+
const remaining = Math.max(
|
|
395
|
+
0,
|
|
396
|
+
Math.round(
|
|
397
|
+
question.timeoutSeconds - (Date.now() - question.receivedAt) / 1e3
|
|
398
|
+
)
|
|
399
|
+
);
|
|
400
|
+
setSecondsLeft(remaining);
|
|
401
|
+
if (remaining <= 0) clearInterval(interval);
|
|
402
|
+
}, 1e3);
|
|
403
|
+
return () => clearInterval(interval);
|
|
404
|
+
}, [hasTimeout, question.timeoutSeconds, question.receivedAt]);
|
|
405
|
+
const timedOut = hasTimeout && secondsLeft <= 0;
|
|
406
|
+
const questionsWithOptions = React11.useMemo(
|
|
407
|
+
() => question.questions.filter((q) => question.options?.[q]?.length),
|
|
408
|
+
[question.questions, question.options]
|
|
409
|
+
);
|
|
410
|
+
const allOptionsSelected = questionsWithOptions.length > 0 && questionsWithOptions.every((q) => selectedOptions[q]);
|
|
411
|
+
const hasFreeformText = freeformText.trim().length > 0;
|
|
412
|
+
const canSubmit = !timedOut && (allOptionsSelected || hasFreeformText);
|
|
413
|
+
const handleOptionClick = React11.useCallback(
|
|
414
|
+
(questionText, option) => {
|
|
415
|
+
if (timedOut) return;
|
|
416
|
+
setSelectedOptions((prev) => {
|
|
417
|
+
if (prev[questionText] === option) {
|
|
418
|
+
const next = { ...prev };
|
|
419
|
+
delete next[questionText];
|
|
420
|
+
return next;
|
|
421
|
+
}
|
|
422
|
+
return { ...prev, [questionText]: option };
|
|
423
|
+
});
|
|
424
|
+
},
|
|
425
|
+
[timedOut]
|
|
426
|
+
);
|
|
427
|
+
const handleSubmit = React11.useCallback(() => {
|
|
428
|
+
if (!canSubmit) return;
|
|
429
|
+
const combined = buildResponseString(
|
|
430
|
+
question.questions,
|
|
431
|
+
selectedOptions,
|
|
432
|
+
freeformText
|
|
433
|
+
);
|
|
434
|
+
onSubmit(combined);
|
|
435
|
+
}, [canSubmit, question.questions, selectedOptions, freeformText, onSubmit]);
|
|
436
|
+
const handleKeyDown = React11.useCallback(
|
|
437
|
+
(e) => {
|
|
438
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
439
|
+
e.preventDefault();
|
|
440
|
+
handleSubmit();
|
|
441
|
+
}
|
|
442
|
+
},
|
|
443
|
+
[handleSubmit]
|
|
444
|
+
);
|
|
445
|
+
const formatTime2 = (s) => {
|
|
446
|
+
const m = Math.floor(s / 60);
|
|
447
|
+
const sec = s % 60;
|
|
448
|
+
return `${m}:${sec.toString().padStart(2, "0")}`;
|
|
449
|
+
};
|
|
450
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
451
|
+
"div",
|
|
452
|
+
{
|
|
453
|
+
ref,
|
|
454
|
+
className: core.cn(
|
|
455
|
+
"rounded-lg border border-border bg-muted p-4 space-y-3",
|
|
456
|
+
className
|
|
457
|
+
),
|
|
458
|
+
...props,
|
|
459
|
+
children: [
|
|
460
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
461
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-foreground", children: question.reason }) }),
|
|
462
|
+
hasTimeout && /* @__PURE__ */ jsxRuntime.jsx(
|
|
463
|
+
"span",
|
|
464
|
+
{
|
|
465
|
+
className: core.cn(
|
|
466
|
+
"text-xs font-mono whitespace-nowrap",
|
|
467
|
+
secondsLeft <= 30 ? "text-destructive" : "text-muted-foreground"
|
|
468
|
+
),
|
|
469
|
+
children: timedOut ? "Timed out" : formatTime2(secondsLeft)
|
|
470
|
+
}
|
|
471
|
+
)
|
|
472
|
+
] }),
|
|
473
|
+
question.context && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground bg-background rounded p-2 border border-border max-h-24 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap font-mono", children: question.context }) }),
|
|
474
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: question.questions.map((q, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
475
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground", children: q }),
|
|
476
|
+
question.options?.[q] && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2 mt-1.5", children: question.options[q].map((option, j) => {
|
|
477
|
+
const isSelected = selectedOptions[q] === option;
|
|
478
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
479
|
+
core.Button,
|
|
480
|
+
{
|
|
481
|
+
variant: isSelected ? "primary" : "outline",
|
|
482
|
+
size: "sm",
|
|
483
|
+
onClick: () => handleOptionClick(q, option),
|
|
484
|
+
disabled: timedOut,
|
|
485
|
+
children: option
|
|
486
|
+
},
|
|
487
|
+
j
|
|
488
|
+
);
|
|
489
|
+
}) })
|
|
490
|
+
] }, i)) }),
|
|
491
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
492
|
+
core.Textarea,
|
|
493
|
+
{
|
|
494
|
+
ref: textareaRef,
|
|
495
|
+
value: freeformText,
|
|
496
|
+
onChange: (e) => setFreeformText(e.target.value),
|
|
497
|
+
onKeyDown: handleKeyDown,
|
|
498
|
+
disabled: timedOut,
|
|
499
|
+
placeholder: "Add additional context or type a full response...",
|
|
500
|
+
rows: 2,
|
|
501
|
+
className: "resize-none"
|
|
502
|
+
}
|
|
503
|
+
),
|
|
504
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
505
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
506
|
+
core.Button,
|
|
507
|
+
{
|
|
508
|
+
variant: "ghost",
|
|
509
|
+
size: "sm",
|
|
510
|
+
onClick: onStop,
|
|
511
|
+
className: "text-destructive hover:text-destructive hover:bg-destructive/10",
|
|
512
|
+
children: "Stop agent"
|
|
513
|
+
}
|
|
514
|
+
),
|
|
515
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
516
|
+
core.Button,
|
|
517
|
+
{
|
|
518
|
+
variant: "primary",
|
|
519
|
+
size: "sm",
|
|
520
|
+
onClick: handleSubmit,
|
|
521
|
+
disabled: !canSubmit,
|
|
522
|
+
children: "Send response"
|
|
523
|
+
}
|
|
524
|
+
)
|
|
525
|
+
] })
|
|
526
|
+
]
|
|
527
|
+
}
|
|
528
|
+
);
|
|
529
|
+
});
|
|
530
|
+
HITLQuestionPanel.displayName = "HITLQuestionPanel";
|
|
531
|
+
function parseResponse(response) {
|
|
532
|
+
const answers = {};
|
|
533
|
+
let additionalContext = null;
|
|
534
|
+
const blocks = response.split("\n\n");
|
|
535
|
+
for (const block of blocks) {
|
|
536
|
+
const qaMatch = block.match(/^Q: (.+)\nA: (.+)$/s);
|
|
537
|
+
if (qaMatch) {
|
|
538
|
+
answers[qaMatch[1].trim()] = qaMatch[2].trim();
|
|
539
|
+
} else if (block.startsWith("Additional context: ")) {
|
|
540
|
+
additionalContext = block.slice("Additional context: ".length).trim();
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
return { answers, additionalContext };
|
|
544
|
+
}
|
|
545
|
+
var HITLInteractionRecord = React11__namespace.forwardRef(({ interaction, className, ...props }, ref) => {
|
|
546
|
+
const { question, response, respondedAt } = interaction;
|
|
547
|
+
const timestamp = new Date(respondedAt).toLocaleTimeString([], {
|
|
548
|
+
hour: "2-digit",
|
|
549
|
+
minute: "2-digit"
|
|
550
|
+
});
|
|
551
|
+
const { answers, additionalContext } = React11.useMemo(
|
|
552
|
+
() => parseResponse(response),
|
|
553
|
+
[response]
|
|
554
|
+
);
|
|
555
|
+
const hasParsedAnswers = Object.keys(answers).length > 0;
|
|
556
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
557
|
+
"div",
|
|
558
|
+
{
|
|
559
|
+
ref,
|
|
560
|
+
className: core.cn(
|
|
561
|
+
"rounded-lg border border-border bg-muted p-3 space-y-2 text-sm",
|
|
562
|
+
className
|
|
563
|
+
),
|
|
564
|
+
...props,
|
|
565
|
+
children: [
|
|
566
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
567
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-muted-foreground", children: "Clarifying Question" }),
|
|
568
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: timestamp })
|
|
569
|
+
] }),
|
|
570
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-foreground font-medium", children: question.reason }),
|
|
571
|
+
question.context && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground bg-background rounded p-2 border border-border", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap font-mono", children: question.context }) }),
|
|
572
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: question.questions.map((q, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
573
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-foreground", children: q }),
|
|
574
|
+
question.options?.[q] && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground ml-2", children: [
|
|
575
|
+
"Options: ",
|
|
576
|
+
question.options[q].join(", ")
|
|
577
|
+
] }),
|
|
578
|
+
hasParsedAnswers && answers[q] && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-foreground ml-2 mt-0.5 bg-background rounded px-2 py-1 border border-border", children: [
|
|
579
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Answer: " }),
|
|
580
|
+
answers[q]
|
|
581
|
+
] })
|
|
582
|
+
] }, i)) }),
|
|
583
|
+
hasParsedAnswers && additionalContext && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-border pt-2", children: [
|
|
584
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs", children: "Additional context:" }),
|
|
585
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-foreground mt-0.5", children: additionalContext })
|
|
586
|
+
] }),
|
|
587
|
+
!hasParsedAnswers && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-border pt-2", children: [
|
|
588
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs", children: "Response:" }),
|
|
589
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-foreground mt-0.5", children: response })
|
|
590
|
+
] })
|
|
591
|
+
]
|
|
592
|
+
}
|
|
593
|
+
);
|
|
594
|
+
});
|
|
595
|
+
HITLInteractionRecord.displayName = "HITLInteractionRecord";
|
|
596
|
+
var HITLSection = React11__namespace.forwardRef(
|
|
597
|
+
({
|
|
598
|
+
interactions,
|
|
599
|
+
defaultExpanded = false,
|
|
600
|
+
isExpanded: controlledExpanded,
|
|
601
|
+
onExpandedChange,
|
|
602
|
+
className,
|
|
603
|
+
...props
|
|
604
|
+
}, ref) => {
|
|
605
|
+
const [uncontrolledExpanded, setUncontrolledExpanded] = React11.useState(defaultExpanded);
|
|
606
|
+
const isControlled = controlledExpanded !== void 0;
|
|
607
|
+
const isExpanded = isControlled ? controlledExpanded : uncontrolledExpanded;
|
|
608
|
+
const toggleExpanded = React11.useCallback(() => {
|
|
609
|
+
const newValue = !isExpanded;
|
|
610
|
+
if (isControlled) {
|
|
611
|
+
onExpandedChange?.(newValue);
|
|
612
|
+
} else {
|
|
613
|
+
setUncontrolledExpanded(newValue);
|
|
614
|
+
}
|
|
615
|
+
}, [isExpanded, isControlled, onExpandedChange]);
|
|
616
|
+
if (!interactions || interactions.length === 0) {
|
|
617
|
+
return null;
|
|
618
|
+
}
|
|
619
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
620
|
+
"div",
|
|
621
|
+
{
|
|
622
|
+
ref,
|
|
623
|
+
className: core.cn("border-t border-border", className),
|
|
624
|
+
...props,
|
|
625
|
+
children: [
|
|
626
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
627
|
+
"button",
|
|
628
|
+
{
|
|
629
|
+
onClick: toggleExpanded,
|
|
630
|
+
className: "w-full flex items-center gap-2 py-2 px-3 hover:bg-muted/50 transition-colors text-left",
|
|
631
|
+
children: [
|
|
632
|
+
isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "w-3.5 h-3.5 text-muted-foreground flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "w-3.5 h-3.5 text-muted-foreground flex-shrink-0" }),
|
|
633
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageCircleQuestion, { className: "w-3.5 h-3.5 text-muted-foreground flex-shrink-0" }),
|
|
634
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-medium text-foreground/80", children: [
|
|
635
|
+
"Clarifying Questions (",
|
|
636
|
+
interactions.length,
|
|
637
|
+
")"
|
|
638
|
+
] })
|
|
639
|
+
]
|
|
640
|
+
}
|
|
641
|
+
),
|
|
642
|
+
isExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pb-3 space-y-2", children: interactions.map((interaction, i) => /* @__PURE__ */ jsxRuntime.jsx(HITLInteractionRecord, { interaction }, i)) })
|
|
643
|
+
]
|
|
644
|
+
}
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
);
|
|
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";
|
|
298
667
|
function useThinkingTimer({
|
|
299
668
|
startTime,
|
|
300
669
|
endTime,
|
|
301
670
|
status
|
|
302
671
|
}) {
|
|
303
|
-
const [elapsed, setElapsed] =
|
|
304
|
-
|
|
672
|
+
const [elapsed, setElapsed] = React11.useState(0);
|
|
673
|
+
React11.useEffect(() => {
|
|
305
674
|
if (!startTime) {
|
|
306
675
|
setElapsed(0);
|
|
307
676
|
return;
|
|
@@ -329,6 +698,7 @@ var initialAgentResponseState = {
|
|
|
329
698
|
toolCalls: [],
|
|
330
699
|
knowledge: [],
|
|
331
700
|
memory: [],
|
|
701
|
+
statusUpdates: [],
|
|
332
702
|
response: "",
|
|
333
703
|
thinkingStartTime: null,
|
|
334
704
|
responseCompleteTime: null,
|
|
@@ -337,9 +707,9 @@ var initialAgentResponseState = {
|
|
|
337
707
|
|
|
338
708
|
// src/components/agent-response/hooks/useAgentResponseAccumulator.ts
|
|
339
709
|
function useAgentResponseAccumulator(options) {
|
|
340
|
-
const [state, setState] =
|
|
710
|
+
const [state, setState] = React11.useState(initialAgentResponseState);
|
|
341
711
|
const topic = options?.topic;
|
|
342
|
-
const handleMessage =
|
|
712
|
+
const handleMessage = React11.useCallback(
|
|
343
713
|
(message) => {
|
|
344
714
|
let payload;
|
|
345
715
|
if (topic) {
|
|
@@ -363,6 +733,23 @@ function useAgentResponseAccumulator(options) {
|
|
|
363
733
|
}
|
|
364
734
|
return { ...prev, status: newStatus };
|
|
365
735
|
case "thinking": {
|
|
736
|
+
if (payload.thinkingStep) {
|
|
737
|
+
const newStep = {
|
|
738
|
+
id: payload.thinkingStep.id || `step-${Date.now()}`,
|
|
739
|
+
label: payload.thinkingStep.label,
|
|
740
|
+
content: payload.thinkingStep.content,
|
|
741
|
+
depth: payload.thinkingStep.depth ?? 0,
|
|
742
|
+
isCollapsed: payload.thinkingStep.isCollapsed
|
|
743
|
+
};
|
|
744
|
+
const thinkingStartTime2 = prev.thinkingStartTime ?? Date.now();
|
|
745
|
+
return {
|
|
746
|
+
...prev,
|
|
747
|
+
status: newStatus,
|
|
748
|
+
thinkingSteps: [...prev.thinkingSteps || [], newStep],
|
|
749
|
+
thinkingStartTime: thinkingStartTime2,
|
|
750
|
+
firstMessageTime
|
|
751
|
+
};
|
|
752
|
+
}
|
|
366
753
|
const newThinking = payload.message || payload.content || "";
|
|
367
754
|
const separator = prev.thinking && newThinking ? "\n\n" : "";
|
|
368
755
|
const thinkingStartTime = prev.thinkingStartTime ?? (newThinking ? Date.now() : null);
|
|
@@ -436,6 +823,24 @@ function useAgentResponseAccumulator(options) {
|
|
|
436
823
|
responseCompleteTime: Date.now(),
|
|
437
824
|
firstMessageTime: prev.firstMessageTime ?? Date.now()
|
|
438
825
|
};
|
|
826
|
+
case "status_update": {
|
|
827
|
+
const statusMessage = payload.message || payload.statusUpdate?.message;
|
|
828
|
+
if (statusMessage) {
|
|
829
|
+
const newStatusItem = {
|
|
830
|
+
id: payload.statusUpdate?.id || `status-${Date.now()}`,
|
|
831
|
+
message: statusMessage,
|
|
832
|
+
agent: payload.statusUpdate?.agent,
|
|
833
|
+
timestamp: Date.now()
|
|
834
|
+
};
|
|
835
|
+
return {
|
|
836
|
+
...prev,
|
|
837
|
+
status: newStatus,
|
|
838
|
+
statusUpdates: [...prev.statusUpdates, newStatusItem],
|
|
839
|
+
firstMessageTime
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
return { ...prev, status: newStatus, firstMessageTime };
|
|
843
|
+
}
|
|
439
844
|
default:
|
|
440
845
|
return { ...prev, status: newStatus, firstMessageTime };
|
|
441
846
|
}
|
|
@@ -443,12 +848,12 @@ function useAgentResponseAccumulator(options) {
|
|
|
443
848
|
},
|
|
444
849
|
[topic]
|
|
445
850
|
);
|
|
446
|
-
const reset =
|
|
851
|
+
const reset = React11.useCallback(() => {
|
|
447
852
|
setState(initialAgentResponseState);
|
|
448
853
|
}, []);
|
|
449
854
|
return { state, handleMessage, reset };
|
|
450
855
|
}
|
|
451
|
-
var AgentResponse =
|
|
856
|
+
var AgentResponse = React11__namespace.forwardRef(
|
|
452
857
|
({
|
|
453
858
|
state,
|
|
454
859
|
id,
|
|
@@ -460,14 +865,18 @@ var AgentResponse = React__namespace.forwardRef(
|
|
|
460
865
|
thinkingExpanded: controlledThinkingExpanded,
|
|
461
866
|
onThinkingExpandedChange,
|
|
462
867
|
actionsVisible = "hover",
|
|
868
|
+
hitlInteractions,
|
|
869
|
+
defaultHITLExpanded = false,
|
|
870
|
+
statusContent,
|
|
463
871
|
renderMarkdown,
|
|
872
|
+
renderThinkingMarkdown,
|
|
464
873
|
className,
|
|
465
874
|
...props
|
|
466
875
|
}, ref) => {
|
|
467
|
-
const [uncontrolledExpanded, setUncontrolledExpanded] =
|
|
876
|
+
const [uncontrolledExpanded, setUncontrolledExpanded] = React11.useState(defaultThinkingExpanded);
|
|
468
877
|
const isThinkingControlled = controlledThinkingExpanded !== void 0;
|
|
469
878
|
const thinkingExpanded = isThinkingControlled ? controlledThinkingExpanded : uncontrolledExpanded;
|
|
470
|
-
const toggleThinking =
|
|
879
|
+
const toggleThinking = React11.useCallback(() => {
|
|
471
880
|
const newValue = !thinkingExpanded;
|
|
472
881
|
if (isThinkingControlled) {
|
|
473
882
|
onThinkingExpandedChange?.(newValue);
|
|
@@ -475,18 +884,20 @@ var AgentResponse = React__namespace.forwardRef(
|
|
|
475
884
|
setUncontrolledExpanded(newValue);
|
|
476
885
|
}
|
|
477
886
|
}, [thinkingExpanded, isThinkingControlled, onThinkingExpandedChange]);
|
|
478
|
-
const [isHovered, setIsHovered] =
|
|
887
|
+
const [isHovered, setIsHovered] = React11.useState(false);
|
|
479
888
|
const elapsedTime = useThinkingTimer({
|
|
480
889
|
startTime: state.thinkingStartTime,
|
|
481
890
|
endTime: state.responseCompleteTime,
|
|
482
891
|
status: state.status
|
|
483
892
|
});
|
|
484
|
-
const totalTimeSeconds =
|
|
893
|
+
const totalTimeSeconds = React11.useMemo(() => {
|
|
485
894
|
if (!state.firstMessageTime || !state.responseCompleteTime) return 0;
|
|
486
895
|
return (state.responseCompleteTime - state.firstMessageTime) / 1e3;
|
|
487
896
|
}, [state.firstMessageTime, state.responseCompleteTime]);
|
|
488
|
-
const
|
|
489
|
-
const
|
|
897
|
+
const hasThinkingContent = !!state.thinking || state.thinkingSteps && state.thinkingSteps.length > 0 || false;
|
|
898
|
+
const hasHITLInteractions = hitlInteractions && hitlInteractions.length > 0;
|
|
899
|
+
const hasAnyContent = hasThinkingContent || state.toolCalls.length > 0 || state.knowledge.length > 0 || state.memory.length > 0 || state.statusUpdates.length > 0 || hasHITLInteractions || state.response;
|
|
900
|
+
const showMetadataRow = hasThinkingContent || state.toolCalls.length > 0 || state.knowledge.length > 0 || state.memory.length > 0 || state.statusUpdates.length > 0 || state.status === "processing";
|
|
490
901
|
const showActionBar = state.status === "complete" && state.response;
|
|
491
902
|
const isActionBarVisible = actionsVisible === true || actionsVisible === "hover" && isHovered;
|
|
492
903
|
if (!hasAnyContent) {
|
|
@@ -506,12 +917,14 @@ var AgentResponse = React__namespace.forwardRef(
|
|
|
506
917
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
507
918
|
MetadataRow,
|
|
508
919
|
{
|
|
509
|
-
hasThinking:
|
|
920
|
+
hasThinking: hasThinkingContent,
|
|
510
921
|
isExpanded: thinkingExpanded,
|
|
511
922
|
onToggle: toggleThinking,
|
|
512
923
|
toolCalls: state.toolCalls,
|
|
513
924
|
knowledge: state.knowledge,
|
|
514
925
|
memory: state.memory,
|
|
926
|
+
statusUpdates: state.statusUpdates,
|
|
927
|
+
statusContent,
|
|
515
928
|
status: state.status,
|
|
516
929
|
elapsedTime
|
|
517
930
|
}
|
|
@@ -519,11 +932,19 @@ var AgentResponse = React__namespace.forwardRef(
|
|
|
519
932
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
520
933
|
ThinkingSection,
|
|
521
934
|
{
|
|
522
|
-
content: state.thinking,
|
|
523
|
-
isExpanded: thinkingExpanded
|
|
935
|
+
content: state.thinkingSteps && state.thinkingSteps.length > 0 ? state.thinkingSteps : state.thinking,
|
|
936
|
+
isExpanded: thinkingExpanded,
|
|
937
|
+
renderMarkdown: renderThinkingMarkdown
|
|
524
938
|
}
|
|
525
939
|
)
|
|
526
940
|
] }),
|
|
941
|
+
hasHITLInteractions && /* @__PURE__ */ jsxRuntime.jsx(
|
|
942
|
+
HITLSection,
|
|
943
|
+
{
|
|
944
|
+
interactions: hitlInteractions,
|
|
945
|
+
defaultExpanded: defaultHITLExpanded
|
|
946
|
+
}
|
|
947
|
+
),
|
|
527
948
|
state.response && /* @__PURE__ */ jsxRuntime.jsx(
|
|
528
949
|
"div",
|
|
529
950
|
{
|
|
@@ -552,12 +973,281 @@ var AgentResponse = React__namespace.forwardRef(
|
|
|
552
973
|
}
|
|
553
974
|
);
|
|
554
975
|
AgentResponse.displayName = "AgentResponse";
|
|
976
|
+
var UserPrompt = React11__namespace.forwardRef(
|
|
977
|
+
({ content, timestamp, className, ...props }, ref) => {
|
|
978
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
979
|
+
"div",
|
|
980
|
+
{
|
|
981
|
+
ref,
|
|
982
|
+
className: core.cn(
|
|
983
|
+
"w-fit max-w-[80%] rounded-lg px-4 pt-3.5 pb-3",
|
|
984
|
+
"bg-secondary text-secondary-foreground",
|
|
985
|
+
className
|
|
986
|
+
),
|
|
987
|
+
...props,
|
|
988
|
+
children: [
|
|
989
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap", children: content }),
|
|
990
|
+
timestamp && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-secondary-foreground/70 mt-1", children: timestamp.toLocaleTimeString([], {
|
|
991
|
+
hour: "2-digit",
|
|
992
|
+
minute: "2-digit"
|
|
993
|
+
}) })
|
|
994
|
+
]
|
|
995
|
+
}
|
|
996
|
+
);
|
|
997
|
+
}
|
|
998
|
+
);
|
|
999
|
+
UserPrompt.displayName = "UserPrompt";
|
|
1000
|
+
function createCodeBlockDecorate(entry) {
|
|
1001
|
+
const [node, path] = entry;
|
|
1002
|
+
const ranges = [];
|
|
1003
|
+
if (!editor.Text.isText(node)) {
|
|
1004
|
+
return ranges;
|
|
1005
|
+
}
|
|
1006
|
+
const { text } = node;
|
|
1007
|
+
const backtickPositions = [];
|
|
1008
|
+
let searchStart = 0;
|
|
1009
|
+
while (true) {
|
|
1010
|
+
const pos = text.indexOf("```", searchStart);
|
|
1011
|
+
if (pos === -1) break;
|
|
1012
|
+
backtickPositions.push(pos);
|
|
1013
|
+
searchStart = pos + 3;
|
|
1014
|
+
}
|
|
1015
|
+
let i = 0;
|
|
1016
|
+
while (i < backtickPositions.length) {
|
|
1017
|
+
const openPos = backtickPositions[i];
|
|
1018
|
+
const closePos = backtickPositions[i + 1];
|
|
1019
|
+
ranges.push({
|
|
1020
|
+
anchor: { path, offset: openPos },
|
|
1021
|
+
focus: { path, offset: openPos + 3 },
|
|
1022
|
+
codeDelimiter: true
|
|
1023
|
+
});
|
|
1024
|
+
if (closePos !== void 0) {
|
|
1025
|
+
if (closePos > openPos + 3) {
|
|
1026
|
+
ranges.push({
|
|
1027
|
+
anchor: { path, offset: openPos + 3 },
|
|
1028
|
+
focus: { path, offset: closePos },
|
|
1029
|
+
codeBlock: true
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1032
|
+
ranges.push({
|
|
1033
|
+
anchor: { path, offset: closePos },
|
|
1034
|
+
focus: { path, offset: closePos + 3 },
|
|
1035
|
+
codeDelimiter: true
|
|
1036
|
+
});
|
|
1037
|
+
i += 2;
|
|
1038
|
+
} else {
|
|
1039
|
+
if (text.length > openPos + 3) {
|
|
1040
|
+
ranges.push({
|
|
1041
|
+
anchor: { path, offset: openPos + 3 },
|
|
1042
|
+
focus: { path, offset: text.length },
|
|
1043
|
+
codeBlock: true
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
i += 1;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
return ranges;
|
|
1050
|
+
}
|
|
1051
|
+
function CodeBlockLeaf({ attributes, children, leaf }) {
|
|
1052
|
+
const leafAny = leaf;
|
|
1053
|
+
if (leafAny.codeBlock) {
|
|
1054
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1055
|
+
"span",
|
|
1056
|
+
{
|
|
1057
|
+
...attributes,
|
|
1058
|
+
className: "bg-muted/50 text-muted-foreground font-mono text-sm rounded px-1",
|
|
1059
|
+
children
|
|
1060
|
+
}
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
if (leafAny.codeDelimiter) {
|
|
1064
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1065
|
+
"span",
|
|
1066
|
+
{
|
|
1067
|
+
...attributes,
|
|
1068
|
+
className: "text-muted-foreground/50 font-mono text-sm",
|
|
1069
|
+
children
|
|
1070
|
+
}
|
|
1071
|
+
);
|
|
1072
|
+
}
|
|
1073
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { ...attributes, children });
|
|
1074
|
+
}
|
|
1075
|
+
var UserPromptInput = React11__namespace.forwardRef(
|
|
1076
|
+
({
|
|
1077
|
+
value = "",
|
|
1078
|
+
onChange,
|
|
1079
|
+
onSubmit,
|
|
1080
|
+
clearOnSubmit = true,
|
|
1081
|
+
placeholder = "Type your message...",
|
|
1082
|
+
disabled = false,
|
|
1083
|
+
isSubmitting = false,
|
|
1084
|
+
onStop,
|
|
1085
|
+
disableWhileSubmitting = true,
|
|
1086
|
+
autoFocus = false,
|
|
1087
|
+
refocusAfterSubmit = false,
|
|
1088
|
+
onReady,
|
|
1089
|
+
minRows = 1,
|
|
1090
|
+
maxRows = 6,
|
|
1091
|
+
renderActions,
|
|
1092
|
+
enableTags = false,
|
|
1093
|
+
onTagCreate,
|
|
1094
|
+
onTagDelete,
|
|
1095
|
+
className,
|
|
1096
|
+
...props
|
|
1097
|
+
}, ref) => {
|
|
1098
|
+
const editorRef = React11__namespace.useRef(null);
|
|
1099
|
+
const [internalValue, setInternalValue] = React11__namespace.useState(value);
|
|
1100
|
+
const prevIsSubmitting = React11__namespace.useRef(isSubmitting);
|
|
1101
|
+
const hasEmittedReady = React11__namespace.useRef(false);
|
|
1102
|
+
React11__namespace.useEffect(() => {
|
|
1103
|
+
setInternalValue(value);
|
|
1104
|
+
}, [value]);
|
|
1105
|
+
React11__namespace.useEffect(() => {
|
|
1106
|
+
if (autoFocus) {
|
|
1107
|
+
requestAnimationFrame(() => {
|
|
1108
|
+
requestAnimationFrame(() => {
|
|
1109
|
+
editorRef.current?.focus();
|
|
1110
|
+
});
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
}, [autoFocus]);
|
|
1114
|
+
React11__namespace.useEffect(() => {
|
|
1115
|
+
if (!hasEmittedReady.current && onReady) {
|
|
1116
|
+
requestAnimationFrame(() => {
|
|
1117
|
+
requestAnimationFrame(() => {
|
|
1118
|
+
hasEmittedReady.current = true;
|
|
1119
|
+
onReady();
|
|
1120
|
+
});
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
}, [onReady]);
|
|
1124
|
+
React11__namespace.useEffect(() => {
|
|
1125
|
+
if (refocusAfterSubmit && prevIsSubmitting.current && !isSubmitting) {
|
|
1126
|
+
requestAnimationFrame(() => {
|
|
1127
|
+
editorRef.current?.focus();
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
prevIsSubmitting.current = isSubmitting;
|
|
1131
|
+
}, [isSubmitting, refocusAfterSubmit]);
|
|
1132
|
+
React11__namespace.useImperativeHandle(
|
|
1133
|
+
ref,
|
|
1134
|
+
() => ({
|
|
1135
|
+
focus: () => {
|
|
1136
|
+
try {
|
|
1137
|
+
editorRef.current?.focus();
|
|
1138
|
+
} catch {
|
|
1139
|
+
requestAnimationFrame(() => {
|
|
1140
|
+
requestAnimationFrame(() => {
|
|
1141
|
+
editorRef.current?.focus();
|
|
1142
|
+
});
|
|
1143
|
+
});
|
|
1144
|
+
}
|
|
1145
|
+
},
|
|
1146
|
+
clear: () => {
|
|
1147
|
+
editorRef.current?.clear();
|
|
1148
|
+
setInternalValue("");
|
|
1149
|
+
},
|
|
1150
|
+
getText: () => editorRef.current?.getText() ?? "",
|
|
1151
|
+
insertText: (text) => editorRef.current?.insertText(text)
|
|
1152
|
+
}),
|
|
1153
|
+
[]
|
|
1154
|
+
);
|
|
1155
|
+
const handleChange = React11__namespace.useCallback(
|
|
1156
|
+
(newValue) => {
|
|
1157
|
+
setInternalValue(newValue);
|
|
1158
|
+
onChange?.(newValue);
|
|
1159
|
+
},
|
|
1160
|
+
[onChange]
|
|
1161
|
+
);
|
|
1162
|
+
const handleSubmit = React11__namespace.useCallback(
|
|
1163
|
+
(text) => {
|
|
1164
|
+
if (disabled || isSubmitting) return;
|
|
1165
|
+
if (!text.trim()) return;
|
|
1166
|
+
onSubmit?.(text.trim());
|
|
1167
|
+
if (clearOnSubmit) {
|
|
1168
|
+
editorRef.current?.clear();
|
|
1169
|
+
setInternalValue("");
|
|
1170
|
+
}
|
|
1171
|
+
},
|
|
1172
|
+
[disabled, isSubmitting, onSubmit, clearOnSubmit]
|
|
1173
|
+
);
|
|
1174
|
+
const handleSendClick = React11__namespace.useCallback(() => {
|
|
1175
|
+
const text = editorRef.current?.getText() ?? "";
|
|
1176
|
+
handleSubmit(text);
|
|
1177
|
+
}, [handleSubmit]);
|
|
1178
|
+
const hasContent = internalValue.trim().length > 0;
|
|
1179
|
+
const canSubmit = hasContent && !disabled && !isSubmitting;
|
|
1180
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1181
|
+
"div",
|
|
1182
|
+
{
|
|
1183
|
+
className: core.cn(
|
|
1184
|
+
"rounded-lg border border-input bg-background",
|
|
1185
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
1186
|
+
className
|
|
1187
|
+
),
|
|
1188
|
+
...props,
|
|
1189
|
+
children: [
|
|
1190
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-2 pr-0 pt-1 pb-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1191
|
+
editor.SlateEditor,
|
|
1192
|
+
{
|
|
1193
|
+
ref: editorRef,
|
|
1194
|
+
value: internalValue,
|
|
1195
|
+
onChange: handleChange,
|
|
1196
|
+
onSubmit: handleSubmit,
|
|
1197
|
+
clearOnSubmit: false,
|
|
1198
|
+
placeholder,
|
|
1199
|
+
disabled: disabled || disableWhileSubmitting && isSubmitting,
|
|
1200
|
+
enableTags,
|
|
1201
|
+
onTagCreate,
|
|
1202
|
+
onTagDelete,
|
|
1203
|
+
minRows,
|
|
1204
|
+
maxRows,
|
|
1205
|
+
decorate: createCodeBlockDecorate,
|
|
1206
|
+
renderLeaf: CodeBlockLeaf
|
|
1207
|
+
}
|
|
1208
|
+
) }),
|
|
1209
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between pl-2 pr-1 pb-1 pt-1", children: [
|
|
1210
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: renderActions?.() }),
|
|
1211
|
+
isSubmitting && onStop ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1212
|
+
core.IconButton,
|
|
1213
|
+
{
|
|
1214
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Square, {}),
|
|
1215
|
+
variant: "filled",
|
|
1216
|
+
size: "sm",
|
|
1217
|
+
"aria-label": "Stop",
|
|
1218
|
+
onClick: onStop
|
|
1219
|
+
}
|
|
1220
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1221
|
+
core.IconButton,
|
|
1222
|
+
{
|
|
1223
|
+
icon: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, {}),
|
|
1224
|
+
variant: "filled",
|
|
1225
|
+
size: "sm",
|
|
1226
|
+
"aria-label": isSubmitting ? "Sending..." : "Send message",
|
|
1227
|
+
disabled: !canSubmit,
|
|
1228
|
+
onClick: handleSendClick
|
|
1229
|
+
}
|
|
1230
|
+
)
|
|
1231
|
+
] })
|
|
1232
|
+
]
|
|
1233
|
+
}
|
|
1234
|
+
);
|
|
1235
|
+
}
|
|
1236
|
+
);
|
|
1237
|
+
UserPromptInput.displayName = "UserPromptInput";
|
|
555
1238
|
|
|
556
1239
|
exports.ActionBar = ActionBar;
|
|
557
1240
|
exports.ActivityIndicators = ActivityIndicators;
|
|
558
1241
|
exports.AgentResponse = AgentResponse;
|
|
1242
|
+
exports.HITLInteractionRecord = HITLInteractionRecord;
|
|
1243
|
+
exports.HITLQuestionPanel = HITLQuestionPanel;
|
|
1244
|
+
exports.HITLSection = HITLSection;
|
|
559
1245
|
exports.MetadataRow = MetadataRow;
|
|
560
1246
|
exports.ThinkingSection = ThinkingSection;
|
|
1247
|
+
exports.TruncatedMessage = TruncatedMessage;
|
|
1248
|
+
exports.UserPrompt = UserPrompt;
|
|
1249
|
+
exports.UserPromptInput = UserPromptInput;
|
|
1250
|
+
exports.buildResponseString = buildResponseString;
|
|
561
1251
|
exports.formatTime = formatTime;
|
|
562
1252
|
exports.formatTotalTime = formatTotalTime;
|
|
563
1253
|
exports.initialAgentResponseState = initialAgentResponseState;
|