From 89a4e192e5fc3c04a9e4c82b6ed7b0128eae1d85 Mon Sep 17 00:00:00 2001 From: yu <2799341137@qq.com> Date: Thu, 6 Aug 2026 15:25:34 +0800 Subject: [PATCH] feat(agent-ui): add inline skill and canvas references --- .../agent/agent-canvas-reference-preview.tsx | 36 ++ .../components/agent/agent-chat-composer.tsx | 43 +- .../agent/agent-chat-inline-tokens.ts | 48 ++ .../components/agent/agent-chat-message.tsx | 58 ++- .../agent/agent-chat-prompt-input.tsx | 433 ++++++++++++++++++ web/src/components/agent/agent-chat.tsx | 4 +- .../agent/agent-event-formatters.ts | 54 +-- .../components/agent/agent-skill-picker.tsx | 87 ---- .../components/agent/local-agent-panel.tsx | 124 ++--- web/src/i18n/locales/en-US.ts | 6 +- web/src/i18n/locales/zh-CN.ts | 6 +- .../lib/canvas/canvas-resource-references.ts | 33 +- web/src/services/api/canvas-agent.ts | 8 + web/src/stores/use-agent-skill-store.ts | 42 +- web/src/stores/use-agent-store.ts | 8 +- 15 files changed, 758 insertions(+), 232 deletions(-) create mode 100644 web/src/components/agent/agent-canvas-reference-preview.tsx create mode 100644 web/src/components/agent/agent-chat-inline-tokens.ts create mode 100644 web/src/components/agent/agent-chat-prompt-input.tsx delete mode 100644 web/src/components/agent/agent-skill-picker.tsx 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 ? {reference.title} : null} + {reference.kind === "video" && previewUrl ?
+ ); +} + +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} -