Skip to content

bug(config): Settings exposes agent.subagents.default but the core parser discards it #247

Description

@MicroMilo

UI-related note: this touches the Settings/UI path and may be lower priority during the ongoing frontend refactor.

Summary

The Settings UI and default config expose agent.subagents.default, but the core config parser drops it as an unknown field. Users can save a default subagent model in the UI, but runtime config does not preserve or consume that setting.

Why it matters

The UI promises a “Default model for subagents on non-router paths.” A user can select a subagent default model and save successfully, but the core parser emits only warnings and returns no effective default model. Runtime then builds subagent settings using only timeoutMs, so the selected model does not affect subagent execution.

Evidence

  • ui/server/services/pilotdeckConfig.js:62 to ui/server/services/pilotdeckConfig.js:69 includes default config subagents: { default: 'inherit', params: {} }.
  • ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx:81 types subagents?: { default?: string; params?: Record<string, unknown> }.
  • ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx:1223 to ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx:1228 reads config.agent?.subagents?.default.
  • ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx:1422 to ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx:1427 writes the selected value to agent.subagents.default.
  • ui/src/i18n/locales/en/settings.json:742 to ui/src/i18n/locales/en/settings.json:746 documents the setting as the subagents default model.
  • src/pilot/config/loadPilotConfig.ts:382 to src/pilot/config/loadPilotConfig.ts:385 parses agent.subagents.
  • src/pilot/config/loadPilotConfig.ts:392 to src/pilot/config/loadPilotConfig.ts:400 warns on every key except timeoutMs, so default and params are treated as unknown fields.
  • src/pilot/config/loadPilotConfig.ts:403 to src/pilot/config/loadPilotConfig.ts:405 returns only timeoutMs.
  • src/cli/createLocalGateway.ts:1089 to src/cli/createLocalGateway.ts:1097 passes only agent.subagents?.timeoutMs into runtime config.

Validation

Validation level: dynamic config parser reproduction.

Repro approach: load a config containing agent.subagents.default: p/m and agent.subagents.params.temperature.

Key output: loadPilotConfig returned subagents: {} and diagnostics included Unknown agent.subagents field default and Unknown agent.subagents field params, both with warning severity. The fields are not fatal, but they are also not retained for runtime use.

Boundary: this validates the config/parser/runtime path, not a full UI click-through. The UI save path and runtime consumption points are anchored above.

Expected behavior

The product should have one consistent contract. If agent.subagents.default is supported, the parser and runtime should preserve and apply it. If it is not supported, the UI/default config/copy should not expose it as a working setting.

Existing coverage checked

Coverage review searched for agent.subagents.default, parseAgentSubagents, and Unknown agent.subagents field default.

Coverage label: not covered. PR #222 fixes multi-subagent concurrency/detail rendering and related event flow, but does not modify agent.subagents.default parser behavior or this UI/core config drift.

Suggested fix

Confirm the intended product semantics first. If the setting should work, add schema/parser support for agent.subagents.default, preserve it in PilotAgentConfig, and wire it into subagent runtime/model selection. If the setting should not exist, remove it from defaults, Settings UI, provider rename repair, and i18n copy.

Suggested tests

  • Supported path: UI/default config with agent.subagents.default survives loadPilotConfig and reaches runtime model selection.
  • Unsupported path: default config and Settings UI no longer emit agent.subagents.default.
  • Parser diagnostics do not silently warn-and-drop a setting that the UI presents as supported.
  • Provider rename repair does not maintain stale refs for an unsupported field, or correctly rewrites it if supported.

Submitted with Codex.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions