@@ -5,12 +5,11 @@ import (
55 "errors"
66 "fmt"
77 "log/slog"
8- "maps"
9- "slices"
108
119 "github.com/docker/docker-agent/pkg/config/latest"
1210 "github.com/docker/docker-agent/pkg/environment"
1311 "github.com/docker/docker-agent/pkg/model/provider"
12+ "github.com/docker/docker-agent/pkg/model/provider/options"
1413 "github.com/docker/docker-agent/pkg/rag/rerank"
1514 "github.com/docker/docker-agent/pkg/rag/strategy"
1615 "github.com/docker/docker-agent/pkg/rag/types"
@@ -21,7 +20,16 @@ type ManagersBuildConfig struct {
2120 ParentDir string
2221 ModelsGateway string
2322 Env environment.Provider
24- Models map [string ]latest.ModelConfig // Model configurations from config
23+ Models map [string ]latest.ModelConfig // Model configurations from config
24+ Providers map [string ]latest.ProviderConfig // Custom provider configurations from config
25+ }
26+
27+ // NewProvider creates a model provider using the build config's environment,
28+ // gateway, and custom provider settings.
29+ func (c ManagersBuildConfig ) NewProvider (ctx context.Context , cfg * latest.ModelConfig ) (provider.Provider , error ) {
30+ return provider .New (ctx , cfg , c .Env ,
31+ options .WithGateway (c .ModelsGateway ),
32+ options .WithProviders (c .Providers ))
2533}
2634
2735// NewManager constructs a single RAG manager from a RAGConfig.
@@ -46,6 +54,7 @@ func NewManager(
4654 ParentDir : buildCfg .ParentDir ,
4755 SharedDocs : GetAbsolutePaths (buildCfg .ParentDir , ragCfg .Docs ),
4856 Models : buildCfg .Models ,
57+ Providers : buildCfg .Providers ,
4958 Env : buildCfg .Env ,
5059 ModelsGateway : buildCfg .ModelsGateway ,
5160 RespectVCS : ragCfg .GetRespectVCS (),
@@ -146,20 +155,21 @@ func buildRerankingConfig(
146155 "model_ref" , rerankCfg .Model )
147156
148157 // Resolve model config - check if it's a reference to a defined model or inline
149- modelCfg , err := resolveModelConfig (rerankCfg .Model , buildCfg )
158+ modelCfgVal , err := strategy . ResolveModelConfig (rerankCfg .Model , buildCfg . Models )
150159 if err != nil {
151160 slog .Error ("Failed to resolve reranking model" ,
152161 "model_ref" , rerankCfg .Model ,
153162 "error" , err )
154163 return nil , fmt .Errorf ("failed to resolve reranking model %q: %w" , rerankCfg .Model , err )
155164 }
165+ modelCfg := & modelCfgVal
156166
157167 slog .Debug ("Resolved reranking model config" ,
158168 "provider" , modelCfg .Provider ,
159169 "model" , modelCfg .Model )
160170
161171 // Create provider for reranking model
162- rerankProvider , err := provider . New (ctx , modelCfg , buildCfg . Env )
172+ rerankProvider , err := buildCfg . NewProvider (ctx , modelCfg )
163173 if err != nil {
164174 slog .Error ("Failed to create reranking provider" ,
165175 "provider" , modelCfg .Provider ,
@@ -206,55 +216,6 @@ func buildRerankingConfig(
206216 }, nil
207217}
208218
209- // resolveModelConfig resolves a model name to a ModelConfig
210- // Handles both inline model references (e.g., "dmr/model-name") and defined model names
211- func resolveModelConfig (modelName string , buildCfg ManagersBuildConfig ) (* latest.ModelConfig , error ) {
212- // Check if it's an inline model reference (contains a '/')
213- if modelName != "" {
214- parts := splitModelRef (modelName )
215- if len (parts ) == 2 {
216- // Inline model reference like "dmr/hf.co/model" or "openai/gpt-5"
217- slog .Debug ("Using inline model reference" ,
218- "provider" , parts [0 ],
219- "model" , parts [1 ])
220- return & latest.ModelConfig {
221- Provider : parts [0 ],
222- Model : parts [1 ],
223- }, nil
224- }
225- }
226-
227- // Try to find model in defined models
228- if modelCfg , exists := buildCfg .Models [modelName ]; exists {
229- slog .Debug ("Using defined model from config" ,
230- "model_name" , modelName ,
231- "provider" , modelCfg .Provider ,
232- "model" , modelCfg .Model )
233- return & modelCfg , nil
234- }
235-
236- slog .Error ("Model not found in configuration" ,
237- "model_name" , modelName ,
238- "available_models" , getModelNames (buildCfg .Models ))
239- return nil , fmt .Errorf ("model %q not found in configuration" , modelName )
240- }
241-
242- // getModelNames extracts model names from the models map for logging
243- func getModelNames (models map [string ]latest.ModelConfig ) []string {
244- return slices .Collect (maps .Keys (models ))
245- }
246-
247- // splitModelRef splits a model reference into provider and model parts
248- func splitModelRef (ref string ) []string {
249- // Handle common patterns: "provider/model"
250- for i := range len (ref ) {
251- if ref [i ] == '/' {
252- return []string {ref [:i ], ref [i + 1 :]}
253- }
254- }
255- return []string {ref }
256- }
257-
258219// buildStrategyConfigs builds the strategy configs for the RAG.
259220// Returns a slice of strategy configs and a channel for receiving strategy events.
260221func buildStrategyConfigs (
0 commit comments