@optilogic/chat 1.0.0-beta.1 → 1.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +232 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +92 -1
- package/dist/index.d.ts +92 -1
- package/dist/index.js +219 -9
- package/dist/index.js.map +1 -1
- package/package.json +10 -4
- 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 +265 -0
- package/src/components/user-prompt-input/index.ts +2 -0
- package/src/components/user-prompt-input/types.ts +42 -0
- package/src/index.ts +10 -0
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React7 = 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,10 +24,10 @@ function _interopNamespace(e) {
|
|
|
23
24
|
return Object.freeze(n);
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
var
|
|
27
|
+
var React7__namespace = /*#__PURE__*/_interopNamespace(React7);
|
|
27
28
|
|
|
28
29
|
// src/components/agent-response/AgentResponse.tsx
|
|
29
|
-
var ActivityIndicators =
|
|
30
|
+
var ActivityIndicators = React7__namespace.forwardRef(
|
|
30
31
|
({ toolCalls, knowledge, memory, className, ...props }, ref) => {
|
|
31
32
|
const hasAnyActivity = toolCalls.length > 0 || knowledge.length > 0 || memory.length > 0;
|
|
32
33
|
if (!hasAnyActivity) return null;
|
|
@@ -125,7 +126,7 @@ function formatTotalTime(seconds) {
|
|
|
125
126
|
const minutes = seconds / 60;
|
|
126
127
|
return `${minutes.toFixed(1)}m`;
|
|
127
128
|
}
|
|
128
|
-
var MetadataRow =
|
|
129
|
+
var MetadataRow = React7__namespace.forwardRef(
|
|
129
130
|
({
|
|
130
131
|
hasThinking,
|
|
131
132
|
isExpanded,
|
|
@@ -189,7 +190,7 @@ var MetadataRow = React__namespace.forwardRef(
|
|
|
189
190
|
}
|
|
190
191
|
);
|
|
191
192
|
MetadataRow.displayName = "MetadataRow";
|
|
192
|
-
var ThinkingSection =
|
|
193
|
+
var ThinkingSection = React7__namespace.forwardRef(
|
|
193
194
|
({ content, isExpanded, className, ...props }, ref) => {
|
|
194
195
|
if (!isExpanded || !content) {
|
|
195
196
|
return null;
|
|
@@ -206,7 +207,7 @@ var ThinkingSection = React__namespace.forwardRef(
|
|
|
206
207
|
}
|
|
207
208
|
);
|
|
208
209
|
ThinkingSection.displayName = "ThinkingSection";
|
|
209
|
-
var ActionBar =
|
|
210
|
+
var ActionBar = React7__namespace.forwardRef(
|
|
210
211
|
({
|
|
211
212
|
response,
|
|
212
213
|
isVisible,
|
|
@@ -217,8 +218,8 @@ var ActionBar = React__namespace.forwardRef(
|
|
|
217
218
|
className,
|
|
218
219
|
...props
|
|
219
220
|
}, ref) => {
|
|
220
|
-
const [copied, setCopied] =
|
|
221
|
-
const handleCopy =
|
|
221
|
+
const [copied, setCopied] = React7.useState(false);
|
|
222
|
+
const handleCopy = React7.useCallback(async () => {
|
|
222
223
|
try {
|
|
223
224
|
await navigator.clipboard.writeText(response);
|
|
224
225
|
setCopied(true);
|
|
@@ -228,11 +229,11 @@ var ActionBar = React__namespace.forwardRef(
|
|
|
228
229
|
console.error("Failed to copy response:", err);
|
|
229
230
|
}
|
|
230
231
|
}, [response, onResponseCopy]);
|
|
231
|
-
const handleThumbsUp =
|
|
232
|
+
const handleThumbsUp = React7.useCallback(() => {
|
|
232
233
|
const newValue = feedback === "up" ? null : "up";
|
|
233
234
|
onFeedbackChange?.(newValue);
|
|
234
235
|
}, [feedback, onFeedbackChange]);
|
|
235
|
-
const handleThumbsDown =
|
|
236
|
+
const handleThumbsDown = React7.useCallback(() => {
|
|
236
237
|
const newValue = feedback === "down" ? null : "down";
|
|
237
238
|
onFeedbackChange?.(newValue);
|
|
238
239
|
}, [feedback, onFeedbackChange]);
|
|
@@ -300,8 +301,8 @@ function useThinkingTimer({
|
|
|
300
301
|
endTime,
|
|
301
302
|
status
|
|
302
303
|
}) {
|
|
303
|
-
const [elapsed, setElapsed] =
|
|
304
|
-
|
|
304
|
+
const [elapsed, setElapsed] = React7.useState(0);
|
|
305
|
+
React7.useEffect(() => {
|
|
305
306
|
if (!startTime) {
|
|
306
307
|
setElapsed(0);
|
|
307
308
|
return;
|
|
@@ -337,9 +338,9 @@ var initialAgentResponseState = {
|
|
|
337
338
|
|
|
338
339
|
// src/components/agent-response/hooks/useAgentResponseAccumulator.ts
|
|
339
340
|
function useAgentResponseAccumulator(options) {
|
|
340
|
-
const [state, setState] =
|
|
341
|
+
const [state, setState] = React7.useState(initialAgentResponseState);
|
|
341
342
|
const topic = options?.topic;
|
|
342
|
-
const handleMessage =
|
|
343
|
+
const handleMessage = React7.useCallback(
|
|
343
344
|
(message) => {
|
|
344
345
|
let payload;
|
|
345
346
|
if (topic) {
|
|
@@ -443,12 +444,12 @@ function useAgentResponseAccumulator(options) {
|
|
|
443
444
|
},
|
|
444
445
|
[topic]
|
|
445
446
|
);
|
|
446
|
-
const reset =
|
|
447
|
+
const reset = React7.useCallback(() => {
|
|
447
448
|
setState(initialAgentResponseState);
|
|
448
449
|
}, []);
|
|
449
450
|
return { state, handleMessage, reset };
|
|
450
451
|
}
|
|
451
|
-
var AgentResponse =
|
|
452
|
+
var AgentResponse = React7__namespace.forwardRef(
|
|
452
453
|
({
|
|
453
454
|
state,
|
|
454
455
|
id,
|
|
@@ -464,10 +465,10 @@ var AgentResponse = React__namespace.forwardRef(
|
|
|
464
465
|
className,
|
|
465
466
|
...props
|
|
466
467
|
}, ref) => {
|
|
467
|
-
const [uncontrolledExpanded, setUncontrolledExpanded] =
|
|
468
|
+
const [uncontrolledExpanded, setUncontrolledExpanded] = React7.useState(defaultThinkingExpanded);
|
|
468
469
|
const isThinkingControlled = controlledThinkingExpanded !== void 0;
|
|
469
470
|
const thinkingExpanded = isThinkingControlled ? controlledThinkingExpanded : uncontrolledExpanded;
|
|
470
|
-
const toggleThinking =
|
|
471
|
+
const toggleThinking = React7.useCallback(() => {
|
|
471
472
|
const newValue = !thinkingExpanded;
|
|
472
473
|
if (isThinkingControlled) {
|
|
473
474
|
onThinkingExpandedChange?.(newValue);
|
|
@@ -475,13 +476,13 @@ var AgentResponse = React__namespace.forwardRef(
|
|
|
475
476
|
setUncontrolledExpanded(newValue);
|
|
476
477
|
}
|
|
477
478
|
}, [thinkingExpanded, isThinkingControlled, onThinkingExpandedChange]);
|
|
478
|
-
const [isHovered, setIsHovered] =
|
|
479
|
+
const [isHovered, setIsHovered] = React7.useState(false);
|
|
479
480
|
const elapsedTime = useThinkingTimer({
|
|
480
481
|
startTime: state.thinkingStartTime,
|
|
481
482
|
endTime: state.responseCompleteTime,
|
|
482
483
|
status: state.status
|
|
483
484
|
});
|
|
484
|
-
const totalTimeSeconds =
|
|
485
|
+
const totalTimeSeconds = React7.useMemo(() => {
|
|
485
486
|
if (!state.firstMessageTime || !state.responseCompleteTime) return 0;
|
|
486
487
|
return (state.responseCompleteTime - state.firstMessageTime) / 1e3;
|
|
487
488
|
}, [state.firstMessageTime, state.responseCompleteTime]);
|
|
@@ -552,12 +553,223 @@ var AgentResponse = React__namespace.forwardRef(
|
|
|
552
553
|
}
|
|
553
554
|
);
|
|
554
555
|
AgentResponse.displayName = "AgentResponse";
|
|
556
|
+
var UserPrompt = React7__namespace.forwardRef(
|
|
557
|
+
({ content, timestamp, className, ...props }, ref) => {
|
|
558
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
559
|
+
"div",
|
|
560
|
+
{
|
|
561
|
+
ref,
|
|
562
|
+
className: core.cn(
|
|
563
|
+
"w-fit max-w-[80%] rounded-lg px-4 pt-3.5 pb-3",
|
|
564
|
+
"bg-secondary text-secondary-foreground",
|
|
565
|
+
className
|
|
566
|
+
),
|
|
567
|
+
...props,
|
|
568
|
+
children: [
|
|
569
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap", children: content }),
|
|
570
|
+
timestamp && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-secondary-foreground/70 mt-1", children: timestamp.toLocaleTimeString([], {
|
|
571
|
+
hour: "2-digit",
|
|
572
|
+
minute: "2-digit"
|
|
573
|
+
}) })
|
|
574
|
+
]
|
|
575
|
+
}
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
);
|
|
579
|
+
UserPrompt.displayName = "UserPrompt";
|
|
580
|
+
function createCodeBlockDecorate(entry) {
|
|
581
|
+
const [node, path] = entry;
|
|
582
|
+
const ranges = [];
|
|
583
|
+
if (!editor.Text.isText(node)) {
|
|
584
|
+
return ranges;
|
|
585
|
+
}
|
|
586
|
+
const { text } = node;
|
|
587
|
+
const backtickPositions = [];
|
|
588
|
+
let searchStart = 0;
|
|
589
|
+
while (true) {
|
|
590
|
+
const pos = text.indexOf("```", searchStart);
|
|
591
|
+
if (pos === -1) break;
|
|
592
|
+
backtickPositions.push(pos);
|
|
593
|
+
searchStart = pos + 3;
|
|
594
|
+
}
|
|
595
|
+
let i = 0;
|
|
596
|
+
while (i < backtickPositions.length) {
|
|
597
|
+
const openPos = backtickPositions[i];
|
|
598
|
+
const closePos = backtickPositions[i + 1];
|
|
599
|
+
ranges.push({
|
|
600
|
+
anchor: { path, offset: openPos },
|
|
601
|
+
focus: { path, offset: openPos + 3 },
|
|
602
|
+
codeDelimiter: true
|
|
603
|
+
});
|
|
604
|
+
if (closePos !== void 0) {
|
|
605
|
+
if (closePos > openPos + 3) {
|
|
606
|
+
ranges.push({
|
|
607
|
+
anchor: { path, offset: openPos + 3 },
|
|
608
|
+
focus: { path, offset: closePos },
|
|
609
|
+
codeBlock: true
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
ranges.push({
|
|
613
|
+
anchor: { path, offset: closePos },
|
|
614
|
+
focus: { path, offset: closePos + 3 },
|
|
615
|
+
codeDelimiter: true
|
|
616
|
+
});
|
|
617
|
+
i += 2;
|
|
618
|
+
} else {
|
|
619
|
+
if (text.length > openPos + 3) {
|
|
620
|
+
ranges.push({
|
|
621
|
+
anchor: { path, offset: openPos + 3 },
|
|
622
|
+
focus: { path, offset: text.length },
|
|
623
|
+
codeBlock: true
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
i += 1;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
return ranges;
|
|
630
|
+
}
|
|
631
|
+
function CodeBlockLeaf({ attributes, children, leaf }) {
|
|
632
|
+
const leafAny = leaf;
|
|
633
|
+
if (leafAny.codeBlock) {
|
|
634
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
635
|
+
"span",
|
|
636
|
+
{
|
|
637
|
+
...attributes,
|
|
638
|
+
className: "bg-muted/50 text-muted-foreground font-mono text-sm rounded px-1",
|
|
639
|
+
children
|
|
640
|
+
}
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
if (leafAny.codeDelimiter) {
|
|
644
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
645
|
+
"span",
|
|
646
|
+
{
|
|
647
|
+
...attributes,
|
|
648
|
+
className: "text-muted-foreground/50 font-mono text-sm",
|
|
649
|
+
children
|
|
650
|
+
}
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { ...attributes, children });
|
|
654
|
+
}
|
|
655
|
+
var UserPromptInput = React7__namespace.forwardRef(
|
|
656
|
+
({
|
|
657
|
+
value = "",
|
|
658
|
+
onChange,
|
|
659
|
+
onSubmit,
|
|
660
|
+
clearOnSubmit = true,
|
|
661
|
+
placeholder = "Type your message...",
|
|
662
|
+
disabled = false,
|
|
663
|
+
isSubmitting = false,
|
|
664
|
+
minRows = 1,
|
|
665
|
+
maxRows = 6,
|
|
666
|
+
renderActions,
|
|
667
|
+
enableTags = false,
|
|
668
|
+
onTagCreate,
|
|
669
|
+
onTagDelete,
|
|
670
|
+
className,
|
|
671
|
+
...props
|
|
672
|
+
}, ref) => {
|
|
673
|
+
const editorRef = React7__namespace.useRef(null);
|
|
674
|
+
const [internalValue, setInternalValue] = React7__namespace.useState(value);
|
|
675
|
+
React7__namespace.useEffect(() => {
|
|
676
|
+
setInternalValue(value);
|
|
677
|
+
}, [value]);
|
|
678
|
+
React7__namespace.useImperativeHandle(
|
|
679
|
+
ref,
|
|
680
|
+
() => ({
|
|
681
|
+
focus: () => editorRef.current?.focus(),
|
|
682
|
+
clear: () => {
|
|
683
|
+
editorRef.current?.clear();
|
|
684
|
+
setInternalValue("");
|
|
685
|
+
},
|
|
686
|
+
getText: () => editorRef.current?.getText() ?? "",
|
|
687
|
+
insertText: (text) => editorRef.current?.insertText(text)
|
|
688
|
+
}),
|
|
689
|
+
[]
|
|
690
|
+
);
|
|
691
|
+
const handleChange = React7__namespace.useCallback(
|
|
692
|
+
(newValue) => {
|
|
693
|
+
setInternalValue(newValue);
|
|
694
|
+
onChange?.(newValue);
|
|
695
|
+
},
|
|
696
|
+
[onChange]
|
|
697
|
+
);
|
|
698
|
+
const handleSubmit = React7__namespace.useCallback(
|
|
699
|
+
(text) => {
|
|
700
|
+
if (disabled || isSubmitting) return;
|
|
701
|
+
if (!text.trim()) return;
|
|
702
|
+
onSubmit?.(text.trim());
|
|
703
|
+
if (clearOnSubmit) {
|
|
704
|
+
editorRef.current?.clear();
|
|
705
|
+
setInternalValue("");
|
|
706
|
+
}
|
|
707
|
+
},
|
|
708
|
+
[disabled, isSubmitting, onSubmit, clearOnSubmit]
|
|
709
|
+
);
|
|
710
|
+
const handleSendClick = React7__namespace.useCallback(() => {
|
|
711
|
+
const text = editorRef.current?.getText() ?? "";
|
|
712
|
+
handleSubmit(text);
|
|
713
|
+
}, [handleSubmit]);
|
|
714
|
+
const hasContent = internalValue.trim().length > 0;
|
|
715
|
+
const canSubmit = hasContent && !disabled && !isSubmitting;
|
|
716
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
717
|
+
"div",
|
|
718
|
+
{
|
|
719
|
+
className: core.cn(
|
|
720
|
+
"rounded-lg border border-input bg-background",
|
|
721
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
722
|
+
className
|
|
723
|
+
),
|
|
724
|
+
...props,
|
|
725
|
+
children: [
|
|
726
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-2 pr-0 pt-1 pb-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
727
|
+
editor.SlateEditor,
|
|
728
|
+
{
|
|
729
|
+
ref: editorRef,
|
|
730
|
+
value: internalValue,
|
|
731
|
+
onChange: handleChange,
|
|
732
|
+
onSubmit: handleSubmit,
|
|
733
|
+
clearOnSubmit: false,
|
|
734
|
+
placeholder,
|
|
735
|
+
disabled: disabled || isSubmitting,
|
|
736
|
+
enableTags,
|
|
737
|
+
onTagCreate,
|
|
738
|
+
onTagDelete,
|
|
739
|
+
minRows,
|
|
740
|
+
maxRows,
|
|
741
|
+
decorate: createCodeBlockDecorate,
|
|
742
|
+
renderLeaf: CodeBlockLeaf
|
|
743
|
+
}
|
|
744
|
+
) }),
|
|
745
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between pl-2 pr-1 pb-1 pt-1", children: [
|
|
746
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: renderActions?.() }),
|
|
747
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
748
|
+
core.IconButton,
|
|
749
|
+
{
|
|
750
|
+
icon: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, {}),
|
|
751
|
+
variant: "filled",
|
|
752
|
+
size: "sm",
|
|
753
|
+
"aria-label": isSubmitting ? "Sending..." : "Send message",
|
|
754
|
+
disabled: !canSubmit,
|
|
755
|
+
onClick: handleSendClick
|
|
756
|
+
}
|
|
757
|
+
)
|
|
758
|
+
] })
|
|
759
|
+
]
|
|
760
|
+
}
|
|
761
|
+
);
|
|
762
|
+
}
|
|
763
|
+
);
|
|
764
|
+
UserPromptInput.displayName = "UserPromptInput";
|
|
555
765
|
|
|
556
766
|
exports.ActionBar = ActionBar;
|
|
557
767
|
exports.ActivityIndicators = ActivityIndicators;
|
|
558
768
|
exports.AgentResponse = AgentResponse;
|
|
559
769
|
exports.MetadataRow = MetadataRow;
|
|
560
770
|
exports.ThinkingSection = ThinkingSection;
|
|
771
|
+
exports.UserPrompt = UserPrompt;
|
|
772
|
+
exports.UserPromptInput = UserPromptInput;
|
|
561
773
|
exports.formatTime = formatTime;
|
|
562
774
|
exports.formatTotalTime = formatTotalTime;
|
|
563
775
|
exports.initialAgentResponseState = initialAgentResponseState;
|