@agents24/chat-react 0.5.29 → 0.5.30
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 +23 -1
- package/dist/chunk-INO5DSSJ.js +86 -0
- package/dist/chunk-INO5DSSJ.js.map +1 -0
- package/dist/registry/agents24-chat.json +249 -0
- package/dist/runtime/index.cjs +1 -1
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.js +11 -78
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/input-contract.d.ts +3 -1
- package/dist/scaffold/app.d.ts +2 -0
- package/dist/scaffold/components/chat/chat-composer.d.ts +2 -3
- package/dist/scaffold/components/chat/theme-menu.d.ts +1 -1
- package/dist/scaffold/components/theme-provider.d.ts +2 -1
- package/dist/scaffold/index.cjs +44 -102
- package/dist/scaffold/index.cjs.map +1 -1
- package/dist/scaffold/index.d.ts +2 -0
- package/dist/scaffold/index.js +41 -103
- package/dist/scaffold/index.js.map +1 -1
- package/dist/ui/agent-chat-composer.d.ts +7 -2
- package/dist/ui/index.cjs +688 -540
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.js +650 -541
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/use-agent-chat-composer.d.ts +48 -0
- package/dist/ui/use-audio-recorder.d.ts +1 -1
- package/package.json +8 -4
- package/scaffold/inherit.css +4 -0
- package/scaffold/src/app.tsx +2 -0
- package/scaffold/src/chat.css +24 -0
- package/scaffold/src/components/chat/chat-composer.tsx +14 -97
- package/scaffold/src/components/chat/chat-shell.tsx +2 -1
- package/scaffold/src/components/chat/theme-menu.tsx +3 -1
- package/scaffold/src/components/theme-provider.tsx +10 -8
- package/scaffold/src/index.css +8 -8
- package/scaffold/src/index.tsx +5 -0
package/dist/scaffold/index.d.ts
CHANGED
|
@@ -12,3 +12,5 @@ export type { Agents24ChatAppearance, Agents24ChatAppearanceController, Agents24
|
|
|
12
12
|
export type { Agents24ChatIdentity, Agents24ChatIdentityState } from "./identity";
|
|
13
13
|
export type { ChatHitlResponse, Agents24ChatScaffoldComponents, Agents24ChatTimelineSlotProps, } from "./app";
|
|
14
14
|
export { TooltipProvider as Agents24ChatTooltipProvider };
|
|
15
|
+
export { ChatComposer as Agents24ChatComposer } from "./components/chat/chat-composer";
|
|
16
|
+
export type { Agents24ChatComposerProps } from "./components/chat/chat-composer";
|
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 {
|
|
@@ -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";
|
|
@@ -119,11 +116,11 @@ function ThemeProvider({
|
|
|
119
116
|
const [portalContainer, setPortalContainer] = React.useState(null);
|
|
120
117
|
const appearance = controller?.appearance ?? internalAppearance;
|
|
121
118
|
React.useEffect(() => {
|
|
122
|
-
if (!controller) setInternalAppearance(storedAppearance());
|
|
119
|
+
if (theme !== "inherit" && !controller) setInternalAppearance(storedAppearance());
|
|
123
120
|
setMounted(true);
|
|
124
|
-
}, [controller]);
|
|
121
|
+
}, [controller, theme]);
|
|
125
122
|
React.useEffect(() => {
|
|
126
|
-
if (!mounted || typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
123
|
+
if (theme === "inherit" || !mounted || typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
127
124
|
const media = window.matchMedia("(prefers-color-scheme: dark)");
|
|
128
125
|
const apply = () => setResolvedAppearance(
|
|
129
126
|
appearance === "system" ? media.matches ? "dark" : "light" : appearance
|
|
@@ -131,8 +128,9 @@ function ThemeProvider({
|
|
|
131
128
|
apply();
|
|
132
129
|
media.addEventListener("change", apply);
|
|
133
130
|
return () => media.removeEventListener("change", apply);
|
|
134
|
-
}, [appearance, mounted]);
|
|
131
|
+
}, [appearance, mounted, theme]);
|
|
135
132
|
const change = React.useCallback((next) => {
|
|
133
|
+
if (theme === "inherit") return;
|
|
136
134
|
if (controller) {
|
|
137
135
|
controller.setAppearance(next);
|
|
138
136
|
return;
|
|
@@ -142,12 +140,12 @@ function ThemeProvider({
|
|
|
142
140
|
} catch {
|
|
143
141
|
}
|
|
144
142
|
setInternalAppearance(next);
|
|
145
|
-
}, [controller]);
|
|
146
|
-
return /* @__PURE__ */ jsx2(ThemeContext.Provider, { value: { appearance, portalContainer, setAppearance: change }, children: /* @__PURE__ */ jsx2(
|
|
143
|
+
}, [controller, theme]);
|
|
144
|
+
return /* @__PURE__ */ jsx2(ThemeContext.Provider, { value: { appearance, inherited: theme === "inherit", portalContainer, setAppearance: change }, children: /* @__PURE__ */ jsx2(
|
|
147
145
|
"div",
|
|
148
146
|
{
|
|
149
147
|
ref: setPortalContainer,
|
|
150
|
-
className: `${resolvedAppearance} size-full`,
|
|
148
|
+
className: theme === "inherit" ? "size-full" : `${resolvedAppearance} size-full`,
|
|
151
149
|
"data-agents24-theme": theme,
|
|
152
150
|
"data-agents24-theme-root": "",
|
|
153
151
|
children
|
|
@@ -498,49 +496,31 @@ function ChatComposer({
|
|
|
498
496
|
restoredDraft,
|
|
499
497
|
utilityRow = "inline"
|
|
500
498
|
}) {
|
|
501
|
-
const [text, setText] = React2.useState("");
|
|
502
|
-
const [files, setFiles] = React2.useState([]);
|
|
503
|
-
const [attachmentError, setAttachmentError] = React2.useState(null);
|
|
504
499
|
const inputRef = React2.useRef(null);
|
|
505
500
|
const textareaRef = React2.useRef(null);
|
|
506
|
-
const
|
|
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({
|
|
521
|
-
textareaRef,
|
|
522
|
-
disabled: Boolean(disabled),
|
|
501
|
+
const composer = useAgentChatComposer({
|
|
502
|
+
inputContract,
|
|
503
|
+
disabled,
|
|
504
|
+
isRunning,
|
|
505
|
+
isCancelling,
|
|
523
506
|
focusKey,
|
|
524
507
|
restoredDraft,
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
revokeAgentChatComposerFiles(filesRef.current);
|
|
528
|
-
setText(draft.text);
|
|
529
|
-
setFiles(draft.files);
|
|
530
|
-
}
|
|
508
|
+
textareaRef,
|
|
509
|
+
onSubmit: ({ text: text2, files: files2 }) => onSubmit(text2, files2)
|
|
531
510
|
});
|
|
532
|
-
const
|
|
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,
|
|
511
|
+
const {
|
|
540
512
|
text,
|
|
541
|
-
files
|
|
542
|
-
|
|
543
|
-
|
|
513
|
+
files,
|
|
514
|
+
setText,
|
|
515
|
+
validationError,
|
|
516
|
+
attachmentError,
|
|
517
|
+
recorder,
|
|
518
|
+
recordingAllowed,
|
|
519
|
+
allowAttachments,
|
|
520
|
+
action,
|
|
521
|
+
submit
|
|
522
|
+
} = composer;
|
|
523
|
+
const isExpanded = forceExpanded || text.includes("\n") || text.length > 62;
|
|
544
524
|
const selectedAgent = agents.find((item) => item.id === agentId);
|
|
545
525
|
const selectedModel = models.find((item) => item.id === modelId);
|
|
546
526
|
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,35 +560,6 @@ function ChatComposer({
|
|
|
580
560
|
] }) : modelSelector;
|
|
581
561
|
const hasContextWindow = Number.isFinite(Number(contextWindow?.max_tokens)) && Number(contextWindow?.max_tokens) > 0;
|
|
582
562
|
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
563
|
return /* @__PURE__ */ jsxs3(
|
|
613
564
|
"div",
|
|
614
565
|
{
|
|
@@ -620,13 +571,7 @@ function ChatComposer({
|
|
|
620
571
|
{
|
|
621
572
|
attachments: files,
|
|
622
573
|
onRemove: (attachment) => {
|
|
623
|
-
if (
|
|
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
|
-
});
|
|
574
|
+
if (attachment.id) composer.removeFile(attachment.id);
|
|
630
575
|
}
|
|
631
576
|
}
|
|
632
577
|
) }),
|
|
@@ -648,11 +593,9 @@ function ChatComposer({
|
|
|
648
593
|
className: "sr-only",
|
|
649
594
|
type: "file",
|
|
650
595
|
multiple: true,
|
|
651
|
-
accept:
|
|
596
|
+
accept: composer.fileAccept,
|
|
652
597
|
onChange: (event) => {
|
|
653
|
-
|
|
654
|
-
setFiles((current) => [...current, ...selected.map(createAgentChatComposerFile)]);
|
|
655
|
-
setAttachmentError(null);
|
|
598
|
+
composer.addFiles(Array.from(event.target.files ?? []));
|
|
656
599
|
event.currentTarget.value = "";
|
|
657
600
|
}
|
|
658
601
|
}
|
|
@@ -672,16 +615,8 @@ function ChatComposer({
|
|
|
672
615
|
"agents24-composer-textarea max-h-56 min-h-9 field-sizing-content resize-none overflow-y-auto border-0 bg-transparent px-2 shadow-none focus-visible:ring-0 dark:bg-transparent",
|
|
673
616
|
isExpanded ? "py-2" : "h-9 py-2"
|
|
674
617
|
),
|
|
675
|
-
onChange: (event) =>
|
|
676
|
-
|
|
677
|
-
setText(event.target.value);
|
|
678
|
-
},
|
|
679
|
-
onKeyDown: (event) => {
|
|
680
|
-
if (event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing) {
|
|
681
|
-
event.preventDefault();
|
|
682
|
-
void submit();
|
|
683
|
-
}
|
|
684
|
-
}
|
|
618
|
+
onChange: (event) => setText(event.target.value),
|
|
619
|
+
onKeyDown: composer.onKeyDown
|
|
685
620
|
}
|
|
686
621
|
),
|
|
687
622
|
/* @__PURE__ */ jsxs3("div", { className: "agents24-composer-actions flex items-center gap-1", children: [
|
|
@@ -713,7 +648,7 @@ function ChatComposer({
|
|
|
713
648
|
) : validationError ? /* @__PURE__ */ jsxs3(Tooltip, { children: [
|
|
714
649
|
/* @__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
650
|
/* @__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, {}) })
|
|
651
|
+
] }) : /* @__PURE__ */ jsx7(Button, { size: "icon", "aria-label": isRunning ? "Queue message" : "Send message", disabled: disabled || !composer.canSubmit, onClick: () => void submit(), children: /* @__PURE__ */ jsx7(ArrowUp, {}) })
|
|
717
652
|
] })
|
|
718
653
|
]
|
|
719
654
|
}
|
|
@@ -1209,7 +1144,7 @@ var options = [
|
|
|
1209
1144
|
{ value: "dark", label: "Dark", icon: Moon }
|
|
1210
1145
|
];
|
|
1211
1146
|
function ThemeMenu() {
|
|
1212
|
-
const { appearance, setAppearance } = useTheme();
|
|
1147
|
+
const { appearance, setAppearance, inherited } = useTheme();
|
|
1213
1148
|
const [open, setOpen] = React5.useState(false);
|
|
1214
1149
|
const rootRef = React5.useRef(null);
|
|
1215
1150
|
const firstItemRef = React5.useRef(null);
|
|
@@ -1231,6 +1166,7 @@ function ThemeMenu() {
|
|
|
1231
1166
|
document.removeEventListener("keydown", closeOnEscape);
|
|
1232
1167
|
};
|
|
1233
1168
|
}, [open]);
|
|
1169
|
+
if (inherited) return null;
|
|
1234
1170
|
const label = appearance === "system" ? "System" : appearance === "light" ? "Light" : "Dark";
|
|
1235
1171
|
return /* @__PURE__ */ jsxs9("div", { ref: rootRef, className: "relative", children: [
|
|
1236
1172
|
/* @__PURE__ */ jsx15(
|
|
@@ -2078,6 +2014,7 @@ function ChatShell({
|
|
|
2078
2014
|
runtime,
|
|
2079
2015
|
sidebar
|
|
2080
2016
|
}) {
|
|
2017
|
+
const Composer = components?.Composer || ChatComposer;
|
|
2081
2018
|
const { controller } = runtime;
|
|
2082
2019
|
const isUploading = controller.runState === "uploading";
|
|
2083
2020
|
const isRunning = controller.runState === "streaming" || controller.runState === "reconnecting" || controller.runState === "paused" || controller.runState === "cancelling";
|
|
@@ -2235,7 +2172,7 @@ function ChatShell({
|
|
|
2235
2172
|
}
|
|
2236
2173
|
),
|
|
2237
2174
|
/* @__PURE__ */ jsx24(
|
|
2238
|
-
|
|
2175
|
+
Composer,
|
|
2239
2176
|
{
|
|
2240
2177
|
restoredDraft,
|
|
2241
2178
|
inputContract: runtime.inputContract || LOADING_INPUT_CONTRACT,
|
|
@@ -2312,6 +2249,7 @@ function Agents24ChatScaffold({ appearanceController, theme, ...props }) {
|
|
|
2312
2249
|
return /* @__PURE__ */ jsx26(ThemeProvider, { controller: appearanceController, theme, children: /* @__PURE__ */ jsx26(TooltipProvider, { children: /* @__PURE__ */ jsx26(App, { ...props }) }) });
|
|
2313
2250
|
}
|
|
2314
2251
|
export {
|
|
2252
|
+
ChatComposer as Agents24ChatComposer,
|
|
2315
2253
|
Agents24ChatScaffold,
|
|
2316
2254
|
App as Agents24ChatScaffoldApp,
|
|
2317
2255
|
ThemeProvider as Agents24ChatThemeProvider,
|