blob: 92df86b78861fe7820f0cd84f0cc8b8e85d2d1ae [file] [log] [blame] [view]
iomodoa97eb222025-07-26 11:18:17 +04001# LLM Interface Package
2
3This package provides a generic interface for different Large Language Model (LLM) providers, with OpenAI's API structure as the primary reference. It supports multiple providers including OpenAI, xAI, Claude, Gemini, and local models.
4
5## Features
6
7- **Unified Interface**: Single interface for all LLM providers
8- **Multiple Providers**: Support for OpenAI, xAI, Claude, Gemini, and local models
9- **Tool/Function Calling**: Support for function calling and tool usage
10- **Embeddings**: Generate embeddings for text
11- **Configurable**: Flexible configuration options for each provider
12- **Thread-Safe**: Thread-safe factory and registry implementations
13
14## Quick Start
15
16```go
17package main
18
19import (
20 "context"
21 "fmt"
22 "log"
23
24 "your-project/server/llm"
25)
26
27func main() {
28 // Create a configuration for OpenAI
29 config := llm.Config{
30 Provider: llm.ProviderOpenAI,
31 APIKey: "your-openai-api-key",
32 BaseURL: "https://api.openai.com/v1",
33 Timeout: 30 * time.Second,
34 }
35
36 // Create a provider (you'll need to register the implementation first)
37 provider, err := llm.CreateProvider(config)
38 if err != nil {
39 log.Fatal(err)
40 }
41 defer provider.Close()
42
43 // Create a chat completion request
44 req := llm.ChatCompletionRequest{
45 Model: "gpt-3.5-turbo",
46 Messages: []llm.Message{
47 {Role: llm.RoleUser, Content: "Hello, how are you?"},
48 },
49 MaxTokens: &[]int{100}[0],
50 Temperature: &[]float64{0.7}[0],
51 }
52
53 // Get the response
54 resp, err := provider.ChatCompletion(context.Background(), req)
55 if err != nil {
56 log.Fatal(err)
57 }
58
59 fmt.Println("Response:", resp.Choices[0].Message.Content)
60}
61```
62
63## Core Types
64
65### Provider
66
67Represents different LLM service providers:
68
69```go
70const (
71 ProviderOpenAI Provider = "openai"
72 ProviderXAI Provider = "xai"
73 ProviderClaude Provider = "claude"
74 ProviderGemini Provider = "gemini"
75 ProviderLocal Provider = "local"
76)
77```
78
79### Message
80
81Represents a single message in a conversation:
82
83```go
84type Message struct {
85 Role Role `json:"role"`
86 Content string `json:"content"`
87 ToolCalls []ToolCall `json:"tool_calls,omitempty"`
88 ToolCallID string `json:"tool_call_id,omitempty"`
89 Name string `json:"name,omitempty"`
90}
91```
92
93### ChatCompletionRequest
94
95Represents a request to complete a chat conversation:
96
97```go
98type ChatCompletionRequest struct {
99 Model string `json:"model"`
100 Messages []Message `json:"messages"`
101 MaxTokens *int `json:"max_tokens,omitempty"`
102 Temperature *float64 `json:"temperature,omitempty"`
103 TopP *float64 `json:"top_p,omitempty"`
104 Stream *bool `json:"stream,omitempty"`
105 Tools []Tool `json:"tools,omitempty"`
106 ToolChoice interface{} `json:"tool_choice,omitempty"`
107 ResponseFormat *ResponseFormat `json:"response_format,omitempty"`
108 ExtraParams map[string]interface{} `json:"-"` // Provider-specific parameters
109}
110```
111
112## Main Interface
113
114### LLMProvider
115
116The main interface that all LLM providers must implement:
117
118```go
119type LLMProvider interface {
120 // ChatCompletion creates a chat completion
121 ChatCompletion(ctx context.Context, req ChatCompletionRequest) (*ChatCompletionResponse, error)
122
123 // CreateEmbeddings generates embeddings for the given input
124 CreateEmbeddings(ctx context.Context, req EmbeddingRequest) (*EmbeddingResponse, error)
125
126 // Close performs any necessary cleanup
127 Close() error
128}
129```
130
131## Provider Factory
132
133The package includes a factory system for creating and managing LLM providers:
134
135```go
136// Register a provider factory
137err := llm.RegisterProvider(llm.ProviderOpenAI, openaiFactory)
138
139// Create a provider
140provider, err := llm.CreateProvider(config)
141
142// Check if a provider is supported
143if llm.SupportsProvider(llm.ProviderOpenAI) {
144 // Provider is available
145}
146
147// List all registered providers
148providers := llm.ListProviders()
149```
150
151## Configuration
152
153Each provider can be configured with specific settings:
154
155```go
156config := llm.Config{
157 Provider: llm.ProviderOpenAI,
158 APIKey: "your-api-key",
159 BaseURL: "https://api.openai.com/v1",
160 Timeout: 30 * time.Second,
161 MaxRetries: 3,
162 ExtraConfig: map[string]interface{}{
163 "organization": "your-org-id",
164 },
165}
166```
167
168## Tool/Function Calling
169
170Support for function calling and tool usage:
171
172```go
173tools := []llm.Tool{
174 {
175 Type: "function",
176 Function: llm.Function{
177 Name: "get_weather",
178 Description: "Get the current weather for a location",
179 Parameters: map[string]interface{}{
180 "type": "object",
181 "properties": map[string]interface{}{
182 "location": map[string]interface{}{
183 "type": "string",
184 "description": "The city and state, e.g. San Francisco, CA",
185 },
186 },
187 "required": []string{"location"},
188 },
189 },
190 },
191}
192
193req := llm.ChatCompletionRequest{
194 Model: "gpt-3.5-turbo",
195 Messages: messages,
196 Tools: tools,
197}
198```
199
200## Embeddings
201
202Generate embeddings for text:
203
204```go
205req := llm.EmbeddingRequest{
206 Input: "Hello, world!",
207 Model: "text-embedding-ada-002",
208}
209
210resp, err := provider.CreateEmbeddings(context.Background(), req)
211if err != nil {
212 log.Fatal(err)
213}
214
215fmt.Printf("Embedding dimensions: %d\n", len(resp.Data[0].Embedding))
216```
217
218## Implementing a New Provider
219
220To implement a new LLM provider:
221
2221. **Implement the LLMProvider interface**:
223
224```go
225type MyProvider struct {
226 config llm.Config
227 client *http.Client
228}
229
230func (p *MyProvider) ChatCompletion(ctx context.Context, req llm.ChatCompletionRequest) (*llm.ChatCompletionResponse, error) {
231 // Implementation here
232}
233
234func (p *MyProvider) CreateEmbeddings(ctx context.Context, req llm.EmbeddingRequest) (*llm.EmbeddingResponse, error) {
235 // Implementation here
236}
237
238func (p *MyProvider) Close() error {
239 // Cleanup implementation
240 return nil
241}
242```
243
2442. **Create a factory**:
245
246```go
247type MyProviderFactory struct{}
248
249func (f *MyProviderFactory) CreateProvider(config llm.Config) (llm.LLMProvider, error) {
250 return &MyProvider{config: config}, nil
251}
252
253func (f *MyProviderFactory) SupportsProvider(provider llm.Provider) bool {
254 return provider == llm.ProviderMyProvider
255}
256```
257
2583. **Register the provider**:
259
260```go
261func init() {
262 llm.RegisterProvider(llm.ProviderMyProvider, &MyProviderFactory{})
263}
264```
265
266## Error Handling
267
268The package defines common error types:
269
270```go
271var (
272 ErrInvalidConfig = fmt.Errorf("invalid configuration")
273 ErrUnsupportedProvider = fmt.Errorf("unsupported provider")
274 ErrAPIKeyRequired = fmt.Errorf("API key is required")
275 ErrModelNotFound = fmt.Errorf("model not found")
276 ErrRateLimitExceeded = fmt.Errorf("rate limit exceeded")
277 ErrContextCancelled = fmt.Errorf("context cancelled")
278 ErrTimeout = fmt.Errorf("request timeout")
279)
280```
281
282## Utilities
283
284The package includes utility functions:
285
286```go
287// Validate configuration
288err := llm.ValidateConfig(config)
289
290// Check if provider is valid
291if llm.IsValidProvider(llm.ProviderOpenAI) {
292 // Provider is valid
293}
294
295// Get default configuration
296config, err := llm.GetDefaultConfig(llm.ProviderOpenAI)
297
298// Merge custom config with defaults
299config = llm.MergeConfig(customConfig)
300
301// Validate requests
302err := llm.ValidateChatCompletionRequest(req)
303err := llm.ValidateEmbeddingRequest(req)
304
305// Estimate tokens
306tokens := llm.EstimateTokens(req)
307```
308
309## Thread Safety
310
311The factory and registry implementations are thread-safe and can be used concurrently from multiple goroutines.
312
313## Default Configurations
314
315The package provides default configurations for each provider:
316
317```go
318var DefaultConfigs = map[llm.Provider]llm.Config{
319 llm.ProviderOpenAI: {
320 Provider: llm.ProviderOpenAI,
321 BaseURL: "https://api.openai.com/v1",
322 Timeout: 30 * time.Second,
323 MaxRetries: 3,
324 },
325 // ... other providers
326}
327```
328
329## Next Steps
330
3311. Implement the actual provider implementations (OpenAI, xAI, Claude, etc.)
3322. Add tests for the interface and implementations
3333. Add more utility functions as needed
3344. Consider adding caching and retry mechanisms
3355. Add support for more provider-specific features