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"` } // 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"` } // 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"` }