ar9avg's picture
fix
17e7bd7
import type { InitResponse, RLState, SchemaGraph, SSEEvent } from './types'
const BASE_URL: string = import.meta.env.VITE_API_URL ?? ''
async function* parseSSE(response: Response): AsyncGenerator<SSEEvent> {
const reader = response.body!.getReader()
const decoder = new TextDecoder()
let buffer = ''
while (true) {
const { done, value } = await reader.read()
if (done) break
buffer += decoder.decode(value, { stream: true })
const lines = buffer.split('\n')
buffer = lines.pop() ?? ''
for (const line of lines) {
if (!line.startsWith('data: ')) continue
const raw = line.slice(6).trim()
if (raw === '[DONE]') return
try {
yield JSON.parse(raw) as SSEEvent
} catch {
// ignore malformed lines
}
}
}
}
export async function* streamExecuteQuery(
question: string,
taskId: string,
previousSql?: string,
): AsyncGenerator<SSEEvent> {
const body: Record<string, unknown> = { question, task_id: taskId }
if (previousSql) body.previousSql = previousSql
const res = await fetch(`${BASE_URL}/api/execute-query`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
})
if (!res.ok) {
throw new Error(`HTTP ${res.status}: ${res.statusText}`)
}
yield* parseSSE(res)
}
export async function* streamBenchmark(
taskId: string,
queryIds?: string[]
): AsyncGenerator<SSEEvent> {
const body: Record<string, unknown> = { task_id: taskId }
if (queryIds) body.queryIds = queryIds
const res = await fetch(`${BASE_URL}/api/benchmark`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
})
if (!res.ok) {
throw new Error(`HTTP ${res.status}: ${res.statusText}`)
}
yield* parseSSE(res)
}
export async function fetchInit(): Promise<InitResponse> {
const res = await fetch(`${BASE_URL}/api/init`)
if (!res.ok) throw new Error(`HTTP ${res.status}`)
return res.json() as Promise<InitResponse>
}
export async function fetchRLState(): Promise<RLState> {
const res = await fetch(`${BASE_URL}/api/rl-state`)
if (!res.ok) throw new Error(`HTTP ${res.status}`)
return res.json() as Promise<RLState>
}
export async function fetchSchemaGraph(): Promise<SchemaGraph> {
const res = await fetch(`${BASE_URL}/api/schema-graph`)
if (!res.ok) throw new Error(`HTTP ${res.status}`)
return res.json() as Promise<SchemaGraph>
}
export async function submitFeedback(
question: string,
sql: string,
correct: boolean,
remark?: string,
): Promise<void> {
await fetch(`${BASE_URL}/api/feedback`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ question, sql, correct, remark }),
})
}
export async function fetchPromptHistory() {
const res = await fetch(`${BASE_URL}/api/prompt-history`)
if (!res.ok) throw new Error(`HTTP ${res.status}`)
return res.json()
}
export async function fetchBenchmarkQuestions(
taskId: string
): Promise<{ questions: { id: string; question: string; difficulty: string }[] }> {
const res = await fetch(`${BASE_URL}/api/benchmark-questions?task_id=${encodeURIComponent(taskId)}`)
if (!res.ok) throw new Error(`HTTP ${res.status}`)
return res.json()
}
const _suggestionsCache = new Map<string, string[]>()
export async function fetchSuggestQuestions(cacheKey: string): Promise<string[]> {
if (_suggestionsCache.has(cacheKey)) return _suggestionsCache.get(cacheKey)!
const res = await fetch(`${BASE_URL}/api/suggest-questions`)
if (!res.ok) return []
const data = await res.json() as { questions: string[] }
_suggestionsCache.set(cacheKey, data.questions ?? [])
return data.questions ?? []
}
export async function connectExternalDb(path: string): Promise<{ success: boolean; message: string; tables: { name: string; rows: number }[]; dbLabel: string }> {
const res = await fetch(`${BASE_URL}/api/connect-db`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ path }),
})
if (!res.ok) throw new Error(`HTTP ${res.status}`)
return res.json()
}