From 7be1c3162ce68588df193cfaac8ff09f6878009e Mon Sep 17 00:00:00 2001 From: Chaim Date: Tue, 2 Jun 2026 12:17:16 +0000 Subject: [PATCH] =?UTF-8?q?fix(#77=20frontend):=20separate=20=D7=9E=D7=A1?= =?UTF-8?q?=D7=A4=D7=A8-=D7=AA=D7=99=D7=A7=20field=20on=20committee=20uplo?= =?UTF-8?q?ad=20+=20editable=20case=5Fnumber=20in=20edit=20sheet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pairs with the backend PR. Stops the citation (מראה-מקום) from being stored as the identifier, and lets a wrong identifier be corrected after the fact. - upload sheet: new required 'מספר תיק (מזהה ייחודי)' field for committee decisions → sent as case_number; the citation field is now sent as the separate citation (→ citation_formatted) instead of as case_number. - edit sheet: the case_number block is now an editable input (was read-only). Halachot/chunks key off case_law_id (UUID), so renaming case_number is safe. - precedent-library.ts: InternalDecisionUploadInput += citation; PrecedentPatch += case_number. - types.ts: regenerated (api:types) — PrecedentUpdateRequest now carries case_number. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../precedents/precedent-edit-sheet.tsx | 31 +- .../precedents/precedent-upload-sheet.tsx | 29 +- web-ui/src/lib/api/precedent-library.ts | 5 + web-ui/src/lib/api/types.ts | 1024 ++++++++++++++++- 4 files changed, 1065 insertions(+), 24 deletions(-) diff --git a/web-ui/src/components/precedents/precedent-edit-sheet.tsx b/web-ui/src/components/precedents/precedent-edit-sheet.tsx index 42f961d..7391713 100644 --- a/web-ui/src/components/precedents/precedent-edit-sheet.tsx +++ b/web-ui/src/components/precedents/precedent-edit-sheet.tsx @@ -35,7 +35,7 @@ type Props = { * each time the sheet opens so the form reflects any auto-fill that * happened in the background. */ type FormState = { - citation: string; + case_number: string; citation_formatted: string; case_name: string; court: string; @@ -54,7 +54,7 @@ type FormState = { }; const EMPTY: FormState = { - citation: "", citation_formatted: "", + case_number: "", citation_formatted: "", case_name: "", court: "", district: "", chair_name: "", decision_date: "", practice_area: "", appeal_subtype: "", source_type: "", precedent_level: "", is_binding: true, subject_tags: "", @@ -76,7 +76,7 @@ export function PrecedentEditSheet({ caseLawId, onOpenChange }: Props) { if (record && record.id !== syncedRecordId) { setSyncedRecordId(record.id as string); setForm({ - citation: record.case_number || "", + case_number: record.case_number || "", citation_formatted: record.citation_formatted || "", case_name: record.case_name || "", court: record.court || "", @@ -117,8 +117,10 @@ export function PrecedentEditSheet({ caseLawId, onOpenChange }: Props) { key_quote: form.key_quote.trim(), }; if (form.decision_date) patch.decision_date = form.decision_date; - // citation (case_number) is the unique key; we don't allow editing it - // here to avoid orphaning halachot. To rename, delete + re-upload. + // case_number is the canonical identifier. Editing it is safe — + // halachot/chunks reference case_law_id (UUID), not the case_number + // text — so a wrong id captured at upload can be corrected here. + if (form.case_number.trim()) patch.case_number = form.case_number.trim(); await update.mutateAsync({ id: caseLawId, patch }); toast.success("נשמר"); onOpenChange(false); @@ -148,7 +150,7 @@ export function PrecedentEditSheet({ caseLawId, onOpenChange }: Props) { עריכת פרטי פסיקה - כל השדות ניתנים לעריכה חוץ ממספר התיק (מזהה ייחודי במערכת). + כל השדות ניתנים לעריכה, כולל מספר התיק (המזהה הייחודי). כפתור "חלץ מטא-דאטה" שולח בקשה לתור מקומי שאני מרוקן מ-Claude Code (ה-LLM רץ מקומית עם claude session, לא ב-API). @@ -162,12 +164,17 @@ export function PrecedentEditSheet({ caseLawId, onOpenChange }: Props) { ) : ( <>
-
-
-
מספר תיק (מזהה ייחודי — לא ניתן לעריכה)
-
- {record.case_number} -
+
+
+ + setForm({ ...form, case_number: e.target.value })} + className="font-mono text-sm" dir="ltr" + placeholder="8027-25" + />
{isCommittee && ( -
+
+
+ + setCaseNumber(e.target.value)} + placeholder="8027-25" + disabled={isProcessing} dir="rtl" + /> +

+ המזהה הנקי בלבד (למשל 8027-25) — לא המראה-מקום המלא. +

+
+
+
)} diff --git a/web-ui/src/lib/api/precedent-library.ts b/web-ui/src/lib/api/precedent-library.ts index f52fc97..8b2d940 100644 --- a/web-ui/src/lib/api/precedent-library.ts +++ b/web-ui/src/lib/api/precedent-library.ts @@ -387,6 +387,9 @@ export function isCommitteeCitation(citation: string): boolean { export type InternalDecisionUploadInput = { file: File; case_number: string; + /** Full citation (מראה-מקום), stored as citation_formatted. Distinct from + * the canonical case_number identifier. */ + citation?: string; chair_name: string; district: CommitteeDistrict | string; case_name?: string; @@ -406,6 +409,7 @@ export function useUploadInternalDecision() { const fd = new FormData(); fd.append("file", input.file); fd.append("case_number", input.case_number); + if (input.citation) fd.append("citation", input.citation); fd.append("chair_name", input.chair_name); fd.append("district", input.district); if (input.case_name) fd.append("case_name", input.case_name); @@ -488,6 +492,7 @@ export function useUnlinkRelatedCase(caseId: string) { } export type PrecedentPatch = Partial<{ + case_number: string; case_name: string; court: string; decision_date: string; diff --git a/web-ui/src/lib/api/types.ts b/web-ui/src/lib/api/types.ts index 965a03e..e01f7ab 100644 --- a/web-ui/src/lib/api/types.ts +++ b/web-ui/src/lib/api/types.ts @@ -267,7 +267,11 @@ export interface paths { delete: operations["training_corpus_delete_api_training_corpus__corpus_id__delete"]; options?: never; head?: never; - patch?: never; + /** + * Training Corpus Patch + * @description Update metadata fields on a corpus row. Only provided fields are touched. + */ + patch: operations["training_corpus_patch_api_training_corpus__corpus_id__patch"]; trace?: never; }; "/api/training/corpus": { @@ -279,7 +283,12 @@ export interface paths { }; /** * Training Corpus List - * @description List all decisions currently in the style corpus. + * @description List all decisions currently in the style corpus, with enriched metadata. + * + * Joins to ``documents`` via FK when available, falling back to the + * title-token match used in the chunking pipeline so legacy rows with + * ``style_corpus.document_id IS NULL`` still resolve to their page_count + * and chunk counts. */ get: operations["training_corpus_list_api_training_corpus_get"]; put?: never; @@ -290,6 +299,251 @@ export interface paths { patch?: never; trace?: never; }; + "/api/training/chat/conversations": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Chat List Conversations */ + get: operations["chat_list_conversations_api_training_chat_conversations_get"]; + put?: never; + /** + * Chat Create Conversation + * @description Create a new style-agent chat conversation. + */ + post: operations["chat_create_conversation_api_training_chat_conversations_post"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/training/chat/conversations/{conv_id}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Chat Get Conversation */ + get: operations["chat_get_conversation_api_training_chat_conversations__conv_id__get"]; + put?: never; + post?: never; + /** Chat Delete Conversation */ + delete: operations["chat_delete_conversation_api_training_chat_conversations__conv_id__delete"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/training/chat/conversations/{conv_id}/messages": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Chat Send Message + * @description Send a user message; stream the assistant response as SSE. + * + * Proxies through ``web.chat_proxy.stream_chat_message`` to the + * legal-chat-service running on the host. + */ + post: operations["chat_send_message_api_training_chat_conversations__conv_id__messages_post"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/training/chat/health": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Chat Health + * @description Probe legal-chat-service liveness from inside the container. + * + * Useful when the UI wants to gracefully degrade ("שירות הצ'אט אינו + * זמין") instead of letting messages fail mid-stream. + */ + get: operations["chat_health_api_training_chat_health_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/training/curator/prompt": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get Curator Prompt + * @description Return the hermes-curator agent's prompt (read-only) + Gitea source URL. + * + * The file is the canonical source of how the curator analyzes Daphna's + * final decisions. Changes go through git/Gitea, not the UI — the UI just + * surfaces it for transparency. + */ + get: operations["get_curator_prompt_api_training_curator_prompt_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/training/curator/style-analyzer-prompt": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get Style Analyzer Prompt + * @description Return the system prompt that style_analyzer.py uses to extract patterns. + * + * Surfaces the *training-time* prompt (Claude Opus 1M context) so the + * chair can compare it against the curator's post-export prompt. Both + * are shown side-by-side in the curator-portrait tab. + */ + get: operations["get_style_analyzer_prompt_api_training_curator_style_analyzer_prompt_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/training/curator/stats": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get Curator Stats + * @description Cheap aggregate stats over decision_lessons + style_corpus. + * + * Used by the Curator-Portrait tab to show "10 curator findings across 24 + * decisions". We deliberately keep this server-side and aggregate so the + * UI can render a single card without fanning out N queries. + */ + get: operations["get_curator_stats_api_training_curator_stats_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/training/curator/proposals": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List Curator Proposals + * @description List proposed-change files in data/curator-proposals/, newest first. + */ + get: operations["list_curator_proposals_api_training_curator_proposals_get"]; + put?: never; + /** + * Create Curator Proposal + * @description Save a proposed change to the curator prompt as a file on disk. + * + * No automatic commit, no overwrite — the chair (chaim) reviews the + * file manually and applies it through git. This is intentional: the + * prompt is too load-bearing to mutate from a web UI. + */ + post: operations["create_curator_proposal_api_training_curator_proposals_post"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/training/corpus/{corpus_id}/lessons": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** List Corpus Lessons */ + get: operations["list_corpus_lessons_api_training_corpus__corpus_id__lessons_get"]; + put?: never; + /** Add Corpus Lesson */ + post: operations["add_corpus_lesson_api_training_corpus__corpus_id__lessons_post"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/training/lessons/{lesson_id}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** Delete Corpus Lesson */ + delete: operations["delete_corpus_lesson_api_training_lessons__lesson_id__delete"]; + options?: never; + head?: never; + /** Patch Corpus Lesson */ + patch: operations["patch_corpus_lesson_api_training_lessons__lesson_id__patch"]; + trace?: never; + }; + "/api/training/corpus/{corpus_id}/full-text": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Training Corpus Full Text + * @description Return the proofread full_text for a single corpus row. + * + * Kept out of the list endpoint because full_text is large (50K-650K chars + * per decision) and the table view only needs counts. The drawer fetches + * it on demand when the chair opens the "content" tab. + */ + get: operations["training_corpus_full_text_api_training_corpus__corpus_id__full_text_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/system/tasks": { parameters: { query?: never; @@ -1317,6 +1571,10 @@ export interface paths { /** * Api Export Docx * @description Trigger DOCX export for a case. + * + * On a successful export, fires a fire-and-forget webhook to the + * Paperclip plugin so it can attach a "final-decision" document + * (markdown body + download link) to the linked issue. */ post: operations["api_export_docx_api_cases__case_number__export_docx_post"]; delete?: never; @@ -1908,15 +2166,27 @@ export interface paths { put?: never; /** * Api Extract Appraiser Facts - * @description Run structured extraction of plans + permits from every appraisal - * document in the case, and detect conflicts between appraisers. + * @description Queue appraiser-fact extraction by waking the legal-analyst agent. * - * Blocks if any appraisal document is missing metadata.appraiser_side — - * the chair must tag every appraisal (committee / appellant / deciding) - * before extraction can identify the deciding appraiser's governing view. + * The extraction itself calls `claude_session.query_json()`, which shells + * out to the local `claude` CLI — present on the agent host, **absent in + * this FastAPI container**. So we cannot run the extractor inline here. * - * Returns the extractor's summary dict as-is. Shape: - * {"status": "completed"|"sides_missing"|"no_appraisals", ...} + * Instead we delegate: create a child Paperclip issue under the case's + * main issue, assigned to the analyst of the correct company, and trigger + * a wakeup with `mutation: extract_appraiser_facts`. The analyst runs the + * MCP tool locally and posts results as a comment. + * + * Pre-check: short-circuits with `sides_missing` if any appraisal is + * untagged, so the chair gets immediate feedback without spinning up an + * agent for nothing. The check uses `_validate_sides_tagged` against the + * documents already in the DB — no LLM call, safe to run in-container. + * + * Response shape: + * {"status": "queued", "sub_issue_id", "analyst_id", "main_issue_id"} + * or {"status": "sides_missing", "missing": [...], "message": "..."} + * or {"status": "no_appraisals", ...} + * or {"status": "skipped", "reason": "no_api_key"|"no_analyst"|"no_issue"} */ post: operations["api_extract_appraiser_facts_api_cases__case_number__extract_appraiser_facts_post"]; delete?: never; @@ -2009,6 +2279,28 @@ export interface paths { patch?: never; trace?: never; }; + "/api/chair/pending": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Api Chair Pending + * @description מרכז אישורים — דפנה: מאגד את כל השערים האנושיים (INV-G10) הממתינים להכרעת + * היו"ר במקום אחד, כדי שאף פריט לא יישכח. כל קטגוריה מחזירה ספירה + מדגם + קישור + * למקום הטיפול. כל ספירה היא שאילתת-מקור ישירה (לא נגזרת מטמונה). + */ + get: operations["api_chair_pending_api_chair_pending_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/precedent-library/upload": { parameters: { query?: never; @@ -2209,6 +2501,13 @@ export interface paths { /** * Internal Decisions Upload * @description Upload a planning appeals-committee decision to the internal corpus. + * + * ``case_number`` is the canonical identifier (e.g. "8027-25"); ``citation`` + * is the full מראה-מקום (e.g. "ערר ... 8027/25 פלוני נ' הוועדה ..."). They + * are distinct fields — previously the UI sent the citation as case_number, + * leaving the identifier polluted and citation_formatted empty until the + * metadata extractor ran. citation is stored as citation_formatted up-front + * so it survives even if extraction is delayed. */ post: operations["internal_decisions_upload_api_internal_decisions_upload_post"]; delete?: never; @@ -2314,6 +2613,10 @@ export interface paths { * Missing Precedent Create * @description Log a new missing precedent (status='open'). Dedupes by * (citation, cited_in_case_id) — duplicate POST returns the existing row. + * + * On first insert (non-duplicate) emits a webhook to the Paperclip + * plugin so it can ask Daphna via an ``askUserQuestions`` interaction + * whether to upload the missing precedent. */ post: operations["missing_precedent_create_api_missing_precedents_post"]; delete?: never; @@ -2366,6 +2669,52 @@ export interface paths { patch?: never; trace?: never; }; + "/api/admin/rag-metrics": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Api Rag Metrics + * @description Return nDCG@k aggregates for the RAG retrieval feedback loop. + * + * Args: + * weeks: window for "recent" metrics (default 12). + * k: nDCG cutoff (default 10). + */ + get: operations["api_rag_metrics_api_admin_rag_metrics_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/admin/rag-metrics/infer": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Api Rag Metrics Infer + * @description Run auto-inference: for every finalized case, mark its cited + * precedents as ``relevance_score=3`` against any search_log where + * they appeared in the top-K. Idempotent. + */ + post: operations["api_rag_metrics_infer_api_admin_rag_metrics_infer_post"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; } export type webhooks = Record; export interface components { @@ -2453,6 +2802,11 @@ export interface components { * @default */ case_name: string; + /** + * Citation + * @default + */ + citation: string; /** * Court * @default @@ -2776,6 +3130,21 @@ export interface components { */ position: string; }; + /** ChatConversationCreate */ + ChatConversationCreate: { + /** + * Title + * @default שיחה חדשה + */ + title: string; + /** Style Corpus Id */ + style_corpus_id?: string | null; + }; + /** ChatMessageRequest */ + ChatMessageRequest: { + /** Content */ + content: string; + }; /** ClassifyRequest */ ClassifyRequest: { /** Filename */ @@ -2813,6 +3182,15 @@ export interface components { */ subject_categories: string[]; }; + /** CuratorProposal */ + CuratorProposal: { + /** Title */ + title: string; + /** Proposed Change */ + proposed_change: string; + /** Rationale */ + rationale: string; + }; /** DirectionRequest */ DirectionRequest: { /** Direction Doc */ @@ -2881,6 +3259,30 @@ export interface components { [key: string]: unknown; }; }; + /** LessonCreate */ + LessonCreate: { + /** Lesson Text */ + lesson_text: string; + /** + * Category + * @default general + */ + category: string; + /** + * Source + * @default manual + */ + source: string; + }; + /** LessonPatch */ + LessonPatch: { + /** Lesson Text */ + lesson_text?: string | null; + /** Category */ + category?: string | null; + /** Applied To Skill */ + applied_to_skill?: boolean | null; + }; /** McpEnvUpdateRequest */ McpEnvUpdateRequest: { /** Value */ @@ -3003,6 +3405,8 @@ export interface components { }; /** PrecedentUpdateRequest */ PrecedentUpdateRequest: { + /** Case Number */ + case_number?: string | null; /** Case Name */ case_name?: string | null; /** Court */ @@ -3033,6 +3437,8 @@ export interface components { district?: string | null; /** Chair Name */ chair_name?: string | null; + /** Citation Formatted */ + citation_formatted?: string | null; }; /** ReviseRequest */ ReviseRequest: { @@ -3063,6 +3469,31 @@ export interface components { */ company_name: string; }; + /** + * TrainingCorpusPatch + * @description Editable metadata fields on a style_corpus row. + * + * full_text is intentionally NOT editable — the corpus is write-once. + * For corrections, re-upload the decision via /api/training/upload. + */ + TrainingCorpusPatch: { + /** Decision Number */ + decision_number?: string | null; + /** Decision Date */ + decision_date?: string | null; + /** Subject Categories */ + subject_categories?: string[] | null; + /** Summary */ + summary?: string | null; + /** Outcome */ + outcome?: string | null; + /** Key Principles */ + key_principles?: string[] | null; + /** Appeal Subtype */ + appeal_subtype?: string | null; + /** Practice Area */ + practice_area?: string | null; + }; /** TrainingUploadRequest */ TrainingUploadRequest: { /** Filename */ @@ -3456,6 +3887,41 @@ export interface operations { }; }; }; + training_corpus_patch_api_training_corpus__corpus_id__patch: { + parameters: { + query?: never; + header?: never; + path: { + corpus_id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["TrainingCorpusPatch"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; training_corpus_list_api_training_corpus_get: { parameters: { query?: never; @@ -3476,6 +3942,463 @@ export interface operations { }; }; }; + chat_list_conversations_api_training_chat_conversations_get: { + parameters: { + query?: { + limit?: number; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + chat_create_conversation_api_training_chat_conversations_post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ChatConversationCreate"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + chat_get_conversation_api_training_chat_conversations__conv_id__get: { + parameters: { + query?: never; + header?: never; + path: { + conv_id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + chat_delete_conversation_api_training_chat_conversations__conv_id__delete: { + parameters: { + query?: never; + header?: never; + path: { + conv_id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + chat_send_message_api_training_chat_conversations__conv_id__messages_post: { + parameters: { + query?: never; + header?: never; + path: { + conv_id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ChatMessageRequest"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + chat_health_api_training_chat_health_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + get_curator_prompt_api_training_curator_prompt_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + get_style_analyzer_prompt_api_training_curator_style_analyzer_prompt_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + get_curator_stats_api_training_curator_stats_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + list_curator_proposals_api_training_curator_proposals_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; + create_curator_proposal_api_training_curator_proposals_post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CuratorProposal"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + list_corpus_lessons_api_training_corpus__corpus_id__lessons_get: { + parameters: { + query?: never; + header?: never; + path: { + corpus_id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + add_corpus_lesson_api_training_corpus__corpus_id__lessons_post: { + parameters: { + query?: never; + header?: never; + path: { + corpus_id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["LessonCreate"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + delete_corpus_lesson_api_training_lessons__lesson_id__delete: { + parameters: { + query?: never; + header?: never; + path: { + lesson_id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + patch_corpus_lesson_api_training_lessons__lesson_id__patch: { + parameters: { + query?: never; + header?: never; + path: { + lesson_id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["LessonPatch"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + training_corpus_full_text_api_training_corpus__corpus_id__full_text_get: { + parameters: { + query?: never; + header?: never; + path: { + corpus_id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; system_tasks_api_system_tasks_get: { parameters: { query?: never; @@ -6108,6 +7031,26 @@ export interface operations { }; }; }; + api_chair_pending_api_chair_pending_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; precedent_library_upload_api_precedent_library_upload_post: { parameters: { query?: never; @@ -6865,4 +7808,67 @@ export interface operations { }; }; }; + api_rag_metrics_api_admin_rag_metrics_get: { + parameters: { + query?: { + weeks?: number; + k?: number; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + api_rag_metrics_infer_api_admin_rag_metrics_infer_post: { + parameters: { + query?: { + limit?: number | null; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; }