diff --git a/web/src/components/agent/agent-canvas-reference-preview.tsx b/web/src/components/agent/agent-canvas-reference-preview.tsx
new file mode 100644
index 0000000..ceebd80
--- /dev/null
+++ b/web/src/components/agent/agent-canvas-reference-preview.tsx
@@ -0,0 +1,36 @@
+import { FileText, Image as ImageIcon, Music2, Video } from "lucide-react";
+import { useTranslation } from "react-i18next";
+
+import i18n from "@/i18n";
+import { canvasThemes } from "@/lib/canvas-theme";
+import type { AgentCanvasReference } from "@/stores/use-agent-store";
+
+export function AgentCanvasReferencePreview({ reference, previewUrl, previewText, theme }: { reference: AgentCanvasReference; previewUrl?: string; previewText?: string; theme: (typeof canvasThemes)[keyof typeof canvasThemes] }) {
+ const { t } = useTranslation();
+ const Icon = canvasReferenceIcon(reference.kind);
+ return (
+
+
+
+ {reference.title}
+
+ {reference.kind === "image" && previewUrl ?

: null}
+ {reference.kind === "video" && previewUrl ?
: null}
+ {reference.kind === "audio" && previewUrl ?
: null}
+ {reference.kind === "text" && previewText ? (
+
+ {previewText}
+
+ ) : null}
+ {!previewUrl && !(reference.kind === "text" && previewText) ?
{t("agent.composer.mentions.previewUnavailable")}
: null}
+
+ );
+}
+
+export function canvasReferenceIcon(kind: AgentCanvasReference["kind"]) {
+ return kind === "audio" ? Music2 : kind === "video" ? Video : kind === "image" ? ImageIcon : FileText;
+}
+
+export function canvasReferenceKindLabel(kind: AgentCanvasReference["kind"]) {
+ return i18n.t(`agent.composer.mentions.kind.${kind}`);
+}
diff --git a/web/src/components/agent/agent-chat-composer.tsx b/web/src/components/agent/agent-chat-composer.tsx
index 73bd554..66f1037 100644
--- a/web/src/components/agent/agent-chat-composer.tsx
+++ b/web/src/components/agent/agent-chat-composer.tsx
@@ -5,11 +5,9 @@ import { useTranslation } from "react-i18next";
import { Select, SelectContent, SelectItem, SelectTrigger } from "@/components/ui/select";
import { canvasThemes } from "@/lib/canvas-theme";
-import { isPlainEnterKey } from "@/lib/keyboard-event";
-import { useAgentSkillStore } from "@/stores/use-agent-skill-store";
-import type { AgentModel, AgentPermissionMode, AgentReasoningEffort } from "@/stores/use-agent-store";
+import { useAgentStore, type AgentModel, type AgentPermissionMode, type AgentReasoningEffort } from "@/stores/use-agent-store";
import type { AgentChatAttachment } from "./agent-chat-message";
-import { AgentSkillPicker } from "./agent-skill-picker";
+import { AgentChatPromptInput } from "./agent-chat-prompt-input";
export function AgentChatComposer({
prompt,
@@ -58,9 +56,8 @@ export function AgentChatComposer({
}) {
const { t } = useTranslation();
const fileInputRef = useRef(null);
- const selectedSkill = useAgentSkillStore((state) => state.selectedSkill);
- const clearSkillSelection = useAgentSkillStore((state) => state.clearSelection);
- const canSubmit = !disabled && !sending && Boolean(prompt.trim() || attachments.length);
+ const canvasReferences = useAgentStore((state) => state.canvasReferences);
+ const canSubmit = !disabled && !sending && Boolean(prompt.trim() || attachments.length || canvasReferences.length);
return (
event.stopPropagation()}>
@@ -78,36 +75,7 @@ export function AgentChatComposer({
))}
) : null}
- {selectedSkill ? (
-
-
- {selectedSkill.interface?.displayName || selectedSkill.name}
-
-
-
- ) : null}
-