refactor: move LLM client implementations to utils directory

Co-Authored-By: Han Xiao <han.xiao@jina.ai>
This commit is contained in:
Devin AI 2025-02-05 09:28:56 +00:00
parent 19a938b888
commit 2266706494
2 changed files with 105 additions and 105 deletions

View File

@ -1,5 +1,6 @@
import dotenv from 'dotenv';
import { ProxyAgent, setGlobalDispatcher } from 'undici';
import { GoogleAIWrapper, LocalLLMClient, LLMClient } from './utils/llm-client';
interface ModelConfig {
model: string;
@ -15,111 +16,6 @@ interface ToolConfigs {
agentBeastMode: ModelConfig;
}
import { GoogleGenerativeAI } from '@google/generative-ai';
interface LLMClientConfig {
model: string;
temperature: number;
generationConfig?: {
responseMimeType?: string;
responseSchema?: any;
};
}
interface LLMResponse {
text(): string;
usageMetadata: {
totalTokenCount: number;
};
}
interface LLMClient {
getGenerativeModel(config: LLMClientConfig): {
generateContent(prompt: string): Promise<{
response: LLMResponse;
}>;
};
}
class GoogleAIWrapper implements LLMClient {
private client: GoogleGenerativeAI;
constructor(apiKey: string) {
this.client = new GoogleGenerativeAI(apiKey);
}
getGenerativeModel(config: LLMClientConfig) {
const model = this.client.getGenerativeModel({
model: config.model,
generationConfig: {
temperature: config.temperature,
...(config.generationConfig || {})
}
});
return {
generateContent: async (prompt: string) => {
const result = await model.generateContent(prompt);
return {
response: {
text: () => result.response.text(),
usageMetadata: {
totalTokenCount: result.response.usageMetadata?.totalTokenCount ?? 0
}
}
};
}
};
}
}
class LocalLLMClient implements LLMClient {
constructor(
private hostname: string,
private port: string,
private model: string
) {}
getGenerativeModel(config: LLMClientConfig) {
return {
generateContent: async (prompt: string) => {
const response = await fetch(`http://${this.hostname}:${this.port}/v1/chat/completions`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: this.model,
messages: [
{
role: 'user',
content: prompt,
},
],
temperature: config.temperature,
response_format: {
type: 'json_schema',
json_schema: config.generationConfig?.responseSchema,
},
max_tokens: 1000,
stream: false,
}),
});
const data = await response.json();
return {
response: {
text: () => data.choices[0].message.content,
usageMetadata: {
totalTokenCount: data.usage?.total_tokens || 0,
},
},
};
},
};
}
}
dotenv.config();

104
src/utils/llm-client.ts Normal file
View File

@ -0,0 +1,104 @@
import { GoogleGenerativeAI } from '@google/generative-ai';
export interface LLMClientConfig {
model: string;
temperature: number;
generationConfig?: {
responseMimeType?: string;
responseSchema?: any;
};
}
export interface LLMResponse {
text(): string;
usageMetadata: {
totalTokenCount: number;
};
}
export interface LLMClient {
getGenerativeModel(config: LLMClientConfig): {
generateContent(prompt: string): Promise<{
response: LLMResponse;
}>;
};
}
export class GoogleAIWrapper implements LLMClient {
private client: GoogleGenerativeAI;
constructor(apiKey: string) {
this.client = new GoogleGenerativeAI(apiKey);
}
getGenerativeModel(config: LLMClientConfig) {
const model = this.client.getGenerativeModel({
model: config.model,
generationConfig: {
temperature: config.temperature,
...(config.generationConfig || {})
}
});
return {
generateContent: async (prompt: string) => {
const result = await model.generateContent(prompt);
return {
response: {
text: () => result.response.text(),
usageMetadata: {
totalTokenCount: result.response.usageMetadata?.totalTokenCount ?? 0
}
}
};
}
};
}
}
export class LocalLLMClient implements LLMClient {
constructor(
private hostname: string,
private port: string,
private model: string
) {}
getGenerativeModel(config: LLMClientConfig) {
return {
generateContent: async (prompt: string) => {
const response = await fetch(`http://${this.hostname}:${this.port}/v1/chat/completions`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: this.model,
messages: [
{
role: 'user',
content: prompt,
},
],
temperature: config.temperature,
response_format: {
type: 'json_schema',
json_schema: config.generationConfig?.responseSchema,
},
max_tokens: 1000,
stream: false,
}),
});
const data = await response.json();
return {
response: {
text: () => data.choices[0].message.content,
usageMetadata: {
totalTokenCount: data.usage?.total_tokens || 0,
},
},
};
},
};
}
}