import { apiRequest } from "./base"; type ApiEnvelope = { code: number; message: string; data: T }; function unwrap(raw: ApiEnvelope | T): T { if (raw && typeof raw === "object" && "code" in (raw as ApiEnvelope) && "data" in (raw as ApiEnvelope)) { return (raw as ApiEnvelope).data; } return raw as T; } export interface ProjectFromTextRequest { input_text: string; } export interface ProjectFromTextRequirementItem { section: string; title: string; description: string; priority?: string; source_kind?: string; source_name?: string; source_identifier?: string; } export interface ProjectFromTextSignalSource { registry_id: number | string; id?: number | string; project_id?: number | string; signal_id?: number | string | null; source_kind: string; source_name: string; source_identifier: string; description?: string | null; requested_via?: string; status?: string; onboarding_status?: string; section?: string; title?: string; priority?: string; origin?: string; raw_context?: Record | null; config?: Record | null; } export interface ProjectFromTextResponse { project: { id: string; name: string; title: string; description: string; status: string }; signal: { id: string; content: string; impact_score: number }; charter: { id: string; title: string; content: string | Record | null }; tasks: Array<{ id: string; title: string; type: string; estimated_hours: number; priority: string }>; risks: Array<{ type: string; description: string; severity: string }>; signal_sources: ProjectFromTextSignalSource[]; analysis: { project_name: string; project_title?: string; tech_stack: string[]; timeline: string; primary_role: string; target_audience?: string; domain_id?: number; key_features?: string[]; competitors?: string[]; success_metrics?: string[]; core_pain_points?: string[]; mvp_features?: string[]; requirement_items?: ProjectFromTextRequirementItem[]; }; } export interface SignalSourceRepairRequest { project_id: number; registry_ids: number[]; sender?: string; } export interface SignalSourceRepairItem { registry_id: number; signal_id: number | null; capture_status: string; work_item_id: number | null; route_status: string; } export interface SignalSourceRepairResponse { project_id: number; items: SignalSourceRepairItem[]; } export interface CognitiveConflict { id: string; type: string; description: string; severity: string; related_users: string[]; } export interface Blocker { id: string; type: string; description: string; severity: string; detected_at: string; } export interface DailyBriefing { date: string; summary: string; highlights: Array<{ type: string; priority: string; content: string }>; your_tasks: Array<{ id: number; title: string; status: string; priority: string }>; risks: Array<{ type: string; task: string; severity: string }>; signals: Array<{ id: number; source: string; content: string; impact_score: number }>; conflicts: Array<{ id: string; type: string; description: string }>; action_items: Array<{ type: string; content: string; priority: string }>; team_updates: Array<{ assignee_id: number; task: string; status: string }>; } export interface ExecutiveBriefingMetric { label: string; value: string | number; tone: string; } export interface ExecutiveBriefingItem { title: string; detail: string; tone: string; kind?: string | null; } export interface ExecutiveBriefingSection { key: string; title: string; summary: string; metrics: ExecutiveBriefingMetric[]; items: ExecutiveBriefingItem[]; drilldown_tab?: string | null; } export interface ExecutiveBriefingHero { title: string; decision_count: number; anomaly_count: number; baseline_generated_at?: string | null; live_generated_at?: string | null; key_alerts: ExecutiveBriefingMetric[]; snapshot_state: "ready" | "missing" | string; } export interface ExecutiveBriefingConfig { enabled: boolean; send_time: string; send_cycle: "workdays" | "daily"; delivery_target_type: "management_group"; delivery_target_ref: string | null; timezone: string; updated_at?: string | null; updated_by?: number | null; } export interface ExecutiveBriefingPayload { brief_date: string; mode: "snapshot" | "live"; summary: Record; hero: ExecutiveBriefingHero; sections: ExecutiveBriefingSection[]; delivery: ExecutiveBriefingConfig; } export type LLMProvider = "deepseek" | "glm" | "openai" | "ollama"; export interface LLMProviderPreset { model: string; base_url: string; api_env: string; } export interface LLMProviderPresetResponse { low: string; high: string; base_url: string; providers: Record; } export interface LLMEngineSettings { enable_local_kb_qa: boolean; local_kb_qa_scope: "kb_qa_only"; } export interface LLMEngine { id: string; name: string; provider: LLMProvider; model: string; base_url: string; api_key_masked: string; updated_at?: string; created_at?: string; } export interface LLMEngineListResponse { active_engine_id: string | null; engines: LLMEngine[]; settings: LLMEngineSettings; } export interface LLMEngineUpsertRequest { name: string; provider: LLMProvider; api_key?: string; model?: string; base_url?: string; set_active?: boolean; } export interface LLMEngineConnectionTestResponse { ok: boolean; engine_id: string; name: string; provider: LLMProvider; model: string; base_url: string; api_key_masked: string; latency_ms: number; response_preview: string; } export const aiStewardApi = { async listCognitiveConflicts(projectId?: number): Promise { const query = typeof projectId === "number" ? `?project_id=${projectId}` : ""; return await apiRequest(`/ai-steward/cognitive-conflicts${query}`); }, async detectConflicts(projectId: number): Promise<{ project_id: number; detected_count: number; conflicts: CognitiveConflict[] }> { return await apiRequest<{ project_id: number; detected_count: number; conflicts: CognitiveConflict[] }>( "/ai-steward/conflicts/detect", { method: "POST", body: JSON.stringify({ project_id: projectId, detect_type: "all" }), } ); }, async listActiveBlockers(): Promise<{ total: number; blockers: Blocker[] }> { return await apiRequest<{ total: number; blockers: Blocker[] }>("/ai-steward/blockers/active"); }, async detectTaskBlockers(): Promise<{ total_detected: number; blockers: Blocker[] }> { return await apiRequest<{ total_detected: number; blockers: Blocker[] }>("/ai-steward/blockers/detect-tasks", { method: "POST", }); }, async getDailyBriefing(): Promise { return await apiRequest("/ai-steward/daily-briefing"); }, async startHnMonitor(intervalMinutes: number = 30): Promise> { return await apiRequest>( `/ai-steward/signal/start-hn-monitor?interval_minutes=${intervalMinutes}`, { method: "POST", } ); }, async getExecutiveBriefing(mode: "snapshot" | "live"): Promise { const raw = await apiRequest>(`/ai-steward/executive-briefing?mode=${mode}`); return unwrap(raw); }, async getExecutiveBriefingConfig(): Promise { const raw = await apiRequest>("/ai-steward/executive-briefing/config"); return unwrap(raw); }, async updateExecutiveBriefingConfig(body: ExecutiveBriefingConfig): Promise { const raw = await apiRequest>("/ai-steward/executive-briefing/config", { method: "PUT", body: JSON.stringify(body), }); return unwrap(raw); }, async getLlmProviderPresets(): Promise { const raw = await apiRequest>("/ai-steward/llm/providers"); return unwrap(raw); }, async listLlmEngines(): Promise { const raw = await apiRequest>("/ai-steward/llm-engines"); return unwrap(raw); }, async createLlmEngine(body: LLMEngineUpsertRequest): Promise { const raw = await apiRequest>("/ai-steward/llm-engines", { method: "POST", body: JSON.stringify(body), }); return unwrap(raw); }, async updateLlmEngine( engineId: string, body: Partial, ): Promise { const raw = await apiRequest>( `/ai-steward/llm-engines/${engineId}`, { method: "PUT", body: JSON.stringify(body), } ); return unwrap(raw); }, async activateLlmEngine(engineId: string): Promise { const raw = await apiRequest>( `/ai-steward/llm-engines/${engineId}/activate`, { method: "POST", } ); return unwrap(raw); }, async deleteLlmEngine( engineId: string, ): Promise { const raw = await apiRequest< ApiEnvelope >(`/ai-steward/llm-engines/${engineId}`, { method: "DELETE", }); return unwrap(raw); }, async updateLlmEngineSettings( body: Pick, ): Promise { const raw = await apiRequest>( "/ai-steward/llm-engines/settings", { method: "PUT", body: JSON.stringify(body), } ); return unwrap(raw); }, async testActiveLlmEngine(): Promise { const raw = await apiRequest>("/ai-steward/llm-engines/test-active", { method: "POST", body: JSON.stringify({}), }); return unwrap(raw); }, async testLlmEngine(engineId: string): Promise { const raw = await apiRequest>( `/ai-steward/llm-engines/${engineId}/test`, { method: "POST", body: JSON.stringify({}), } ); return unwrap(raw); }, async repairDirtySignalSources(body: SignalSourceRepairRequest): Promise { const raw = await apiRequest>("/ai-steward/signal-sources/repair-dirty", { method: "POST", body: JSON.stringify(body), }); return unwrap(raw); }, async createProjectFromText(body: ProjectFromTextRequest): Promise { const raw = await apiRequest>("/ai-steward/project-from-text", { method: "POST", body: JSON.stringify(body), }); return unwrap(raw); }, };