LoadWithConfig loads an agent team and returns both the team and config info needed for runtime model switching.
(ctx context.Context, agentSource config.Source, runConfig *config.RuntimeConfig, opts ...Opt)
| 108 | // LoadWithConfig loads an agent team and returns both the team and config info |
| 109 | // needed for runtime model switching. |
| 110 | func LoadWithConfig(ctx context.Context, agentSource config.Source, runConfig *config.RuntimeConfig, opts ...Opt) (result *LoadResult, err error) { |
| 111 | // Cold-start path: parses config, resolves model aliases, may pull |
| 112 | // referenced sub-agents over the network, and starts every toolset. |
| 113 | // All synchronous from the caller's perspective. The span makes the |
| 114 | // breakdown attributable when first-use latency is high. |
| 115 | ctx, span := otel.Tracer("github.com/docker/docker-agent/pkg/teamloader").Start( |
| 116 | ctx, "teamloader.load", |
| 117 | trace.WithSpanKind(trace.SpanKindInternal), |
| 118 | ) |
| 119 | defer func() { |
| 120 | if err != nil { |
| 121 | span.RecordError(err) |
| 122 | span.SetStatus(codes.Error, err.Error()) |
| 123 | } |
| 124 | span.End() |
| 125 | }() |
| 126 | |
| 127 | var loadOpts loadOptions |
| 128 | loadOpts.toolsetRegistry = NewDefaultToolsetRegistry() |
| 129 | loadOpts.providerRegistry = provider.DefaultRegistry() |
| 130 | |
| 131 | for _, o := range opts { |
| 132 | if err := o(&loadOpts); err != nil { |
| 133 | return nil, err |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | // Load the agent's configuration |
| 138 | cfg, err := config.Load(ctx, agentSource) |
| 139 | if err != nil { |
| 140 | return nil, err |
| 141 | } |
| 142 | if cfg != nil { |
| 143 | span.SetAttributes( |
| 144 | attribute.Int("cagent.teamloader.agent_count", len(cfg.Agents)), |
| 145 | attribute.Int("cagent.teamloader.model_count", len(cfg.Models)), |
| 146 | ) |
| 147 | } |
| 148 | |
| 149 | // Resolve model aliases (e.g., "claude-sonnet-4-5" -> "claude-sonnet-4-5-20250929") |
| 150 | // This ensures the API uses the pinned model version. The original name is preserved |
| 151 | // in DisplayModel so the sidebar and other UI elements show the user-configured name. |
| 152 | modelsStore, err := runConfig.ModelsDevStore() |
| 153 | if err != nil { |
| 154 | slog.DebugContext(ctx, "Failed to create modelsdev store for alias resolution", "error", err) |
| 155 | } |
| 156 | |
| 157 | // Apply model overrides from CLI flags before checking required env vars |
| 158 | if err := config.ApplyModelOverrides(cfg, loadOpts.modelOverrides); err != nil { |
| 159 | return nil, err |
| 160 | } |
| 161 | |
| 162 | // Early check for required env vars before loading models and tools. |
| 163 | env := runConfig.EnvProvider() |
| 164 | |
| 165 | // Snapshot which models are `first_available` selectors before resolution |
| 166 | // rewrites them in place, so we can prefer locally-available DMR models for |
| 167 | // any selector that falls back to Docker Model Runner. |