| import type { |
| ChatMessage, |
| ChatCompletionResponse, |
| ChatCompletionChunk, |
| ChatToolDefinition, |
| ChatToolChoice, |
| Platform, |
| } from '@freellmapi/shared/types.js'; |
|
|
| export interface CompletionOptions { |
| model?: string; |
| temperature?: number; |
| max_tokens?: number; |
| top_p?: number; |
| tools?: ChatToolDefinition[]; |
| tool_choice?: ChatToolChoice; |
| parallel_tool_calls?: boolean; |
| } |
|
|
| export abstract class BaseProvider { |
| abstract readonly platform: Platform; |
| abstract readonly name: string; |
|
|
| abstract chatCompletion( |
| apiKey: string, |
| messages: ChatMessage[], |
| modelId: string, |
| options?: CompletionOptions, |
| ): Promise<ChatCompletionResponse>; |
|
|
| abstract streamChatCompletion( |
| apiKey: string, |
| messages: ChatMessage[], |
| modelId: string, |
| options?: CompletionOptions, |
| ): AsyncGenerator<ChatCompletionChunk>; |
|
|
| abstract validateKey(apiKey: string): Promise<boolean>; |
|
|
| protected async fetchWithTimeout( |
| url: string, |
| init: RequestInit, |
| timeoutMs = 15000, |
| ): Promise<Response> { |
| const controller = new AbortController(); |
| const timeout = setTimeout(() => controller.abort(), timeoutMs); |
| try { |
| return await fetch(url, { ...init, signal: controller.signal }); |
| } finally { |
| clearTimeout(timeout); |
| } |
| } |
|
|
| protected makeId(): string { |
| return `chatcmpl-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; |
| } |
| } |
|
|