import { request, getApiKey, getBaseUrlValue } from '../client' export interface SessionSummary { id: string source: string model: string title: string | null preview?: string started_at: number ended_at: number | null last_active?: number message_count: number tool_call_count: number input_tokens: number output_tokens: number cache_read_tokens: number cache_write_tokens: number reasoning_tokens: number billing_provider: string | null estimated_cost_usd: number actual_cost_usd: number | null cost_status: string workspace?: string | null } export interface SessionDetail extends SessionSummary { messages: HermesMessage[] } export interface SessionSearchResult extends SessionSummary { matched_message_id: number | null snippet: string rank: number } export interface HermesMessage { id: number session_id: string role: 'user' | 'assistant' | 'system' | 'tool' content: string tool_call_id: string | null tool_calls: any[] | null tool_name: string | null timestamp: number token_count: number | null finish_reason: string | null reasoning: string | null } export async function fetchSessions(source?: string, limit?: number): Promise { const params = new URLSearchParams() if (source) params.set('source', source) if (limit) params.set('limit', String(limit)) const query = params.toString() const res = await request<{ sessions: SessionSummary[] }>(`/api/hermes/sessions${query ? `?${query}` : ''}`) return res.sessions } /** * Fetch Hermes sessions only (exclude api_server source) */ export async function fetchHermesSessions(source?: string, limit?: number): Promise { const params = new URLSearchParams() if (source) params.set('source', source) if (limit) params.set('limit', String(limit)) const query = params.toString() const res = await request<{ sessions: SessionSummary[] }>(`/api/hermes/sessions/hermes${query ? `?${query}` : ''}`) return res.sessions } export async function searchSessions(q: string, source?: string, limit?: number): Promise { const params = new URLSearchParams() params.set('q', q) if (source) params.set('source', source) if (limit) params.set('limit', String(limit)) const query = params.toString() const res = await request<{ results: SessionSearchResult[] }>(`/api/hermes/search/sessions?${query}`) return res.results } export async function fetchSession(id: string): Promise { try { const res = await request<{ session: SessionDetail }>(`/api/hermes/sessions/${id}`) return res.session } catch { return null } } /** * Fetch Hermes session detail only (exclude api_server source) */ export async function fetchHermesSession(id: string): Promise { try { const res = await request<{ session: SessionDetail }>(`/api/hermes/sessions/hermes/${id}`) return res.session } catch { return null } } export async function deleteSession(id: string): Promise { try { await request(`/api/hermes/sessions/${id}`, { method: 'DELETE' }) return true } catch { return false } } export async function batchDeleteSessions(ids: string[]): Promise<{ deleted: number; failed: number; errors: Array<{ id: string; error: string }> }> { try { const res = await request<{ deleted: number; failed: number; errors: Array<{ id: string; error: string }> }>( '/api/hermes/sessions/batch-delete', { method: 'POST', body: JSON.stringify({ ids }), } ) return res } catch (err: any) { throw err } } export async function renameSession(id: string, title: string): Promise { try { await request(`/api/hermes/sessions/${id}/rename`, { method: 'POST', body: JSON.stringify({ title }), }) return true } catch { return false } } export async function setSessionWorkspace(id: string, workspace: string | null): Promise { try { await request(`/api/hermes/sessions/${id}/workspace`, { method: 'POST', body: JSON.stringify({ workspace: workspace || '' }), }) return true } catch { return false } } export async function exportSession(id: string, mode: 'full' | 'compressed' = 'full', ext: 'json' | 'txt' = 'json'): Promise { const baseUrl = getBaseUrlValue() const token = getApiKey() const url = `${baseUrl}/api/hermes/sessions/${id}/export?mode=${mode}&ext=${ext}&token=${encodeURIComponent(token)}` const res = await fetch(url) if (!res.ok) throw new Error('Export failed') const blob = await res.blob() const contentDisposition = res.headers.get('Content-Disposition') || '' let filename = `session_${id}.${ext}` const match = contentDisposition.match(/filename\*?=(?:UTF-8'')?([^;\n]+)/i) if (match) filename = decodeURIComponent(match[1].replace(/"/g, '')) const a = document.createElement('a') a.href = URL.createObjectURL(blob) a.download = filename a.click() URL.revokeObjectURL(a.href) } export interface UsageStatsResponse { total_input_tokens: number total_output_tokens: number total_cache_read_tokens: number total_cache_write_tokens: number total_reasoning_tokens: number total_sessions: number total_cost: number total_api_calls?: number period_days?: number model_usage: Array<{ model: string input_tokens: number output_tokens: number cache_read_tokens: number cache_write_tokens: number reasoning_tokens: number sessions: number }> daily_usage: Array<{ date: string input_tokens: number output_tokens: number cache_read_tokens: number cache_write_tokens: number sessions: number errors: number cost: number }> } export async function fetchUsageStats(days = 30): Promise { const safeDays = Number.isFinite(days) ? Math.max(1, Math.floor(days)) : 30 const params = new URLSearchParams() params.set('days', String(safeDays)) return request(`/api/hermes/usage/stats?${params}`) } export async function fetchSessionUsage(ids: string[]): Promise> { if (ids.length === 0) return {} const params = new URLSearchParams() params.set('ids', ids.join(',')) return request(`/api/hermes/sessions/usage?${params}`) } export async function fetchSessionUsageSingle(id: string): Promise<{ input_tokens: number; output_tokens: number } | null> { try { return await request<{ input_tokens: number; output_tokens: number }>(`/api/hermes/sessions/${id}/usage`) } catch { return null } } export async function fetchContextLength(profile?: string): Promise { const params = new URLSearchParams() if (profile) params.set('profile', profile) const query = params.toString() const res = await request<{ context_length: number }>(`/api/hermes/sessions/context-length${query ? `?${query}` : ''}`) return res.context_length }