import { defineStore } from 'pinia'; export type ModelKey = string; export interface ModelOption { key: ModelKey; label: string; description: string; visible?: boolean; multimodal?: string; supportsImage?: boolean; supportsVideo?: boolean; contextWindow?: number | null; maxOutputTokens?: number | null; fastOnly: boolean; supportsThinking: boolean; deepOnly?: boolean; } interface ModelState { currentModelKey: ModelKey; models: ModelOption[]; } export const useModelStore = defineStore('model', { state: (): ModelState => ({ currentModelKey: 'kimi-k2.5', models: [ { key: 'kimi-k2.5', label: 'Kimi-k2.5', description: '新版 Kimi,支持图文 & 思考开关', multimodal: 'image,video', supportsImage: true, supportsVideo: true, fastOnly: false, supportsThinking: true }, { key: 'kimi', label: 'Kimi-k2', description: '综合能力较强', fastOnly: false, supportsThinking: true }, { key: 'deepseek', label: 'Deepseek-V3.2', description: '数学能力较强', fastOnly: false, supportsThinking: true }, { key: 'qwen3-vl-plus', label: 'Qwen3.5', description: '图文视频多模态 + 深度思考', multimodal: 'image,video', supportsImage: true, supportsVideo: true, fastOnly: false, supportsThinking: true }, { key: 'minimax-m2.5', label: 'MiniMax-M2.5', description: '仅深度思考,超长上下文', fastOnly: false, supportsThinking: true, deepOnly: true } ] }), getters: { currentModel(state): ModelOption { return state.models.find((m) => m.key === state.currentModelKey) || state.models[0]; } }, actions: { setModels(models: ModelOption[]) { if (!Array.isArray(models) || !models.length) return; this.models = models; const exists = this.models.some((m) => m.key === this.currentModelKey); if (!exists && this.models[0]) { this.currentModelKey = this.models[0].key; } }, setModel(key: ModelKey) { if (this.currentModelKey === key) return; const exists = this.models.some((m) => m.key === key); if (exists) { this.currentModelKey = key; } }, async fetchModels() { const resp = await fetch('/api/v1/models', { cache: 'no-store' }); const data = await resp.json(); if (!resp.ok || !data?.success || !Array.isArray(data.items)) { throw new Error(data?.error || '加载模型列表失败'); } const mapped: ModelOption[] = data.items .filter((item: any) => item && item.model_key) .map((item: any) => { const multimodal = String(item.multimodal || 'none'); const supportsImage = multimodal === 'image' || multimodal === 'image,video'; const supportsVideo = multimodal === 'video' || multimodal === 'image,video'; return { key: String(item.model_key), label: String(item.name || item.model_key), description: String(item.description || ''), visible: item.visible !== false, multimodal, supportsImage, supportsVideo, contextWindow: typeof item.context_window === 'number' ? item.context_window : null, maxOutputTokens: typeof item.max_output_tokens === 'number' ? item.max_output_tokens : null, fastOnly: !!item.fast_only, supportsThinking: !!item.supports_thinking, deepOnly: !!item.deep_only }; }); if (mapped.length) { this.setModels(mapped); } } } });