Initial TrueGrowth source import
This commit is contained in:
360
specs/003-chat-drawer/contracts/chat-api.ts
Normal file
360
specs/003-chat-drawer/contracts/chat-api.ts
Normal file
@@ -0,0 +1,360 @@
|
||||
/**
|
||||
* Chat Drawer API Contracts
|
||||
*
|
||||
* This file defines the TypeScript interfaces for the Chat Drawer feature.
|
||||
* These interfaces serve as contracts between components, services, and storage layers.
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// Enums
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 消息状态枚举
|
||||
*/
|
||||
export enum MessageStatus {
|
||||
/** 发送中 */
|
||||
SENDING = 'sending',
|
||||
/** AI正在生成中 */
|
||||
STREAMING = 'streaming',
|
||||
/** 发送成功 */
|
||||
SUCCESS = 'success',
|
||||
/** 发送失败 */
|
||||
FAILED = 'failed',
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息角色枚举
|
||||
*/
|
||||
export enum MessageRole {
|
||||
/** 用户消息 */
|
||||
USER = 'user',
|
||||
/** AI助手消息 */
|
||||
ASSISTANT = 'assistant',
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Entities
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 附件接口
|
||||
*/
|
||||
export interface Attachment {
|
||||
/** 附件唯一标识 (UUID v4) */
|
||||
id: string;
|
||||
/** 文件名 */
|
||||
name: string;
|
||||
/** MIME类型 (e.g., 'image/png', 'application/pdf') */
|
||||
type: string;
|
||||
/** 文件大小 (bytes) */
|
||||
size: number;
|
||||
/** 文件数据 (Base64 或 Blob URL) */
|
||||
data: string;
|
||||
/** 是否为Blob URL (用于清理) */
|
||||
isBlob: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对话消息接口
|
||||
*/
|
||||
export interface ChatMessage {
|
||||
/** 消息唯一标识 (UUID v4) */
|
||||
id: string;
|
||||
/** 所属会话ID */
|
||||
sessionId: string;
|
||||
/** 消息角色 */
|
||||
role: MessageRole;
|
||||
/** 消息内容 (Markdown格式) */
|
||||
content: string;
|
||||
/** 发送时间戳 (Unix milliseconds) */
|
||||
timestamp: number;
|
||||
/** 消息状态 */
|
||||
status: MessageStatus;
|
||||
/** 附件列表 (可选) */
|
||||
attachments?: Attachment[];
|
||||
/** 错误信息 (可选) */
|
||||
error?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对话会话接口
|
||||
*/
|
||||
export interface ChatSession {
|
||||
/** 会话唯一标识 (UUID v4) */
|
||||
id: string;
|
||||
/** 会话标题 (从首条消息自动生成,max 30字符) */
|
||||
title: string;
|
||||
/** 创建时间戳 (Unix milliseconds) */
|
||||
createdAt: number;
|
||||
/** 最后更新时间戳 (Unix milliseconds) */
|
||||
updatedAt: number;
|
||||
/** 消息数量 */
|
||||
messageCount: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 抽屉状态接口
|
||||
*/
|
||||
export interface DrawerState {
|
||||
/** 是否展开 */
|
||||
isOpen: boolean;
|
||||
/** 当前宽度 (px) */
|
||||
width: number;
|
||||
/** 当前活跃会话ID */
|
||||
activeSessionId: string | null;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Service Interfaces
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 发送消息请求
|
||||
*/
|
||||
export interface SendMessageRequest {
|
||||
/** 会话ID */
|
||||
sessionId: string;
|
||||
/** 消息内容 */
|
||||
content: string;
|
||||
/** 附件列表 (可选) */
|
||||
attachments?: File[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息响应
|
||||
*/
|
||||
export interface SendMessageResponse {
|
||||
/** 用户消息 */
|
||||
userMessage: ChatMessage;
|
||||
/** AI响应消息 (初始状态为 streaming) */
|
||||
assistantMessage: ChatMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 流式响应事件
|
||||
*/
|
||||
export interface StreamEvent {
|
||||
/** 事件类型 */
|
||||
type: 'content' | 'done' | 'error';
|
||||
/** 增量内容 (type='content' 时) */
|
||||
content?: string;
|
||||
/** 错误信息 (type='error' 时) */
|
||||
error?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 聊天服务接口
|
||||
*/
|
||||
export interface IChatService {
|
||||
/**
|
||||
* 发送消息并获取流式响应
|
||||
* @param request 发送消息请求
|
||||
* @param onStream 流式回调
|
||||
* @param signal 取消信号
|
||||
*/
|
||||
sendMessage(
|
||||
request: SendMessageRequest,
|
||||
onStream: (event: StreamEvent) => void,
|
||||
signal?: AbortSignal
|
||||
): Promise<ChatMessage>;
|
||||
|
||||
/**
|
||||
* 停止当前生成
|
||||
*/
|
||||
stopGeneration(): void;
|
||||
|
||||
/**
|
||||
* 重新生成最后一条AI回复
|
||||
* @param sessionId 会话ID
|
||||
* @param onStream 流式回调
|
||||
*/
|
||||
regenerateLastResponse(
|
||||
sessionId: string,
|
||||
onStream: (event: StreamEvent) => void
|
||||
): Promise<ChatMessage>;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Storage Interfaces
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 聊天存储服务接口
|
||||
*/
|
||||
export interface IChatStorageService {
|
||||
// Session operations
|
||||
createSession(): Promise<ChatSession>;
|
||||
getSession(id: string): Promise<ChatSession | null>;
|
||||
getAllSessions(): Promise<ChatSession[]>;
|
||||
updateSession(id: string, updates: Partial<ChatSession>): Promise<void>;
|
||||
deleteSession(id: string): Promise<void>;
|
||||
|
||||
// Message operations
|
||||
addMessage(message: ChatMessage): Promise<void>;
|
||||
getMessages(sessionId: string): Promise<ChatMessage[]>;
|
||||
updateMessage(id: string, updates: Partial<ChatMessage>): Promise<void>;
|
||||
deleteMessage(id: string): Promise<void>;
|
||||
|
||||
// Drawer state operations
|
||||
getDrawerState(): DrawerState;
|
||||
setDrawerState(state: Partial<DrawerState>): void;
|
||||
|
||||
// Cleanup operations
|
||||
clearAllData(): Promise<void>;
|
||||
pruneOldSessions(keepCount: number): Promise<void>;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Component Props Interfaces
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* ChatDrawer 组件 Props
|
||||
*/
|
||||
export interface ChatDrawerProps {
|
||||
/** 初始是否展开 */
|
||||
defaultOpen?: boolean;
|
||||
/** 展开状态变化回调 */
|
||||
onOpenChange?: (isOpen: boolean) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* MessageList 组件 Props
|
||||
*/
|
||||
export interface MessageListProps {
|
||||
/** 消息列表 */
|
||||
messages: ChatMessage[];
|
||||
/** 是否正在加载 */
|
||||
isLoading?: boolean;
|
||||
/** 复制消息回调 */
|
||||
onCopyMessage?: (message: ChatMessage) => void;
|
||||
/** 重新生成回调 */
|
||||
onRegenerate?: (message: ChatMessage) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* MessageInput 组件 Props
|
||||
*/
|
||||
export interface MessageInputProps {
|
||||
/** 是否禁用 */
|
||||
disabled?: boolean;
|
||||
/** 是否正在生成 */
|
||||
isGenerating?: boolean;
|
||||
/** 发送消息回调 */
|
||||
onSend: (content: string, attachments?: File[]) => void;
|
||||
/** 停止生成回调 */
|
||||
onStop?: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* SessionList 组件 Props
|
||||
*/
|
||||
export interface SessionListProps {
|
||||
/** 会话列表 */
|
||||
sessions: ChatSession[];
|
||||
/** 当前活跃会话ID */
|
||||
activeSessionId: string | null;
|
||||
/** 切换会话回调 */
|
||||
onSelectSession: (sessionId: string) => void;
|
||||
/** 新建会话回调 */
|
||||
onNewSession: () => void;
|
||||
/** 删除会话回调 */
|
||||
onDeleteSession: (sessionId: string) => void;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Hook Return Types
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* useChatSessions Hook 返回类型
|
||||
*/
|
||||
export interface UseChatSessionsReturn {
|
||||
sessions: ChatSession[];
|
||||
activeSession: ChatSession | null;
|
||||
isLoading: boolean;
|
||||
createSession: () => Promise<ChatSession>;
|
||||
selectSession: (sessionId: string) => void;
|
||||
deleteSession: (sessionId: string) => Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* useChatMessages Hook 返回类型
|
||||
*/
|
||||
export interface UseChatMessagesReturn {
|
||||
messages: ChatMessage[];
|
||||
isLoading: boolean;
|
||||
isGenerating: boolean;
|
||||
sendMessage: (content: string, attachments?: File[]) => Promise<void>;
|
||||
stopGeneration: () => void;
|
||||
regenerate: (messageId: string) => Promise<void>;
|
||||
copyMessage: (messageId: string) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* useChatStream Hook 返回类型
|
||||
*/
|
||||
export interface UseChatStreamReturn {
|
||||
streamContent: string;
|
||||
isStreaming: boolean;
|
||||
startStream: (
|
||||
request: SendMessageRequest,
|
||||
onComplete: (content: string) => void
|
||||
) => void;
|
||||
stopStream: () => void;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Constants
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* 聊天相关常量
|
||||
*/
|
||||
export const CHAT_CONSTANTS = {
|
||||
/** 最大会话数量 */
|
||||
MAX_SESSIONS: 50,
|
||||
/** 每会话最大消息数 */
|
||||
MAX_MESSAGES_PER_SESSION: 100,
|
||||
/** 会话标题最大长度 */
|
||||
MAX_TITLE_LENGTH: 30,
|
||||
/** 用户消息最大长度 */
|
||||
MAX_USER_MESSAGE_LENGTH: 10000,
|
||||
/** 单个附件最大大小 (10MB) */
|
||||
MAX_ATTACHMENT_SIZE: 10 * 1024 * 1024,
|
||||
/** 单条消息最大附件数 */
|
||||
MAX_ATTACHMENTS_PER_MESSAGE: 5,
|
||||
/** 单条消息最大附件总大小 (20MB) */
|
||||
MAX_TOTAL_ATTACHMENTS_SIZE: 20 * 1024 * 1024,
|
||||
/** 抽屉最小宽度 */
|
||||
DRAWER_MIN_WIDTH: 320,
|
||||
/** 抽屉最大宽度 */
|
||||
DRAWER_MAX_WIDTH: 500,
|
||||
/** 抽屉默认宽度比例 */
|
||||
DRAWER_DEFAULT_WIDTH_RATIO: 0.3,
|
||||
/** 存储防抖延迟 (ms) */
|
||||
STORAGE_DEBOUNCE_DELAY: 500,
|
||||
/** AI响应超时时间 (ms) */
|
||||
AI_RESPONSE_TIMEOUT: 60000,
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* 支持的附件MIME类型
|
||||
*/
|
||||
export const SUPPORTED_ATTACHMENT_TYPES = [
|
||||
// 图片
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'image/gif',
|
||||
'image/webp',
|
||||
// 文档
|
||||
'application/pdf',
|
||||
'text/plain',
|
||||
'text/markdown',
|
||||
// 其他
|
||||
'application/json',
|
||||
'text/csv',
|
||||
] as const;
|
||||
|
||||
export type SupportedAttachmentType = typeof SUPPORTED_ATTACHMENT_TYPES[number];
|
||||
Reference in New Issue
Block a user