chrysopedia/frontend/src/api/admin-pipeline.ts
jlightner 39e169b4ce feat: Split 945-line public-client.ts into 10 domain API modules with s…
- "frontend/src/api/client.ts"
- "frontend/src/api/index.ts"
- "frontend/src/api/search.ts"
- "frontend/src/api/techniques.ts"
- "frontend/src/api/creators.ts"
- "frontend/src/api/topics.ts"
- "frontend/src/api/stats.ts"
- "frontend/src/api/reports.ts"

GSD-Task: S05/T01
2026-04-03 23:04:56 +00:00

333 lines
8.9 KiB
TypeScript

import { request, BASE } from "./client";
// ── Types ────────────────────────────────────────────────────────────────────
export interface PipelineVideoItem {
id: string;
filename: string;
processing_status: string;
creator_name: string;
created_at: string | null;
updated_at: string | null;
event_count: number;
total_tokens_used: number;
last_event_at: string | null;
active_stage: string | null;
active_stage_status: string | null;
stage_started_at: string | null;
latest_run: {
id: string;
run_number: number;
trigger: string;
status: string;
started_at: string | null;
finished_at: string | null;
error_stage: string | null;
total_tokens: number;
} | null;
}
export interface PipelineVideoListResponse {
items: PipelineVideoItem[];
total: number;
}
export interface PipelineEvent {
id: string;
video_id: string;
stage: string;
event_type: string;
prompt_tokens: number | null;
completion_tokens: number | null;
total_tokens: number | null;
model: string | null;
duration_ms: number | null;
payload: Record<string, unknown> | null;
system_prompt_text: string | null;
user_prompt_text: string | null;
response_text: string | null;
created_at: string | null;
}
export interface PipelineEventListResponse {
items: PipelineEvent[];
total: number;
offset: number;
limit: number;
}
export interface WorkerTask {
id: string;
name: string;
args: unknown[];
time_start: number | null;
}
export interface WorkerInfo {
name: string;
active_tasks: WorkerTask[];
reserved_tasks: number;
total_completed: number;
uptime: string | null;
pool_size: number | null;
}
export interface WorkerStatusResponse {
online: boolean;
workers: WorkerInfo[];
error?: string;
}
export interface TriggerResponse {
status: string;
video_id: string;
current_processing_status?: string;
}
export interface RevokeResponse {
status: string;
video_id: string;
tasks_revoked: number;
}
export interface RecentActivityItem {
id: string;
video_id: string;
filename: string;
creator_name: string;
stage: string;
event_type: string;
total_tokens: number | null;
duration_ms: number | null;
created_at: string | null;
}
export interface RecentActivityResponse {
items: RecentActivityItem[];
}
export interface PipelineRunItem {
id: string;
run_number: number;
trigger: string;
status: string;
started_at: string | null;
finished_at: string | null;
error_stage: string | null;
total_tokens: number;
event_count: number;
}
export interface PipelineRunsResponse {
items: PipelineRunItem[];
legacy_event_count: number;
}
export interface CleanRetriggerResponse {
status: string;
video_id: string;
cleaned: Record<string, string>;
}
export interface ChunkingTopicBoundary {
topic_label: string;
segment_count: number;
start_time: number;
end_time: number;
start_index: number;
end_index: number;
}
export interface ChunkingSynthesisGroup {
category: string;
moment_count: number;
exceeds_chunk_threshold: boolean;
chunks_needed: number;
}
export interface ChunkingDataResponse {
video_id: string;
total_segments: number;
total_moments: number;
classification_source: string;
synthesis_chunk_size: number;
topic_boundaries: ChunkingTopicBoundary[];
key_moments: Array<{
id: string;
title: string;
content_type: string;
start_time: number;
end_time: number;
plugins: string[];
technique_page_id: string | null;
}>;
classification: Array<Record<string, unknown>>;
synthesis_groups: ChunkingSynthesisGroup[];
}
export interface RerunStageResponse {
status: string;
video_id: string;
stage: string;
prompt_override: boolean;
}
export interface StalePageCreator {
creator: string;
stale_count: number;
page_slugs: string[];
}
export interface StalePagesResponse {
current_prompt_hash: string;
total_pages: number;
stale_pages: number;
fresh_pages: number;
stale_by_creator: StalePageCreator[];
}
export interface BulkResynthResponse {
status: string;
stage: string;
total: number;
dispatched: number;
skipped: Array<{ video_id: string; reason: string }> | null;
}
export interface WipeAllResponse {
status: string;
deleted: Record<string, string | number>;
}
export interface DebugModeResponse {
debug_mode: boolean;
}
export interface UpdateCreatorProfilePayload {
bio?: string | null;
social_links?: Record<string, string> | null;
featured?: boolean;
avatar_url?: string | null;
}
export interface UpdateCreatorProfileResponse {
status: string;
creator: string;
fields: string[];
}
// ── Functions ────────────────────────────────────────────────────────────────
export async function fetchPipelineVideos(): Promise<PipelineVideoListResponse> {
return request<PipelineVideoListResponse>(`${BASE}/admin/pipeline/videos`);
}
export async function fetchRecentActivity(limit = 10): Promise<RecentActivityResponse> {
return request<RecentActivityResponse>(`${BASE}/admin/pipeline/recent-activity?limit=${limit}`);
}
export async function fetchPipelineRuns(videoId: string): Promise<PipelineRunsResponse> {
return request<PipelineRunsResponse>(`${BASE}/admin/pipeline/runs/${videoId}`);
}
export async function fetchPipelineEvents(
videoId: string,
params: { offset?: number; limit?: number; stage?: string; event_type?: string; run_id?: string; order?: "asc" | "desc" } = {},
): Promise<PipelineEventListResponse> {
const qs = new URLSearchParams();
if (params.offset !== undefined) qs.set("offset", String(params.offset));
if (params.limit !== undefined) qs.set("limit", String(params.limit));
if (params.stage) qs.set("stage", params.stage);
if (params.event_type) qs.set("event_type", params.event_type);
if (params.run_id) qs.set("run_id", params.run_id);
if (params.order) qs.set("order", params.order);
const query = qs.toString();
return request<PipelineEventListResponse>(
`${BASE}/admin/pipeline/events/${videoId}${query ? `?${query}` : ""}`,
);
}
export async function fetchWorkerStatus(): Promise<WorkerStatusResponse> {
return request<WorkerStatusResponse>(`${BASE}/admin/pipeline/worker-status`);
}
export async function triggerPipeline(videoId: string): Promise<TriggerResponse> {
return request<TriggerResponse>(`${BASE}/admin/pipeline/trigger/${videoId}`, {
method: "POST",
});
}
export async function revokePipeline(videoId: string): Promise<RevokeResponse> {
return request<RevokeResponse>(`${BASE}/admin/pipeline/revoke/${videoId}`, {
method: "POST",
});
}
export async function cleanRetriggerPipeline(videoId: string): Promise<CleanRetriggerResponse> {
return request<CleanRetriggerResponse>(`${BASE}/admin/pipeline/clean-retrigger/${videoId}`, {
method: "POST",
});
}
export async function fetchChunkingData(videoId: string): Promise<ChunkingDataResponse> {
return request<ChunkingDataResponse>(`${BASE}/admin/pipeline/chunking/${videoId}`);
}
export async function rerunStage(
videoId: string,
stageName: string,
promptOverride?: string,
): Promise<RerunStageResponse> {
const body: Record<string, string | undefined> = {};
if (promptOverride) {
body.prompt_override = promptOverride;
}
return request<RerunStageResponse>(
`${BASE}/admin/pipeline/rerun-stage/${videoId}/${stageName}`,
{
method: "POST",
body: Object.keys(body).length > 0 ? JSON.stringify(body) : undefined,
},
);
}
export async function fetchStalePages(): Promise<StalePagesResponse> {
return request<StalePagesResponse>(`${BASE}/admin/pipeline/stale-pages`);
}
export async function bulkResynthesize(
videoIds?: string[],
stage = "stage5_synthesis",
): Promise<BulkResynthResponse> {
return request<BulkResynthResponse>(`${BASE}/admin/pipeline/bulk-resynthesize`, {
method: "POST",
body: JSON.stringify({ video_ids: videoIds ?? null, stage }),
});
}
export async function wipeAllOutput(): Promise<WipeAllResponse> {
return request<WipeAllResponse>(`${BASE}/admin/pipeline/wipe-all-output`, {
method: "POST",
});
}
export async function fetchDebugMode(): Promise<DebugModeResponse> {
return request<DebugModeResponse>(`${BASE}/admin/pipeline/debug-mode`);
}
export async function setDebugMode(enabled: boolean): Promise<DebugModeResponse> {
return request<DebugModeResponse>(`${BASE}/admin/pipeline/debug-mode`, {
method: "PUT",
body: JSON.stringify({ debug_mode: enabled }),
});
}
export async function updateCreatorProfile(
creatorId: string,
payload: UpdateCreatorProfilePayload,
): Promise<UpdateCreatorProfileResponse> {
return request<UpdateCreatorProfileResponse>(
`${BASE}/admin/pipeline/creators/${creatorId}`,
{ method: "PUT", body: JSON.stringify(payload) },
);
}