package adapter import ( "context" "fmt" "io" "sync" "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 { mu sync.RWMutex adapters map[string]ModelAdapter } func NewRegistry() *Registry { return &Registry{adapters: make(map[string]ModelAdapter)} } // Register 注册一个 adapter,如果同名 adapter 已存在则覆盖。 func (r *Registry) Register(name string, adapter ModelAdapter) { r.mu.Lock() defer r.mu.Unlock() r.adapters[name] = adapter } // RegisterIfAbsent 注册一个 adapter,仅当该 provider 尚未注册时才创建。 // 返回 true 表示新注册,false 表示已存在。 func (r *Registry) RegisterIfAbsent(name string, factory func() ModelAdapter) bool { r.mu.Lock() defer r.mu.Unlock() if _, exists := r.adapters[name]; exists { return false } r.adapters[name] = factory() return true } // Get 返回指定名称的 adapter。 func (r *Registry) Get(name string) (ModelAdapter, error) { r.mu.RLock() defer r.mu.RUnlock() a, ok := r.adapters[name] if !ok { return nil, fmt.Errorf("adapter not found: %s", name) } return a, nil } // Names 返回所有已注册 adapter 的名称列表。 func (r *Registry) Names() []string { r.mu.RLock() defer r.mu.RUnlock() 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