@agent-native/toolkit 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/composer/AgentComposerFrame.d.ts +19 -0
- package/dist/composer/AgentComposerFrame.d.ts.map +1 -0
- package/dist/composer/AgentComposerFrame.js +14 -0
- package/dist/composer/AgentComposerFrame.js.map +1 -0
- package/dist/composer/ComposerPlusMenu.d.ts +17 -0
- package/dist/composer/ComposerPlusMenu.d.ts.map +1 -0
- package/dist/composer/ComposerPlusMenu.js +501 -0
- package/dist/composer/ComposerPlusMenu.js.map +1 -0
- package/dist/composer/MentionPopover.d.ts +29 -0
- package/dist/composer/MentionPopover.d.ts.map +1 -0
- package/dist/composer/MentionPopover.js +180 -0
- package/dist/composer/MentionPopover.js.map +1 -0
- package/dist/composer/PastedTextChip.d.ts +9 -0
- package/dist/composer/PastedTextChip.d.ts.map +1 -0
- package/dist/composer/PastedTextChip.js +47 -0
- package/dist/composer/PastedTextChip.js.map +1 -0
- package/dist/composer/PromptComposer.d.ts +114 -0
- package/dist/composer/PromptComposer.d.ts.map +1 -0
- package/dist/composer/PromptComposer.js +302 -0
- package/dist/composer/PromptComposer.js.map +1 -0
- package/dist/composer/PromptComposer.spec.d.ts +2 -0
- package/dist/composer/PromptComposer.spec.d.ts.map +1 -0
- package/dist/composer/PromptComposer.spec.js +64 -0
- package/dist/composer/PromptComposer.spec.js.map +1 -0
- package/dist/composer/RealtimeVoiceMode.d.ts +104 -0
- package/dist/composer/RealtimeVoiceMode.d.ts.map +1 -0
- package/dist/composer/RealtimeVoiceMode.js +245 -0
- package/dist/composer/RealtimeVoiceMode.js.map +1 -0
- package/dist/composer/RealtimeVoiceMode.spec.d.ts +2 -0
- package/dist/composer/RealtimeVoiceMode.spec.d.ts.map +1 -0
- package/dist/composer/RealtimeVoiceMode.spec.js +439 -0
- package/dist/composer/RealtimeVoiceMode.spec.js.map +1 -0
- package/dist/composer/TiptapComposer.d.ts +221 -0
- package/dist/composer/TiptapComposer.d.ts.map +1 -0
- package/dist/composer/TiptapComposer.js +1838 -0
- package/dist/composer/TiptapComposer.js.map +1 -0
- package/dist/composer/TiptapComposer.spec.d.ts +2 -0
- package/dist/composer/TiptapComposer.spec.d.ts.map +1 -0
- package/dist/composer/TiptapComposer.spec.js +277 -0
- package/dist/composer/TiptapComposer.spec.js.map +1 -0
- package/dist/composer/VoiceButton.d.ts +25 -0
- package/dist/composer/VoiceButton.d.ts.map +1 -0
- package/dist/composer/VoiceButton.js +100 -0
- package/dist/composer/VoiceButton.js.map +1 -0
- package/dist/composer/VoiceButton.spec.d.ts +2 -0
- package/dist/composer/VoiceButton.spec.d.ts.map +1 -0
- package/dist/composer/VoiceButton.spec.js +19 -0
- package/dist/composer/VoiceButton.spec.js.map +1 -0
- package/dist/composer/asset-picker-url.d.ts +16 -0
- package/dist/composer/asset-picker-url.d.ts.map +1 -0
- package/dist/composer/asset-picker-url.js +64 -0
- package/dist/composer/asset-picker-url.js.map +1 -0
- package/dist/composer/asset-picker-url.spec.d.ts +2 -0
- package/dist/composer/asset-picker-url.spec.d.ts.map +1 -0
- package/dist/composer/asset-picker-url.spec.js +23 -0
- package/dist/composer/asset-picker-url.spec.js.map +1 -0
- package/dist/composer/attachment-accept.d.ts +9 -0
- package/dist/composer/attachment-accept.d.ts.map +1 -0
- package/dist/composer/attachment-accept.js +65 -0
- package/dist/composer/attachment-accept.js.map +1 -0
- package/dist/composer/attachment-accept.spec.d.ts +2 -0
- package/dist/composer/attachment-accept.spec.d.ts.map +1 -0
- package/dist/composer/attachment-accept.spec.js +15 -0
- package/dist/composer/attachment-accept.spec.js.map +1 -0
- package/dist/composer/draft-key.d.ts +2 -0
- package/dist/composer/draft-key.d.ts.map +1 -0
- package/dist/composer/draft-key.js +8 -0
- package/dist/composer/draft-key.js.map +1 -0
- package/dist/composer/draft-key.spec.d.ts +2 -0
- package/dist/composer/draft-key.spec.d.ts.map +1 -0
- package/dist/composer/draft-key.spec.js +13 -0
- package/dist/composer/draft-key.spec.js.map +1 -0
- package/dist/composer/extensions/FileReference.d.ts +3 -0
- package/dist/composer/extensions/FileReference.d.ts.map +1 -0
- package/dist/composer/extensions/FileReference.js +36 -0
- package/dist/composer/extensions/FileReference.js.map +1 -0
- package/dist/composer/extensions/MentionReference.d.ts +3 -0
- package/dist/composer/extensions/MentionReference.d.ts.map +1 -0
- package/dist/composer/extensions/MentionReference.js +66 -0
- package/dist/composer/extensions/MentionReference.js.map +1 -0
- package/dist/composer/extensions/SkillReference.d.ts +3 -0
- package/dist/composer/extensions/SkillReference.d.ts.map +1 -0
- package/dist/composer/extensions/SkillReference.js +40 -0
- package/dist/composer/extensions/SkillReference.js.map +1 -0
- package/dist/composer/index.d.ts +14 -0
- package/dist/composer/index.d.ts.map +1 -0
- package/dist/composer/index.js +13 -0
- package/dist/composer/index.js.map +1 -0
- package/dist/composer/pasted-text.d.ts +31 -0
- package/dist/composer/pasted-text.d.ts.map +1 -0
- package/dist/composer/pasted-text.js +130 -0
- package/dist/composer/pasted-text.js.map +1 -0
- package/dist/composer/pasted-text.spec.d.ts +2 -0
- package/dist/composer/pasted-text.spec.d.ts.map +1 -0
- package/dist/composer/pasted-text.spec.js +107 -0
- package/dist/composer/pasted-text.spec.js.map +1 -0
- package/dist/composer/prompt-attachments.d.ts +18 -0
- package/dist/composer/prompt-attachments.d.ts.map +1 -0
- package/dist/composer/prompt-attachments.js +65 -0
- package/dist/composer/prompt-attachments.js.map +1 -0
- package/dist/composer/prompt-attachments.spec.d.ts +2 -0
- package/dist/composer/prompt-attachments.spec.d.ts.map +1 -0
- package/dist/composer/prompt-attachments.spec.js +63 -0
- package/dist/composer/prompt-attachments.spec.js.map +1 -0
- package/dist/composer/realtime-voice-audio-level.d.ts +14 -0
- package/dist/composer/realtime-voice-audio-level.d.ts.map +1 -0
- package/dist/composer/realtime-voice-audio-level.js +47 -0
- package/dist/composer/realtime-voice-audio-level.js.map +1 -0
- package/dist/composer/realtime-voice-audio-level.spec.d.ts +2 -0
- package/dist/composer/realtime-voice-audio-level.spec.d.ts.map +1 -0
- package/dist/composer/realtime-voice-audio-level.spec.js +25 -0
- package/dist/composer/realtime-voice-audio-level.spec.js.map +1 -0
- package/dist/composer/realtime-voice-transcript.d.ts +26 -0
- package/dist/composer/realtime-voice-transcript.d.ts.map +1 -0
- package/dist/composer/realtime-voice-transcript.js +103 -0
- package/dist/composer/realtime-voice-transcript.js.map +1 -0
- package/dist/composer/realtime-voice-transcript.spec.d.ts +2 -0
- package/dist/composer/realtime-voice-transcript.spec.d.ts.map +1 -0
- package/dist/composer/realtime-voice-transcript.spec.js +76 -0
- package/dist/composer/realtime-voice-transcript.spec.js.map +1 -0
- package/dist/composer/runtime-adapters.d.ts +163 -0
- package/dist/composer/runtime-adapters.d.ts.map +1 -0
- package/dist/composer/runtime-adapters.js +130 -0
- package/dist/composer/runtime-adapters.js.map +1 -0
- package/dist/composer/types.d.ts +60 -0
- package/dist/composer/types.d.ts.map +1 -0
- package/dist/composer/types.js +2 -0
- package/dist/composer/types.js.map +1 -0
- package/dist/composer/use-file-search.d.ts +6 -0
- package/dist/composer/use-file-search.d.ts.map +1 -0
- package/dist/composer/use-file-search.js +53 -0
- package/dist/composer/use-file-search.js.map +1 -0
- package/dist/composer/use-mention-search.d.ts +6 -0
- package/dist/composer/use-mention-search.d.ts.map +1 -0
- package/dist/composer/use-mention-search.js +75 -0
- package/dist/composer/use-mention-search.js.map +1 -0
- package/dist/composer/use-skills.d.ts +7 -0
- package/dist/composer/use-skills.d.ts.map +1 -0
- package/dist/composer/use-skills.js +40 -0
- package/dist/composer/use-skills.js.map +1 -0
- package/dist/composer/useRealtimeVoiceMode.d.ts +179 -0
- package/dist/composer/useRealtimeVoiceMode.d.ts.map +1 -0
- package/dist/composer/useRealtimeVoiceMode.js +1657 -0
- package/dist/composer/useRealtimeVoiceMode.js.map +1 -0
- package/dist/composer/useRealtimeVoiceMode.spec.d.ts +2 -0
- package/dist/composer/useRealtimeVoiceMode.spec.d.ts.map +1 -0
- package/dist/composer/useRealtimeVoiceMode.spec.js +618 -0
- package/dist/composer/useRealtimeVoiceMode.spec.js.map +1 -0
- package/dist/composer/useVoiceDictation.d.ts +57 -0
- package/dist/composer/useVoiceDictation.d.ts.map +1 -0
- package/dist/composer/useVoiceDictation.js +1004 -0
- package/dist/composer/useVoiceDictation.js.map +1 -0
- package/dist/composer/useVoiceDictation.spec.d.ts +2 -0
- package/dist/composer/useVoiceDictation.spec.d.ts.map +1 -0
- package/dist/composer/useVoiceDictation.spec.js +32 -0
- package/dist/composer/useVoiceDictation.spec.js.map +1 -0
- package/dist/editor/RegistryBlockContext.d.ts +68 -0
- package/dist/editor/RegistryBlockContext.d.ts.map +1 -0
- package/dist/editor/RegistryBlockContext.js +10 -0
- package/dist/editor/RegistryBlockContext.js.map +1 -0
- package/dist/editor/RegistryBlockNode.d.ts +66 -0
- package/dist/editor/RegistryBlockNode.d.ts.map +1 -0
- package/dist/editor/RegistryBlockNode.js +406 -0
- package/dist/editor/RegistryBlockNode.js.map +1 -0
- package/dist/editor/RegistryBlockNode.spec.d.ts +2 -0
- package/dist/editor/RegistryBlockNode.spec.d.ts.map +1 -0
- package/dist/editor/RegistryBlockNode.spec.js +215 -0
- package/dist/editor/RegistryBlockNode.spec.js.map +1 -0
- package/dist/editor/index.d.ts +2 -0
- package/dist/editor/index.d.ts.map +1 -1
- package/dist/editor/index.js +2 -0
- package/dist/editor/index.js.map +1 -1
- package/dist/editor/registrySlashCommands.d.ts +68 -0
- package/dist/editor/registrySlashCommands.d.ts.map +1 -0
- package/dist/editor/registrySlashCommands.js +51 -0
- package/dist/editor/registrySlashCommands.js.map +1 -0
- package/package.json +16 -1
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { AssistantRuntimeProvider, ThreadPrimitive, useAui, useComposer, useLocalRuntime, } from "@assistant-ui/react";
|
|
3
|
+
import { CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, } from "@assistant-ui/react";
|
|
4
|
+
import { IconX } from "@tabler/icons-react";
|
|
5
|
+
import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
6
|
+
import { TooltipProvider } from "../ui/tooltip.js";
|
|
7
|
+
import { cn } from "../utils.js";
|
|
8
|
+
import { AgentComposerFrame } from "./AgentComposerFrame.js";
|
|
9
|
+
import { IMAGE_ATTACHMENT_ACCEPT } from "./attachment-accept.js";
|
|
10
|
+
import { PROMPT_DOCUMENT_ATTACHMENT_ACCEPT, TextAttachmentAdapter, } from "./attachment-accept.js";
|
|
11
|
+
import { isPastedTextAttachmentName } from "./pasted-text.js";
|
|
12
|
+
import { PastedTextChip } from "./PastedTextChip.js";
|
|
13
|
+
import { escapePromptAttachmentAttribute } from "./prompt-attachments.js";
|
|
14
|
+
import { useComposerRuntimeAdapters, } from "./runtime-adapters.js";
|
|
15
|
+
import { DEFAULT_VOICE_DICTATION_ENABLED, TiptapComposer, } from "./TiptapComposer.js";
|
|
16
|
+
const MAX_INLINE_TEXT_FILE_CHARS = 60_000;
|
|
17
|
+
const SUBMIT_ENGINE_STATUS_TIMEOUT_MS = 1000;
|
|
18
|
+
// Minimal pass-through adapter. PromptComposer always submits through
|
|
19
|
+
// onSubmitOverride, so the runtime never actually calls this — but
|
|
20
|
+
// `useLocalRuntime` needs *something* shaped like a ChatModelAdapter.
|
|
21
|
+
const NOOP_ADAPTER = {
|
|
22
|
+
async *run() {
|
|
23
|
+
return;
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Local binary document adapter so reference PDFs, decks, and docs can be
|
|
28
|
+
* attached without dragging the whole assistant chat module into bundles that
|
|
29
|
+
* just want a prompt popover.
|
|
30
|
+
*/
|
|
31
|
+
class BinaryDocumentAttachmentAdapter {
|
|
32
|
+
accept = PROMPT_DOCUMENT_ATTACHMENT_ACCEPT;
|
|
33
|
+
async add(state) {
|
|
34
|
+
return {
|
|
35
|
+
id: state.file.name,
|
|
36
|
+
type: "document",
|
|
37
|
+
name: state.file.name,
|
|
38
|
+
contentType: state.file.type || "application/octet-stream",
|
|
39
|
+
file: state.file,
|
|
40
|
+
status: { type: "requires-action", reason: "composer-send" },
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
async send(attachment) {
|
|
44
|
+
return {
|
|
45
|
+
...attachment,
|
|
46
|
+
status: { type: "complete" },
|
|
47
|
+
content: [],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async remove() {
|
|
51
|
+
/* noop */
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
class RasterImageAttachmentAdapter extends SimpleImageAttachmentAdapter {
|
|
55
|
+
accept = IMAGE_ATTACHMENT_ACCEPT;
|
|
56
|
+
}
|
|
57
|
+
function isInlineableTextFile(file) {
|
|
58
|
+
if (file.type.startsWith("text/"))
|
|
59
|
+
return true;
|
|
60
|
+
if (file.type === "application/json")
|
|
61
|
+
return true;
|
|
62
|
+
return /\.(txt|md|markdown|csv|json|yaml|yml|html?|css|xml)$/i.test(file.name);
|
|
63
|
+
}
|
|
64
|
+
function formatInlineTextFile(name, text) {
|
|
65
|
+
const truncated = text.length > MAX_INLINE_TEXT_FILE_CHARS;
|
|
66
|
+
const body = truncated ? text.slice(0, MAX_INLINE_TEXT_FILE_CHARS) : text;
|
|
67
|
+
return [
|
|
68
|
+
`<uploaded-text-file name="${escapePromptAttachmentAttribute(name)}">`,
|
|
69
|
+
body,
|
|
70
|
+
truncated
|
|
71
|
+
? `[Truncated after ${MAX_INLINE_TEXT_FILE_CHARS} characters.]`
|
|
72
|
+
: "",
|
|
73
|
+
"</uploaded-text-file>",
|
|
74
|
+
]
|
|
75
|
+
.filter(Boolean)
|
|
76
|
+
.join("\n");
|
|
77
|
+
}
|
|
78
|
+
export async function buildPromptComposerSubmission(options) {
|
|
79
|
+
const files = [];
|
|
80
|
+
const pastedTextBlocks = [];
|
|
81
|
+
const rawText = options.text;
|
|
82
|
+
for (const att of options.attachments ?? []) {
|
|
83
|
+
const a = att;
|
|
84
|
+
if ("file" in a && a.file instanceof File) {
|
|
85
|
+
const file = a.file;
|
|
86
|
+
if (isPastedTextAttachmentName(file.name)) {
|
|
87
|
+
try {
|
|
88
|
+
pastedTextBlocks.push(await file.text());
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
files.push(file);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
if (isInlineableTextFile(file)) {
|
|
96
|
+
try {
|
|
97
|
+
pastedTextBlocks.push(formatInlineTextFile(file.name, await file.text()));
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Keep the upload path fallback below.
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Note: images are NOT inlined into the prompt text even when small.
|
|
104
|
+
// Inlining a base64 data-URL into a text string consumes an enormous
|
|
105
|
+
// number of tokens (≈ 700 K per MB) and most hosts handle images via
|
|
106
|
+
// proper attachment channels. The `files` array below carries the image
|
|
107
|
+
// for the host to process through a dedicated attachment pipeline.
|
|
108
|
+
files.push(file);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
text: pastedTextBlocks.length
|
|
114
|
+
? [rawText.trim(), ...pastedTextBlocks].filter(Boolean).join("\n\n")
|
|
115
|
+
: rawText,
|
|
116
|
+
files,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function getImageSrc(attachment) {
|
|
120
|
+
if (attachment.type !== "image")
|
|
121
|
+
return null;
|
|
122
|
+
if ("file" in attachment && attachment.file) {
|
|
123
|
+
return URL.createObjectURL(attachment.file);
|
|
124
|
+
}
|
|
125
|
+
const imagePart = attachment.content?.find((part) => part.type === "image");
|
|
126
|
+
return imagePart && "image" in imagePart ? imagePart.image : null;
|
|
127
|
+
}
|
|
128
|
+
function ImagePreviewLightbox({ src, alt, onClose, }) {
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
const handler = (e) => {
|
|
131
|
+
if (e.key === "Escape")
|
|
132
|
+
onClose();
|
|
133
|
+
};
|
|
134
|
+
document.addEventListener("keydown", handler);
|
|
135
|
+
document.body.style.overflow = "hidden";
|
|
136
|
+
return () => {
|
|
137
|
+
document.removeEventListener("keydown", handler);
|
|
138
|
+
document.body.style.overflow = "";
|
|
139
|
+
};
|
|
140
|
+
}, [onClose]);
|
|
141
|
+
return (_jsxs("div", { role: "dialog", "aria-label": "Image preview", onClick: onClose, className: "fixed inset-0 z-[300] flex items-center justify-center bg-black/80 p-6 cursor-zoom-out", children: [_jsx("img", { src: src, alt: alt, onClick: (e) => e.stopPropagation(), className: "max-h-full max-w-full object-contain rounded-md shadow-2xl cursor-default" }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close preview", className: "absolute end-4 top-4 flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border border-white/30 bg-black/40 text-white hover:bg-black/60", children: _jsx(IconX, { className: "h-4 w-4" }) })] }));
|
|
142
|
+
}
|
|
143
|
+
function AttachmentChip({ attachment, onRemove, }) {
|
|
144
|
+
const src = useMemo(() => getImageSrc(attachment), [attachment]);
|
|
145
|
+
const [previewOpen, setPreviewOpen] = useState(false);
|
|
146
|
+
useEffect(() => () => {
|
|
147
|
+
if (src?.startsWith("blob:"))
|
|
148
|
+
URL.revokeObjectURL(src);
|
|
149
|
+
}, [src]);
|
|
150
|
+
if (isPastedTextAttachmentName(attachment.name)) {
|
|
151
|
+
return _jsx(PastedTextChip, { attachment: attachment, onRemove: onRemove });
|
|
152
|
+
}
|
|
153
|
+
if (src) {
|
|
154
|
+
return (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: () => setPreviewOpen(true), "aria-label": `Preview ${attachment.name}`, className: "agent-composer-attachment-image group relative flex h-16 min-w-16 max-w-28 cursor-zoom-in items-center justify-center overflow-hidden rounded-lg border border-border/70 bg-muted/50", children: [_jsx("img", { src: src, alt: attachment.name, className: "max-h-full max-w-full object-contain p-1" }), _jsx("span", { role: "button", tabIndex: 0, onClick: (e) => {
|
|
155
|
+
e.stopPropagation();
|
|
156
|
+
onRemove(attachment.id);
|
|
157
|
+
}, onKeyDown: (e) => {
|
|
158
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
159
|
+
e.preventDefault();
|
|
160
|
+
e.stopPropagation();
|
|
161
|
+
onRemove(attachment.id);
|
|
162
|
+
}
|
|
163
|
+
}, "aria-label": `Remove ${attachment.name}`, className: "absolute end-1 top-1 flex h-5 w-5 cursor-pointer items-center justify-center rounded-full border border-border/60 bg-background/90 text-muted-foreground hover:text-foreground", children: _jsx(IconX, { className: "h-3 w-3" }) })] }), previewOpen ? (_jsx(ImagePreviewLightbox, { src: src, alt: attachment.name, onClose: () => setPreviewOpen(false) })) : null] }));
|
|
164
|
+
}
|
|
165
|
+
return (_jsxs("div", { className: "agent-composer-attachment-chip group relative inline-flex max-w-[200px] items-center gap-2 rounded-md border border-border/70 bg-muted/50 px-2 py-1.5 text-xs", children: [_jsx("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center rounded bg-background text-[9px] font-semibold uppercase text-muted-foreground", children: attachment.name.split(".").pop() || "file" }), _jsx("span", { className: "min-w-0 truncate font-medium", children: attachment.name }), _jsx("button", { type: "button", onClick: () => onRemove(attachment.id), "aria-label": `Remove ${attachment.name}`, className: "flex h-5 w-5 shrink-0 cursor-pointer items-center justify-center rounded text-muted-foreground hover:text-foreground", children: _jsx(IconX, { className: "h-3 w-3" }) })] }));
|
|
166
|
+
}
|
|
167
|
+
function PromptAttachmentStrip() {
|
|
168
|
+
const attachments = useComposer((state) => state.attachments);
|
|
169
|
+
const aui = useAui();
|
|
170
|
+
const handleRemove = useCallback((id) => {
|
|
171
|
+
void aui.composer().attachment({ id }).remove();
|
|
172
|
+
}, [aui]);
|
|
173
|
+
if (attachments.length === 0)
|
|
174
|
+
return null;
|
|
175
|
+
return (_jsx("div", { className: "agent-composer-attachment-strip flex flex-wrap gap-2 px-2 pt-2", children: attachments.map((attachment) => (_jsx(AttachmentChip, { attachment: attachment, onRemove: handleRemove }, attachment.id))) }));
|
|
176
|
+
}
|
|
177
|
+
function PromptComposerInner({ onSubmit, placeholder, disabled, autoFocus, className, style, rootClassName, rootStyle, draftScope, preserveDraftOnSubmit = false, showModelSelector = true, voiceEnabled = DEFAULT_VOICE_DICTATION_ENABLED, attachmentsEnabled = true, plusMenuMode, initialText, initialTextKey, modeControl, toolbarSlot, attachButton, actionButton, extraActionButton, layoutVariant, slashCommands, slashSkills, includeDefaultSlashCommands, includeDefaultSlashSkills, onSlashCommand, availableModels, modelListLoading, selectedModel, selectedEngine, selectedEffort, onModelChange, onEffortChange, modelStatusChecksEnabled, onTextChange, onConnectProvider, onConnectLocalRuntime, composerRef, }) {
|
|
178
|
+
const adapters = useComposerRuntimeAdapters();
|
|
179
|
+
const modelsAdapter = adapters.models;
|
|
180
|
+
const BuilderSetupCard = modelsAdapter.BuilderSetupCard;
|
|
181
|
+
const BuilderSetupContent = modelsAdapter.BuilderSetupContent;
|
|
182
|
+
const localRef = useRef(null);
|
|
183
|
+
const handleRef = composerRef ?? localRef;
|
|
184
|
+
const hostManagedModels = Boolean(availableModels && selectedModel && onModelChange);
|
|
185
|
+
const resolvedModelStatusChecksEnabled = modelStatusChecksEnabled ?? !hostManagedModels;
|
|
186
|
+
const models = modelsAdapter.useChatModels({
|
|
187
|
+
enabled: showModelSelector && resolvedModelStatusChecksEnabled,
|
|
188
|
+
});
|
|
189
|
+
const composerModel = showModelSelector
|
|
190
|
+
? (selectedModel ?? models.selectedModel)
|
|
191
|
+
: undefined;
|
|
192
|
+
const composerEngine = showModelSelector
|
|
193
|
+
? (selectedEngine ?? models.selectedEngine)
|
|
194
|
+
: undefined;
|
|
195
|
+
const composerEffort = showModelSelector
|
|
196
|
+
? (selectedEffort ?? models.selectedEffort)
|
|
197
|
+
: undefined;
|
|
198
|
+
const composerModelGroups = showModelSelector
|
|
199
|
+
? (availableModels ?? models.availableModels)
|
|
200
|
+
: undefined;
|
|
201
|
+
const composerModelListLoading = showModelSelector &&
|
|
202
|
+
(modelListLoading ??
|
|
203
|
+
(availableModels ? availableModels.length === 0 : models.isLoading));
|
|
204
|
+
const handleModelChange = showModelSelector
|
|
205
|
+
? (onModelChange ?? models.onModelChange)
|
|
206
|
+
: undefined;
|
|
207
|
+
const handleEffortChange = showModelSelector
|
|
208
|
+
? (onEffortChange ?? models.onEffortChange)
|
|
209
|
+
: undefined;
|
|
210
|
+
const agentEngineConfigured = modelsAdapter.useAgentEngineConfigured(resolvedModelStatusChecksEnabled);
|
|
211
|
+
const missingApiKey = agentEngineConfigured.missing;
|
|
212
|
+
const [missingKeyBouncePulse, setMissingKeyBouncePulse] = useState(0);
|
|
213
|
+
const bounceMissingKeySetup = useCallback(() => {
|
|
214
|
+
setMissingKeyBouncePulse((pulse) => pulse + 1);
|
|
215
|
+
if (typeof window !== "undefined") {
|
|
216
|
+
window.dispatchEvent(new Event("agent-chat:missing-api-key"));
|
|
217
|
+
}
|
|
218
|
+
}, []);
|
|
219
|
+
const handleBuilderConnected = useCallback(() => {
|
|
220
|
+
if (typeof window !== "undefined") {
|
|
221
|
+
window.dispatchEvent(new Event("agent-engine:configured-changed"));
|
|
222
|
+
}
|
|
223
|
+
}, []);
|
|
224
|
+
const ensureAgentEngineReadyForSubmit = useCallback(async () => {
|
|
225
|
+
if (!resolvedModelStatusChecksEnabled)
|
|
226
|
+
return true;
|
|
227
|
+
const state = agentEngineConfigured.state === "missing"
|
|
228
|
+
? "missing"
|
|
229
|
+
: await modelsAdapter.fetchAgentEngineConfiguredState(resolvedModelStatusChecksEnabled, {
|
|
230
|
+
timeoutMs: SUBMIT_ENGINE_STATUS_TIMEOUT_MS,
|
|
231
|
+
});
|
|
232
|
+
if (state !== "missing")
|
|
233
|
+
return true;
|
|
234
|
+
bounceMissingKeySetup();
|
|
235
|
+
return false;
|
|
236
|
+
}, [
|
|
237
|
+
agentEngineConfigured.state,
|
|
238
|
+
bounceMissingKeySetup,
|
|
239
|
+
modelsAdapter,
|
|
240
|
+
resolvedModelStatusChecksEnabled,
|
|
241
|
+
]);
|
|
242
|
+
useEffect(() => {
|
|
243
|
+
if (!autoFocus)
|
|
244
|
+
return;
|
|
245
|
+
const id = window.setTimeout(() => {
|
|
246
|
+
const target = typeof handleRef === "object" && handleRef && "current" in handleRef
|
|
247
|
+
? handleRef.current
|
|
248
|
+
: null;
|
|
249
|
+
target?.focus();
|
|
250
|
+
}, 50);
|
|
251
|
+
return () => window.clearTimeout(id);
|
|
252
|
+
}, [autoFocus, handleRef]);
|
|
253
|
+
const handleSubmit = useCallback(async (text, references, attachments, submitOptions) => {
|
|
254
|
+
// PromptComposer hosts (NewWorkspaceAppFlow, create-extension, create-deck,
|
|
255
|
+
// …) submit a single string prompt — they don't run the assistant-ui
|
|
256
|
+
// attachment send pipeline. TiptapComposer auto-converts large pastes
|
|
257
|
+
// into a "Pasted text" chip, which would otherwise disappear into an
|
|
258
|
+
// unprocessed File. Inline the chip body back into the prompt text so
|
|
259
|
+
// newlines and full content survive the round-trip.
|
|
260
|
+
const { text: finalText, files } = await buildPromptComposerSubmission({
|
|
261
|
+
text,
|
|
262
|
+
attachments,
|
|
263
|
+
});
|
|
264
|
+
onSubmit(finalText, files, references, {
|
|
265
|
+
intent: submitOptions?.intent ?? "immediate",
|
|
266
|
+
model: composerModel,
|
|
267
|
+
engine: composerEngine,
|
|
268
|
+
effort: composerEffort,
|
|
269
|
+
});
|
|
270
|
+
}, [composerEffort, composerEngine, composerModel, onSubmit]);
|
|
271
|
+
const useInlineMissingKeySetup = layoutVariant === "compact";
|
|
272
|
+
return (_jsxs(_Fragment, { children: [missingApiKey && !useInlineMissingKeySetup && BuilderSetupCard ? (_jsx(BuilderSetupCard, { onConnected: handleBuilderConnected, bouncePulse: missingKeyBouncePulse, fullWidth: true, layout: "sidebar" })) : null, missingApiKey && useInlineMissingKeySetup && BuilderSetupContent ? (_jsx("div", { className: "mb-2 rounded-md border border-border/80 bg-background/80 p-2.5 text-start shadow-sm", children: _jsx(BuilderSetupContent, { onConnected: handleBuilderConnected, layout: "sidebar" }) })) : null, _jsxs(AgentComposerFrame, { className: cn("text-start", missingApiKey && "cursor-pointer", className), rootClassName: rootClassName, style: style, rootStyle: rootStyle, layoutVariant: layoutVariant, onClick: missingApiKey ? bounceMissingKeySetup : undefined, children: [_jsx(PromptAttachmentStrip, {}), _jsx(TiptapComposer, { focusRef: handleRef, disabled: disabled || missingApiKey, placeholder: missingApiKey ? "Connect AI above to continue..." : placeholder, initialText: initialText, initialTextKey: initialTextKey, onSubmit: handleSubmit, onBeforeSubmit: ensureAgentEngineReadyForSubmit, clearOnSubmit: !preserveDraftOnSubmit, plusMenuMode: plusMenuMode ?? (attachmentsEnabled ? "upload-only" : "hidden"), attachButton: attachButton, modeControl: modeControl, toolbarSlot: toolbarSlot, actionButton: actionButton, extraActionButton: extraActionButton, layoutVariant: layoutVariant, slashCommands: slashCommands, slashSkills: slashSkills, includeDefaultSlashCommands: includeDefaultSlashCommands, includeDefaultSlashSkills: includeDefaultSlashSkills, onSlashCommand: onSlashCommand, voiceEnabled: voiceEnabled, onTextChange: onTextChange, draftScope: draftScope, selectedModel: composerModel, selectedEffort: composerEffort, availableModels: composerModelGroups, modelListLoading: composerModelListLoading, onModelChange: handleModelChange, onEffortChange: handleEffortChange, providerConnectStatusEnabled: resolvedModelStatusChecksEnabled, onConnectProvider: onConnectProvider, onConnectLocalRuntime: onConnectLocalRuntime })] })] }));
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Standalone composer that mirrors the agent sidebar's input experience —
|
|
276
|
+
* voice dictation, file upload, model selector, submit-on-Enter — for use in
|
|
277
|
+
* popovers and inline prompt forms (create tool, create deck, create dashboard,
|
|
278
|
+
* the Dispatch new-app flow, etc.).
|
|
279
|
+
*
|
|
280
|
+
* The host owns submission: when the user presses Enter or clicks submit,
|
|
281
|
+
* `onSubmit(text, files, references, options)` is called. PromptComposer runs
|
|
282
|
+
* its own minimal assistant-ui runtime so it can be dropped into any subtree
|
|
283
|
+
* without needing the outer chat to be mounted.
|
|
284
|
+
*/
|
|
285
|
+
export function PromptComposer(props) {
|
|
286
|
+
const StaleIndexBoundary = useComposerRuntimeAdapters().agentChat.StaleIndexBoundary;
|
|
287
|
+
const attachmentAdapter = useMemo(() => new CompositeAttachmentAdapter([
|
|
288
|
+
new RasterImageAttachmentAdapter(),
|
|
289
|
+
new BinaryDocumentAttachmentAdapter(),
|
|
290
|
+
new TextAttachmentAdapter(),
|
|
291
|
+
]), []);
|
|
292
|
+
const runtime = useLocalRuntime(NOOP_ADAPTER, {
|
|
293
|
+
adapters: { attachments: attachmentAdapter },
|
|
294
|
+
});
|
|
295
|
+
const resetKey = [
|
|
296
|
+
props.draftScope ?? "",
|
|
297
|
+
props.initialTextKey ?? "",
|
|
298
|
+
props.initialText ?? "",
|
|
299
|
+
].join(":");
|
|
300
|
+
return (_jsx(TooltipProvider, { delayDuration: 200, children: _jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx(ThreadPrimitive.Root, { className: "contents", style: { display: "contents" }, children: _jsx(StaleIndexBoundary, { resetKey: resetKey, componentName: "PromptComposer", children: _jsx(PromptComposerInner, { ...props }) }) }) }) }));
|
|
301
|
+
}
|
|
302
|
+
//# sourceMappingURL=PromptComposer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PromptComposer.js","sourceRoot":"","sources":["../../src/composer/PromptComposer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PromptComposer.spec.d.ts","sourceRoot":"","sources":["../../src/composer/PromptComposer.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { buildPromptComposerSubmission } from "./PromptComposer.js";
|
|
4
|
+
describe("buildPromptComposerSubmission", () => {
|
|
5
|
+
it("passes images through files only — never inlines base64 into prompt text", async () => {
|
|
6
|
+
// Images are passed to `files` for the host to process through the
|
|
7
|
+
// attachment pipeline. They must NOT be inlined as base64 in `text`
|
|
8
|
+
// (≈700K tokens per MB of image data).
|
|
9
|
+
const file = new File(["fake image"], "sketch.png", {
|
|
10
|
+
type: "image/png",
|
|
11
|
+
});
|
|
12
|
+
const result = await buildPromptComposerSubmission({
|
|
13
|
+
text: "",
|
|
14
|
+
attachments: [
|
|
15
|
+
{
|
|
16
|
+
id: "sketch.png",
|
|
17
|
+
name: "sketch.png",
|
|
18
|
+
type: "image",
|
|
19
|
+
file,
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
});
|
|
23
|
+
expect(result.files).toEqual([file]);
|
|
24
|
+
// text must not contain any base64 data or uploaded-image markup
|
|
25
|
+
expect(result.text).not.toContain("data:image");
|
|
26
|
+
expect(result.text).not.toContain("<uploaded-image");
|
|
27
|
+
});
|
|
28
|
+
it("escapes inline attachment metadata in standalone submissions", async () => {
|
|
29
|
+
const file = new File(["hello"], 'bad"name&.md', {
|
|
30
|
+
type: "text/markdown",
|
|
31
|
+
});
|
|
32
|
+
const result = await buildPromptComposerSubmission({
|
|
33
|
+
text: "Review this",
|
|
34
|
+
attachments: [
|
|
35
|
+
{
|
|
36
|
+
id: "bad",
|
|
37
|
+
name: file.name,
|
|
38
|
+
type: "document",
|
|
39
|
+
file,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
});
|
|
43
|
+
expect(result.text).toContain('name="bad"name&.md"');
|
|
44
|
+
expect(result.text).not.toContain('name="bad"name&.md"');
|
|
45
|
+
});
|
|
46
|
+
it("does not include image data in prompt text regardless of file size", async () => {
|
|
47
|
+
// Both small and large images stay in `files` only.
|
|
48
|
+
const smallFile = new File(["small image"], "small.png", {
|
|
49
|
+
type: "image/png",
|
|
50
|
+
});
|
|
51
|
+
const largeFile = new File([new Uint8Array(3 * 1024 * 1024)], "large.png", {
|
|
52
|
+
type: "image/png",
|
|
53
|
+
});
|
|
54
|
+
for (const file of [smallFile, largeFile]) {
|
|
55
|
+
const result = await buildPromptComposerSubmission({
|
|
56
|
+
text: "",
|
|
57
|
+
attachments: [{ id: file.name, name: file.name, type: "image", file }],
|
|
58
|
+
});
|
|
59
|
+
expect(result.files).toEqual([file]);
|
|
60
|
+
expect(result.text).not.toContain("data:image");
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=PromptComposer.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PromptComposer.spec.js","sourceRoot":"","sources":["../../src/composer/PromptComposer.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { type RealtimeVoiceAudioLevelStore } from "./realtime-voice-audio-level.js";
|
|
2
|
+
export type RealtimeVoiceModeState = "connecting" | "listening" | "speaking" | "working" | "error" | "ending";
|
|
3
|
+
/**
|
|
4
|
+
* User-visible copy stays outside the shared component so host catalogs remain
|
|
5
|
+
* the source of truth. Callers should provide these values through `useT()`.
|
|
6
|
+
*/
|
|
7
|
+
export interface RealtimeVoiceModeCopy {
|
|
8
|
+
entryButtonLabel: string;
|
|
9
|
+
promptTitle: string;
|
|
10
|
+
promptDescription: string;
|
|
11
|
+
setupTitle: string;
|
|
12
|
+
setupDescription: string;
|
|
13
|
+
connectBuilder: string;
|
|
14
|
+
useOpenAiKey: string;
|
|
15
|
+
startWithOpenAiKey: string;
|
|
16
|
+
startVoiceMode: string;
|
|
17
|
+
keepDictating: string;
|
|
18
|
+
showChat: string;
|
|
19
|
+
hideChat: string;
|
|
20
|
+
endVoiceMode: string;
|
|
21
|
+
voiceSettings: string;
|
|
22
|
+
settings: {
|
|
23
|
+
microphone: string;
|
|
24
|
+
defaultMicrophone: string;
|
|
25
|
+
microphoneSwitchFailed: string;
|
|
26
|
+
language: string;
|
|
27
|
+
autoLanguage: string;
|
|
28
|
+
languages: Record<Exclude<import("./useRealtimeVoiceMode.js").RealtimeVoiceLanguage, "auto">, string>;
|
|
29
|
+
intelligence: string;
|
|
30
|
+
intelligenceLevels: Record<import("./useRealtimeVoiceMode.js").RealtimeVoiceIntelligence, string>;
|
|
31
|
+
voiceStyle: string;
|
|
32
|
+
voiceChangePending: string;
|
|
33
|
+
voiceDescriptions: Record<import("./useRealtimeVoiceMode.js").RealtimeVoice, string>;
|
|
34
|
+
};
|
|
35
|
+
status: Record<RealtimeVoiceModeState, string>;
|
|
36
|
+
errors: {
|
|
37
|
+
unsupported: string;
|
|
38
|
+
responseFailed: string;
|
|
39
|
+
sessionFailed: string;
|
|
40
|
+
channelDisconnected: string;
|
|
41
|
+
connectionTimedOut?: string;
|
|
42
|
+
connectionFailed: string;
|
|
43
|
+
offerFailed: string;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export interface RealtimeVoiceModeEntryProps {
|
|
47
|
+
copy: RealtimeVoiceModeCopy;
|
|
48
|
+
disabled?: boolean;
|
|
49
|
+
providerStatusPending?: boolean;
|
|
50
|
+
open?: boolean;
|
|
51
|
+
onOpenChange?: (open: boolean) => void;
|
|
52
|
+
onStartVoiceMode: () => void;
|
|
53
|
+
onKeepDictating: () => void;
|
|
54
|
+
setupRequired?: boolean;
|
|
55
|
+
openAiConfigured?: boolean;
|
|
56
|
+
connectingBuilder?: boolean;
|
|
57
|
+
onConnectBuilder?: () => void;
|
|
58
|
+
onUseOpenAiKey?: () => void;
|
|
59
|
+
className?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Composer mic entry point for apps that support a full-duplex voice session.
|
|
63
|
+
* The first click offers voice mode without silently changing the existing
|
|
64
|
+
* editable-dictation behavior.
|
|
65
|
+
*/
|
|
66
|
+
export declare function RealtimeVoiceModeEntry({ copy, disabled, providerStatusPending, open: controlledOpen, onOpenChange, onStartVoiceMode, onKeepDictating, setupRequired, openAiConfigured, connectingBuilder, onConnectBuilder, onUseOpenAiKey, className, }: RealtimeVoiceModeEntryProps): import("react").JSX.Element;
|
|
67
|
+
export interface RealtimeVoiceModeDockProps {
|
|
68
|
+
state: RealtimeVoiceModeState;
|
|
69
|
+
copy: RealtimeVoiceModeCopy;
|
|
70
|
+
chatVisible: boolean;
|
|
71
|
+
audioLevels?: RealtimeVoiceAudioLevelStore;
|
|
72
|
+
onToggleChat: () => void;
|
|
73
|
+
onEndVoiceMode: () => void;
|
|
74
|
+
settings?: RealtimeVoiceModeInlineSettings;
|
|
75
|
+
errorMessage?: string | null;
|
|
76
|
+
className?: string;
|
|
77
|
+
}
|
|
78
|
+
export interface RealtimeVoiceModeSettingOption {
|
|
79
|
+
value: string;
|
|
80
|
+
label: string;
|
|
81
|
+
description?: string;
|
|
82
|
+
}
|
|
83
|
+
export interface RealtimeVoiceModeSelectSetting {
|
|
84
|
+
label: string;
|
|
85
|
+
value: string;
|
|
86
|
+
options: readonly RealtimeVoiceModeSettingOption[];
|
|
87
|
+
onValueChange: (value: string) => void;
|
|
88
|
+
disabled?: boolean;
|
|
89
|
+
}
|
|
90
|
+
export interface RealtimeVoiceModeInlineSettings {
|
|
91
|
+
dialogLabel: string;
|
|
92
|
+
appliesNextConversationNote?: string;
|
|
93
|
+
microphoneError?: string;
|
|
94
|
+
microphone: RealtimeVoiceModeSelectSetting;
|
|
95
|
+
language: RealtimeVoiceModeSelectSetting;
|
|
96
|
+
intelligence: RealtimeVoiceModeSelectSetting;
|
|
97
|
+
voiceStyle: RealtimeVoiceModeSelectSetting;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Persistent voice-session control. Toggling the main orb only changes chat
|
|
101
|
+
* visibility; ending the realtime session is intentionally a separate action.
|
|
102
|
+
*/
|
|
103
|
+
export declare function RealtimeVoiceModeDock({ state, copy, chatVisible, audioLevels, onToggleChat, onEndVoiceMode, settings, errorMessage, className, }: RealtimeVoiceModeDockProps): import("react").JSX.Element;
|
|
104
|
+
//# sourceMappingURL=RealtimeVoiceMode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RealtimeVoiceMode.d.ts","sourceRoot":"","sources":["../../src/composer/RealtimeVoiceMode.tsx"],"names":[],"mappings":"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"}
|