import type { ChatSession } from '@agent-server/chat-ui' import type { AgentClient } from '@agent-server/client' import type { FileDto } from '@agent-server/shared' import { computed, ref, watch, type Ref, type ShallowRef } from 'vue' /** 本会话的上传与产出文件;收到 file.changed 或上传完成(user.message 带附件)时刷新 */ export function useSessionFiles(client: AgentClient, sessionId: Ref, chat: ShallowRef) { const files = ref([]) const loading = ref(false) let timer: ReturnType | undefined let token = 0 async function refresh() { const id = sessionId.value const my = ++token if (!id) { files.value = [] return } loading.value = true try { const list = await client.sessions.files(id) if (my === token) files.value = list } catch { if (my === token) files.value = [] } finally { if (my === token) loading.value = false } } function refreshSoon() { clearTimeout(timer) timer = setTimeout(() => void refresh(), 500) } watch(sessionId, () => void refresh(), { immediate: true }) // 文件卡片数量或最新文件事件变化时刷新(含历史加载完成) watch( () => { const items = chat.value?.state.items ?? [] let sig = '' for (const i of items) { if (i.kind === 'file') sig += `${i.fileId}:${i.seq};` else if (i.kind === 'user' && i.attachments.length) sig += `u${i.seq};` } return sig }, () => refreshSoon(), ) const uploads = computed(() => sortNewest(files.value.filter(f => f.origin === 'upload'))) const outputs = computed(() => sortNewest(files.value.filter(f => f.origin === 'agent'))) return { files, uploads, outputs, loading, refresh } } function sortNewest(list: FileDto[]) { return [...list].sort((a, b) => Date.parse(b.updatedAt) - Date.parse(a.updatedAt)) }