import { create } from 'zustand'; import { hostApiFetch } from '@/lib/host-api'; import type { ChannelType } from '@/types/channel'; import type { AgentSummary, AgentsSnapshot } from '@/types/agent'; interface AgentsState { agents: AgentSummary[]; defaultAgentId: string; defaultModelRef: string | null; configuredChannelTypes: string[]; channelOwners: Record; channelAccountOwners: Record; loading: boolean; error: string | null; fetchAgents: () => Promise; createAgent: (name: string, options?: { inheritWorkspace?: boolean }) => Promise; updateAgent: (agentId: string, name: string) => Promise; updateAgentModel: (agentId: string, modelRef: string | null) => Promise; updateDefaultModel: (modelRef: string | null) => Promise; deleteAgent: (agentId: string) => Promise; assignChannel: (agentId: string, channelType: ChannelType) => Promise; removeChannel: (agentId: string, channelType: ChannelType) => Promise; clearError: () => void; } function applySnapshot(snapshot: AgentsSnapshot | undefined) { return snapshot ? { agents: snapshot.agents ?? [], defaultAgentId: snapshot.defaultAgentId ?? 'main', defaultModelRef: snapshot.defaultModelRef ?? null, configuredChannelTypes: snapshot.configuredChannelTypes ?? [], channelOwners: snapshot.channelOwners ?? {}, channelAccountOwners: snapshot.channelAccountOwners ?? {}, } : {}; } export const useAgentsStore = create((set) => ({ agents: [], defaultAgentId: 'main', defaultModelRef: null, configuredChannelTypes: [], channelOwners: {}, channelAccountOwners: {}, loading: false, error: null, fetchAgents: async () => { set({ loading: true, error: null }); try { const snapshot = await hostApiFetch('/api/agents'); set({ ...applySnapshot(snapshot), loading: false, }); } catch (error) { set({ loading: false, error: String(error) }); } }, createAgent: async (name: string, options?: { inheritWorkspace?: boolean }) => { set({ error: null }); try { const snapshot = await hostApiFetch('/api/agents', { method: 'POST', body: JSON.stringify({ name, inheritWorkspace: options?.inheritWorkspace }), }); set(applySnapshot(snapshot)); } catch (error) { set({ error: String(error) }); throw error; } }, updateAgent: async (agentId: string, name: string) => { set({ error: null }); try { const snapshot = await hostApiFetch( `/api/agents/${encodeURIComponent(agentId)}`, { method: 'PUT', body: JSON.stringify({ name }), } ); set(applySnapshot(snapshot)); } catch (error) { set({ error: String(error) }); throw error; } }, updateAgentModel: async (agentId: string, modelRef: string | null) => { set({ error: null }); try { const snapshot = await hostApiFetch( `/api/agents/${encodeURIComponent(agentId)}/model`, { method: 'PUT', body: JSON.stringify({ modelRef }), } ); set(applySnapshot(snapshot)); } catch (error) { set({ error: String(error) }); throw error; } }, updateDefaultModel: async (modelRef: string | null) => { set({ error: null }); try { const snapshot = await hostApiFetch( '/api/agents/default-model', { method: 'PUT', body: JSON.stringify({ modelRef }), } ); set(applySnapshot(snapshot)); } catch (error) { set({ error: String(error) }); throw error; } }, deleteAgent: async (agentId: string) => { set({ error: null }); try { const snapshot = await hostApiFetch( `/api/agents/${encodeURIComponent(agentId)}`, { method: 'DELETE' } ); set(applySnapshot(snapshot)); } catch (error) { set({ error: String(error) }); throw error; } }, assignChannel: async (agentId: string, channelType: ChannelType) => { set({ error: null }); try { const snapshot = await hostApiFetch( `/api/agents/${encodeURIComponent(agentId)}/channels/${encodeURIComponent(channelType)}`, { method: 'PUT' } ); set(applySnapshot(snapshot)); } catch (error) { set({ error: String(error) }); throw error; } }, removeChannel: async (agentId: string, channelType: ChannelType) => { set({ error: null }); try { const snapshot = await hostApiFetch( `/api/agents/${encodeURIComponent(agentId)}/channels/${encodeURIComponent(channelType)}`, { method: 'DELETE' } ); set(applySnapshot(snapshot)); } catch (error) { set({ error: String(error) }); throw error; } }, clearError: () => set({ error: null }), }));