fix(agent): resolve primary provider from frontmatter model
This commit is contained in:
parent
871892ff15
commit
ffa184d183
2 changed files with 93 additions and 0 deletions
|
|
@ -150,6 +150,7 @@ func NewAgentInstance(
|
||||||
subagents = agentCfg.Subagents
|
subagents = agentCfg.Subagents
|
||||||
skillsFilter = resolveAgentSkillsFilter(agentCfg, definition)
|
skillsFilter = resolveAgentSkillsFilter(agentCfg, definition)
|
||||||
}
|
}
|
||||||
|
provider = resolvePrimaryProviderForAgent(cfg, workspace, agentID, model, provider)
|
||||||
warnOnUnknownAgentMCPServerDeclarations(agentID, workspace, cfg, definition)
|
warnOnUnknownAgentMCPServerDeclarations(agentID, workspace, cfg, definition)
|
||||||
|
|
||||||
maxIter := defaults.MaxToolIterations
|
maxIter := defaults.MaxToolIterations
|
||||||
|
|
@ -305,6 +306,47 @@ func populateCandidateProvidersFromNames(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resolvePrimaryProviderForAgent resolves a dedicated provider for the active
|
||||||
|
// primary model when the model points at a model_list entry. This keeps the
|
||||||
|
// agent's single-candidate path aligned with the selected model's own
|
||||||
|
// provider/api_base/api_key instead of inheriting the process default provider.
|
||||||
|
func resolvePrimaryProviderForAgent(
|
||||||
|
cfg *config.Config,
|
||||||
|
workspace string,
|
||||||
|
agentID string,
|
||||||
|
model string,
|
||||||
|
fallback providers.LLMProvider,
|
||||||
|
) providers.LLMProvider {
|
||||||
|
model = strings.TrimSpace(model)
|
||||||
|
if cfg == nil || model == "" {
|
||||||
|
return fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
modelCfg := lookupModelConfigByRef(cfg, model)
|
||||||
|
if modelCfg == nil {
|
||||||
|
return fallback
|
||||||
|
}
|
||||||
|
clone := *modelCfg
|
||||||
|
if clone.Workspace == "" {
|
||||||
|
clone.Workspace = workspace
|
||||||
|
}
|
||||||
|
|
||||||
|
resolvedProvider, _, err := providers.CreateProviderFromConfig(&clone)
|
||||||
|
if err != nil {
|
||||||
|
logger.WarnCF("agent", "Primary model provider init failed; using injected provider",
|
||||||
|
map[string]any{
|
||||||
|
"agent_id": agentID,
|
||||||
|
"model": model,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return fallback
|
||||||
|
}
|
||||||
|
if resolvedProvider == nil {
|
||||||
|
return fallback
|
||||||
|
}
|
||||||
|
return resolvedProvider
|
||||||
|
}
|
||||||
|
|
||||||
// resolveAgentWorkspace determines the workspace directory for an agent.
|
// resolveAgentWorkspace determines the workspace directory for an agent.
|
||||||
func resolveAgentWorkspace(agentCfg *config.AgentConfig, defaults *config.AgentDefaults) string {
|
func resolveAgentWorkspace(agentCfg *config.AgentConfig, defaults *config.AgentDefaults) string {
|
||||||
if agentCfg != nil && strings.TrimSpace(agentCfg.Workspace) != "" {
|
if agentCfg != nil && strings.TrimSpace(agentCfg.Workspace) != "" {
|
||||||
|
|
|
||||||
|
|
@ -666,6 +666,57 @@ Use frontmatter identity.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewAgentInstance_UsesResolvedProviderForFrontmatterPrimaryModel(t *testing.T) {
|
||||||
|
workspace := setupWorkspace(t, map[string]string{
|
||||||
|
"AGENT.md": `---
|
||||||
|
model: claude-frontmatter
|
||||||
|
---
|
||||||
|
# Agent
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
defer cleanupWorkspace(t, workspace)
|
||||||
|
|
||||||
|
cfg := &config.Config{
|
||||||
|
Agents: config.AgentsConfig{
|
||||||
|
Defaults: config.AgentDefaults{
|
||||||
|
Workspace: workspace,
|
||||||
|
Provider: "openai",
|
||||||
|
ModelName: "default-model",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ModelList: []*config.ModelConfig{
|
||||||
|
{
|
||||||
|
ModelName: "claude-frontmatter",
|
||||||
|
Model: "anthropic/claude-3-7-sonnet",
|
||||||
|
APIKeys: config.SimpleSecureStrings("test-anthropic-key"),
|
||||||
|
Workspace: workspace,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultProvider := &mockProvider{}
|
||||||
|
agent := NewAgentInstance(&config.AgentConfig{
|
||||||
|
ID: "research",
|
||||||
|
Workspace: workspace,
|
||||||
|
}, &cfg.Agents.Defaults, cfg, defaultProvider)
|
||||||
|
|
||||||
|
if agent.Model != "claude-frontmatter" {
|
||||||
|
t.Fatalf("agent.Model = %q, want %q", agent.Model, "claude-frontmatter")
|
||||||
|
}
|
||||||
|
if len(agent.Candidates) != 1 {
|
||||||
|
t.Fatalf("len(agent.Candidates) = %d, want 1", len(agent.Candidates))
|
||||||
|
}
|
||||||
|
if got := agent.Candidates[0].Provider; got != "anthropic" {
|
||||||
|
t.Fatalf("primary candidate provider = %q, want %q", got, "anthropic")
|
||||||
|
}
|
||||||
|
if got := agent.Candidates[0].Model; got != "claude-3-7-sonnet" {
|
||||||
|
t.Fatalf("primary candidate model = %q, want %q", got, "claude-3-7-sonnet")
|
||||||
|
}
|
||||||
|
if agent.Provider == defaultProvider {
|
||||||
|
t.Fatal("expected primary provider to be resolved from model_list instead of using injected default provider")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestNewAgentInstance_InvalidFrontmatterFailsClosedForToolsAndMCPServers(t *testing.T) {
|
func TestNewAgentInstance_InvalidFrontmatterFailsClosedForToolsAndMCPServers(t *testing.T) {
|
||||||
workspace := setupWorkspace(t, map[string]string{
|
workspace := setupWorkspace(t, map[string]string{
|
||||||
"AGENT.md": `---
|
"AGENT.md": `---
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue