package adapter import ( "context" "fmt" "io" "github.com/edgeai/gateway/pkg/api" ) // ModelAdapter is the interface that all inference engine adapters must implement. type ModelAdapter interface { // Name returns the adapter name (e.g., "ollama", "vllm"). Name() string // ChatCompletion sends a non-streaming chat completion request. ChatCompletion(ctx context.Context, req *ChatRequest) (*ChatResponse, error) // ChatCompletionStream sends a streaming chat completion request. ChatCompletionStream(ctx context.Context, req *ChatRequest) (<-chan StreamChunk, error) // ListModels returns available models from the engine. ListModels(ctx context.Context) ([]ModelInfo, error) // HealthCheck checks if the engine is reachable. HealthCheck(ctx context.Context) error // Cancel cancels an in-progress request by request ID. Cancel(requestID string) error } // ChatRequest is the internal request sent to an adapter. type ChatRequest struct { RequestID string Model string // actual model name Messages []api.Message MaxTokens int Temperature *float64 TopP *float64 Stream bool CancelCh <-chan struct{} } // ChatResponse is the internal response from an adapter. type ChatResponse struct { Content string FinishReason string InputTokens int OutputTokens int ActualModel string } // StreamChunk represents a single chunk in a streaming response. type StreamChunk struct { Delta string FinishReason string InputTokens int OutputTokens int Error error Done bool } // ModelInfo describes a model available in the engine. type ModelInfo struct { Name string ContextWindow int } // Registry manages model adapters by provider name. type Registry struct { adapters map[string]ModelAdapter } func NewRegistry() *Registry { return &Registry{adapters: make(map[string]ModelAdapter)} } func (r *Registry) Register(name string, adapter ModelAdapter) { r.adapters[name] = adapter } func (r *Registry) Get(name string) (ModelAdapter, error) { a, ok := r.adapters[name] if !ok { return nil, fmt.Errorf("adapter not found: %s", name) } return a, nil } func (r *Registry) Names() []string { names := make([]string, 0, len(r.adapters)) for n := range r.adapters { names = append(names, n) } return names } // Ensure io is imported for future use (streaming readers). var _ = io.EOF