|
|
|
|
|
const API_BASE_URL = import.meta.env.PROD ? '' : 'http://localhost:8000'; |
|
|
|
|
|
|
|
|
const DUMMY_MODE = false; |
|
|
|
|
|
interface GenerateRequest { |
|
|
model_name: string; |
|
|
prompt: string; |
|
|
system_prompt: string; |
|
|
max_tokens: number; |
|
|
temperature: number; |
|
|
top_p: number; |
|
|
top_k: number; |
|
|
image?: string; |
|
|
} |
|
|
|
|
|
interface GenerateResponse { |
|
|
generated_text: string; |
|
|
model_used: string; |
|
|
} |
|
|
|
|
|
interface ProgressCallback { |
|
|
status: 'loading' | 'generating' | 'ready' | 'error'; |
|
|
progress?: number; |
|
|
message?: string; |
|
|
} |
|
|
|
|
|
interface GenerateOptions extends GenerateRequest { |
|
|
onToken?: (token: string) => void; |
|
|
onProgress?: (progress: ProgressCallback) => void; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const DUMMY_RESPONSES = [ |
|
|
`<start_working_out> |
|
|
Kullanıcı 121 sayısının karekökünü soruyor. |
|
|
|
|
|
Adım 1: Problemi Analiz Et |
|
|
- Hedef: $\\sqrt{121}$ değerini bulmak. |
|
|
- Hangi sayıyı kendisiyle çarparsam 121 eder? |
|
|
|
|
|
Adım 2: Tahmin Yürütme |
|
|
- 10 x 10 = 100 (Çok küçük) |
|
|
- 12 x 12 = 144 (Çok büyük) |
|
|
- Cevap 10 ile 12 arasında olmalı. |
|
|
|
|
|
Adım 3: Hesaplama |
|
|
- Sonu 1 ile biten bir sayı arıyorum (121). |
|
|
- 11 sayısını deneyelim: |
|
|
11 x 10 = 110 |
|
|
110 + 11 = 121 |
|
|
|
|
|
Sonuç doğrulandı. |
|
|
<end_working_out> |
|
|
|
|
|
<SOLUTION> |
|
|
121 sayısının karekökü **11**'dir. |
|
|
|
|
|
Matematiksel işlemi şöyledir: |
|
|
$$ \\sqrt{121} = 11 $$ |
|
|
|
|
|
Sağlaması: |
|
|
11 x 11 = 121 |
|
|
</SOLUTION>` |
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function generateResponse(options: GenerateOptions): Promise<void> { |
|
|
const { |
|
|
model_name, |
|
|
prompt, |
|
|
system_prompt, |
|
|
max_tokens, |
|
|
temperature, |
|
|
top_p, |
|
|
top_k, |
|
|
image, |
|
|
onToken, |
|
|
onProgress |
|
|
} = options; |
|
|
|
|
|
|
|
|
if (DUMMY_MODE) { |
|
|
try { |
|
|
onProgress?.({ status: 'loading', message: 'Model yükleniyor...' }); |
|
|
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 800)); |
|
|
|
|
|
onProgress?.({ status: 'generating', message: 'Yanıt oluşturuluyor...' }); |
|
|
|
|
|
|
|
|
const dummyText = DUMMY_RESPONSES[Math.floor(Math.random() * DUMMY_RESPONSES.length)]; |
|
|
|
|
|
|
|
|
let currentText = ''; |
|
|
const words = dummyText.split(' '); |
|
|
|
|
|
for (let i = 0; i < words.length; i++) { |
|
|
currentText += (i > 0 ? ' ' : '') + words[i]; |
|
|
onToken?.(currentText); |
|
|
|
|
|
|
|
|
const delay = 50 + Math.random() * 100; |
|
|
await new Promise(resolve => setTimeout(resolve, delay)); |
|
|
} |
|
|
|
|
|
onProgress?.({ status: 'ready', message: 'Tamamlandı' }); |
|
|
|
|
|
} catch (error) { |
|
|
console.error('Dummy response error:', error); |
|
|
onProgress?.({ |
|
|
status: 'error', |
|
|
message: 'Dummy yanıt oluşturulurken hata oluştu' |
|
|
}); |
|
|
throw error; |
|
|
} |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
try { |
|
|
onProgress?.({ status: 'loading', message: 'Model yükleniyor...' }); |
|
|
|
|
|
const requestBody: GenerateRequest = { |
|
|
model_name, |
|
|
prompt, |
|
|
system_prompt, |
|
|
max_tokens, |
|
|
temperature, |
|
|
top_p, |
|
|
top_k, |
|
|
image |
|
|
}; |
|
|
|
|
|
const response = await fetch(`${API_BASE_URL}/generate`, { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json', |
|
|
}, |
|
|
body: JSON.stringify(requestBody), |
|
|
}); |
|
|
|
|
|
if (!response.ok) { |
|
|
const error = await response.json().catch(() => ({ detail: 'Unknown error' })); |
|
|
throw new Error(error.detail || `HTTP error! status: ${response.status}`); |
|
|
} |
|
|
|
|
|
onProgress?.({ status: 'generating', message: 'Yanıt oluşturuluyor...' }); |
|
|
|
|
|
const data: GenerateResponse = await response.json(); |
|
|
|
|
|
if (onToken) { |
|
|
const text = data.generated_text; |
|
|
let currentText = ''; |
|
|
|
|
|
for (let i = 0; i < text.length; i++) { |
|
|
currentText += text[i]; |
|
|
onToken(currentText); |
|
|
|
|
|
if (i % 5 === 0) { |
|
|
await new Promise(resolve => setTimeout(resolve, 10)); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
onProgress?.({ status: 'ready', message: 'Tamamlandı' }); |
|
|
|
|
|
} catch (error) { |
|
|
console.error('Error generating response:', error); |
|
|
onProgress?.({ |
|
|
status: 'error', |
|
|
message: error instanceof Error ? error.message : 'Bir hata oluştu' |
|
|
}); |
|
|
throw error; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function getAvailableModels() { |
|
|
if (DUMMY_MODE) { |
|
|
|
|
|
return [ |
|
|
{ name: "Gemma 3 1B Turkish", path: "dummy/gemma-1b" }, |
|
|
{ name: "Gemma 3 12B Turkish", path: "dummy/gemma-12b" }, |
|
|
]; |
|
|
} |
|
|
|
|
|
try { |
|
|
const response = await fetch(`${API_BASE_URL}/models`); |
|
|
if (!response.ok) { |
|
|
throw new Error(`HTTP error! status: ${response.status}`); |
|
|
} |
|
|
const data = await response.json(); |
|
|
return data.models; |
|
|
} catch (error) { |
|
|
console.error('Error fetching models:', error); |
|
|
throw error; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function checkApiHealth(): Promise<boolean> { |
|
|
if (DUMMY_MODE) { |
|
|
return true; |
|
|
} |
|
|
|
|
|
try { |
|
|
const response = await fetch(`${API_BASE_URL}/`); |
|
|
return response.ok; |
|
|
} catch (error) { |
|
|
console.error('API health check failed:', error); |
|
|
return false; |
|
|
} |
|
|
} |