@agents24/chat-react 0.5.29 → 0.5.31
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 +28 -1
- package/dist/chunk-INO5DSSJ.js +86 -0
- package/dist/chunk-INO5DSSJ.js.map +1 -0
- package/dist/generated/delegation-types.d.ts +129 -0
- package/dist/registry/agents24-chat.json +267 -0
- package/dist/runtime/index.cjs +53 -1
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +62 -78
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/input-contract.d.ts +3 -1
- package/dist/runtime/use-delegation-tasks.d.ts +20 -0
- package/dist/scaffold/app.d.ts +3 -0
- package/dist/scaffold/components/chat/chat-composer.d.ts +5 -3
- package/dist/scaffold/components/chat/subagent-tasks.d.ts +3 -0
- package/dist/scaffold/components/chat/theme-menu.d.ts +1 -1
- package/dist/scaffold/components/theme-provider.d.ts +3 -1
- package/dist/scaffold/index.cjs +420 -333
- package/dist/scaffold/index.cjs.map +1 -1
- package/dist/scaffold/index.d.ts +5 -2
- package/dist/scaffold/index.js +415 -332
- package/dist/scaffold/index.js.map +1 -1
- package/dist/styles.css +14 -0
- package/dist/ui/adapters.d.ts +5 -2
- package/dist/ui/agent-chat-composer.d.ts +8 -2
- package/dist/ui/agent-chat-queue.d.ts +0 -2
- package/dist/ui/index.cjs +817 -623
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.js +776 -622
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/tool-sessions.d.ts +10 -2
- package/dist/ui/use-agent-chat-composer.d.ts +47 -0
- package/dist/ui/use-audio-recorder.d.ts +5 -3
- package/package.json +11 -6
- package/scaffold/host-styles.css +3 -0
- package/scaffold/inherit.css +4 -0
- package/scaffold/manifest.json +2 -2
- package/scaffold/src/app.tsx +5 -0
- package/scaffold/src/chat.css +35 -1
- package/scaffold/src/components/chat/chat-composer.tsx +31 -97
- package/scaffold/src/components/chat/chat-shell.tsx +7 -5
- package/scaffold/src/components/chat/external-link-dialog.tsx +6 -5
- package/scaffold/src/components/chat/identity-control.tsx +0 -1
- package/scaffold/src/components/chat/subagent-tasks.tsx +109 -0
- package/scaffold/src/components/chat/theme-menu.tsx +3 -1
- package/scaffold/src/components/theme-provider.tsx +28 -23
- package/scaffold/src/components/ui/tooltip.tsx +3 -0
- package/scaffold/src/host.css +11 -0
- package/scaffold/src/index.css +1 -213
- package/scaffold/src/index.tsx +9 -2
- package/scaffold/src/theme.css +215 -0
package/dist/scaffold/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
// scaffold/src/app.tsx
|
|
2
4
|
import { createBrowserVisibility } from "@agents24/client/browser";
|
|
3
5
|
import {
|
|
@@ -13,7 +15,7 @@ import {
|
|
|
13
15
|
} from "@agents24/chat-react/runtime";
|
|
14
16
|
import { AgentChatQueue, queuedMessageComposerFiles, useLiveCompletionRuns } from "@agents24/chat-react/ui";
|
|
15
17
|
import { CircleAlert, LoaderCircle as LoaderCircle3, SquarePen as SquarePen2, X } from "lucide-react";
|
|
16
|
-
import * as
|
|
18
|
+
import * as React9 from "react";
|
|
17
19
|
|
|
18
20
|
// scaffold/src/components/chat/chat-composer.tsx
|
|
19
21
|
import { ArrowUp, ChevronDown, LoaderCircle, Mic, Square } from "lucide-react";
|
|
@@ -21,13 +23,8 @@ import * as React2 from "react";
|
|
|
21
23
|
import {
|
|
22
24
|
AgentChatContextStatus,
|
|
23
25
|
ChatAttachmentRows,
|
|
24
|
-
|
|
25
|
-
createAgentChatComposerFile,
|
|
26
|
-
revokeAgentChatComposerFiles,
|
|
27
|
-
useAudioRecorder,
|
|
28
|
-
useChatComposerFocus
|
|
26
|
+
useAgentChatComposer
|
|
29
27
|
} from "@agents24/chat-react/ui";
|
|
30
|
-
import { attachmentFileAccept, inputMimeTypes, validateAgentChatSubmission } from "@agents24/chat-react/runtime";
|
|
31
28
|
|
|
32
29
|
// scaffold/src/components/ui/button.tsx
|
|
33
30
|
import { cva } from "class-variance-authority";
|
|
@@ -99,6 +96,21 @@ import { CheckIcon, ChevronRightIcon } from "lucide-react";
|
|
|
99
96
|
import * as React from "react";
|
|
100
97
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
101
98
|
var ThemeContext = React.createContext(null);
|
|
99
|
+
var appearanceEvent = "agents24-chat-appearance-change";
|
|
100
|
+
var subscribeAppearance = (notify) => {
|
|
101
|
+
window.addEventListener("storage", notify);
|
|
102
|
+
window.addEventListener(appearanceEvent, notify);
|
|
103
|
+
return () => {
|
|
104
|
+
window.removeEventListener("storage", notify);
|
|
105
|
+
window.removeEventListener(appearanceEvent, notify);
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
var subscribeDarkMode = (notify) => {
|
|
109
|
+
const media = window.matchMedia?.("(prefers-color-scheme: dark)");
|
|
110
|
+
media?.addEventListener("change", notify);
|
|
111
|
+
return () => media?.removeEventListener("change", notify);
|
|
112
|
+
};
|
|
113
|
+
var getDarkMode = () => window.matchMedia?.("(prefers-color-scheme: dark)").matches ?? false;
|
|
102
114
|
var storageKey = "agents24-chat-appearance";
|
|
103
115
|
function storedAppearance() {
|
|
104
116
|
try {
|
|
@@ -111,43 +123,33 @@ function storedAppearance() {
|
|
|
111
123
|
function ThemeProvider({
|
|
112
124
|
children,
|
|
113
125
|
controller,
|
|
114
|
-
theme = "soft"
|
|
126
|
+
theme = "soft",
|
|
127
|
+
mode = "isolated"
|
|
115
128
|
}) {
|
|
116
|
-
const [
|
|
117
|
-
const
|
|
118
|
-
const
|
|
129
|
+
const [sessionAppearance, setSessionAppearance] = React.useState(null);
|
|
130
|
+
const stored = React.useSyncExternalStore(subscribeAppearance, storedAppearance, () => "system");
|
|
131
|
+
const systemDark = React.useSyncExternalStore(subscribeDarkMode, getDarkMode, () => false);
|
|
119
132
|
const [portalContainer, setPortalContainer] = React.useState(null);
|
|
120
|
-
const appearance = controller?.appearance ??
|
|
121
|
-
|
|
122
|
-
if (!controller) setInternalAppearance(storedAppearance());
|
|
123
|
-
setMounted(true);
|
|
124
|
-
}, [controller]);
|
|
125
|
-
React.useEffect(() => {
|
|
126
|
-
if (!mounted || typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
127
|
-
const media = window.matchMedia("(prefers-color-scheme: dark)");
|
|
128
|
-
const apply = () => setResolvedAppearance(
|
|
129
|
-
appearance === "system" ? media.matches ? "dark" : "light" : appearance
|
|
130
|
-
);
|
|
131
|
-
apply();
|
|
132
|
-
media.addEventListener("change", apply);
|
|
133
|
-
return () => media.removeEventListener("change", apply);
|
|
134
|
-
}, [appearance, mounted]);
|
|
133
|
+
const appearance = controller?.appearance ?? sessionAppearance ?? stored;
|
|
134
|
+
const resolvedAppearance = appearance === "system" ? systemDark ? "dark" : "light" : appearance;
|
|
135
135
|
const change = React.useCallback((next) => {
|
|
136
136
|
if (controller) {
|
|
137
137
|
controller.setAppearance(next);
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
140
|
+
setSessionAppearance(next);
|
|
140
141
|
try {
|
|
141
142
|
window.localStorage.setItem(storageKey, next);
|
|
142
143
|
} catch {
|
|
143
144
|
}
|
|
144
|
-
|
|
145
|
+
window.dispatchEvent(new Event(appearanceEvent));
|
|
145
146
|
}, [controller]);
|
|
146
|
-
return /* @__PURE__ */ jsx2(ThemeContext.Provider, { value: { appearance, portalContainer, setAppearance: change }, children: /* @__PURE__ */ jsx2(
|
|
147
|
+
return /* @__PURE__ */ jsx2(ThemeContext.Provider, { value: { appearance, portalContainer, setAppearance: change, inherited: mode === "inherit" }, children: /* @__PURE__ */ jsx2(
|
|
147
148
|
"div",
|
|
148
149
|
{
|
|
149
150
|
ref: setPortalContainer,
|
|
150
|
-
className: `${resolvedAppearance} size-full`,
|
|
151
|
+
className: mode === "inherit" ? "size-full" : `${resolvedAppearance} size-full`,
|
|
152
|
+
"data-agents24-theme-mode": mode,
|
|
151
153
|
"data-agents24-theme": theme,
|
|
152
154
|
"data-agents24-theme-root": "",
|
|
153
155
|
children
|
|
@@ -449,6 +451,7 @@ function TooltipTrigger({
|
|
|
449
451
|
asChild: _asChild,
|
|
450
452
|
...props
|
|
451
453
|
}) {
|
|
454
|
+
void _asChild;
|
|
452
455
|
return /* @__PURE__ */ jsx6(Slot2.Root, { "data-slot": "tooltip-trigger", ...props });
|
|
453
456
|
}
|
|
454
457
|
function TooltipContent({
|
|
@@ -458,6 +461,8 @@ function TooltipContent({
|
|
|
458
461
|
sideOffset: _sideOffset,
|
|
459
462
|
...props
|
|
460
463
|
}) {
|
|
464
|
+
void _align;
|
|
465
|
+
void _sideOffset;
|
|
461
466
|
return /* @__PURE__ */ jsx6(
|
|
462
467
|
"span",
|
|
463
468
|
{
|
|
@@ -481,6 +486,8 @@ function TooltipContent({
|
|
|
481
486
|
import { Fragment, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
482
487
|
function ChatComposer({
|
|
483
488
|
inputContract,
|
|
489
|
+
queue,
|
|
490
|
+
onRecordingStreamChange,
|
|
484
491
|
disabled,
|
|
485
492
|
contextWindow,
|
|
486
493
|
focusKey,
|
|
@@ -498,49 +505,35 @@ function ChatComposer({
|
|
|
498
505
|
restoredDraft,
|
|
499
506
|
utilityRow = "inline"
|
|
500
507
|
}) {
|
|
501
|
-
const [text, setText] = React2.useState("");
|
|
502
|
-
const [files, setFiles] = React2.useState([]);
|
|
503
|
-
const [attachmentError, setAttachmentError] = React2.useState(null);
|
|
504
508
|
const inputRef = React2.useRef(null);
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
const allowAttachments = attachmentMimeTypes.length > 0;
|
|
512
|
-
const recordingAllowed = inputContract.modalities.audio.recording_enabled;
|
|
513
|
-
React2.useEffect(() => {
|
|
514
|
-
filesRef.current = files;
|
|
515
|
-
}, [files]);
|
|
516
|
-
React2.useEffect(() => () => {
|
|
517
|
-
revokeAgentChatComposerFiles(filesRef.current);
|
|
518
|
-
revokeAgentChatComposerFiles(inFlightFilesRef.current);
|
|
519
|
-
}, []);
|
|
520
|
-
const focusComposer = useChatComposerFocus({
|
|
509
|
+
const {
|
|
510
|
+
text,
|
|
511
|
+
setText,
|
|
512
|
+
files,
|
|
513
|
+
removeFile,
|
|
514
|
+
addFiles,
|
|
521
515
|
textareaRef,
|
|
522
|
-
|
|
516
|
+
submit,
|
|
517
|
+
attachmentError,
|
|
518
|
+
attachmentMimeTypes,
|
|
519
|
+
allowAttachments,
|
|
520
|
+
recordingAllowed,
|
|
521
|
+
recorder,
|
|
522
|
+
isExpanded,
|
|
523
|
+
validationError,
|
|
524
|
+
action,
|
|
525
|
+
canSubmit
|
|
526
|
+
} = useAgentChatComposer({
|
|
527
|
+
inputContract,
|
|
528
|
+
disabled,
|
|
523
529
|
focusKey,
|
|
530
|
+
forceExpanded,
|
|
531
|
+
isCancelling,
|
|
532
|
+
isRunning,
|
|
533
|
+
onSubmit,
|
|
524
534
|
restoredDraft,
|
|
525
|
-
|
|
526
|
-
draftRevisionRef.current += 1;
|
|
527
|
-
revokeAgentChatComposerFiles(filesRef.current);
|
|
528
|
-
setText(draft.text);
|
|
529
|
-
setFiles(draft.files);
|
|
530
|
-
}
|
|
535
|
+
onRecordingStreamChange
|
|
531
536
|
});
|
|
532
|
-
const addRecording = React2.useCallback((file) => {
|
|
533
|
-
draftRevisionRef.current += 1;
|
|
534
|
-
setFiles((current) => [...current, createAgentChatComposerFile(file)]);
|
|
535
|
-
}, []);
|
|
536
|
-
const recorder = useAudioRecorder(addRecording);
|
|
537
|
-
const isExpanded = forceExpanded || text.includes("\n") || text.length > 62;
|
|
538
|
-
const validationError = validateAgentChatSubmission(
|
|
539
|
-
inputContract,
|
|
540
|
-
text,
|
|
541
|
-
files.map((file) => ({ data: file.source || new Uint8Array(), mediaType: file.mediaType }))
|
|
542
|
-
);
|
|
543
|
-
const action = chatComposerAction({ hasDraft: Boolean(text.trim() || files.length), isRunning, isCancelling });
|
|
544
537
|
const selectedAgent = agents.find((item) => item.id === agentId);
|
|
545
538
|
const selectedModel = models.find((item) => item.id === modelId);
|
|
546
539
|
const modelSelector = models.length > 0 ? /* @__PURE__ */ jsx7("div", { className: "w-fit max-w-40", children: /* @__PURE__ */ jsxs3(Select, { disabled: disabled || isRunning, onValueChange: onModelChange, value: modelId || void 0, children: [
|
|
@@ -580,66 +573,35 @@ function ChatComposer({
|
|
|
580
573
|
] }) : modelSelector;
|
|
581
574
|
const hasContextWindow = Number.isFinite(Number(contextWindow?.max_tokens)) && Number(contextWindow?.max_tokens) > 0;
|
|
582
575
|
const showUtilityRow = utilityRow === "below";
|
|
583
|
-
const submit = async () => {
|
|
584
|
-
if (disabled || isCancelling || submittingRef.current || validationError) return;
|
|
585
|
-
const value = text;
|
|
586
|
-
const selectedFiles = files;
|
|
587
|
-
const clearedRevision = draftRevisionRef.current + 1;
|
|
588
|
-
draftRevisionRef.current = clearedRevision;
|
|
589
|
-
submittingRef.current = true;
|
|
590
|
-
inFlightFilesRef.current = selectedFiles;
|
|
591
|
-
setText("");
|
|
592
|
-
setFiles([]);
|
|
593
|
-
focusComposer();
|
|
594
|
-
try {
|
|
595
|
-
await onSubmit(value, selectedFiles);
|
|
596
|
-
revokeAgentChatComposerFiles(selectedFiles);
|
|
597
|
-
inFlightFilesRef.current = [];
|
|
598
|
-
} catch {
|
|
599
|
-
if (draftRevisionRef.current === clearedRevision) {
|
|
600
|
-
draftRevisionRef.current += 1;
|
|
601
|
-
setText(value);
|
|
602
|
-
setFiles(selectedFiles);
|
|
603
|
-
inFlightFilesRef.current = [];
|
|
604
|
-
} else {
|
|
605
|
-
revokeAgentChatComposerFiles(selectedFiles);
|
|
606
|
-
inFlightFilesRef.current = [];
|
|
607
|
-
}
|
|
608
|
-
} finally {
|
|
609
|
-
submittingRef.current = false;
|
|
610
|
-
}
|
|
611
|
-
};
|
|
612
576
|
return /* @__PURE__ */ jsxs3(
|
|
613
577
|
"div",
|
|
614
578
|
{
|
|
615
579
|
className: "relative z-10 w-full pb-[max(1rem,env(safe-area-inset-bottom))]",
|
|
616
580
|
"data-agents24-chat-composer": "",
|
|
617
581
|
children: [
|
|
618
|
-
|
|
619
|
-
ChatAttachmentRows,
|
|
620
|
-
{
|
|
621
|
-
attachments: files,
|
|
622
|
-
onRemove: (attachment) => {
|
|
623
|
-
if (!attachment.id) return;
|
|
624
|
-
draftRevisionRef.current += 1;
|
|
625
|
-
setFiles((current) => {
|
|
626
|
-
const removed = current.find((file) => file.id === attachment.id);
|
|
627
|
-
if (removed) revokeAgentChatComposerFiles([removed]);
|
|
628
|
-
return current.filter((file) => file.id !== attachment.id);
|
|
629
|
-
});
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
) }),
|
|
582
|
+
queue,
|
|
633
583
|
attachmentError || recorder.error ? /* @__PURE__ */ jsx7("p", { className: "mb-2 text-xs text-destructive", role: "alert", children: attachmentError || recorder.error }) : null,
|
|
634
584
|
/* @__PURE__ */ jsxs3(
|
|
635
585
|
"div",
|
|
636
586
|
{
|
|
637
587
|
"data-expanded": isExpanded || void 0,
|
|
588
|
+
"data-attachments": files.length > 0 || void 0,
|
|
638
589
|
className: cn(
|
|
639
590
|
"agents24-composer-grid grid min-w-0 items-center gap-2 rounded-xl border bg-background shadow-sm",
|
|
640
591
|
isExpanded ? "p-2" : "p-1.5"
|
|
641
592
|
),
|
|
642
593
|
children: [
|
|
594
|
+
allowAttachments && files.length > 0 && /* @__PURE__ */ jsx7("div", { className: "agents24-composer-attachments min-w-0", children: /* @__PURE__ */ jsx7(
|
|
595
|
+
ChatAttachmentRows,
|
|
596
|
+
{
|
|
597
|
+
layout: "composer",
|
|
598
|
+
attachments: files,
|
|
599
|
+
onRemove: (attachment) => {
|
|
600
|
+
if (!attachment.id) return;
|
|
601
|
+
removeFile(attachment.id);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
) }),
|
|
643
605
|
allowAttachments ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
644
606
|
/* @__PURE__ */ jsx7(
|
|
645
607
|
"input",
|
|
@@ -648,11 +610,9 @@ function ChatComposer({
|
|
|
648
610
|
className: "sr-only",
|
|
649
611
|
type: "file",
|
|
650
612
|
multiple: true,
|
|
651
|
-
accept:
|
|
613
|
+
accept: attachmentMimeTypes.join(","),
|
|
652
614
|
onChange: (event) => {
|
|
653
|
-
|
|
654
|
-
setFiles((current) => [...current, ...selected.map(createAgentChatComposerFile)]);
|
|
655
|
-
setAttachmentError(null);
|
|
615
|
+
addFiles(Array.from(event.target.files ?? []));
|
|
656
616
|
event.currentTarget.value = "";
|
|
657
617
|
}
|
|
658
618
|
}
|
|
@@ -673,7 +633,6 @@ function ChatComposer({
|
|
|
673
633
|
isExpanded ? "py-2" : "h-9 py-2"
|
|
674
634
|
),
|
|
675
635
|
onChange: (event) => {
|
|
676
|
-
draftRevisionRef.current += 1;
|
|
677
636
|
setText(event.target.value);
|
|
678
637
|
},
|
|
679
638
|
onKeyDown: (event) => {
|
|
@@ -713,7 +672,7 @@ function ChatComposer({
|
|
|
713
672
|
) : validationError ? /* @__PURE__ */ jsxs3(Tooltip, { children: [
|
|
714
673
|
/* @__PURE__ */ jsx7(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx7("span", { tabIndex: 0, "aria-label": validationError, children: /* @__PURE__ */ jsx7(Button, { size: "icon", "aria-label": isRunning ? "Queue message" : "Send message", disabled: true, onClick: () => void submit(), children: /* @__PURE__ */ jsx7(ArrowUp, {}) }) }) }),
|
|
715
674
|
/* @__PURE__ */ jsx7(TooltipContent, { children: validationError })
|
|
716
|
-
] }) : /* @__PURE__ */ jsx7(Button, { size: "icon", "aria-label": isRunning ? "Queue message" : "Send message", disabled, onClick: () => void submit(), children: /* @__PURE__ */ jsx7(ArrowUp, {}) })
|
|
675
|
+
] }) : /* @__PURE__ */ jsx7(Button, { size: "icon", "aria-label": isRunning ? "Queue message" : "Send message", disabled: !canSubmit, onClick: () => void submit(), children: /* @__PURE__ */ jsx7(ArrowUp, {}) })
|
|
717
676
|
] })
|
|
718
677
|
]
|
|
719
678
|
}
|
|
@@ -925,19 +884,20 @@ function DialogDescription({
|
|
|
925
884
|
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
926
885
|
function ExternalLinkDialog({ isOpen, onClose, onConfirm, url }) {
|
|
927
886
|
const [copied, setCopied] = React4.useState(false);
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
887
|
+
const close = () => {
|
|
888
|
+
setCopied(false);
|
|
889
|
+
onClose();
|
|
890
|
+
};
|
|
931
891
|
const copyUrl = async () => {
|
|
932
892
|
await navigator.clipboard.writeText(url);
|
|
933
893
|
setCopied(true);
|
|
934
894
|
};
|
|
935
895
|
const openUrl = () => {
|
|
936
896
|
onConfirm();
|
|
937
|
-
|
|
897
|
+
close();
|
|
938
898
|
};
|
|
939
899
|
return /* @__PURE__ */ jsx10(Dialog, { open: isOpen, onOpenChange: (open) => {
|
|
940
|
-
if (!open)
|
|
900
|
+
if (!open) close();
|
|
941
901
|
}, children: /* @__PURE__ */ jsxs6(DialogContent, { className: "max-h-[calc(100dvh-2rem)] min-w-0 overflow-hidden sm:max-w-md", children: [
|
|
942
902
|
/* @__PURE__ */ jsxs6(DialogHeader, { children: [
|
|
943
903
|
/* @__PURE__ */ jsx10(DialogTitle, { children: "Open external link?" }),
|
|
@@ -1199,23 +1159,147 @@ function ChatMessage({
|
|
|
1199
1159
|
] }) });
|
|
1200
1160
|
}
|
|
1201
1161
|
|
|
1202
|
-
// scaffold/src/components/chat/
|
|
1203
|
-
import { Laptop, Moon, Sun } from "lucide-react";
|
|
1162
|
+
// scaffold/src/components/chat/subagent-tasks.tsx
|
|
1204
1163
|
import * as React5 from "react";
|
|
1164
|
+
import { useAgentClient, partsFromResponseBlocks } from "@agents24/react";
|
|
1165
|
+
import { AgentResponseTimeline as AgentResponseTimeline2 } from "@agents24/chat-react/ui";
|
|
1166
|
+
import { useDelegationTasks } from "@agents24/chat-react/runtime";
|
|
1205
1167
|
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1168
|
+
function SubagentTasks({ threadId }) {
|
|
1169
|
+
const client = useAgentClient();
|
|
1170
|
+
const source = React5.useMemo(() => ({ events: (input) => client.threads.delegations.events(input) }), [client]);
|
|
1171
|
+
const { tasks, error, refresh } = useDelegationTasks({ threadId, source });
|
|
1172
|
+
const [selection, setSelection] = React5.useState({ threadId: null, handle: null });
|
|
1173
|
+
const selected = selection.threadId === threadId ? selection.handle : null;
|
|
1174
|
+
if (!threadId || !tasks.length && !error) return null;
|
|
1175
|
+
return /* @__PURE__ */ jsx15("section", { "aria-label": "Subagent tasks", className: "mx-auto w-full max-w-3xl px-4 py-2 text-sm", children: /* @__PURE__ */ jsxs9("details", { children: [
|
|
1176
|
+
/* @__PURE__ */ jsxs9("summary", { className: "cursor-pointer font-medium", children: [
|
|
1177
|
+
"Tasks (",
|
|
1178
|
+
tasks.length,
|
|
1179
|
+
")"
|
|
1180
|
+
] }),
|
|
1181
|
+
error ? /* @__PURE__ */ jsx15("p", { role: "alert", children: "Task updates are unavailable. Retrying\u2026" }) : null,
|
|
1182
|
+
/* @__PURE__ */ jsx15("ul", { className: "max-h-56 overflow-y-auto", children: tasks.map((task) => /* @__PURE__ */ jsx15("li", { style: { paddingInlineStart: Math.max(0, task.depth - 1) * 12 }, children: /* @__PURE__ */ jsxs9(
|
|
1183
|
+
"button",
|
|
1184
|
+
{
|
|
1185
|
+
type: "button",
|
|
1186
|
+
className: "flex w-full items-center justify-between gap-3 rounded-md px-2 py-2 text-start hover:bg-muted",
|
|
1187
|
+
onClick: () => setSelection({ threadId, handle: selected === task.handle ? null : task.handle }),
|
|
1188
|
+
"aria-expanded": selected === task.handle,
|
|
1189
|
+
children: [
|
|
1190
|
+
/* @__PURE__ */ jsxs9("span", { className: "min-w-0 truncate", children: [
|
|
1191
|
+
task.name,
|
|
1192
|
+
task.background ? " \xB7 Background" : ""
|
|
1193
|
+
] }),
|
|
1194
|
+
/* @__PURE__ */ jsx15("span", { className: "shrink-0 text-xs text-muted-foreground", children: task.status.replaceAll("_", " ") })
|
|
1195
|
+
]
|
|
1196
|
+
}
|
|
1197
|
+
) }, task.handle)) }),
|
|
1198
|
+
tasks.filter((task) => task.handle === selected).map((task) => /* @__PURE__ */ jsx15(TaskConversation, { threadId, task, onChanged: refresh }, `${threadId}:${task.handle}`))
|
|
1199
|
+
] }) });
|
|
1200
|
+
}
|
|
1201
|
+
function TaskConversation({ threadId, task, onChanged }) {
|
|
1202
|
+
const client = useAgentClient();
|
|
1203
|
+
const [history, setHistory] = React5.useState(null);
|
|
1204
|
+
const [earlier, setEarlier] = React5.useState([]);
|
|
1205
|
+
const historyInitialized = React5.useRef(false);
|
|
1206
|
+
const [before, setBefore] = React5.useState(null);
|
|
1207
|
+
const [error, setError] = React5.useState(null);
|
|
1208
|
+
const [busy, setBusy] = React5.useState(false);
|
|
1209
|
+
const operation = React5.useRef(null);
|
|
1210
|
+
React5.useEffect(() => {
|
|
1211
|
+
const controller = new AbortController();
|
|
1212
|
+
let timer;
|
|
1213
|
+
const refresh = async () => {
|
|
1214
|
+
try {
|
|
1215
|
+
const page = await client.threads.delegations.history({ threadId, handle: task.handle, signal: controller.signal });
|
|
1216
|
+
if (controller.signal.aborted) return;
|
|
1217
|
+
setHistory(page);
|
|
1218
|
+
if (!historyInitialized.current) {
|
|
1219
|
+
historyInitialized.current = true;
|
|
1220
|
+
setBefore(page.paging.next_before_turn_index);
|
|
1221
|
+
}
|
|
1222
|
+
} catch {
|
|
1223
|
+
if (!controller.signal.aborted) setError("Task history could not be loaded.");
|
|
1224
|
+
} finally {
|
|
1225
|
+
if (!controller.signal.aborted) timer = setTimeout(refresh, 2e3);
|
|
1226
|
+
}
|
|
1227
|
+
};
|
|
1228
|
+
void refresh();
|
|
1229
|
+
return () => {
|
|
1230
|
+
controller.abort();
|
|
1231
|
+
clearTimeout(timer);
|
|
1232
|
+
};
|
|
1233
|
+
}, [client, threadId, task.handle]);
|
|
1234
|
+
const loadEarlier = async () => {
|
|
1235
|
+
if (before === null) return;
|
|
1236
|
+
setBusy(true);
|
|
1237
|
+
try {
|
|
1238
|
+
const page = await client.threads.delegations.history({ threadId, handle: task.handle, before });
|
|
1239
|
+
setEarlier((current) => [...page.turns, ...current]);
|
|
1240
|
+
setBefore(page.paging.next_before_turn_index);
|
|
1241
|
+
} catch {
|
|
1242
|
+
setError("Earlier task history could not be loaded.");
|
|
1243
|
+
} finally {
|
|
1244
|
+
setBusy(false);
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
const act = async (action) => {
|
|
1248
|
+
setBusy(true);
|
|
1249
|
+
setError(null);
|
|
1250
|
+
if (operation.current?.action !== action) operation.current = { action, id: crypto.randomUUID() };
|
|
1251
|
+
try {
|
|
1252
|
+
await client.threads.delegations.act({
|
|
1253
|
+
threadId,
|
|
1254
|
+
handle: task.handle,
|
|
1255
|
+
action: { action, operation_id: operation.current.id }
|
|
1256
|
+
});
|
|
1257
|
+
operation.current = null;
|
|
1258
|
+
onChanged();
|
|
1259
|
+
} catch {
|
|
1260
|
+
setError("The task action could not be completed. Try again.");
|
|
1261
|
+
} finally {
|
|
1262
|
+
setBusy(false);
|
|
1263
|
+
}
|
|
1264
|
+
};
|
|
1265
|
+
const turns = Array.from(new Map([...earlier, ...history?.turns || []].map((turn) => [turn.id, turn])).values()).sort((a, b) => a.turn_index - b.turn_index);
|
|
1266
|
+
return /* @__PURE__ */ jsxs9("div", { className: "space-y-3 rounded-md bg-muted/30 p-3", children: [
|
|
1267
|
+
/* @__PURE__ */ jsx15("h3", { className: "font-medium", children: task.name }),
|
|
1268
|
+
error ? /* @__PURE__ */ jsx15("p", { role: "alert", children: error }) : null,
|
|
1269
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap gap-2", children: [
|
|
1270
|
+
task.capabilities.interrupt ? /* @__PURE__ */ jsx15(Button, { variant: "secondary", size: "sm", disabled: busy, onClick: () => void act("interrupt"), children: "Interrupt" }) : null,
|
|
1271
|
+
task.capabilities.cancel ? /* @__PURE__ */ jsx15(Button, { variant: "secondary", size: "sm", disabled: busy, onClick: () => void act("cancel"), children: "Cancel task" }) : null,
|
|
1272
|
+
before !== null ? /* @__PURE__ */ jsx15(Button, { variant: "ghost", size: "sm", disabled: busy, onClick: () => void loadEarlier(), children: "Earlier exchanges" }) : null
|
|
1273
|
+
] }),
|
|
1274
|
+
/* @__PURE__ */ jsx15("div", { className: "max-h-[55dvh] space-y-4 overflow-y-auto break-words", children: turns.map((turn) => /* @__PURE__ */ jsxs9("article", { className: "space-y-2", children: [
|
|
1275
|
+
turn.assignment_instruction ? /* @__PURE__ */ jsx15("p", { className: "whitespace-pre-wrap text-muted-foreground", children: turn.assignment_instruction }) : null,
|
|
1276
|
+
turn.user_input_text ? /* @__PURE__ */ jsx15("p", { className: "whitespace-pre-wrap", children: turn.user_input_text }) : null,
|
|
1277
|
+
turn.exchanges?.map((exchange) => /* @__PURE__ */ jsxs9("div", { className: "whitespace-pre-wrap break-words text-sm", children: [
|
|
1278
|
+
/* @__PURE__ */ jsx15("p", { className: "text-xs font-medium", children: exchange.sender === "parent" ? "Parent Agent" : "Subagent update" }),
|
|
1279
|
+
exchange.text
|
|
1280
|
+
] }, exchange.id)),
|
|
1281
|
+
/* @__PURE__ */ jsx15(AgentResponseTimeline2, { message: { id: turn.id, role: "assistant", createdAt: turn.created_at, content: turn.assistant_output_text || "", parts: partsFromResponseBlocks(turn.response_blocks) } })
|
|
1282
|
+
] }, turn.id)) })
|
|
1283
|
+
] });
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
// scaffold/src/components/chat/theme-menu.tsx
|
|
1287
|
+
import { Laptop, Moon, Sun } from "lucide-react";
|
|
1288
|
+
import * as React6 from "react";
|
|
1289
|
+
import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1206
1290
|
var options = [
|
|
1207
1291
|
{ value: "system", label: "System", icon: Laptop },
|
|
1208
1292
|
{ value: "light", label: "Light", icon: Sun },
|
|
1209
1293
|
{ value: "dark", label: "Dark", icon: Moon }
|
|
1210
1294
|
];
|
|
1211
1295
|
function ThemeMenu() {
|
|
1212
|
-
const { appearance, setAppearance } = useTheme();
|
|
1213
|
-
const [open, setOpen] =
|
|
1214
|
-
const rootRef =
|
|
1215
|
-
const firstItemRef =
|
|
1216
|
-
const menuId =
|
|
1296
|
+
const { appearance, setAppearance, inherited } = useTheme();
|
|
1297
|
+
const [open, setOpen] = React6.useState(false);
|
|
1298
|
+
const rootRef = React6.useRef(null);
|
|
1299
|
+
const firstItemRef = React6.useRef(null);
|
|
1300
|
+
const menuId = React6.useId();
|
|
1217
1301
|
const ActiveIcon = options.find((item) => item.value === appearance)?.icon ?? Laptop;
|
|
1218
|
-
|
|
1302
|
+
React6.useEffect(() => {
|
|
1219
1303
|
if (!open) return;
|
|
1220
1304
|
firstItemRef.current?.focus();
|
|
1221
1305
|
const closeOnOutsidePointer = (event) => {
|
|
@@ -1231,9 +1315,10 @@ function ThemeMenu() {
|
|
|
1231
1315
|
document.removeEventListener("keydown", closeOnEscape);
|
|
1232
1316
|
};
|
|
1233
1317
|
}, [open]);
|
|
1318
|
+
if (inherited) return null;
|
|
1234
1319
|
const label = appearance === "system" ? "System" : appearance === "light" ? "Light" : "Dark";
|
|
1235
|
-
return /* @__PURE__ */
|
|
1236
|
-
/* @__PURE__ */
|
|
1320
|
+
return /* @__PURE__ */ jsxs10("div", { ref: rootRef, className: "relative", children: [
|
|
1321
|
+
/* @__PURE__ */ jsx16(
|
|
1237
1322
|
Button,
|
|
1238
1323
|
{
|
|
1239
1324
|
"aria-controls": menuId,
|
|
@@ -1243,16 +1328,16 @@ function ThemeMenu() {
|
|
|
1243
1328
|
onClick: () => setOpen((value) => !value),
|
|
1244
1329
|
size: "icon-sm",
|
|
1245
1330
|
variant: "ghost",
|
|
1246
|
-
children: /* @__PURE__ */
|
|
1331
|
+
children: /* @__PURE__ */ jsx16(ActiveIcon, {})
|
|
1247
1332
|
}
|
|
1248
1333
|
),
|
|
1249
|
-
open ? /* @__PURE__ */
|
|
1334
|
+
open ? /* @__PURE__ */ jsx16(
|
|
1250
1335
|
"div",
|
|
1251
1336
|
{
|
|
1252
1337
|
id: menuId,
|
|
1253
1338
|
className: "absolute end-0 top-full z-50 mt-1 flex min-w-44 flex-col rounded-xl border bg-popover p-1 text-popover-foreground shadow-md",
|
|
1254
1339
|
role: "menu",
|
|
1255
|
-
children: options.map(({ value, label: optionLabel, icon: Icon }, index) => /* @__PURE__ */
|
|
1340
|
+
children: options.map(({ value, label: optionLabel, icon: Icon }, index) => /* @__PURE__ */ jsxs10(
|
|
1256
1341
|
Button,
|
|
1257
1342
|
{
|
|
1258
1343
|
ref: index === 0 ? firstItemRef : void 0,
|
|
@@ -1266,7 +1351,7 @@ function ThemeMenu() {
|
|
|
1266
1351
|
size: "sm",
|
|
1267
1352
|
variant: "ghost",
|
|
1268
1353
|
children: [
|
|
1269
|
-
/* @__PURE__ */
|
|
1354
|
+
/* @__PURE__ */ jsx16(Icon, {}),
|
|
1270
1355
|
" ",
|
|
1271
1356
|
optionLabel
|
|
1272
1357
|
]
|
|
@@ -1286,16 +1371,16 @@ import { LoaderCircle as LoaderCircle2, SquarePen, Trash2 } from "lucide-react";
|
|
|
1286
1371
|
import { LogIn, LogOut, UserRound } from "lucide-react";
|
|
1287
1372
|
|
|
1288
1373
|
// scaffold/src/components/ui/sidebar.tsx
|
|
1289
|
-
import * as
|
|
1374
|
+
import * as React8 from "react";
|
|
1290
1375
|
import { cva as cva3 } from "class-variance-authority";
|
|
1291
1376
|
import { Slot as Slot4 } from "radix-ui";
|
|
1292
1377
|
|
|
1293
1378
|
// scaffold/src/hooks/use-mobile.ts
|
|
1294
|
-
import * as
|
|
1379
|
+
import * as React7 from "react";
|
|
1295
1380
|
var MOBILE_BREAKPOINT = 768;
|
|
1296
1381
|
function useIsMobile() {
|
|
1297
|
-
const [isMobile, setIsMobile] =
|
|
1298
|
-
|
|
1382
|
+
const [isMobile, setIsMobile] = React7.useState(void 0);
|
|
1383
|
+
React7.useEffect(() => {
|
|
1299
1384
|
const onChange = () => {
|
|
1300
1385
|
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
1301
1386
|
};
|
|
@@ -1313,31 +1398,31 @@ function useIsMobile() {
|
|
|
1313
1398
|
}
|
|
1314
1399
|
|
|
1315
1400
|
// scaffold/src/components/ui/input.tsx
|
|
1316
|
-
import { jsx as
|
|
1401
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
1317
1402
|
|
|
1318
1403
|
// scaffold/src/components/ui/separator.tsx
|
|
1319
1404
|
import { Separator as SeparatorPrimitive } from "radix-ui";
|
|
1320
|
-
import { jsx as
|
|
1405
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1321
1406
|
|
|
1322
1407
|
// scaffold/src/components/ui/sheet.tsx
|
|
1323
1408
|
import { Dialog as SheetPrimitive } from "radix-ui";
|
|
1324
1409
|
import { XIcon as XIcon2 } from "lucide-react";
|
|
1325
|
-
import { jsx as
|
|
1410
|
+
import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1326
1411
|
function Sheet({ ...props }) {
|
|
1327
|
-
return /* @__PURE__ */
|
|
1412
|
+
return /* @__PURE__ */ jsx19(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
|
|
1328
1413
|
}
|
|
1329
1414
|
function SheetPortal({
|
|
1330
1415
|
container,
|
|
1331
1416
|
...props
|
|
1332
1417
|
}) {
|
|
1333
1418
|
const themeContainer = useThemePortalContainer();
|
|
1334
|
-
return /* @__PURE__ */
|
|
1419
|
+
return /* @__PURE__ */ jsx19(SheetPrimitive.Portal, { container: container || themeContainer || void 0, "data-slot": "sheet-portal", ...props });
|
|
1335
1420
|
}
|
|
1336
1421
|
function SheetOverlay({
|
|
1337
1422
|
className,
|
|
1338
1423
|
...props
|
|
1339
1424
|
}) {
|
|
1340
|
-
return /* @__PURE__ */
|
|
1425
|
+
return /* @__PURE__ */ jsx19(
|
|
1341
1426
|
SheetPrimitive.Overlay,
|
|
1342
1427
|
{
|
|
1343
1428
|
"data-slot": "sheet-overlay",
|
|
@@ -1356,9 +1441,9 @@ function SheetContent({
|
|
|
1356
1441
|
showCloseButton = true,
|
|
1357
1442
|
...props
|
|
1358
1443
|
}) {
|
|
1359
|
-
return /* @__PURE__ */
|
|
1360
|
-
/* @__PURE__ */
|
|
1361
|
-
/* @__PURE__ */
|
|
1444
|
+
return /* @__PURE__ */ jsxs11(SheetPortal, { children: [
|
|
1445
|
+
/* @__PURE__ */ jsx19(SheetOverlay, {}),
|
|
1446
|
+
/* @__PURE__ */ jsxs11(
|
|
1362
1447
|
SheetPrimitive.Content,
|
|
1363
1448
|
{
|
|
1364
1449
|
"data-slot": "sheet-content",
|
|
@@ -1370,18 +1455,18 @@ function SheetContent({
|
|
|
1370
1455
|
...props,
|
|
1371
1456
|
children: [
|
|
1372
1457
|
children,
|
|
1373
|
-
showCloseButton && /* @__PURE__ */
|
|
1458
|
+
showCloseButton && /* @__PURE__ */ jsx19(SheetPrimitive.Close, { "data-slot": "sheet-close", asChild: true, children: /* @__PURE__ */ jsxs11(
|
|
1374
1459
|
Button,
|
|
1375
1460
|
{
|
|
1376
1461
|
variant: "ghost",
|
|
1377
1462
|
className: "absolute top-4 right-4 bg-secondary",
|
|
1378
1463
|
size: "icon-sm",
|
|
1379
1464
|
children: [
|
|
1380
|
-
/* @__PURE__ */
|
|
1465
|
+
/* @__PURE__ */ jsx19(
|
|
1381
1466
|
XIcon2,
|
|
1382
1467
|
{}
|
|
1383
1468
|
),
|
|
1384
|
-
/* @__PURE__ */
|
|
1469
|
+
/* @__PURE__ */ jsx19("span", { className: "sr-only", children: "Close" })
|
|
1385
1470
|
]
|
|
1386
1471
|
}
|
|
1387
1472
|
) })
|
|
@@ -1391,7 +1476,7 @@ function SheetContent({
|
|
|
1391
1476
|
] });
|
|
1392
1477
|
}
|
|
1393
1478
|
function SheetHeader({ className, ...props }) {
|
|
1394
|
-
return /* @__PURE__ */
|
|
1479
|
+
return /* @__PURE__ */ jsx19(
|
|
1395
1480
|
"div",
|
|
1396
1481
|
{
|
|
1397
1482
|
"data-slot": "sheet-header",
|
|
@@ -1404,7 +1489,7 @@ function SheetTitle({
|
|
|
1404
1489
|
className,
|
|
1405
1490
|
...props
|
|
1406
1491
|
}) {
|
|
1407
|
-
return /* @__PURE__ */
|
|
1492
|
+
return /* @__PURE__ */ jsx19(
|
|
1408
1493
|
SheetPrimitive.Title,
|
|
1409
1494
|
{
|
|
1410
1495
|
"data-slot": "sheet-title",
|
|
@@ -1420,7 +1505,7 @@ function SheetDescription({
|
|
|
1420
1505
|
className,
|
|
1421
1506
|
...props
|
|
1422
1507
|
}) {
|
|
1423
|
-
return /* @__PURE__ */
|
|
1508
|
+
return /* @__PURE__ */ jsx19(
|
|
1424
1509
|
SheetPrimitive.Description,
|
|
1425
1510
|
{
|
|
1426
1511
|
"data-slot": "sheet-description",
|
|
@@ -1431,17 +1516,17 @@ function SheetDescription({
|
|
|
1431
1516
|
}
|
|
1432
1517
|
|
|
1433
1518
|
// scaffold/src/components/ui/skeleton.tsx
|
|
1434
|
-
import { jsx as
|
|
1519
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
1435
1520
|
|
|
1436
1521
|
// scaffold/src/components/ui/sidebar.tsx
|
|
1437
1522
|
import { PanelLeftIcon } from "lucide-react";
|
|
1438
|
-
import { jsx as
|
|
1523
|
+
import { jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1439
1524
|
var SIDEBAR_COOKIE_NAME = "sidebar_state";
|
|
1440
1525
|
var SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
|
|
1441
1526
|
var SIDEBAR_KEYBOARD_SHORTCUT = "b";
|
|
1442
|
-
var SidebarContext =
|
|
1527
|
+
var SidebarContext = React8.createContext(null);
|
|
1443
1528
|
function useSidebar() {
|
|
1444
|
-
const context =
|
|
1529
|
+
const context = React8.useContext(SidebarContext);
|
|
1445
1530
|
if (!context) {
|
|
1446
1531
|
throw new Error("useSidebar must be used within a SidebarProvider.");
|
|
1447
1532
|
}
|
|
@@ -1456,10 +1541,10 @@ function SidebarProvider({
|
|
|
1456
1541
|
...props
|
|
1457
1542
|
}) {
|
|
1458
1543
|
const isMobile = useIsMobile();
|
|
1459
|
-
const [openMobile, setOpenMobile] =
|
|
1460
|
-
const [_open, _setOpen] =
|
|
1544
|
+
const [openMobile, setOpenMobile] = React8.useState(false);
|
|
1545
|
+
const [_open, _setOpen] = React8.useState(defaultOpen);
|
|
1461
1546
|
const open = openProp ?? _open;
|
|
1462
|
-
const setOpen =
|
|
1547
|
+
const setOpen = React8.useCallback(
|
|
1463
1548
|
(value) => {
|
|
1464
1549
|
const openState = typeof value === "function" ? value(open) : value;
|
|
1465
1550
|
if (setOpenProp) {
|
|
@@ -1471,10 +1556,10 @@ function SidebarProvider({
|
|
|
1471
1556
|
},
|
|
1472
1557
|
[setOpenProp, open]
|
|
1473
1558
|
);
|
|
1474
|
-
const toggleSidebar =
|
|
1559
|
+
const toggleSidebar = React8.useCallback(() => {
|
|
1475
1560
|
return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
|
|
1476
1561
|
}, [isMobile, setOpen, setOpenMobile]);
|
|
1477
|
-
|
|
1562
|
+
React8.useEffect(() => {
|
|
1478
1563
|
const handleKeyDown = (event) => {
|
|
1479
1564
|
if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
|
|
1480
1565
|
event.preventDefault();
|
|
@@ -1485,7 +1570,7 @@ function SidebarProvider({
|
|
|
1485
1570
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
1486
1571
|
}, [toggleSidebar]);
|
|
1487
1572
|
const state = open ? "expanded" : "collapsed";
|
|
1488
|
-
const contextValue =
|
|
1573
|
+
const contextValue = React8.useMemo(
|
|
1489
1574
|
() => ({
|
|
1490
1575
|
state,
|
|
1491
1576
|
open,
|
|
@@ -1497,7 +1582,7 @@ function SidebarProvider({
|
|
|
1497
1582
|
}),
|
|
1498
1583
|
[state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
|
|
1499
1584
|
);
|
|
1500
|
-
return /* @__PURE__ */
|
|
1585
|
+
return /* @__PURE__ */ jsx21(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx21(
|
|
1501
1586
|
"div",
|
|
1502
1587
|
{
|
|
1503
1588
|
"data-slot": "sidebar-wrapper",
|
|
@@ -1521,7 +1606,7 @@ function Sidebar({
|
|
|
1521
1606
|
}) {
|
|
1522
1607
|
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
|
|
1523
1608
|
if (collapsible === "none") {
|
|
1524
|
-
return /* @__PURE__ */
|
|
1609
|
+
return /* @__PURE__ */ jsx21(
|
|
1525
1610
|
"div",
|
|
1526
1611
|
{
|
|
1527
1612
|
"data-slot": "sidebar",
|
|
@@ -1535,7 +1620,7 @@ function Sidebar({
|
|
|
1535
1620
|
);
|
|
1536
1621
|
}
|
|
1537
1622
|
if (isMobile) {
|
|
1538
|
-
return /* @__PURE__ */
|
|
1623
|
+
return /* @__PURE__ */ jsx21(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ jsxs12(
|
|
1539
1624
|
SheetContent,
|
|
1540
1625
|
{
|
|
1541
1626
|
dir,
|
|
@@ -1545,16 +1630,16 @@ function Sidebar({
|
|
|
1545
1630
|
className: "w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [--sidebar-width:18rem] [&>button]:hidden",
|
|
1546
1631
|
side,
|
|
1547
1632
|
children: [
|
|
1548
|
-
/* @__PURE__ */
|
|
1549
|
-
/* @__PURE__ */
|
|
1550
|
-
/* @__PURE__ */
|
|
1633
|
+
/* @__PURE__ */ jsxs12(SheetHeader, { className: "sr-only", children: [
|
|
1634
|
+
/* @__PURE__ */ jsx21(SheetTitle, { children: "Sidebar" }),
|
|
1635
|
+
/* @__PURE__ */ jsx21(SheetDescription, { children: "Displays the mobile sidebar." })
|
|
1551
1636
|
] }),
|
|
1552
|
-
/* @__PURE__ */
|
|
1637
|
+
/* @__PURE__ */ jsx21("div", { className: "flex h-full w-full flex-col", children })
|
|
1553
1638
|
]
|
|
1554
1639
|
}
|
|
1555
1640
|
) });
|
|
1556
1641
|
}
|
|
1557
|
-
return /* @__PURE__ */
|
|
1642
|
+
return /* @__PURE__ */ jsxs12(
|
|
1558
1643
|
"div",
|
|
1559
1644
|
{
|
|
1560
1645
|
className: "group peer hidden text-sidebar-foreground md:block",
|
|
@@ -1564,7 +1649,7 @@ function Sidebar({
|
|
|
1564
1649
|
"data-side": side,
|
|
1565
1650
|
"data-slot": "sidebar",
|
|
1566
1651
|
children: [
|
|
1567
|
-
/* @__PURE__ */
|
|
1652
|
+
/* @__PURE__ */ jsx21(
|
|
1568
1653
|
"div",
|
|
1569
1654
|
{
|
|
1570
1655
|
"data-slot": "sidebar-gap",
|
|
@@ -1576,7 +1661,7 @@ function Sidebar({
|
|
|
1576
1661
|
)
|
|
1577
1662
|
}
|
|
1578
1663
|
),
|
|
1579
|
-
/* @__PURE__ */
|
|
1664
|
+
/* @__PURE__ */ jsx21(
|
|
1580
1665
|
"div",
|
|
1581
1666
|
{
|
|
1582
1667
|
"data-slot": "sidebar-container",
|
|
@@ -1588,7 +1673,7 @@ function Sidebar({
|
|
|
1588
1673
|
className
|
|
1589
1674
|
),
|
|
1590
1675
|
...props,
|
|
1591
|
-
children: /* @__PURE__ */
|
|
1676
|
+
children: /* @__PURE__ */ jsx21(
|
|
1592
1677
|
"div",
|
|
1593
1678
|
{
|
|
1594
1679
|
"data-sidebar": "sidebar",
|
|
@@ -1609,7 +1694,7 @@ function SidebarTrigger({
|
|
|
1609
1694
|
...props
|
|
1610
1695
|
}) {
|
|
1611
1696
|
const { toggleSidebar } = useSidebar();
|
|
1612
|
-
return /* @__PURE__ */
|
|
1697
|
+
return /* @__PURE__ */ jsxs12(
|
|
1613
1698
|
Button,
|
|
1614
1699
|
{
|
|
1615
1700
|
"data-sidebar": "trigger",
|
|
@@ -1623,15 +1708,15 @@ function SidebarTrigger({
|
|
|
1623
1708
|
},
|
|
1624
1709
|
...props,
|
|
1625
1710
|
children: [
|
|
1626
|
-
/* @__PURE__ */
|
|
1627
|
-
/* @__PURE__ */
|
|
1711
|
+
/* @__PURE__ */ jsx21(PanelLeftIcon, {}),
|
|
1712
|
+
/* @__PURE__ */ jsx21("span", { className: "sr-only", children: "Toggle Sidebar" })
|
|
1628
1713
|
]
|
|
1629
1714
|
}
|
|
1630
1715
|
);
|
|
1631
1716
|
}
|
|
1632
1717
|
function SidebarRail({ className, ...props }) {
|
|
1633
1718
|
const { toggleSidebar } = useSidebar();
|
|
1634
|
-
return /* @__PURE__ */
|
|
1719
|
+
return /* @__PURE__ */ jsx21(
|
|
1635
1720
|
"button",
|
|
1636
1721
|
{
|
|
1637
1722
|
"data-sidebar": "rail",
|
|
@@ -1654,7 +1739,7 @@ function SidebarRail({ className, ...props }) {
|
|
|
1654
1739
|
);
|
|
1655
1740
|
}
|
|
1656
1741
|
function SidebarInset({ className, ...props }) {
|
|
1657
|
-
return /* @__PURE__ */
|
|
1742
|
+
return /* @__PURE__ */ jsx21(
|
|
1658
1743
|
"main",
|
|
1659
1744
|
{
|
|
1660
1745
|
"data-slot": "sidebar-inset",
|
|
@@ -1667,7 +1752,7 @@ function SidebarInset({ className, ...props }) {
|
|
|
1667
1752
|
);
|
|
1668
1753
|
}
|
|
1669
1754
|
function SidebarHeader({ className, ...props }) {
|
|
1670
|
-
return /* @__PURE__ */
|
|
1755
|
+
return /* @__PURE__ */ jsx21(
|
|
1671
1756
|
"div",
|
|
1672
1757
|
{
|
|
1673
1758
|
"data-slot": "sidebar-header",
|
|
@@ -1681,7 +1766,7 @@ function SidebarHeader({ className, ...props }) {
|
|
|
1681
1766
|
);
|
|
1682
1767
|
}
|
|
1683
1768
|
function SidebarFooter({ className, ...props }) {
|
|
1684
|
-
return /* @__PURE__ */
|
|
1769
|
+
return /* @__PURE__ */ jsx21(
|
|
1685
1770
|
"div",
|
|
1686
1771
|
{
|
|
1687
1772
|
"data-slot": "sidebar-footer",
|
|
@@ -1692,7 +1777,7 @@ function SidebarFooter({ className, ...props }) {
|
|
|
1692
1777
|
);
|
|
1693
1778
|
}
|
|
1694
1779
|
function SidebarContent({ className, ...props }) {
|
|
1695
|
-
return /* @__PURE__ */
|
|
1780
|
+
return /* @__PURE__ */ jsx21(
|
|
1696
1781
|
"div",
|
|
1697
1782
|
{
|
|
1698
1783
|
"data-slot": "sidebar-content",
|
|
@@ -1706,7 +1791,7 @@ function SidebarContent({ className, ...props }) {
|
|
|
1706
1791
|
);
|
|
1707
1792
|
}
|
|
1708
1793
|
function SidebarGroup({ className, ...props }) {
|
|
1709
|
-
return /* @__PURE__ */
|
|
1794
|
+
return /* @__PURE__ */ jsx21(
|
|
1710
1795
|
"div",
|
|
1711
1796
|
{
|
|
1712
1797
|
"data-slot": "sidebar-group",
|
|
@@ -1720,7 +1805,7 @@ function SidebarGroupContent({
|
|
|
1720
1805
|
className,
|
|
1721
1806
|
...props
|
|
1722
1807
|
}) {
|
|
1723
|
-
return /* @__PURE__ */
|
|
1808
|
+
return /* @__PURE__ */ jsx21(
|
|
1724
1809
|
"div",
|
|
1725
1810
|
{
|
|
1726
1811
|
"data-slot": "sidebar-group-content",
|
|
@@ -1731,7 +1816,7 @@ function SidebarGroupContent({
|
|
|
1731
1816
|
);
|
|
1732
1817
|
}
|
|
1733
1818
|
function SidebarMenu({ className, ...props }) {
|
|
1734
|
-
return /* @__PURE__ */
|
|
1819
|
+
return /* @__PURE__ */ jsx21(
|
|
1735
1820
|
"ul",
|
|
1736
1821
|
{
|
|
1737
1822
|
"data-slot": "sidebar-menu",
|
|
@@ -1742,7 +1827,7 @@ function SidebarMenu({ className, ...props }) {
|
|
|
1742
1827
|
);
|
|
1743
1828
|
}
|
|
1744
1829
|
function SidebarMenuItem({ className, ...props }) {
|
|
1745
|
-
return /* @__PURE__ */
|
|
1830
|
+
return /* @__PURE__ */ jsx21(
|
|
1746
1831
|
"li",
|
|
1747
1832
|
{
|
|
1748
1833
|
"data-slot": "sidebar-menu-item",
|
|
@@ -1783,7 +1868,7 @@ function SidebarMenuButton({
|
|
|
1783
1868
|
}) {
|
|
1784
1869
|
const Comp = asChild ? Slot4.Root : "button";
|
|
1785
1870
|
const { isMobile, state } = useSidebar();
|
|
1786
|
-
const button = /* @__PURE__ */
|
|
1871
|
+
const button = /* @__PURE__ */ jsx21(
|
|
1787
1872
|
Comp,
|
|
1788
1873
|
{
|
|
1789
1874
|
"data-slot": "sidebar-menu-button",
|
|
@@ -1802,9 +1887,9 @@ function SidebarMenuButton({
|
|
|
1802
1887
|
children: tooltip
|
|
1803
1888
|
};
|
|
1804
1889
|
}
|
|
1805
|
-
return /* @__PURE__ */
|
|
1806
|
-
/* @__PURE__ */
|
|
1807
|
-
/* @__PURE__ */
|
|
1890
|
+
return /* @__PURE__ */ jsxs12(Tooltip, { children: [
|
|
1891
|
+
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: button }),
|
|
1892
|
+
/* @__PURE__ */ jsx21(
|
|
1808
1893
|
TooltipContent,
|
|
1809
1894
|
{
|
|
1810
1895
|
side: "right",
|
|
@@ -1822,7 +1907,7 @@ function SidebarMenuAction({
|
|
|
1822
1907
|
...props
|
|
1823
1908
|
}) {
|
|
1824
1909
|
const Comp = asChild ? Slot4.Root : "button";
|
|
1825
|
-
return /* @__PURE__ */
|
|
1910
|
+
return /* @__PURE__ */ jsx21(
|
|
1826
1911
|
Comp,
|
|
1827
1912
|
{
|
|
1828
1913
|
"data-slot": "sidebar-menu-action",
|
|
@@ -1838,7 +1923,7 @@ function SidebarMenuAction({
|
|
|
1838
1923
|
}
|
|
1839
1924
|
|
|
1840
1925
|
// scaffold/src/components/chat/identity-control.tsx
|
|
1841
|
-
import { jsx as
|
|
1926
|
+
import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1842
1927
|
function identityLabel(identity) {
|
|
1843
1928
|
if (identity.displayName) return identity.displayName;
|
|
1844
1929
|
if (identity.state === "authenticated") return "Signed in";
|
|
@@ -1848,44 +1933,43 @@ function identityLabel(identity) {
|
|
|
1848
1933
|
return "Guest";
|
|
1849
1934
|
}
|
|
1850
1935
|
function IdentityAvatar({ identity }) {
|
|
1851
|
-
const label = identityLabel(identity);
|
|
1852
1936
|
if (identity.avatarUrl) {
|
|
1853
|
-
return /* @__PURE__ */
|
|
1937
|
+
return /* @__PURE__ */ jsx22("img", { alt: "", className: "size-6 rounded-full object-cover", src: identity.avatarUrl });
|
|
1854
1938
|
}
|
|
1855
|
-
return /* @__PURE__ */
|
|
1939
|
+
return /* @__PURE__ */ jsx22("span", { className: "flex size-6 items-center justify-center rounded-full bg-sidebar-accent text-[10px] font-semibold", "aria-hidden": "true", children: identity.displayName ? identity.displayName.slice(0, 1).toUpperCase() : /* @__PURE__ */ jsx22(UserRound, { className: "size-3.5" }) });
|
|
1856
1940
|
}
|
|
1857
1941
|
function IdentityControl({ identity }) {
|
|
1858
1942
|
const label = identityLabel(identity);
|
|
1859
1943
|
const canSignOut = identity.state === "authenticated" && Boolean(identity.onSignOut);
|
|
1860
1944
|
const canSignIn = (identity.state === "guest" || identity.state === "signed_out" || identity.state === "error") && Boolean(identity.onSignIn);
|
|
1861
|
-
return /* @__PURE__ */
|
|
1862
|
-
/* @__PURE__ */
|
|
1945
|
+
return /* @__PURE__ */ jsx22(SidebarMenu, { className: "w-full min-w-0", children: /* @__PURE__ */ jsx22(SidebarMenuItem, { className: "w-full min-w-0", children: /* @__PURE__ */ jsxs13(DropdownMenu, { children: [
|
|
1946
|
+
/* @__PURE__ */ jsx22(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs13(
|
|
1863
1947
|
SidebarMenuButton,
|
|
1864
1948
|
{
|
|
1865
1949
|
size: "lg",
|
|
1866
1950
|
"aria-label": `Account: ${label}`,
|
|
1867
1951
|
className: "w-full min-w-0 justify-start",
|
|
1868
1952
|
children: [
|
|
1869
|
-
/* @__PURE__ */
|
|
1870
|
-
/* @__PURE__ */
|
|
1871
|
-
/* @__PURE__ */
|
|
1872
|
-
identity.secondaryText ? /* @__PURE__ */
|
|
1953
|
+
/* @__PURE__ */ jsx22(IdentityAvatar, { identity }),
|
|
1954
|
+
/* @__PURE__ */ jsxs13("span", { className: "min-w-0 flex-1 overflow-hidden text-start", children: [
|
|
1955
|
+
/* @__PURE__ */ jsx22("span", { className: "block truncate text-sm font-medium", children: label }),
|
|
1956
|
+
identity.secondaryText ? /* @__PURE__ */ jsx22("span", { className: "block truncate text-xs text-muted-foreground", children: identity.secondaryText }) : null
|
|
1873
1957
|
] })
|
|
1874
1958
|
]
|
|
1875
1959
|
}
|
|
1876
1960
|
) }),
|
|
1877
|
-
/* @__PURE__ */
|
|
1878
|
-
/* @__PURE__ */
|
|
1879
|
-
/* @__PURE__ */
|
|
1880
|
-
identity.secondaryText ? /* @__PURE__ */
|
|
1961
|
+
/* @__PURE__ */ jsxs13(DropdownMenuContent, { align: "start", side: "top", sideOffset: 8, children: [
|
|
1962
|
+
/* @__PURE__ */ jsxs13(DropdownMenuLabel, { children: [
|
|
1963
|
+
/* @__PURE__ */ jsx22("span", { className: "block truncate", children: label }),
|
|
1964
|
+
identity.secondaryText ? /* @__PURE__ */ jsx22("span", { className: "mt-0.5 block truncate text-xs font-normal text-muted-foreground", children: identity.secondaryText }) : null
|
|
1881
1965
|
] }),
|
|
1882
|
-
canSignIn || canSignOut ? /* @__PURE__ */
|
|
1883
|
-
canSignIn ? /* @__PURE__ */
|
|
1884
|
-
/* @__PURE__ */
|
|
1966
|
+
canSignIn || canSignOut ? /* @__PURE__ */ jsx22(DropdownMenuSeparator, {}) : null,
|
|
1967
|
+
canSignIn ? /* @__PURE__ */ jsxs13(DropdownMenuItem, { onSelect: () => identity.onSignIn?.(), children: [
|
|
1968
|
+
/* @__PURE__ */ jsx22(LogIn, {}),
|
|
1885
1969
|
"Sign in"
|
|
1886
1970
|
] }) : null,
|
|
1887
|
-
canSignOut ? /* @__PURE__ */
|
|
1888
|
-
/* @__PURE__ */
|
|
1971
|
+
canSignOut ? /* @__PURE__ */ jsxs13(DropdownMenuItem, { onSelect: () => identity.onSignOut?.(), children: [
|
|
1972
|
+
/* @__PURE__ */ jsx22(LogOut, {}),
|
|
1889
1973
|
"Sign out"
|
|
1890
1974
|
] }) : null
|
|
1891
1975
|
] })
|
|
@@ -1893,25 +1977,25 @@ function IdentityControl({ identity }) {
|
|
|
1893
1977
|
}
|
|
1894
1978
|
|
|
1895
1979
|
// scaffold/src/components/chat/thread-sidebar.tsx
|
|
1896
|
-
import { jsx as
|
|
1980
|
+
import { jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1897
1981
|
function ThreadStatus({ thread }) {
|
|
1898
1982
|
const activity = getThreadActivity(thread);
|
|
1899
1983
|
if (!activity.isSpinning) return null;
|
|
1900
1984
|
const label = activity.status === "cancelling" ? "Cancelling" : activity.status === "queued" ? "Queued" : "Running";
|
|
1901
|
-
return /* @__PURE__ */
|
|
1985
|
+
return /* @__PURE__ */ jsx23(
|
|
1902
1986
|
"span",
|
|
1903
1987
|
{
|
|
1904
1988
|
className: "pointer-events-none absolute end-1 top-1/2 hidden size-5 -translate-y-1/2 items-center justify-center text-muted-foreground transition-opacity group-hover/menu-item:opacity-0 md:flex",
|
|
1905
1989
|
role: "status",
|
|
1906
1990
|
"aria-label": label,
|
|
1907
1991
|
title: label,
|
|
1908
|
-
children: /* @__PURE__ */
|
|
1992
|
+
children: /* @__PURE__ */ jsx23(LoaderCircle2, { className: "size-3.5 animate-spin" })
|
|
1909
1993
|
}
|
|
1910
1994
|
);
|
|
1911
1995
|
}
|
|
1912
1996
|
function ThreadSidebar({ activeThreadId, hasMore, identity, isLoading, isLoadingMore, onDelete, onLoadMore, onNew, onOpen, threads }) {
|
|
1913
1997
|
const { setOpenMobile } = useSidebar();
|
|
1914
|
-
return /* @__PURE__ */
|
|
1998
|
+
return /* @__PURE__ */ jsxs14(
|
|
1915
1999
|
Sidebar,
|
|
1916
2000
|
{
|
|
1917
2001
|
"aria-label": "Conversations",
|
|
@@ -1919,19 +2003,19 @@ function ThreadSidebar({ activeThreadId, hasMore, identity, isLoading, isLoading
|
|
|
1919
2003
|
"data-agents24-chat-sidebar": "",
|
|
1920
2004
|
role: "navigation",
|
|
1921
2005
|
children: [
|
|
1922
|
-
/* @__PURE__ */
|
|
1923
|
-
/* @__PURE__ */
|
|
1924
|
-
/* @__PURE__ */
|
|
2006
|
+
/* @__PURE__ */ jsxs14(SidebarHeader, { className: "gap-1 p-2", children: [
|
|
2007
|
+
/* @__PURE__ */ jsx23("div", { className: "h-8 shrink-0", "aria-hidden": "true" }),
|
|
2008
|
+
/* @__PURE__ */ jsxs14(Button, { className: "w-full justify-start", variant: "ghost", onClick: () => {
|
|
1925
2009
|
onNew();
|
|
1926
2010
|
setOpenMobile(false);
|
|
1927
2011
|
}, children: [
|
|
1928
|
-
/* @__PURE__ */
|
|
2012
|
+
/* @__PURE__ */ jsx23(SquarePen, {}),
|
|
1929
2013
|
" New chat"
|
|
1930
2014
|
] })
|
|
1931
2015
|
] }),
|
|
1932
|
-
/* @__PURE__ */
|
|
1933
|
-
/* @__PURE__ */
|
|
1934
|
-
/* @__PURE__ */
|
|
2016
|
+
/* @__PURE__ */ jsx23(SidebarContent, { children: /* @__PURE__ */ jsx23(SidebarGroup, { children: /* @__PURE__ */ jsxs14(SidebarGroupContent, { children: [
|
|
2017
|
+
/* @__PURE__ */ jsx23(SidebarMenu, { children: threads.map((thread) => /* @__PURE__ */ jsxs14(SidebarMenuItem, { children: [
|
|
2018
|
+
/* @__PURE__ */ jsx23(
|
|
1935
2019
|
SidebarMenuButton,
|
|
1936
2020
|
{
|
|
1937
2021
|
className: "pr-8 pl-3",
|
|
@@ -1941,11 +2025,11 @@ function ThreadSidebar({ activeThreadId, hasMore, identity, isLoading, isLoading
|
|
|
1941
2025
|
void onOpen(thread.id).catch(() => void 0);
|
|
1942
2026
|
setOpenMobile(false);
|
|
1943
2027
|
},
|
|
1944
|
-
children: /* @__PURE__ */
|
|
2028
|
+
children: /* @__PURE__ */ jsx23("span", { className: "min-w-0 truncate", children: String(thread.title || "New conversation") })
|
|
1945
2029
|
}
|
|
1946
2030
|
),
|
|
1947
|
-
/* @__PURE__ */
|
|
1948
|
-
/* @__PURE__ */
|
|
2031
|
+
/* @__PURE__ */ jsx23(ThreadStatus, { thread }),
|
|
2032
|
+
/* @__PURE__ */ jsx23(
|
|
1949
2033
|
SidebarMenuAction,
|
|
1950
2034
|
{
|
|
1951
2035
|
showOnHover: true,
|
|
@@ -1955,12 +2039,12 @@ function ThreadSidebar({ activeThreadId, hasMore, identity, isLoading, isLoading
|
|
|
1955
2039
|
event.stopPropagation();
|
|
1956
2040
|
if (window.confirm("Delete this conversation?")) void onDelete(thread.id).catch(() => void 0);
|
|
1957
2041
|
},
|
|
1958
|
-
children: /* @__PURE__ */
|
|
2042
|
+
children: /* @__PURE__ */ jsx23(Trash2, {})
|
|
1959
2043
|
}
|
|
1960
2044
|
)
|
|
1961
2045
|
] }, thread.id)) }),
|
|
1962
|
-
!isLoading && threads.length === 0 && /* @__PURE__ */
|
|
1963
|
-
hasMore && /* @__PURE__ */
|
|
2046
|
+
!isLoading && threads.length === 0 && /* @__PURE__ */ jsx23("p", { className: "px-2 py-8 text-center text-xs text-muted-foreground", children: "No conversations" }),
|
|
2047
|
+
hasMore && /* @__PURE__ */ jsxs14(
|
|
1964
2048
|
Button,
|
|
1965
2049
|
{
|
|
1966
2050
|
className: "mt-2 w-full",
|
|
@@ -1969,14 +2053,14 @@ function ThreadSidebar({ activeThreadId, hasMore, identity, isLoading, isLoading
|
|
|
1969
2053
|
variant: "ghost",
|
|
1970
2054
|
onClick: () => void onLoadMore().catch(() => void 0),
|
|
1971
2055
|
children: [
|
|
1972
|
-
isLoadingMore && /* @__PURE__ */
|
|
2056
|
+
isLoadingMore && /* @__PURE__ */ jsx23(LoaderCircle2, { className: "animate-spin" }),
|
|
1973
2057
|
"Load more"
|
|
1974
2058
|
]
|
|
1975
2059
|
}
|
|
1976
2060
|
)
|
|
1977
2061
|
] }) }) }),
|
|
1978
|
-
/* @__PURE__ */
|
|
1979
|
-
/* @__PURE__ */
|
|
2062
|
+
/* @__PURE__ */ jsx23(SidebarFooter, { className: "w-full min-w-0 p-2", children: /* @__PURE__ */ jsx23(IdentityControl, { identity }) }),
|
|
2063
|
+
/* @__PURE__ */ jsx23(SidebarRail, {})
|
|
1980
2064
|
]
|
|
1981
2065
|
}
|
|
1982
2066
|
);
|
|
@@ -1984,7 +2068,7 @@ function ThreadSidebar({ activeThreadId, hasMore, identity, isLoading, isLoading
|
|
|
1984
2068
|
|
|
1985
2069
|
// scaffold/src/components/chat/turn-outline.tsx
|
|
1986
2070
|
import { LatestThreadScroller } from "@agents24/chat-react";
|
|
1987
|
-
import { jsx as
|
|
2071
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
1988
2072
|
function turnsFromMessages(messages) {
|
|
1989
2073
|
return messages.reduce((turns, message) => {
|
|
1990
2074
|
if (message.role === "user") {
|
|
@@ -2003,7 +2087,7 @@ function turnsFromMessages(messages) {
|
|
|
2003
2087
|
}, []);
|
|
2004
2088
|
}
|
|
2005
2089
|
function TurnOutline({ messages }) {
|
|
2006
|
-
return /* @__PURE__ */
|
|
2090
|
+
return /* @__PURE__ */ jsx24(
|
|
2007
2091
|
LatestThreadScroller.Outline,
|
|
2008
2092
|
{
|
|
2009
2093
|
items: turnsFromMessages(messages),
|
|
@@ -2030,7 +2114,7 @@ import {
|
|
|
2030
2114
|
LatestThreadScroller as LatestThreadScroller2,
|
|
2031
2115
|
latestThreadAnchorId
|
|
2032
2116
|
} from "@agents24/chat-react";
|
|
2033
|
-
import { Fragment as Fragment3, jsx as
|
|
2117
|
+
import { Fragment as Fragment3, jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2034
2118
|
var LOADING_INPUT_CONTRACT = {
|
|
2035
2119
|
version: "agents24.runtime-inputs.v2",
|
|
2036
2120
|
modalities: {
|
|
@@ -2043,31 +2127,31 @@ var LOADING_INPUT_CONTRACT = {
|
|
|
2043
2127
|
retention: { mode: "thread_lifetime" }
|
|
2044
2128
|
};
|
|
2045
2129
|
function PersistentSidebarTrigger() {
|
|
2046
|
-
return /* @__PURE__ */
|
|
2130
|
+
return /* @__PURE__ */ jsx25("div", { className: "pointer-events-none fixed start-3 top-0 z-[60] flex h-12 items-center", children: /* @__PURE__ */ jsx25(SidebarTrigger, { className: "pointer-events-auto [&_svg]:size-[18px]" }) });
|
|
2047
2131
|
}
|
|
2048
2132
|
function CollapsedHeaderActions({ onNew }) {
|
|
2049
2133
|
const { isMobile, openMobile, state } = useSidebar();
|
|
2050
2134
|
const sidebarVisible = isMobile ? openMobile : state === "expanded";
|
|
2051
2135
|
if (sidebarVisible) return null;
|
|
2052
|
-
return /* @__PURE__ */
|
|
2053
|
-
/* @__PURE__ */
|
|
2054
|
-
/* @__PURE__ */
|
|
2136
|
+
return /* @__PURE__ */ jsxs15(Fragment3, { children: [
|
|
2137
|
+
/* @__PURE__ */ jsx25("div", { className: "h-8 w-17 shrink-0", "aria-hidden": "true" }),
|
|
2138
|
+
/* @__PURE__ */ jsx25("div", { className: "pointer-events-none fixed start-12 top-0 z-[60] flex h-12 items-center", children: /* @__PURE__ */ jsx25(Button, { className: "pointer-events-auto", variant: "ghost", size: "icon-sm", "aria-label": "New chat", onClick: onNew, children: /* @__PURE__ */ jsx25(SquarePen2, {}) }) })
|
|
2055
2139
|
] });
|
|
2056
2140
|
}
|
|
2057
2141
|
function OperationErrorNotice({ runtime }) {
|
|
2058
2142
|
const error = runtime.operationError || runtime.backgroundError;
|
|
2059
2143
|
if (!error) return null;
|
|
2060
|
-
return /* @__PURE__ */
|
|
2061
|
-
/* @__PURE__ */
|
|
2062
|
-
/* @__PURE__ */
|
|
2063
|
-
/* @__PURE__ */
|
|
2144
|
+
return /* @__PURE__ */ jsx25("div", { className: "pointer-events-none absolute inset-x-0 top-3 z-40 flex justify-center px-4", children: /* @__PURE__ */ jsxs15("div", { className: "pointer-events-auto flex max-w-lg items-start gap-2 rounded-lg border border-destructive/20 bg-background px-3 py-2 text-sm shadow-md", role: "alert", children: [
|
|
2145
|
+
/* @__PURE__ */ jsx25(CircleAlert, { className: "mt-0.5 size-4 shrink-0 text-destructive" }),
|
|
2146
|
+
/* @__PURE__ */ jsx25("span", { className: "min-w-0 flex-1 wrap-break-word", children: agentChatRuntimeErrorMessage(error) || "The chat could not complete that action." }),
|
|
2147
|
+
/* @__PURE__ */ jsx25(
|
|
2064
2148
|
Button,
|
|
2065
2149
|
{
|
|
2066
2150
|
"aria-label": "Dismiss error",
|
|
2067
2151
|
onClick: runtime.operationError ? runtime.clearOperationError : runtime.controller.clearBackgroundError,
|
|
2068
2152
|
size: "icon-xs",
|
|
2069
2153
|
variant: "ghost",
|
|
2070
|
-
children: /* @__PURE__ */
|
|
2154
|
+
children: /* @__PURE__ */ jsx25(X, {})
|
|
2071
2155
|
}
|
|
2072
2156
|
)
|
|
2073
2157
|
] }) });
|
|
@@ -2078,6 +2162,7 @@ function ChatShell({
|
|
|
2078
2162
|
runtime,
|
|
2079
2163
|
sidebar
|
|
2080
2164
|
}) {
|
|
2165
|
+
const Composer = components?.Composer || ChatComposer;
|
|
2081
2166
|
const { controller } = runtime;
|
|
2082
2167
|
const isUploading = controller.runState === "uploading";
|
|
2083
2168
|
const isRunning = controller.runState === "streaming" || controller.runState === "reconnecting" || controller.runState === "paused" || controller.runState === "cancelling";
|
|
@@ -2087,11 +2172,11 @@ function ChatShell({
|
|
|
2087
2172
|
const hasBlockingError = Boolean(runtime.fatalError && controller.messages.length === 0);
|
|
2088
2173
|
const isEmptyState = controller.activeThreadId === null && controller.messages.length === 0 && !hasBlockingError;
|
|
2089
2174
|
const latestAnchorId = latestThreadAnchorId(controller.messages);
|
|
2090
|
-
const composerOverlayRef =
|
|
2091
|
-
const [composerOverlayHeight, setComposerOverlayHeight] =
|
|
2092
|
-
const [restoredDraft, setRestoredDraft] =
|
|
2093
|
-
const draftRevisionRef =
|
|
2094
|
-
const retractForEdit =
|
|
2175
|
+
const composerOverlayRef = React9.useRef(null);
|
|
2176
|
+
const [composerOverlayHeight, setComposerOverlayHeight] = React9.useState(192);
|
|
2177
|
+
const [restoredDraft, setRestoredDraft] = React9.useState(null);
|
|
2178
|
+
const draftRevisionRef = React9.useRef(0);
|
|
2179
|
+
const retractForEdit = React9.useCallback(async (message) => {
|
|
2095
2180
|
const draft = await controller.retractPendingMessage(message);
|
|
2096
2181
|
setRestoredDraft({
|
|
2097
2182
|
revision: ++draftRevisionRef.current,
|
|
@@ -2099,7 +2184,7 @@ function ChatShell({
|
|
|
2099
2184
|
files: queuedMessageComposerFiles(draft)
|
|
2100
2185
|
});
|
|
2101
2186
|
}, [controller]);
|
|
2102
|
-
|
|
2187
|
+
React9.useLayoutEffect(() => {
|
|
2103
2188
|
const overlay = composerOverlayRef.current;
|
|
2104
2189
|
if (!overlay || isEmptyState) return;
|
|
2105
2190
|
const updateHeight = () => {
|
|
@@ -2110,15 +2195,15 @@ function ChatShell({
|
|
|
2110
2195
|
resizeObserver.observe(overlay);
|
|
2111
2196
|
return () => resizeObserver.disconnect();
|
|
2112
2197
|
}, [isEmptyState]);
|
|
2113
|
-
return /* @__PURE__ */
|
|
2198
|
+
return /* @__PURE__ */ jsxs15(
|
|
2114
2199
|
SidebarProvider,
|
|
2115
2200
|
{
|
|
2116
2201
|
className: "h-svh min-h-0 overflow-hidden",
|
|
2117
2202
|
"data-agents24-chat": "",
|
|
2118
2203
|
"data-agents24-chat-layout": "",
|
|
2119
2204
|
children: [
|
|
2120
|
-
/* @__PURE__ */
|
|
2121
|
-
sidebar || /* @__PURE__ */
|
|
2205
|
+
/* @__PURE__ */ jsx25(PersistentSidebarTrigger, {}),
|
|
2206
|
+
sidebar || /* @__PURE__ */ jsx25(
|
|
2122
2207
|
ThreadSidebar,
|
|
2123
2208
|
{
|
|
2124
2209
|
activeThreadId: controller.activeThreadId,
|
|
@@ -2133,57 +2218,58 @@ function ChatShell({
|
|
|
2133
2218
|
onOpen: runtime.openThread
|
|
2134
2219
|
}
|
|
2135
2220
|
),
|
|
2136
|
-
/* @__PURE__ */
|
|
2137
|
-
/* @__PURE__ */
|
|
2221
|
+
/* @__PURE__ */ jsxs15(SidebarInset, { className: "h-svh min-h-0 overflow-hidden bg-background", children: [
|
|
2222
|
+
/* @__PURE__ */ jsxs15(
|
|
2138
2223
|
"header",
|
|
2139
2224
|
{
|
|
2140
2225
|
className: "flex h-12 shrink-0 items-center gap-2 border-b border-border/50 px-3 sm:px-4",
|
|
2141
2226
|
"data-agents24-chat-header": "",
|
|
2142
2227
|
children: [
|
|
2143
|
-
/* @__PURE__ */
|
|
2144
|
-
/* @__PURE__ */
|
|
2145
|
-
/* @__PURE__ */
|
|
2228
|
+
/* @__PURE__ */ jsx25(CollapsedHeaderActions, { onNew: runtime.newThread }),
|
|
2229
|
+
/* @__PURE__ */ jsx25("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx25("h1", { className: "truncate text-sm font-medium", children: String(activeTitle || "New chat") }) }),
|
|
2230
|
+
/* @__PURE__ */ jsx25(ThemeMenu, {})
|
|
2146
2231
|
]
|
|
2147
2232
|
}
|
|
2148
2233
|
),
|
|
2149
|
-
/* @__PURE__ */
|
|
2234
|
+
/* @__PURE__ */ jsxs15(
|
|
2150
2235
|
"section",
|
|
2151
2236
|
{
|
|
2152
2237
|
"aria-label": "Conversation",
|
|
2153
2238
|
className: "relative flex min-h-0 flex-1 flex-col overflow-hidden",
|
|
2154
2239
|
"data-agents24-chat-transcript": "",
|
|
2155
2240
|
children: [
|
|
2156
|
-
/* @__PURE__ */
|
|
2157
|
-
/* @__PURE__ */
|
|
2158
|
-
|
|
2159
|
-
|
|
2241
|
+
/* @__PURE__ */ jsx25(OperationErrorNotice, { runtime }),
|
|
2242
|
+
/* @__PURE__ */ jsx25(SubagentTasks, { threadId: controller.activeThreadId }),
|
|
2243
|
+
/* @__PURE__ */ jsxs15(LatestThreadScroller2.Provider, { autoScroll: true, defaultScrollPosition: "last-anchor", scrollPreviousItemPeek: 64, children: [
|
|
2244
|
+
!isEmptyState && /* @__PURE__ */ jsxs15(LatestThreadScroller2.Root, { className: "relative min-h-0 flex-1", children: [
|
|
2245
|
+
/* @__PURE__ */ jsx25(LatestThreadScroller2.Viewport, { preserveScrollOnPrepend: true, children: /* @__PURE__ */ jsxs15(
|
|
2160
2246
|
LatestThreadScroller2.Content,
|
|
2161
2247
|
{
|
|
2162
2248
|
className: "mx-auto w-full max-w-3xl gap-3 px-4 pt-8 pb-0 sm:px-6 sm:pt-12",
|
|
2163
2249
|
style: { paddingBottom: composerOverlayHeight + 72 },
|
|
2164
2250
|
children: [
|
|
2165
|
-
controller.hasOlderTurns && /* @__PURE__ */
|
|
2251
|
+
controller.hasOlderTurns && /* @__PURE__ */ jsxs15(Button, { className: "self-center", variant: "ghost", size: "sm", disabled: controller.isLoadingOlder, onClick: () => {
|
|
2166
2252
|
void controller.loadOlder().catch(() => void 0);
|
|
2167
2253
|
}, children: [
|
|
2168
|
-
controller.isLoadingOlder && /* @__PURE__ */
|
|
2254
|
+
controller.isLoadingOlder && /* @__PURE__ */ jsx25(LoaderCircle3, { className: "animate-spin" }),
|
|
2169
2255
|
" Load earlier messages"
|
|
2170
2256
|
] }),
|
|
2171
|
-
runtime.isBootstrapping && /* @__PURE__ */
|
|
2172
|
-
hasBlockingError && /* @__PURE__ */
|
|
2173
|
-
/* @__PURE__ */
|
|
2174
|
-
/* @__PURE__ */
|
|
2175
|
-
/* @__PURE__ */
|
|
2176
|
-
/* @__PURE__ */
|
|
2257
|
+
runtime.isBootstrapping && /* @__PURE__ */ jsx25("div", { "aria-label": "Loading conversation", className: "flex flex-1 items-center justify-center py-24 text-muted-foreground", role: "status", children: /* @__PURE__ */ jsx25(LoaderCircle3, { className: "size-4 animate-spin" }) }),
|
|
2258
|
+
hasBlockingError && /* @__PURE__ */ jsxs15("div", { className: "flex flex-1 flex-col items-center justify-center gap-3 py-24 text-center", children: [
|
|
2259
|
+
/* @__PURE__ */ jsx25(CircleAlert, { className: "size-5 text-destructive" }),
|
|
2260
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
2261
|
+
/* @__PURE__ */ jsx25("h2", { className: "font-medium", children: "Couldn\u2019t connect" }),
|
|
2262
|
+
/* @__PURE__ */ jsx25("p", { className: "mt-1 max-w-md text-sm text-muted-foreground", children: runtime.errorMessage })
|
|
2177
2263
|
] }),
|
|
2178
|
-
/* @__PURE__ */
|
|
2264
|
+
/* @__PURE__ */ jsx25(Button, { variant: "outline", onClick: () => void runtime.retryBootstrap(), children: "Try again" })
|
|
2179
2265
|
] }),
|
|
2180
|
-
controller.messages.map((message) => /* @__PURE__ */
|
|
2266
|
+
controller.messages.map((message) => /* @__PURE__ */ jsx25(
|
|
2181
2267
|
LatestThreadScroller2.Item,
|
|
2182
2268
|
{
|
|
2183
2269
|
messageId: message.id,
|
|
2184
2270
|
scrollAnchor: isRunning && message.id === latestAnchorId,
|
|
2185
2271
|
className: "overflow-visible [content-visibility:visible]",
|
|
2186
|
-
children: /* @__PURE__ */
|
|
2272
|
+
children: /* @__PURE__ */ jsx25(
|
|
2187
2273
|
ChatMessage,
|
|
2188
2274
|
{
|
|
2189
2275
|
animateCompletion: wasLiveRun(message.runId),
|
|
@@ -2209,9 +2295,9 @@ function ChatShell({
|
|
|
2209
2295
|
]
|
|
2210
2296
|
}
|
|
2211
2297
|
) }),
|
|
2212
|
-
/* @__PURE__ */
|
|
2298
|
+
/* @__PURE__ */ jsx25(TurnOutline, { messages: controller.messages })
|
|
2213
2299
|
] }),
|
|
2214
|
-
/* @__PURE__ */
|
|
2300
|
+
/* @__PURE__ */ jsxs15(
|
|
2215
2301
|
"div",
|
|
2216
2302
|
{
|
|
2217
2303
|
ref: composerOverlayRef,
|
|
@@ -2220,56 +2306,52 @@ function ChatShell({
|
|
|
2220
2306
|
background: "linear-gradient(to bottom, transparent 0%, color-mix(in oklch, var(--background) 85%, transparent) 45%, var(--background) 65%, var(--background) 100%)"
|
|
2221
2307
|
},
|
|
2222
2308
|
children: [
|
|
2223
|
-
isEmptyState ? /* @__PURE__ */
|
|
2224
|
-
/* @__PURE__ */
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
utilityRow: isEmptyState ? "inline" : "below"
|
|
2270
|
-
}
|
|
2271
|
-
)
|
|
2272
|
-
] })
|
|
2309
|
+
isEmptyState ? /* @__PURE__ */ jsx25("div", { className: "mx-auto mb-8 w-full max-w-3xl px-4 text-center sm:px-6", children: /* @__PURE__ */ jsx25("h2", { className: "text-3xl font-semibold tracking-tight sm:text-4xl", children: "Ready when you are." }) }) : /* @__PURE__ */ jsx25("div", { className: "pointer-events-auto absolute inset-x-0 top-0 flex -translate-y-full justify-center pb-3", children: /* @__PURE__ */ jsx25(LatestThreadScroller2.Button, { className: "!relative !inset-auto !translate-x-0 rtl:!translate-x-0" }) }),
|
|
2310
|
+
/* @__PURE__ */ jsx25("div", { className: "pointer-events-auto mx-auto w-full max-w-3xl px-4 sm:px-6", children: /* @__PURE__ */ jsx25(
|
|
2311
|
+
Composer,
|
|
2312
|
+
{
|
|
2313
|
+
queue: /* @__PURE__ */ jsx25(
|
|
2314
|
+
AgentChatQueue,
|
|
2315
|
+
{
|
|
2316
|
+
pending: controller.pendingMessages,
|
|
2317
|
+
queue: controller.messageQueue,
|
|
2318
|
+
onRemove: controller.removePendingMessage,
|
|
2319
|
+
onEdit: retractForEdit,
|
|
2320
|
+
onResume: controller.resumeQueue
|
|
2321
|
+
}
|
|
2322
|
+
),
|
|
2323
|
+
restoredDraft,
|
|
2324
|
+
inputContract: runtime.inputContract || LOADING_INPUT_CONTRACT,
|
|
2325
|
+
contextWindow: runtime.contextWindow,
|
|
2326
|
+
disabled: runtime.isBootstrapping || runtime.isChangingAgent || isUploading || hasBlockingError,
|
|
2327
|
+
focusKey: controller.activeThreadId,
|
|
2328
|
+
forceExpanded: isEmptyState,
|
|
2329
|
+
isCancelling,
|
|
2330
|
+
isRunning,
|
|
2331
|
+
agentId: runtime.agentId,
|
|
2332
|
+
agents: runtime.agents,
|
|
2333
|
+
onAgentChange: (agentId) => {
|
|
2334
|
+
void runtime.changeAgent(agentId);
|
|
2335
|
+
},
|
|
2336
|
+
onStop: () => {
|
|
2337
|
+
void controller.cancelRun().catch(() => void 0);
|
|
2338
|
+
},
|
|
2339
|
+
modelId: runtime.modelId,
|
|
2340
|
+
models: runtime.models,
|
|
2341
|
+
onModelChange: runtime.changeModel,
|
|
2342
|
+
onSubmit: (text, files) => runtime.submit({
|
|
2343
|
+
text,
|
|
2344
|
+
files: files.filter((file) => file.source).map((file) => ({
|
|
2345
|
+
data: file.source,
|
|
2346
|
+
mediaType: file.mediaType,
|
|
2347
|
+
name: file.filename
|
|
2348
|
+
})),
|
|
2349
|
+
attachmentIds: files.flatMap((file) => file.persistedAttachmentId ? [file.persistedAttachmentId] : []),
|
|
2350
|
+
attachments: files
|
|
2351
|
+
}),
|
|
2352
|
+
utilityRow: isEmptyState ? "inline" : "below"
|
|
2353
|
+
}
|
|
2354
|
+
) })
|
|
2273
2355
|
]
|
|
2274
2356
|
}
|
|
2275
2357
|
)
|
|
@@ -2287,7 +2369,7 @@ function ChatShell({
|
|
|
2287
2369
|
var GUEST_CHAT_IDENTITY = { state: "guest" };
|
|
2288
2370
|
|
|
2289
2371
|
// scaffold/src/app.tsx
|
|
2290
|
-
import { jsx as
|
|
2372
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
2291
2373
|
var createBrowserAbortController = () => new AbortController();
|
|
2292
2374
|
var browserVisibility = createBrowserVisibility();
|
|
2293
2375
|
function RuntimeChat({
|
|
@@ -2299,19 +2381,20 @@ function RuntimeChat({
|
|
|
2299
2381
|
...props,
|
|
2300
2382
|
mcpRedirectUri: props.mcpRedirectUri || (typeof window === "undefined" ? void 0 : window.location.href)
|
|
2301
2383
|
});
|
|
2302
|
-
return /* @__PURE__ */
|
|
2384
|
+
return /* @__PURE__ */ jsx26(ChatShell, { components, identity, runtime, sidebar: props.sidebar });
|
|
2303
2385
|
}
|
|
2304
2386
|
function App(props) {
|
|
2305
2387
|
const identity = props.identity || GUEST_CHAT_IDENTITY;
|
|
2306
|
-
return /* @__PURE__ */
|
|
2388
|
+
return /* @__PURE__ */ jsx26(Agents24Provider, { client: props.client, createAbortController: createBrowserAbortController, visibility: browserVisibility, children: /* @__PURE__ */ jsx26(RuntimeChat, { ...props }, identity.state) });
|
|
2307
2389
|
}
|
|
2308
2390
|
|
|
2309
2391
|
// scaffold/src/index.tsx
|
|
2310
|
-
import { jsx as
|
|
2311
|
-
function Agents24ChatScaffold({ appearanceController, theme, ...props }) {
|
|
2312
|
-
return /* @__PURE__ */
|
|
2392
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
2393
|
+
function Agents24ChatScaffold({ appearanceController, theme, themeMode, ...props }) {
|
|
2394
|
+
return /* @__PURE__ */ jsx27(ThemeProvider, { controller: appearanceController, theme, mode: themeMode, children: /* @__PURE__ */ jsx27(TooltipProvider, { children: /* @__PURE__ */ jsx27(App, { ...props }) }) });
|
|
2313
2395
|
}
|
|
2314
2396
|
export {
|
|
2397
|
+
ChatComposer as Agents24ChatComposer,
|
|
2315
2398
|
Agents24ChatScaffold,
|
|
2316
2399
|
App as Agents24ChatScaffoldApp,
|
|
2317
2400
|
ThemeProvider as Agents24ChatThemeProvider,
|