Files
ThothII/frontend/src/api/sessions.ts
T

93 lines
3.5 KiB
TypeScript

import { apiFetch } from "./client";
import { getSettings } from "./settings";
import { workspacePolicyGate, workspacePreferences, type WorkspacePreference } from "../workspaces/drafts";
import type {
Principal, ResumeSessionResult, SessionScope, SessionSummary, SessionDocument, UiResponse,
} from "./types";
type NewSessionInput = { question: string; name?: string } & Partial<WorkspacePreference>;
async function selectedPreferences(): Promise<WorkspacePreference> {
const saved = workspacePreferences.load();
if (saved.workspaceId && saved.provider && saved.model && saved.thinking) return saved;
// A direct new-session entry point can run before the composer has mounted. Seed its
// browser-local preferences from the legacy read-only defaults once, then keep them local.
const legacy = await getSettings();
return workspacePreferences.save({
workspaceId: saved.workspaceId ?? legacy.workspace,
provider: saved.provider ?? legacy.provider,
model: saved.model ?? legacy.model,
thinking: saved.thinking ?? legacy.thinking,
});
}
export async function createSession(i: NewSessionInput) {
await selectedPreferences();
const selection = await workspacePolicyGate.waitForCurrent(() => workspacePreferences.load());
return apiFetch<{ id: string }>("/sessions", {
method: "POST",
body: JSON.stringify({ ...i, ...selection }),
});
}
/** Best-effort warm-up; callers must not await it before showing the composer. */
export const prewarmRuntime = () =>
apiFetch<void>("/runtime/prewarm", { method: "POST" });
export const getMe = () => apiFetch<Principal>("/me");
export const listSessions = (scope: SessionScope = "mine") =>
apiFetch<SessionSummary[]>(`/sessions?scope=${scope}`);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const getSession = (id: string) => apiFetch<any>(`/sessions/${id}`);
export const postResponse = (id: string, uiResponse: UiResponse) =>
apiFetch<void>(`/sessions/${id}/response`, {
method: "POST",
body: JSON.stringify({ ui_response: uiResponse }),
});
export const postSteer = (id: string, text: string) =>
apiFetch<void>(`/sessions/${id}/steer`, {
method: "POST",
body: JSON.stringify({ text }),
});
export const closeSession = (id: string) =>
apiFetch<void>(`/sessions/${id}/close`, { method: "POST" });
export const resumeSession = (id: string) =>
apiFetch<ResumeSessionResult>(`/sessions/${id}/resume`, { method: "POST" });
export const renameSession = (id: string, name: string) =>
apiFetch<void>(`/sessions/${id}/rename`, { method: "POST", body: JSON.stringify({ name }) });
export const setSessionGroup = (id: string, group: string) =>
apiFetch<void>(`/sessions/${id}/group`, { method: "POST", body: JSON.stringify({ group }) });
export const archiveSession = (id: string) =>
apiFetch<void>(`/sessions/${id}/archive`, { method: "POST" });
export const unarchiveSession = (id: string) =>
apiFetch<void>(`/sessions/${id}/unarchive`, { method: "POST" });
export const deleteSession = (id: string) =>
apiFetch<void>(`/sessions/${id}`, { method: "DELETE" });
export const getSessionDocuments = (id: string) =>
apiFetch<SessionDocument[]>(`/sessions/${id}/documents`);
export async function checkDwhHealth(): Promise<{ ok: boolean }> {
const timeout = new Promise<{ ok: false }>((r) => setTimeout(() => r({ ok: false }), 5000));
try {
return await Promise.race([
apiFetch<{ ok: boolean; detail: string }>("/health/dwh"),
timeout,
]);
} catch {
return { ok: false };
}
}