Skip to content

feat: add subAgentsTemperature config for per-agent temperature tuning #843

Description

@avoidwork

Summary

Add a subAgentsTemperature config section that allows per-agent temperature tuning for sub-agents. This is a new config-driven feature that enables fine-grained control over agent behavior by setting temperature values per agent type.

Motivation

Currently, all agents share the same provider-level temperature (0.4 for OpenAI). This doesn't account for the different roles agents play — a code-review agent should be deterministic and precise (low temperature), while a brainstorming agent should be creative (higher temperature). Per-agent temperature tuning lets operators calibrate agent behavior to their specific role, reducing hallucination in critical tasks and enabling more creative exploration where appropriate.

Proposed Solution

Add a new config section subAgentsTemperature as a flat record of agent name to temperature value:

subAgentsTemperature:
  coding: 0.3
  search: 0.3
  debug: 0.2
  code-review: 0.1
  security-audit: 0.1
  testing: 0.3
  documentation: 0.2
  performance: 0.2
  research: 0.5
  • Config key is subAgentsTemperature (camelCase) — a flat record of agent name → number (0–2).
  • Env vars follow the existing convention: subAgentsTemperature.codingSUB_AGENTS_TEMPERATURE_CODING=0.3. Hyphens in agent names become underscores in env vars.
  • We do NOT include general-purpose in the config — we don't own that agent. If an agent isn't listed in the config, the provider/model default applies.
  • A small accessor utility (getSubAgentTemperature(agentName)) reads from config and returns undefined if the agent isn't listed, letting the model use its default.

Alternatives Considered

  • Global temperature override: A single subAgentTemperature value for all agents. Rejected because different agents have different precision requirements.
  • Template-based temperature: Define temperature in skill definitions. Rejected because temperature is an operational concern, not a skill concern.
  • Hardcoded defaults in code: Rejected because it breaks the config-driven principle and makes runtime tuning impossible.

Dependencies

  • No new dependencies — this uses the existing config schema system (Zod) and env var resolution infrastructure already in place.

Testing Strategy

  • Unit tests: Verify Zod schema validation for valid temperatures (0–2), invalid temperatures (out of range, non-numeric), and empty config.
  • Env var resolution: Verify that SUB_AGENTS_TEMPERATURE_CODING=0.3 correctly populates subAgentsTemperature.coding in the resolved config.
  • Accessor function: Verify that getSubAgentTemperature('coding') returns the correct value, and that unlisted agents return undefined.
  • Edge cases: Empty string agent names, very high/low values, non-numeric env var values.

Security Considerations

  • Input validation: All temperature values validated via Zod schema (0–2 range, numeric).
  • No secrets involved: This is a pure configuration feature — no credentials, API keys, or sensitive data.
  • Env var safety: Follows existing env var resolution patterns — no new attack surface.

Environment

  • OS: Linux 7.0.2-7-pve
  • Node.js: v25.8.1
  • madz version: 1.7.5
  • LLM provider: OpenAI gpt-4o

OpenSpec Note

This project uses OpenSpec for feature development. If this request is approved, I will:

  1. Run /opsx:propose to generate a full proposal with specs and tasks
  2. Iterate on the design before any code is written
  3. Follow the task-driven implementation workflow

Additional Context

The implementation touches the config layer (schema, loader, accessor) and the agent invocation layer where sub-agents are spawned. The temperature values are derived from the agent's role:

Agent Role Suggested Temp
code-review Precision, no hallucination 0.1
security-audit Precision, no hallucination 0.1
debug Tracing, logical 0.2
documentation Clear, factual 0.2
performance Analytical 0.2
coding Balanced between precision and creativity 0.3
search Synthesis, factual 0.3
testing Structured, repeatable 0.3
research Exploratory but grounded 0.5

Audit Findings (for Issue #843)

  • src/config/schemas/providers.js:71 — Shows the existing pattern for temperature validation: z.number().min(0).max(2).default(0.4). The subAgentsTemperature schema should follow this same pattern but as a record, not a scalar.
  • src/config/config.js:36-51 — Root ConfigSchema where subAgentsTemperature needs to be added as a new property. Follows the pattern of importing from ./schemas/ and adding to the z.object.
  • src/config/schemas/index.js — Re-exports individual schemas. The new SubAgentsTemperatureSchema needs to be exported here.
  • src/config/loader.js:56-64 — The DROPPED_KEYS array in _resolveEnvRecursively controls how config paths flatten to env vars. subAgentsTemperature needs to be added here so env vars flatten correctly: subAgentsTemperature.coding → SUB_AGENTS_TEMPERATURE_CODING.
  • src/config/loader.js:20-32 — The _toUpperSnake function handles camelCase to SNAKE_CASE conversion. Agent names with hyphens (e.g., code-review) will need special handling — the env var should be SUB_AGENTS_TEMPERATURE_CODE_REVIEW (hyphens to underscores).
  • src/config/config.js:55 — DEFAULT_CONFIG is derived from the Zod schema via ConfigSchema.parse({}), so adding the schema to ConfigSchema automatically populates the default.

Fix Steps

  1. Create schema file — Add src/config/schemas/subAgentsTemperature.js with SubAgentsTemperatureSchema = z.record(z.string(), z.number().min(0).max(2)).
  2. Export from schemas/index.js — Add export { SubAgentsTemperatureSchema } from './subAgentsTemperature.js';
  3. Add to root ConfigSchema — In src/config/config.js, import the new schema and add subAgentsTemperature: SubAgentsTemperatureSchema.default({}) to the ConfigSchema object.
  4. Add to DROPPED_KEYS — In src/config/loader.js, add 'subAgentsTemperature' to the DROPPED_KEYS array so env vars flatten correctly.
  5. Handle hyphens in agent names — Modify _toUpperSnake or add a preprocessing step to convert hyphens to underscores before the snake_case conversion, so code-review → CODE_REVIEW.
  6. Add accessor function — In src/config/config.js (or a new utility), add getSubAgentTemperature(agentName) that reads from config.subAgentsTemperature[agentName] and returns undefined if not found.
  7. Write unit tests — Create tests/unit/config-subAgentsTemperature.test.js covering schema validation, env var resolution, and the accessor function.
  8. Wire into spawn — Update the agent invocation layer to read temperature from config and pass it when spawning sub-agents.
  9. Verify — Run npm run test, npm run lint, and npm run coverage to confirm everything passes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions