55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
import { getLlamacppUrl, getLlamacppApiKey, getLlamacppPreamble } from '../config.js';
|
|
|
|
interface LlamaRequest {
|
|
messages: Array<{ role: string; content: string }>;
|
|
}
|
|
|
|
interface LlamaChatChoice {
|
|
message: {
|
|
content: string;
|
|
};
|
|
}
|
|
|
|
interface LlamaResponse {
|
|
choices?: LlamaChatChoice[];
|
|
}
|
|
|
|
export const llamacppService = {
|
|
async chat(messages: Array<{ role: string; content: string }>): Promise<string> {
|
|
const apiUrl = getLlamacppUrl();
|
|
if (!apiUrl) {
|
|
return '';
|
|
}
|
|
|
|
const apiKey = getLlamacppApiKey();
|
|
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
|
|
if (apiKey) {
|
|
headers['Authorization'] = `Bearer ${apiKey}`;
|
|
}
|
|
|
|
const response = await fetch(apiUrl, {
|
|
method: 'POST',
|
|
headers,
|
|
body: JSON.stringify({ messages } satisfies LlamaRequest),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const text = await response.text().catch(() => '');
|
|
throw new Error(`llama.cpp request failed (${response.status}): ${text.slice(0, 300)}`);
|
|
}
|
|
|
|
const data = (await response.json()) as LlamaResponse;
|
|
const content = data.choices?.[0]?.message?.content?.trim() ?? '';
|
|
return content;
|
|
},
|
|
|
|
async chatWithPreamble(userText: string): Promise<string> {
|
|
const preamble = getLlamacppPreamble();
|
|
const messages = preamble ? [
|
|
{ role: 'system', content: preamble },
|
|
{ role: 'user', content: userText },
|
|
] : [{ role: 'user', content: userText }];
|
|
return this.chat(messages);
|
|
},
|
|
};
|