feat: iddianame-first case summary + remove hardcoded AI endpoint
- summarizeCase: if an iddianame is among the case's documents, run a narrow first-pass analysis on it alone (isnatEdilenSuc, iddiaOzeti, onemliTarihler), then feed that as context into the general case-wide evaluation instead of treating every document equally. - ANALYSIS_SYSTEM_PROMPT no longer asks the AI to guess "taraflar" - that now comes from real UYAP data (cases.parties) instead. - Removed the hardcoded RunPod proxy URL fallback from every call site (document/chat/precedent controllers + lib/openai.ts) - it was a real infra endpoint checked into source. New lib/aiConfig.ts throws if RUNPOD_API_BASE_URL isn't set rather than silently falling back to it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
af5a03db92
commit
c939dcf564
@@ -4,12 +4,14 @@ import { AuthenticatedRequest } from '../middleware/auth';
|
||||
import * as officeParser from 'officeparser';
|
||||
import Tesseract from 'tesseract.js';
|
||||
import { findOrCreateCaseByTitle } from '../lib/caseLookup';
|
||||
import { getAiConfig } from '../lib/aiConfig';
|
||||
const heicConvert = require('heic-convert');
|
||||
|
||||
// "taraflar" (davacı/davalı/sanık) burada YOK — o bilgiyi UYAP Evrak İndirici
|
||||
// eklentisinden gerçek veri olarak alıyoruz (cases.parties), AI'ye tahmin ettirmiyoruz.
|
||||
const ANALYSIS_SYSTEM_PROMPT = `
|
||||
Sen uzman bir Türk avukatısın. Sana verilen dava dosyasını/belgeyi okuyup analiz edeceksin.
|
||||
Çıktıyı KESİNLİKLE geçerli bir JSON formatında vermelisin. JSON şu anahtarları içermelidir:
|
||||
- "taraflar": (string) Davacı ve Davalı bilgileri
|
||||
- "tarihler": (string) Belgedeki kritik tarihler (Dava tarihi, tebliğ vb.)
|
||||
- "hukukiDayanak": (string) Belgedeki ilgili kanun maddeleri ve hukuki temeller
|
||||
- "ilkDegerlendirme": (string) Dosyaya dair ilk stratejik ve hukuki değerlendirmen
|
||||
@@ -17,12 +19,20 @@ const ANALYSIS_SYSTEM_PROMPT = `
|
||||
Sadece ve sadece JSON döndür, başka hiçbir açıklama ekleme.
|
||||
`;
|
||||
|
||||
// uploadDocument, registerLocalDocument ve summarizeCase'in (case.controller.ts)
|
||||
// ortak kullandığı AI analiz adımı: çıkarılmış metni modele gönderip yapılandırılmış
|
||||
// özet JSON'u üretir.
|
||||
export async function runDocumentAnalysis(extractedText: string): Promise<{ summaryJson: any; aiModel: string }> {
|
||||
const aiModel = process.env.AI_MODEL || 'mizan-fixed';
|
||||
const runpodUrl = process.env.RUNPOD_API_BASE_URL || 'https://q190env94stwis-11434.proxy.runpod.net';
|
||||
// summarizeCase (case.controller.ts) dosyada iddianame bulursa önce SADECE onun
|
||||
// üzerinden bir ön çıkarım yapıyor, genel değerlendirme buna dayanıyor.
|
||||
const IDDIANAME_SYSTEM_PROMPT = `
|
||||
Sen uzman bir Türk ceza avukatısın. Sana bir iddianame metni verilecek.
|
||||
Çıktıyı KESİNLİKLE geçerli bir JSON formatında ver. JSON şu anahtarları içermelidir:
|
||||
- "isnatEdilenSuc": (string) İsnat edilen suç(lar) ve ilgili kanun maddeleri
|
||||
- "iddiaOzeti": (string) İddia makamının olay örgüsü, delilleri ve talebinin özeti
|
||||
- "onemliTarihler": (string) İddianamedeki kritik tarihler
|
||||
|
||||
Sadece ve sadece JSON döndür, başka hiçbir açıklama ekleme.
|
||||
`;
|
||||
|
||||
async function callAiModel(systemPrompt: string, userText: string): Promise<{ resultJson: any; aiModel: string }> {
|
||||
const { runpodUrl, aiModel } = getAiConfig();
|
||||
|
||||
const response = await fetch(`${runpodUrl}/v1/chat/completions`, {
|
||||
method: 'POST',
|
||||
@@ -30,8 +40,8 @@ export async function runDocumentAnalysis(extractedText: string): Promise<{ summ
|
||||
body: JSON.stringify({
|
||||
model: aiModel,
|
||||
messages: [
|
||||
{ role: 'system', content: ANALYSIS_SYSTEM_PROMPT },
|
||||
{ role: 'user', content: extractedText.substring(0, 15000) }
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userText.substring(0, 15000) }
|
||||
],
|
||||
think: false,
|
||||
stream: false,
|
||||
@@ -44,14 +54,27 @@ export async function runDocumentAnalysis(extractedText: string): Promise<{ summ
|
||||
|
||||
const data = await response.json();
|
||||
const aiContent = data.message?.content || (data.choices && data.choices[0]?.message?.content);
|
||||
let summaryJson: any = {};
|
||||
let resultJson: any = {};
|
||||
try {
|
||||
summaryJson = JSON.parse(aiContent || '{}');
|
||||
resultJson = JSON.parse(aiContent || '{}');
|
||||
} catch (e) {
|
||||
console.error('Failed to parse AI response as JSON:', aiContent);
|
||||
summaryJson = { error: 'AI did not return valid JSON', raw: aiContent };
|
||||
resultJson = { error: 'AI did not return valid JSON', raw: aiContent };
|
||||
}
|
||||
return { summaryJson, aiModel };
|
||||
return { resultJson, aiModel };
|
||||
}
|
||||
|
||||
// uploadDocument, registerLocalDocument ve summarizeCase'in (case.controller.ts)
|
||||
// ortak kullandığı genel analiz adımı.
|
||||
export async function runDocumentAnalysis(extractedText: string): Promise<{ summaryJson: any; aiModel: string }> {
|
||||
const { resultJson, aiModel } = await callAiModel(ANALYSIS_SYSTEM_PROMPT, extractedText);
|
||||
return { summaryJson: resultJson, aiModel };
|
||||
}
|
||||
|
||||
// summarizeCase'in iddianame ön-analizi için kullandığı, dar kapsamlı adım.
|
||||
export async function runIddianameAnalysis(extractedText: string): Promise<{ summaryJson: any; aiModel: string }> {
|
||||
const { resultJson, aiModel } = await callAiModel(IDDIANAME_SYSTEM_PROMPT, extractedText);
|
||||
return { summaryJson: resultJson, aiModel };
|
||||
}
|
||||
|
||||
// UYAP Evrak İndirici eklentisinden gelen, Electron ana sürecinde YERELDE metni
|
||||
|
||||
Reference in New Issue
Block a user