@agents24/chat-react 0.5.28 → 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 +10 -14
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.js +12 -85
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/input-contract.d.ts +6 -3
- 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 -106
- package/dist/scaffold/index.cjs.map +1 -1
- package/dist/scaffold/index.d.ts +2 -0
- package/dist/scaffold/index.js +41 -107
- package/dist/scaffold/index.js.map +1 -1
- package/dist/ui/agent-chat-composer.d.ts +7 -2
- package/dist/ui/composer-attachments.d.ts +1 -1
- package/dist/ui/index.cjs +688 -539
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.js +650 -540
- 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 +10 -6
- 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 -105
- 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 { canonicalInputMimeType, 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,15 +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
|
-
const accepted = selected.filter((file) => attachmentMimeTypes.includes(canonicalInputMimeType(file.type)));
|
|
655
|
-
draftRevisionRef.current += 1;
|
|
656
|
-
setFiles((current) => [...current, ...accepted.map(createAgentChatComposerFile)]);
|
|
657
|
-
setAttachmentError(
|
|
658
|
-
accepted.length === selected.length ? null : "One or more selected file types are not supported by this Agent."
|
|
659
|
-
);
|
|
598
|
+
composer.addFiles(Array.from(event.target.files ?? []));
|
|
660
599
|
event.currentTarget.value = "";
|
|
661
600
|
}
|
|
662
601
|
}
|
|
@@ -676,16 +615,8 @@ function ChatComposer({
|
|
|
676
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",
|
|
677
616
|
isExpanded ? "py-2" : "h-9 py-2"
|
|
678
617
|
),
|
|
679
|
-
onChange: (event) =>
|
|
680
|
-
|
|
681
|
-
setText(event.target.value);
|
|
682
|
-
},
|
|
683
|
-
onKeyDown: (event) => {
|
|
684
|
-
if (event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing) {
|
|
685
|
-
event.preventDefault();
|
|
686
|
-
void submit();
|
|
687
|
-
}
|
|
688
|
-
}
|
|
618
|
+
onChange: (event) => setText(event.target.value),
|
|
619
|
+
onKeyDown: composer.onKeyDown
|
|
689
620
|
}
|
|
690
621
|
),
|
|
691
622
|
/* @__PURE__ */ jsxs3("div", { className: "agents24-composer-actions flex items-center gap-1", children: [
|
|
@@ -717,7 +648,7 @@ function ChatComposer({
|
|
|
717
648
|
) : validationError ? /* @__PURE__ */ jsxs3(Tooltip, { children: [
|
|
718
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, {}) }) }) }),
|
|
719
650
|
/* @__PURE__ */ jsx7(TooltipContent, { children: validationError })
|
|
720
|
-
] }) : /* @__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, {}) })
|
|
721
652
|
] })
|
|
722
653
|
]
|
|
723
654
|
}
|
|
@@ -1213,7 +1144,7 @@ var options = [
|
|
|
1213
1144
|
{ value: "dark", label: "Dark", icon: Moon }
|
|
1214
1145
|
];
|
|
1215
1146
|
function ThemeMenu() {
|
|
1216
|
-
const { appearance, setAppearance } = useTheme();
|
|
1147
|
+
const { appearance, setAppearance, inherited } = useTheme();
|
|
1217
1148
|
const [open, setOpen] = React5.useState(false);
|
|
1218
1149
|
const rootRef = React5.useRef(null);
|
|
1219
1150
|
const firstItemRef = React5.useRef(null);
|
|
@@ -1235,6 +1166,7 @@ function ThemeMenu() {
|
|
|
1235
1166
|
document.removeEventListener("keydown", closeOnEscape);
|
|
1236
1167
|
};
|
|
1237
1168
|
}, [open]);
|
|
1169
|
+
if (inherited) return null;
|
|
1238
1170
|
const label = appearance === "system" ? "System" : appearance === "light" ? "Light" : "Dark";
|
|
1239
1171
|
return /* @__PURE__ */ jsxs9("div", { ref: rootRef, className: "relative", children: [
|
|
1240
1172
|
/* @__PURE__ */ jsx15(
|
|
@@ -2082,6 +2014,7 @@ function ChatShell({
|
|
|
2082
2014
|
runtime,
|
|
2083
2015
|
sidebar
|
|
2084
2016
|
}) {
|
|
2017
|
+
const Composer = components?.Composer || ChatComposer;
|
|
2085
2018
|
const { controller } = runtime;
|
|
2086
2019
|
const isUploading = controller.runState === "uploading";
|
|
2087
2020
|
const isRunning = controller.runState === "streaming" || controller.runState === "reconnecting" || controller.runState === "paused" || controller.runState === "cancelling";
|
|
@@ -2239,7 +2172,7 @@ function ChatShell({
|
|
|
2239
2172
|
}
|
|
2240
2173
|
),
|
|
2241
2174
|
/* @__PURE__ */ jsx24(
|
|
2242
|
-
|
|
2175
|
+
Composer,
|
|
2243
2176
|
{
|
|
2244
2177
|
restoredDraft,
|
|
2245
2178
|
inputContract: runtime.inputContract || LOADING_INPUT_CONTRACT,
|
|
@@ -2316,6 +2249,7 @@ function Agents24ChatScaffold({ appearanceController, theme, ...props }) {
|
|
|
2316
2249
|
return /* @__PURE__ */ jsx26(ThemeProvider, { controller: appearanceController, theme, children: /* @__PURE__ */ jsx26(TooltipProvider, { children: /* @__PURE__ */ jsx26(App, { ...props }) }) });
|
|
2317
2250
|
}
|
|
2318
2251
|
export {
|
|
2252
|
+
ChatComposer as Agents24ChatComposer,
|
|
2319
2253
|
Agents24ChatScaffold,
|
|
2320
2254
|
App as Agents24ChatScaffoldApp,
|
|
2321
2255
|
ThemeProvider as Agents24ChatThemeProvider,
|