fix(config): handle 'local-agent' provider in getLLMConfig - #124
Closed
StizDev wants to merge 1 commit into
Closed
Conversation
…nius#113) The LLMProvider type union includes 'local-agent' (Claude Code / Codex / Hermes CLI backends), but ConfigManager.getLLMConfig had no case for it, so any mission dispatched with provider='local-agent' fell through to `default:` and threw `Unknown provider: local-agent`. The UI showed the agent as "connected" (the health-check uses a separate registry), but the mission was refused with "the live-tools backend failed: Unknown provider: local-agent". The team had already worked around the throw at server.ts:6168 with a try/catch comment ("getLLMConfig throws for...the legitimate 'local-agent'"), but left the root cause in place — so other call sites (recon/whitebox, the default-config resolver) still crashed. Fix: add `case 'local-agent':` to getLLMConfig and setDefaultProvider. Local-agent is keyless (each CLI uses its own login); the agent id (codex|claude|hermes) travels in `model`, defaulting to 'codex' to match LocalAgentAdapter.chat (src/llm/index.ts:1317). Verification: - npm run typecheck -> pass - npm test -> pass (30/30) - npm run doctor -> pass - npm run verify-claims -> pass (27/27) - npm run lint -> pass (0 errors) - npm run build -> pass
Author
|
Closing as a duplicate of #118 (hoptoad-off), which fixes the same problem: getLLMConfig's switch had no case 'local-agent', so keyless missions fell through to default: and threw Unknown provider: local-agent. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
ConfigManager.getLLMConfig(src/config/index.ts) had aswitchoverprovider names with a
default:that threwUnknown provider: ${actualProvider}. TheLLMProvidertype union includes'local-agent'(Claude Code / Codex / Hermes CLI backends), and the UI correctly sends
provider='local-agent', but the switch had nocase 'local-agent':—so any mission dispatched with that provider fell through to the throw.
The UI showed the agent as "connected" (the health-check uses a separate
in-memory registry,
connectedLocalAgents), but the mission was refusedwith:
Refused: the live-tools backend failed: Unknown provider: local-agent
A prior workaround at
server.ts:6168swallowed the throw inside/api/models(comment: "getLLMConfig throws for...the legitimate'local-agent'"), but the root cause remained — so other call sites that
resolve LLM config without the
resolveGeneralLLMConfigshort-circuit(
recon/whitebox.ts, the default-config resolver, the mission path whena base URL is supplied) still crashed.
Why it changed
Selecting a connected local agent (e.g. Hermes) as the LLM backend is a
first-class, keyless path in the UI and the
LocalAgentAdapter(
src/llm/index.ts:1294), but the config resolver rejected it. The fixmakes
'local-agent'a first-class case ingetLLMConfigandsetDefaultProvider, matching howcodex(the other keyless local-CLIprovider) is already handled — minus the stored provider block, since
local-agent has no apiKey/baseUrl.
What the change does
getLLMConfig:case 'local-agent':setsactualModel = model || 'codex'.The agent id (codex|claude|hermes) travels in
model; default'codex'matches
LocalAgentAdapter.chat(src/llm/index.ts:1317). No apiKey orbaseUrl is set — keyless, each CLI uses its own login.
setDefaultProvider:case 'local-agent':setsdefaultModelto'codex'so selecting it as the default is not a silent no-op.No change to
LocalAgentAdapter,requireLiveLocalAgent, the connected-agent registry, or the
resolveGeneralLLMConfigshort-circuit atserver.ts:6823— they were already correct; they just couldn't bereached reliably because the config resolver threw first.
Commands run
npm run typecheck-> passnpm test-> pass (30/30: vitest src, ops preflight 11, model-matrix 19)npm run doctor-> pass (offline API health endpoint is pre-existing, unrelated)npm run verify-claims-> pass (27/27)npm run lint-> pass (0 errors, 128 pre-existing warnings unchanged)npm run build-> passScope audit
git diff --name-status main...HEAD:M src/config/index.ts
Single file, 10 insertions. No benchmark, provenance, provider-config,
redaction, or safety-test paths touched.
Contribution Receipt
case 'local-agent':toConfigManager.getLLMConfigandsetDefaultProviderso the keyless local-agent CLI backend (ClaudeCode / Codex / Hermes) resolves like other providers instead of
throwing
Unknown provider: local-agent.agent_runtime=Claude Code/Codex/Hermes, harness=getLLMConfig,
tool_access=none, target_class=static_fixture, run_mode=planning_only,
attempts=0, successes=0, failures=0, abstentions=0
npm run typecheck-> passnpm test-> pass (30/30)npm run doctor-> passnpm run verify-claims-> pass (27/27)setDefaultModel('local-agent', ...)still falls throughthe second switch as a no-op — intentional, since local-agent has no
stored provider block to merge a defaultModel into, and the agent id is
always passed directly in
modelat call time. No behavior change vs.pre-fix for that path.