Files
gochat/backend/internal/llm/provider.go
T

145 lines
5.3 KiB
Go

package llm
import "context"
// Provider defines the interface for LLM operations.
// Inspired by Chatwoot's CaptainAI which uses OpenAI API for:
// 1. Chat completion (copilot message suggestions)
// 2. Embedding generation (knowledge base document vectorization)
// 3. RAG Q&A (retrieve relevant documents via embedding then generate answers)
// 4. Streaming chat completion (SSE streaming for captain task endpoints)
type Provider interface {
// ChatCompletion sends a chat completion request and returns the response.
ChatCompletion(ctx context.Context, req ChatRequest) (*ChatResponse, error)
// CreateEmbedding generates embeddings for the given input texts.
CreateEmbedding(ctx context.Context, req EmbeddingRequest) (*EmbeddingResponse, error)
// ChatCompletionStream sends a streaming chat completion request.
// Chunks are delivered via the onChunk callback. Return nil when the
// stream completes naturally, or an error on failure. The caller is
// responsible for flushing/closing the downstream SSE connection.
ChatCompletionStream(ctx context.Context, req ChatRequest, onChunk func(StreamChunk) error) error
}
// StreamingProvider is a narrowed interface for contexts that only need
// streaming capability (e.g. SSE handler wiring in bootstrap). Providers
// that implement Provider automatically satisfy StreamingProvider since
// ChatCompletionStream is on the base interface.
type StreamingProvider interface {
ChatCompletionStream(ctx context.Context, req ChatRequest, onChunk func(StreamChunk) error) error
}
// ChatRequest represents a request to the chat completion API.
type ChatRequest struct {
Model string `json:"model"`
Messages []ChatMessage `json:"messages"`
Temperature float64 `json:"temperature,omitempty"`
MaxTokens int `json:"max_tokens,omitempty"`
Tools []ToolDefinition `json:"tools,omitempty"`
Stream bool `json:"stream,omitempty"`
}
// ChatMessage represents a single message in a chat conversation.
type ChatMessage struct {
Role string `json:"role"`
Content string `json:"content,omitempty"`
ToolCalls []ToolCall `json:"tool_calls,omitempty"` // assistant message: tool calls initiated by the model
ToolCallID string `json:"tool_call_id,omitempty"` // tool role message: ID of the tool call this responds to
Name string `json:"name,omitempty"` // tool role message: name of the tool
}
// ToolCall represents a tool call requested by the LLM.
type ToolCall struct {
ID string `json:"id"`
Type string `json:"type"` // always "function"
Function ToolCallFunction `json:"function"`
}
// ToolCallFunction holds the function name and arguments for a tool call.
type ToolCallFunction struct {
Name string `json:"name"`
Arguments string `json:"arguments"` // JSON string of arguments
}
// ToolDefinition represents a tool that the model can call.
type ToolDefinition struct {
Type string `json:"type"`
Function ToolFunction `json:"function"`
}
// ToolFunction describes a function tool definition.
type ToolFunction struct {
Name string `json:"name"`
Description string `json:"description"`
Parameters map[string]interface{} `json:"parameters"`
}
// ChatResponse represents the response from a chat completion API.
type ChatResponse struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
Model string `json:"model"`
Choices []ChatChoice `json:"choices"`
Usage TokenUsage `json:"usage"`
}
// ChatChoice represents a single choice in a chat completion response.
type ChatChoice struct {
Index int `json:"index"`
Message ChatMessage `json:"message"`
FinishReason string `json:"finish_reason"`
}
// TokenUsage represents token usage statistics.
type TokenUsage struct {
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
TotalTokens int `json:"total_tokens"`
}
// EmbeddingRequest represents a request to the embeddings API.
type EmbeddingRequest struct {
Model string `json:"model"`
Input []string `json:"input"`
Dimensions int `json:"dimensions,omitempty"`
}
// EmbeddingResponse represents the response from an embeddings API.
type EmbeddingResponse struct {
Object string `json:"object"`
Data []EmbeddingData `json:"data"`
Model string `json:"model"`
Usage TokenUsage `json:"usage"`
}
// EmbeddingData represents a single embedding result.
type EmbeddingData struct {
Object string `json:"object"`
Index int `json:"index"`
Embedding []float64 `json:"embedding"`
}
// StreamChunk represents a single chunk in a streaming response.
type StreamChunk struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
Model string `json:"model"`
Choices []StreamChoice `json:"choices"`
}
// StreamChoice represents a single choice in a streaming chunk.
type StreamChoice struct {
Index int `json:"index"`
Delta StreamDelta `json:"delta"`
FinishReason string `json:"finish_reason"`
}
// StreamDelta represents the delta content in a streaming chunk.
type StreamDelta struct {
Role string `json:"role,omitempty"`
Content string `json:"content,omitempty"`
}