- Add TemplateExample struct and examples scanning (local dir + git repo) - Exclude examples/ from copy_dir_recursive - Frontend: recent templates (localStorage), template-specific example buttons
123 lines
4.0 KiB
TypeScript
123 lines
4.0 KiB
TypeScript
import type { Project, Workflow, ExecutionLogEntry, Comment, Timer, KbArticle, KbArticleSummary, PlanStepInfo, LlmCallLogEntry, ChatMessage } from './types'
|
|
|
|
const BASE = `${import.meta.env.BASE_URL.replace(/\/$/, '')}/api`
|
|
|
|
async function request<T>(path: string, options?: RequestInit): Promise<T> {
|
|
const res = await fetch(`${BASE}${path}`, {
|
|
headers: { 'Content-Type': 'application/json' },
|
|
...options,
|
|
})
|
|
if (!res.ok) {
|
|
const text = await res.text()
|
|
throw new Error(`API error ${res.status}: ${text}`)
|
|
}
|
|
return res.json()
|
|
}
|
|
|
|
export const api = {
|
|
listProjects: () => request<Project[]>('/projects'),
|
|
|
|
createProject: (name: string, description = '') =>
|
|
request<Project>('/projects', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ name, description }),
|
|
}),
|
|
|
|
getProject: (id: string) => request<Project | null>(`/projects/${id}`),
|
|
|
|
updateProject: (id: string, data: { name?: string; description?: string }) =>
|
|
request<Project | null>(`/projects/${id}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(data),
|
|
}),
|
|
|
|
deleteProject: (id: string) =>
|
|
request<boolean>(`/projects/${id}`, { method: 'DELETE' }),
|
|
|
|
listWorkflows: (projectId: string) =>
|
|
request<Workflow[]>(`/projects/${projectId}/workflows`),
|
|
|
|
createWorkflow: (projectId: string, requirement: string, templateId?: string) =>
|
|
request<Workflow>(`/projects/${projectId}/workflows`, {
|
|
method: 'POST',
|
|
body: JSON.stringify({ requirement, template_id: templateId || undefined }),
|
|
}),
|
|
|
|
listTemplates: () =>
|
|
request<{ id: string; name: string; description: string; examples: { label: string; text: string }[] }[]>('/templates'),
|
|
|
|
listSteps: (workflowId: string) =>
|
|
request<ExecutionLogEntry[]>(`/workflows/${workflowId}/steps`),
|
|
|
|
listComments: (workflowId: string) =>
|
|
request<Comment[]>(`/workflows/${workflowId}/comments`),
|
|
|
|
createComment: (workflowId: string, content: string) =>
|
|
request<Comment>(`/workflows/${workflowId}/comments`, {
|
|
method: 'POST',
|
|
body: JSON.stringify({ content }),
|
|
}),
|
|
|
|
getReport: (workflowId: string) =>
|
|
request<{ report: string }>(`/workflows/${workflowId}/report`),
|
|
|
|
listPlanSteps: (workflowId: string) =>
|
|
request<PlanStepInfo[]>(`/workflows/${workflowId}/plan`),
|
|
|
|
listLlmCalls: (workflowId: string) =>
|
|
request<LlmCallLogEntry[]>(`/workflows/${workflowId}/llm-calls`),
|
|
|
|
listTimers: (projectId: string) =>
|
|
request<Timer[]>(`/projects/${projectId}/timers`),
|
|
|
|
createTimer: (projectId: string, data: { name: string; interval_secs: number; requirement: string }) =>
|
|
request<Timer>(`/projects/${projectId}/timers`, {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
}),
|
|
|
|
updateTimer: (timerId: string, data: { name?: string; interval_secs?: number; requirement?: string; enabled?: boolean }) =>
|
|
request<Timer>(`/timers/${timerId}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(data),
|
|
}),
|
|
|
|
deleteTimer: (timerId: string) =>
|
|
request<void>(`/timers/${timerId}`, { method: 'DELETE' }),
|
|
|
|
getKb: () => request<{ content: string }>('/kb'),
|
|
|
|
listArticles: () => request<KbArticleSummary[]>('/kb/articles'),
|
|
|
|
createArticle: (title: string) =>
|
|
request<KbArticle>('/kb/articles', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ title }),
|
|
}),
|
|
|
|
getArticle: (id: string) => request<KbArticle>(`/kb/articles/${id}`),
|
|
|
|
updateArticle: (id: string, data: { title?: string; content?: string }) =>
|
|
request<KbArticle>(`/kb/articles/${id}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(data),
|
|
}),
|
|
|
|
deleteArticle: (id: string) =>
|
|
request<boolean>(`/kb/articles/${id}`, { method: 'DELETE' }),
|
|
|
|
chat: (messages: ChatMessage[]) =>
|
|
request<{ reply: string }>('/chat', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ messages }),
|
|
}),
|
|
|
|
getSettings: () => request<Record<string, string>>('/settings'),
|
|
|
|
putSetting: (key: string, value: string) =>
|
|
request<Record<string, string>>(`/settings/${key}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify({ value }),
|
|
}),
|
|
}
|