Add biome config and update plugin source + dependencies
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
373
src/legal-api.ts
373
src/legal-api.ts
@@ -3,227 +3,260 @@
|
||||
*/
|
||||
|
||||
export class LegalApi {
|
||||
constructor(private baseUrl: string) {}
|
||||
constructor(private baseUrl: string) {}
|
||||
|
||||
private async request<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
const res = await fetch(`${this.baseUrl}${path}`, {
|
||||
...init,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...init?.headers,
|
||||
},
|
||||
});
|
||||
if (!res.ok) {
|
||||
const text = await res.text();
|
||||
throw new Error(`Legal API ${res.status}: ${text}`);
|
||||
}
|
||||
return res.json() as Promise<T>;
|
||||
}
|
||||
private async request<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
const res = await fetch(`${this.baseUrl}${path}`, {
|
||||
...init,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...init?.headers,
|
||||
},
|
||||
});
|
||||
if (!res.ok) {
|
||||
const text = await res.text();
|
||||
throw new Error(`Legal API ${res.status}: ${text}`);
|
||||
}
|
||||
return res.json() as Promise<T>;
|
||||
}
|
||||
|
||||
async listCases(): Promise<CaseSummary[]> {
|
||||
return this.request("/api/cases");
|
||||
}
|
||||
async listCases(): Promise<CaseSummary[]> {
|
||||
return this.request("/api/cases");
|
||||
}
|
||||
|
||||
async getCase(caseNumber: string): Promise<CaseDetails> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/details`);
|
||||
}
|
||||
async getCase(caseNumber: string): Promise<CaseDetails> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/details`);
|
||||
}
|
||||
|
||||
async createCase(data: CaseCreateInput): Promise<CaseDetails> {
|
||||
return this.request("/api/cases/create", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
async createCase(data: CaseCreateInput): Promise<CaseDetails> {
|
||||
return this.request("/api/cases/create", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
||||
async updateCase(caseNumber: string, data: CaseUpdateInput): Promise<CaseDetails> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
async updateCase(
|
||||
caseNumber: string,
|
||||
data: CaseUpdateInput,
|
||||
): Promise<CaseDetails> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
||||
async getCaseStatus(caseNumber: string): Promise<WorkflowStatus> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/status`);
|
||||
}
|
||||
async getCaseStatus(caseNumber: string): Promise<WorkflowStatus> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/status`);
|
||||
}
|
||||
|
||||
async search(query: string, limit = 10, sectionType = ""): Promise<SearchResult[]> {
|
||||
const params = new URLSearchParams({ query, limit: String(limit) });
|
||||
if (sectionType) params.set("section_type", sectionType);
|
||||
return this.request(`/api/search?${params}`);
|
||||
}
|
||||
async search(
|
||||
query: string,
|
||||
limit = 10,
|
||||
sectionType = "",
|
||||
): Promise<SearchResult[]> {
|
||||
const params = new URLSearchParams({ query, limit: String(limit) });
|
||||
if (sectionType) params.set("section_type", sectionType);
|
||||
return this.request(`/api/search?${params}`);
|
||||
}
|
||||
|
||||
async searchCase(caseNumber: string, query: string, limit = 10): Promise<SearchResult[]> {
|
||||
const params = new URLSearchParams({ query, limit: String(limit) });
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/search?${params}`);
|
||||
}
|
||||
async searchCase(
|
||||
caseNumber: string,
|
||||
query: string,
|
||||
limit = 10,
|
||||
): Promise<SearchResult[]> {
|
||||
const params = new URLSearchParams({ query, limit: String(limit) });
|
||||
return this.request(
|
||||
`/api/cases/${encodeURIComponent(caseNumber)}/search?${params}`,
|
||||
);
|
||||
}
|
||||
|
||||
async getTemplate(caseNumber: string): Promise<{ template: string }> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/template`);
|
||||
}
|
||||
async getTemplate(caseNumber: string): Promise<{ template: string }> {
|
||||
return this.request(
|
||||
`/api/cases/${encodeURIComponent(caseNumber)}/template`,
|
||||
);
|
||||
}
|
||||
|
||||
async getProcessingStatus(): Promise<ProcessingStatus> {
|
||||
return this.request("/api/processing-status");
|
||||
}
|
||||
async getProcessingStatus(): Promise<ProcessingStatus> {
|
||||
return this.request("/api/processing-status");
|
||||
}
|
||||
|
||||
async health(): Promise<{ status: string }> {
|
||||
return this.request("/health");
|
||||
}
|
||||
async health(): Promise<{ status: string }> {
|
||||
return this.request("/health");
|
||||
}
|
||||
|
||||
// ── New methods for expanded workflow ──
|
||||
// ── New methods for expanded workflow ──
|
||||
|
||||
async listDocuments(caseNumber: string): Promise<DocumentInfo[]> {
|
||||
const details = await this.getCase(caseNumber);
|
||||
return details.documents || [];
|
||||
}
|
||||
async listDocuments(caseNumber: string): Promise<DocumentInfo[]> {
|
||||
const details = await this.getCase(caseNumber);
|
||||
return details.documents || [];
|
||||
}
|
||||
|
||||
async getDocumentText(docId: string): Promise<string> {
|
||||
return this.request(`/api/documents/${docId}/text`);
|
||||
}
|
||||
async getDocumentText(docId: string): Promise<string> {
|
||||
return this.request(`/api/documents/${docId}/text`);
|
||||
}
|
||||
|
||||
async findSimilarCases(caseNumber: string): Promise<SearchResult[]> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/search?query=similar&limit=5`);
|
||||
}
|
||||
async findSimilarCases(caseNumber: string): Promise<SearchResult[]> {
|
||||
return this.request(
|
||||
`/api/cases/${encodeURIComponent(caseNumber)}/search?query=similar&limit=5`,
|
||||
);
|
||||
}
|
||||
|
||||
async setOutcome(caseNumber: string, outcome: string, reasoning?: string): Promise<{ status: string }> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/outcome`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ outcome, reasoning: reasoning || "" }),
|
||||
});
|
||||
}
|
||||
async setOutcome(
|
||||
caseNumber: string,
|
||||
outcome: string,
|
||||
reasoning?: string,
|
||||
): Promise<{ status: string }> {
|
||||
return this.request(
|
||||
`/api/cases/${encodeURIComponent(caseNumber)}/outcome`,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify({ outcome, reasoning: reasoning || "" }),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async getClaims(caseNumber: string): Promise<ClaimsResponse> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/claims`);
|
||||
}
|
||||
async getClaims(caseNumber: string): Promise<ClaimsResponse> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/claims`);
|
||||
}
|
||||
|
||||
async setDirection(caseNumber: string, directionDoc: Record<string, unknown>): Promise<{ status: string }> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/direction`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ direction_doc: directionDoc }),
|
||||
});
|
||||
}
|
||||
async setDirection(
|
||||
caseNumber: string,
|
||||
directionDoc: Record<string, unknown>,
|
||||
): Promise<{ status: string }> {
|
||||
return this.request(
|
||||
`/api/cases/${encodeURIComponent(caseNumber)}/direction`,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify({ direction_doc: directionDoc }),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async runQA(caseNumber: string): Promise<QAResponse> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/qa`, {
|
||||
method: "POST",
|
||||
});
|
||||
}
|
||||
async runQA(caseNumber: string): Promise<QAResponse> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/qa`, {
|
||||
method: "POST",
|
||||
});
|
||||
}
|
||||
|
||||
async triggerLearning(caseNumber: string): Promise<{ status: string }> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/learn`, {
|
||||
method: "POST",
|
||||
});
|
||||
}
|
||||
async triggerLearning(caseNumber: string): Promise<{ status: string }> {
|
||||
return this.request(`/api/cases/${encodeURIComponent(caseNumber)}/learn`, {
|
||||
method: "POST",
|
||||
});
|
||||
}
|
||||
|
||||
async getStyleGuide(): Promise<string> {
|
||||
// Return static style guide reference
|
||||
return "ראה skill-legal-decision/SKILL.md — מדריך סגנון מלא של דפנה תמיר";
|
||||
}
|
||||
async getStyleGuide(): Promise<string> {
|
||||
// Return static style guide reference
|
||||
return "ראה skill-legal-decision/SKILL.md — מדריך סגנון מלא של דפנה תמיר";
|
||||
}
|
||||
}
|
||||
|
||||
// Types
|
||||
|
||||
export interface CaseSummary {
|
||||
case_number: string;
|
||||
title: string;
|
||||
status: string;
|
||||
case_number: string;
|
||||
title: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export interface CaseDetails {
|
||||
id: string;
|
||||
case_number: string;
|
||||
title: string;
|
||||
status: string;
|
||||
appellants: string[];
|
||||
respondents: string[];
|
||||
subject: string;
|
||||
property_address: string;
|
||||
expected_outcome: string;
|
||||
documents?: DocumentInfo[];
|
||||
[key: string]: unknown;
|
||||
id: string;
|
||||
case_number: string;
|
||||
title: string;
|
||||
status: string;
|
||||
appellants: string[];
|
||||
respondents: string[];
|
||||
subject: string;
|
||||
property_address: string;
|
||||
expected_outcome: string;
|
||||
documents?: DocumentInfo[];
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export interface CaseCreateInput {
|
||||
case_number: string;
|
||||
title: string;
|
||||
appellants?: string[];
|
||||
respondents?: string[];
|
||||
subject?: string;
|
||||
property_address?: string;
|
||||
permit_number?: string;
|
||||
committee_type?: string;
|
||||
hearing_date?: string;
|
||||
notes?: string;
|
||||
expected_outcome?: string;
|
||||
case_number: string;
|
||||
title: string;
|
||||
appellants?: string[];
|
||||
respondents?: string[];
|
||||
subject?: string;
|
||||
property_address?: string;
|
||||
permit_number?: string;
|
||||
committee_type?: string;
|
||||
hearing_date?: string;
|
||||
notes?: string;
|
||||
expected_outcome?: string;
|
||||
}
|
||||
|
||||
export interface CaseUpdateInput {
|
||||
status?: string;
|
||||
title?: string;
|
||||
subject?: string;
|
||||
notes?: string;
|
||||
hearing_date?: string;
|
||||
decision_date?: string;
|
||||
tags?: string[];
|
||||
expected_outcome?: string;
|
||||
status?: string;
|
||||
title?: string;
|
||||
subject?: string;
|
||||
notes?: string;
|
||||
hearing_date?: string;
|
||||
decision_date?: string;
|
||||
tags?: string[];
|
||||
expected_outcome?: string;
|
||||
}
|
||||
|
||||
export interface DocumentInfo {
|
||||
id: string;
|
||||
title: string;
|
||||
doc_type: string;
|
||||
extraction_status: string;
|
||||
page_count?: number;
|
||||
id: string;
|
||||
title: string;
|
||||
doc_type: string;
|
||||
extraction_status: string;
|
||||
page_count?: number;
|
||||
}
|
||||
|
||||
export interface WorkflowStatus {
|
||||
case_number: string;
|
||||
title: string;
|
||||
status: string;
|
||||
documents: Array<{
|
||||
title: string;
|
||||
type: string;
|
||||
extraction: string;
|
||||
chunks: number;
|
||||
pages?: number;
|
||||
}>;
|
||||
total_documents: number;
|
||||
total_chunks: number;
|
||||
has_draft: boolean;
|
||||
draft_size_bytes: number;
|
||||
next_steps: string[];
|
||||
case_number: string;
|
||||
title: string;
|
||||
status: string;
|
||||
documents: Array<{
|
||||
title: string;
|
||||
type: string;
|
||||
extraction: string;
|
||||
chunks: number;
|
||||
pages?: number;
|
||||
}>;
|
||||
total_documents: number;
|
||||
total_chunks: number;
|
||||
has_draft: boolean;
|
||||
draft_size_bytes: number;
|
||||
next_steps: string[];
|
||||
}
|
||||
|
||||
export interface SearchResult {
|
||||
score: number;
|
||||
case_number?: string;
|
||||
document: string;
|
||||
section: string;
|
||||
page: number;
|
||||
content: string;
|
||||
score: number;
|
||||
case_number?: string;
|
||||
document: string;
|
||||
section: string;
|
||||
page: number;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface ProcessingStatus {
|
||||
cases: number;
|
||||
documents: number;
|
||||
pending_processing: number;
|
||||
chunks: number;
|
||||
style_corpus_entries: number;
|
||||
style_patterns: number;
|
||||
cases: number;
|
||||
documents: number;
|
||||
pending_processing: number;
|
||||
chunks: number;
|
||||
style_corpus_entries: number;
|
||||
style_patterns: number;
|
||||
}
|
||||
|
||||
export interface ClaimsResponse {
|
||||
case_number: string;
|
||||
claims: Record<string, Array<{ party_role: string; claim_text: string; claim_index: number }>>;
|
||||
total: number;
|
||||
case_number: string;
|
||||
claims: Record<
|
||||
string,
|
||||
Array<{ party_role: string; claim_text: string; claim_index: number }>
|
||||
>;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface QAResponse {
|
||||
passed: boolean;
|
||||
checks: Array<{
|
||||
check_name: string;
|
||||
passed: boolean;
|
||||
severity: string;
|
||||
details: string;
|
||||
}>;
|
||||
status: string;
|
||||
passed: boolean;
|
||||
checks: Array<{
|
||||
check_name: string;
|
||||
passed: boolean;
|
||||
severity: string;
|
||||
details: string;
|
||||
}>;
|
||||
status: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user