78 lines
3.1 KiB
TypeScript
78 lines
3.1 KiB
TypeScript
import { defineStore } from 'pinia';
|
|
import axios from 'axios';
|
|
import { useAuthStore } from './authStore';
|
|
|
|
export interface ConversationSummary { _id: string; title: string; modelId: string; updatedAt: string; }
|
|
export interface ConversationMessage { role: 'user' | 'assistant' | 'system'; content: string; transient?: boolean }
|
|
|
|
interface ConversationState {
|
|
list: ConversationSummary[];
|
|
loading: boolean;
|
|
error: string | null;
|
|
currentId: string | null;
|
|
messages: ConversationMessage[];
|
|
}
|
|
|
|
export const useConversationStore = defineStore('conversation', {
|
|
state: (): ConversationState => ({ list: [], loading: false, error: null, currentId: null, messages: [] }),
|
|
actions: {
|
|
async fetchList() {
|
|
const auth = useAuthStore();
|
|
if (!auth.token) { this.list = []; return; }
|
|
this.loading = true; this.error = null;
|
|
try {
|
|
const { data } = await axios.get('/api/conversations', { headers: { Authorization: 'Bearer ' + auth.token } });
|
|
this.list = data;
|
|
} catch (e:any) { this.error = e.response?.data?.error || e.message; }
|
|
finally { this.loading = false; }
|
|
},
|
|
async loadConversation(id: string) {
|
|
const auth = useAuthStore();
|
|
if (!auth.token) return;
|
|
this.loading = true; this.error = null;
|
|
try {
|
|
const { data } = await axios.get('/api/conversations/' + id, { headers: { Authorization: 'Bearer ' + auth.token } });
|
|
this.currentId = id;
|
|
this.messages = data.messages || [];
|
|
} catch (e:any) { this.error = e.response?.data?.error || e.message; }
|
|
finally { this.loading = false; }
|
|
},
|
|
resetCurrent() { this.currentId = null; this.messages = []; },
|
|
createNewConversation(notify?: string) {
|
|
this.currentId = null;
|
|
this.messages = [];
|
|
if (notify) {
|
|
this.messages.push({ role: 'system', content: notify, transient: true });
|
|
}
|
|
},
|
|
async createConversation(modelId: string, messages: any[] = [], title?: string) {
|
|
const auth = useAuthStore();
|
|
if (!auth.token) return null;
|
|
try {
|
|
const { data } = await axios.post('/api/conversations', { modelId, messages, title }, { headers: { Authorization: 'Bearer ' + auth.token } });
|
|
// prepend to list
|
|
this.list.unshift(data);
|
|
this.currentId = data._id;
|
|
return data;
|
|
} catch (e:any) { this.error = e.response?.data?.error || e.message; return null; }
|
|
},
|
|
pushMessage(m: ConversationMessage) { this.messages.push(m); },
|
|
patchLastAssistant(content: string) {
|
|
for (let i = this.messages.length - 1; i >=0; i--) {
|
|
const msg = this.messages[i];
|
|
if (msg.role === 'assistant') { msg.content = content; return; }
|
|
}
|
|
}
|
|
,
|
|
async deleteConversation(id: string) {
|
|
const auth = useAuthStore();
|
|
if (!auth.token) return;
|
|
try {
|
|
await axios.delete('/api/conversations/' + id, { headers: { Authorization: 'Bearer ' + auth.token } });
|
|
this.list = this.list.filter(l => l._id !== id);
|
|
if (this.currentId === id) this.resetCurrent();
|
|
} catch (e:any) { this.error = e.response?.data?.error || e.message; }
|
|
}
|
|
}
|
|
});
|