diff --git a/src/api/types.ts b/src/api/types.ts index 6ec5f14..c0aff93 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -278,6 +278,25 @@ export type AiChatEvent = ({ conversation_id?: string } +/** + * 多模态消息内容片(F-260614-05 Phase 2b 前端类型,对齐后端 df-ai-core ContentPart)。 + * + * 后端 serde:`#[serde(tag = "type", rename_all = "snake_case")]`, + * 前端 discriminator 用字面量 `type` 字段('text' | 'image'),与后端 wire 格式严格对齐。 + * Image 片:url / base64 二选一(base64 非空时 url 忽略),media_type 仅 base64 模式必填。 + */ +export type ContentPart = + | { type: 'text'; text: string } + | { + type: 'image' + url?: string | null + base64?: string | null + /** base64 模式必填(image/png|jpeg|webp|gif);url 模式可空 */ + media_type?: string | null + /** 可选 alt(vision 模型/降级文本时用) */ + alt?: string | null + } + /** AI 消息(前端渲染用,isError 标记错误消息用于差异化样式) */ export interface AiMessage { id: string @@ -287,6 +306,13 @@ export interface AiMessage { toolCalls?: AiToolCallInfo[] /** 生成该消息的 model(仅 assistant 消息,历史消息从 DB 读) */ model?: string + /** + * 多模态内容片(F-260614-05 Phase 2b)。 + * undefined/空=纯文本消息(content 即全部载荷);非空含 Image 片=多模态消息, + * 用户气泡内渲染 (base64 data URI 或 url)。仅 user 消息有(parts 来自粘贴/拖拽输入)。 + * 历史消息从 DB JSON 反序列化时透传(useAiConversations switchConversation)。 + */ + parts?: ContentPart[] timestamp: number } diff --git a/src/components/AiChat.vue b/src/components/AiChat.vue index b7c512e..0c75145 100644 --- a/src/components/AiChat.vue +++ b/src/components/AiChat.vue @@ -410,6 +410,20 @@
{{ item.msg.content }} + +
+ +
+
+ + +
+
@@ -714,8 +744,8 @@