Spaces:
Sleeping
Sleeping
File size: 3,419 Bytes
8b9f7d9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | import type {
ChatMessage,
ChatResponse,
ImageResponse,
ModelsResponse,
StatsResponse,
HealthResponse,
AuthConfig,
AuthResponse,
AuthUser,
} from './types'
const BASE_URL = '/api'
// ---------------------------------------------------------------------------
// Token management
// ---------------------------------------------------------------------------
const TOKEN_KEY = 'lp_auth_token'
export function getToken(): string | null {
return localStorage.getItem(TOKEN_KEY)
}
export function setToken(token: string) {
localStorage.setItem(TOKEN_KEY, token)
}
export function clearToken() {
localStorage.removeItem(TOKEN_KEY)
}
function authHeaders(): Record<string, string> {
const token = getToken()
return token ? { Authorization: `Bearer ${token}` } : {}
}
// ---------------------------------------------------------------------------
// Generic request helper
// ---------------------------------------------------------------------------
async function request<T>(path: string, options?: RequestInit): Promise<T> {
const res = await fetch(`${BASE_URL}${path}`, {
headers: { 'Content-Type': 'application/json', ...authHeaders() },
...options,
})
if (!res.ok) {
const err = await res.json().catch(() => ({ detail: res.statusText }))
throw new Error(err.detail || `HTTP ${res.status}`)
}
return res.json()
}
// ---------------------------------------------------------------------------
// Auth
// ---------------------------------------------------------------------------
export async function getAuthConfig(): Promise<AuthConfig> {
return request('/auth/config')
}
export async function loginWithGoogle(credential: string): Promise<AuthResponse> {
return request('/auth/google', {
method: 'POST',
body: JSON.stringify({ credential }),
})
}
export async function getMe(): Promise<AuthUser> {
return request('/auth/me')
}
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
export async function getHealth(): Promise<HealthResponse> {
return request('/health')
}
export async function getModels(): Promise<ModelsResponse> {
return request('/models')
}
export async function getStats(): Promise<StatsResponse> {
return request('/stats')
}
// ---------------------------------------------------------------------------
// Protected API
// ---------------------------------------------------------------------------
export async function sendChat(
message: string,
model: string,
history: ChatMessage[],
): Promise<ChatResponse> {
return request('/chat', {
method: 'POST',
body: JSON.stringify({
message,
model,
history: history.map((m) => ({ role: m.role, content: m.content })),
}),
})
}
export async function analyzeImage(
imageFile: File,
question: string,
model: string,
): Promise<ImageResponse> {
const formData = new FormData()
formData.append('image', imageFile)
formData.append('question', question)
formData.append('model', model)
const res = await fetch(`${BASE_URL}/analyze-image`, {
method: 'POST',
body: formData,
headers: authHeaders(),
})
if (!res.ok) {
const err = await res.json().catch(() => ({ detail: res.statusText }))
throw new Error(err.detail || `HTTP ${res.status}`)
}
return res.json()
}
|