Skip to content

config: accept per-agent verboseDefault and elevatedDefault overrides (#73680)#74643

Open
lonexreb wants to merge 4 commits intoopenclaw:mainfrom
lonexreb:fix/73680-per-agent-verbose-elevated-defaults
Open

config: accept per-agent verboseDefault and elevatedDefault overrides (#73680)#74643
lonexreb wants to merge 4 commits intoopenclaw:mainfrom
lonexreb:fix/73680-per-agent-verbose-elevated-defaults

Conversation

@lonexreb
Copy link
Copy Markdown
Contributor

@lonexreb lonexreb commented Apr 29, 2026

Summary

  • Problem: AgentEntrySchema (per-agent agents.list[] shape) accepts thinkingDefault, reasoningDefault, and fastModeDefault per-agent, but does not declare verboseDefault or elevatedDefault. The runtime resolver chain already reads both per-agent first and only falls back to agents.defaults.* (see references below). The result: openclaw config set agents.list.0.verboseDefault on (or elevatedDefault) is rejected with Unrecognized key, forcing a global default even when the operator only wants to change one agent.
  • Why it matters: As reported in Per-agent verboseDefault / elevatedDefault rejected by config schema, despite resolver and SDK types supporting them #73680, the rest of the stack — resolver, plugin-SDK type, status text, command handlers, dispatch fallback — already supports per-agent values; only the strict schema entry blocks them. agents.defaults.* works, but only as a global default.
  • What changed:
    • Added verboseDefault and elevatedDefault to AgentEntrySchema in src/config/zod-schema.agent-runtime.ts mirroring the enums already used in AgentDefaultsSchema.
    • Added elevatedDefault to the AgentConfig public type in src/config/types.agents.ts (verboseDefault was already there).
    • Added matching labels in src/config/schema.labels.ts and help text in src/config/schema.help.ts, mirroring the existing per-agent thinkingDefault / reasoningDefault / fastModeDefault entries.
    • Regenerated src/config/schema.base.generated.ts and docs/.generated/config-baseline.sha256 per the repo drift-check workflow.
    • Added 3 regression tests in src/config/config.schema-regressions.test.ts (positive case + 2 invalid-enum cases).
  • What did NOT change (scope boundary): No runtime behavior, no resolver logic, no compaction/session reset controls. The runtime already reads these keys per-agent; this PR only stops the validator from rejecting them and aligns the public type / metadata.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause (if applicable)

  • Root cause: When per-agent override fields were grown out of AgentDefaultsSchema into AgentEntrySchema (thinkingDefault, reasoningDefault, fastModeDefault), verboseDefault and elevatedDefault were not promoted. Meanwhile the resolver, status text, dispatch fallback, and SDK type evolved to consume them per-agent, so the schema entry became the only place blocking the durable config path.
  • Missing detection / guardrail: There is no parser-level test asserting that every per-agent override the runtime resolver reads is also accepted by AgentEntrySchema. This PR adds the most direct kind of regression test for the two specific keys.
  • Contributing context: References (current main):
    • src/agents/agent-scope-config.ts:121verboseDefault: entry.verboseDefault ?? agentDefaults?.verboseDefault
    • src/auto-reply/reply/dispatch-from-config.ts:375-376sessionAgentCfg?.verboseDefault ?? cfg.agents?.defaults?.verboseDefault
    • src/auto-reply/reply/get-reply-directives.ts:434,463 — reads agentCfg?.verboseDefault and agentCfg?.elevatedDefault
    • src/auto-reply/reply/directive-handling.persist.ts:145 — reads agentCfg?.elevatedDefault
    • src/status/status-message.ts:798,808 — reads args.agent?.verboseDefault / args.agent?.elevatedDefault
    • src/agents/agent-command.ts:602 — reads agentCfg?.verboseDefault

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
  • Target test or file: src/config/config.schema-regressions.test.ts
  • Scenario the test should lock in:
    • Positive: validateConfigObject({ agents: { list: [{ id: "main", verboseDefault: "on", elevatedDefault: "ask" }] } }) returns ok.
    • Negative on verboseDefault: "loud" is rejected (off|on|full enum).
    • Negative on elevatedDefault: "always" is rejected (off|on|ask|full enum).
  • Why this is the smallest reliable guardrail: The bug is purely at the zod validation layer; a parser-level test directly on validateConfigObject covers both accept and reject paths.
  • Existing test that already covers this: No.
  • If no new test is added, why not: N/A (3 new tests added).

Test Plan

  • pnpm test src/config/config.schema-regressions.test.ts — 21/21 pass (3 new + 18 existing)
  • pnpm check:base-config-schema — clean after regenerate
  • pnpm config:docs:check — clean after regenerate (docs/.generated/config-baseline.sha256 updated and committed)
  • pnpm check:changed — clean (typecheck, oxlint, runtime sidecar guard, import-cycle guard, pairing/auth guards)
  • pnpm exec oxfmt --write --threads=1 ... — clean

Notes

  • Enum values mirror AgentDefaultsSchema exactly (verboseDefault: off|on|full, elevatedDefault: off|on|ask|full), so the per-agent and global surfaces stay aligned.
  • AgentEntrySchema remains .strict() so unknown per-agent keys continue to fail closed.

Real behavior proof


@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation size: S labels Apr 29, 2026
@lonexreb lonexreb force-pushed the fix/73680-per-agent-verbose-elevated-defaults branch from ab3939a to f24402d Compare April 30, 2026 05:55
@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime agents Agent runtime and tooling labels Apr 30, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Apr 30, 2026

Codex review: needs real behavior proof before merge.

Summary
The PR adds per-agent elevatedDefault schema/type/config metadata and docs, documents per-agent verboseDefault, wires reply directive resolution to read agent entries before global defaults, updates generated baseline hashes, and adds regression tests.

Reproducibility: yes. Source inspection shows current main still rejects agents.list[].elevatedDefault at the strict schema, and PR head still leaves direct agent verbose resolution on global defaults only; I did not run artifact-producing CLI/tests in this read-only review.

Real behavior proof
Needs real behavior proof before merge: The PR body has an empty real behavior proof block, and the follow-up comment lists tests/typechecks rather than after-fix CLI or runtime output.

Next step before merge
Contributor action is needed: fix the remaining review blockers and add real behavior proof before maintainers consider merge; ClawSweeper should not queue repair while the external proof gate is missing.

Security
Cleared: Cleared: the diff changes operator-controlled config schema/types, docs, generated metadata, and tests; no CI, dependency, secrets, or supply-chain change was found, and elevated execution remains behind the existing enable/allowlist gates.

Review findings

  • [P2] Honor per-agent defaults in direct agent runs — docs/tools/thinking.md:83
  • [P3] Use valid verbose levels in directive tests — src/auto-reply/reply/directive-handling.levels.test.ts:175-204
  • [P3] Add the required changelog entry — src/config/zod-schema.agent-runtime.ts:856
Review details

Best possible solution:

Land one aligned fix that accepts the per-agent keys, resolves them consistently across reply and direct agent paths, uses valid enum coverage, updates the changelog, and includes real CLI/runtime proof.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection shows current main still rejects agents.list[].elevatedDefault at the strict schema, and PR head still leaves direct agent verbose resolution on global defaults only; I did not run artifact-producing CLI/tests in this read-only review.

Is this the best way to solve the issue?

No. The schema/docs/reply changes are the right direction, but the proposed patch is incomplete until direct agent command runs consume selected-agent defaults and the tests/changelog/proof are cleaned up.

Full review comments:

  • [P2] Honor per-agent defaults in direct agent runs — docs/tools/thinking.md:83
    This documents and accepts per-agent verbose/elevated defaults, but direct openclaw agent --agent <id> still builds agentCfg from cfg.agents?.defaults and resolves verbose from that object only. A saved agents.list[].verboseDefault will validate but be ignored on direct agent runs; resolve the selected agent config before computing direct-run verbose and cover that path.
    Confidence: 0.9
  • [P3] Use valid verbose levels in directive tests — src/auto-reply/reply/directive-handling.levels.test.ts:175-204
    VerboseLevel is off | on | full, but the new directive-level tests use high and low. Because the resolver accepts unknown and casts, these tests can pass while asserting impossible config values; use valid verbose levels so the guard matches the schema contract.
    Confidence: 0.88
  • [P3] Add the required changelog entry — src/config/zod-schema.agent-runtime.ts:856
    This is a user-facing config validation/runtime fix, but PR head does not update CHANGELOG.md. Add a single-line entry under the active ### Fixes section before merge.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.9

What I checked:

Likely related people:

  • steipete: Current-main blame in the checked-out history points the central agent config resolver, direct agent command, reply directive resolver, and config schema/type surfaces at recent agent/config work authored by Peter Steinberger. (role: recent maintainer / likely follow-up owner; confidence: medium; commits: e0fafdcc1d1d, 5dfaed184608; files: src/agents/agent-command.ts, src/agents/agent-scope-config.ts, src/auto-reply/reply/get-reply-directives.ts)
  • vincentkoc: The current-main log shows recent work on src/status/status-message.ts, one of the surfaces that reports resolved per-agent verbose/elevated defaults. (role: adjacent status-surface maintainer; confidence: low; commits: a17d4371d101; files: src/status/status-message.ts)

Remaining risk / open question:

  • The patch can make agents.list[].verboseDefault look supported everywhere while direct openclaw agent --agent <id> runs still ignore the per-agent value.
  • The added verbose-default tests use impossible enum values, so they can pass without protecting the actual config contract.
  • The contributor has not supplied after-fix real behavior proof from a real OpenClaw setup.

Codex review notes: model gpt-5.5, reasoning high; reviewed against a17d4371d101.

lonexreb added a commit to lonexreb/paloa-claw that referenced this pull request Apr 30, 2026
…er (openclaw#73680)

Address Codex P3 finding on PR openclaw#74643. The /verbose directive section
previously only mentioned session/global defaults; now that
agents.list[].verboseDefault is accepted, the directive page lists the
full resolution order to match the reasoning section.
lonexreb added a commit to lonexreb/paloa-claw that referenced this pull request Apr 30, 2026
…er (openclaw#73680)

Address Codex P3 finding on PR openclaw#74643. The /verbose directive section
previously only mentioned session/global defaults; now that
agents.list[].verboseDefault is accepted, the directive page lists the
full resolution order to match the reasoning section.
@lonexreb lonexreb force-pushed the fix/73680-per-agent-verbose-elevated-defaults branch from 3135181 to ec802fe Compare April 30, 2026 18:54
lonexreb added a commit to lonexreb/paloa-claw that referenced this pull request Apr 30, 2026
…directive resolution

Codex review on PR openclaw#74643 found that schema/types/docs accept
`verboseDefault` and `elevatedDefault` per-agent (under
`agents.list[]`), but the runtime resolver still falls back to global
`agentCfg` defaults — `getReply` passes `cfg.agents?.defaults` as
`agentCfg`, so per-agent values were stored but never read on actual
replies. The reasoning/fastMode paths already consult `agentEntry` first;
verbose and elevated did not.

Wire the same agentEntry-first precedence for verbose and elevated:

- `src/auto-reply/reply/directive-handling.levels.ts`: extend the
  `agentEntry` parameter type with `verboseDefault`/`elevatedDefault`,
  and check `agentEntry?.verboseDefault` and `agentEntry?.elevatedDefault`
  before falling back to `agentCfg?.*`.
- `src/auto-reply/reply/get-reply-directives.ts`: same agentEntry-first
  fallback for `resolvedVerboseLevel` and `resolvedElevatedLevel`.
  Session and explicit-directive precedence preserved.

Add 6 regression tests in `directive-handling.levels.test.ts`:

- per-agent verboseDefault wins over agentCfg verboseDefault
- agentCfg verboseDefault still applies when agentEntry is absent
- session verboseLevel wins over per-agent verboseDefault
- per-agent elevatedDefault wins over agentCfg elevatedDefault
- agentCfg elevatedDefault still applies when agentEntry is absent
- session elevatedLevel wins over per-agent elevatedDefault

Refs openclaw#73680
@lonexreb
Copy link
Copy Markdown
Contributor Author

P2 review addressed in 423b321. The bot was right — the schema/types changes alone left the per-agent values stored but ignored at runtime, so #73680 was only partially fixed.

Wired agentEntry-first precedence for both fields in the same pattern that reasoningDefault already uses:

  • src/auto-reply/reply/directive-handling.levels.ts — extended the agentEntry parameter type with verboseDefault / elevatedDefault and the resolver now reads agentEntry?.verboseDefault and agentEntry?.elevatedDefault before falling back to agentCfg?.*.
  • src/auto-reply/reply/get-reply-directives.ts — same agentEntry-first fallback for resolvedVerboseLevel (around line 431) and resolvedElevatedLevel (around line 460). Explicit directive and session-state precedence preserved.

Added 6 regression cases in directive-handling.levels.test.ts that exercise the full precedence chain for both knobs:

  • per-agent verboseDefault wins over agentCfg.verboseDefault
  • agentCfg.verboseDefault still applies when no agentEntry value is set
  • session verboseLevel wins over per-agent verboseDefault
  • per-agent elevatedDefault wins over agentCfg.elevatedDefault
  • agentCfg.elevatedDefault still applies when no agentEntry value is set
  • session elevatedLevel wins over per-agent elevatedDefault

Acceptance criteria checked locally:

  • pnpm test src/auto-reply/reply/get-reply-directives.target-session.test.ts src/auto-reply/reply/directive-handling.levels.test.ts src/agents/agent-scope.test.ts src/config/config.schema-regressions.test.ts — all pass (54/54)
  • pnpm tsgo:core — clean
  • pnpm tsgo:core:test — clean
  • pnpm exec oxfmt --check --threads=1 src/auto-reply/reply/directive-handling.levels.ts src/auto-reply/reply/get-reply-directives.ts src/auto-reply/reply/directive-handling.levels.test.ts — clean

PTAL.

lonexreb added a commit to lonexreb/paloa-claw that referenced this pull request May 3, 2026
…er (openclaw#73680)

Address Codex P3 finding on PR openclaw#74643. The /verbose directive section
previously only mentioned session/global defaults; now that
agents.list[].verboseDefault is accepted, the directive page lists the
full resolution order to match the reasoning section.
@lonexreb lonexreb force-pushed the fix/73680-per-agent-verbose-elevated-defaults branch from 423b321 to 5fa4c2a Compare May 3, 2026 08:06
lonexreb added a commit to lonexreb/paloa-claw that referenced this pull request May 3, 2026
…directive resolution

Codex review on PR openclaw#74643 found that schema/types/docs accept
`verboseDefault` and `elevatedDefault` per-agent (under
`agents.list[]`), but the runtime resolver still falls back to global
`agentCfg` defaults — `getReply` passes `cfg.agents?.defaults` as
`agentCfg`, so per-agent values were stored but never read on actual
replies. The reasoning/fastMode paths already consult `agentEntry` first;
verbose and elevated did not.

Wire the same agentEntry-first precedence for verbose and elevated:

- `src/auto-reply/reply/directive-handling.levels.ts`: extend the
  `agentEntry` parameter type with `verboseDefault`/`elevatedDefault`,
  and check `agentEntry?.verboseDefault` and `agentEntry?.elevatedDefault`
  before falling back to `agentCfg?.*`.
- `src/auto-reply/reply/get-reply-directives.ts`: same agentEntry-first
  fallback for `resolvedVerboseLevel` and `resolvedElevatedLevel`.
  Session and explicit-directive precedence preserved.

Add 6 regression tests in `directive-handling.levels.test.ts`:

- per-agent verboseDefault wins over agentCfg verboseDefault
- agentCfg verboseDefault still applies when agentEntry is absent
- session verboseLevel wins over per-agent verboseDefault
- per-agent elevatedDefault wins over agentCfg elevatedDefault
- agentCfg elevatedDefault still applies when agentEntry is absent
- session elevatedLevel wins over per-agent elevatedDefault

Refs openclaw#73680
lonexreb added a commit to lonexreb/paloa-claw that referenced this pull request May 4, 2026
…er (openclaw#73680)

Address Codex P3 finding on PR openclaw#74643. The /verbose directive section
previously only mentioned session/global defaults; now that
agents.list[].verboseDefault is accepted, the directive page lists the
full resolution order to match the reasoning section.
lonexreb added a commit to lonexreb/paloa-claw that referenced this pull request May 4, 2026
…directive resolution

Codex review on PR openclaw#74643 found that schema/types/docs accept
`verboseDefault` and `elevatedDefault` per-agent (under
`agents.list[]`), but the runtime resolver still falls back to global
`agentCfg` defaults — `getReply` passes `cfg.agents?.defaults` as
`agentCfg`, so per-agent values were stored but never read on actual
replies. The reasoning/fastMode paths already consult `agentEntry` first;
verbose and elevated did not.

Wire the same agentEntry-first precedence for verbose and elevated:

- `src/auto-reply/reply/directive-handling.levels.ts`: extend the
  `agentEntry` parameter type with `verboseDefault`/`elevatedDefault`,
  and check `agentEntry?.verboseDefault` and `agentEntry?.elevatedDefault`
  before falling back to `agentCfg?.*`.
- `src/auto-reply/reply/get-reply-directives.ts`: same agentEntry-first
  fallback for `resolvedVerboseLevel` and `resolvedElevatedLevel`.
  Session and explicit-directive precedence preserved.

Add 6 regression tests in `directive-handling.levels.test.ts`:

- per-agent verboseDefault wins over agentCfg verboseDefault
- agentCfg verboseDefault still applies when agentEntry is absent
- session verboseLevel wins over per-agent verboseDefault
- per-agent elevatedDefault wins over agentCfg elevatedDefault
- agentCfg elevatedDefault still applies when agentEntry is absent
- session elevatedLevel wins over per-agent elevatedDefault

Refs openclaw#73680
@lonexreb lonexreb force-pushed the fix/73680-per-agent-verbose-elevated-defaults branch from 5fa4c2a to f0fa64f Compare May 4, 2026 09:52
lonexreb added 4 commits May 5, 2026 00:35
…w#73680)

Address Codex review on issue openclaw#73680 follow-ups for the per-agent
verbose/elevated defaults schema fix:

- Add elevatedDefault to ResolvedAgentConfig and have resolveAgentConfig
  read entry.elevatedDefault first with fallback to agents.defaults so
  the resolver actually surfaces the per-agent override.
- Document the new per-agent verboseDefault and elevatedDefault keys in
  agents.list[] config docs and add the per-agent step to the elevated
  resolution order.
- Cover per-agent vs global elevatedDefault precedence in agent-scope
  unit tests.
- Refresh config-baseline.sha256 after the upstream rebase.
…er (openclaw#73680)

Address Codex P3 finding on PR openclaw#74643. The /verbose directive section
previously only mentioned session/global defaults; now that
agents.list[].verboseDefault is accepted, the directive page lists the
full resolution order to match the reasoning section.
…directive resolution

Codex review on PR openclaw#74643 found that schema/types/docs accept
`verboseDefault` and `elevatedDefault` per-agent (under
`agents.list[]`), but the runtime resolver still falls back to global
`agentCfg` defaults — `getReply` passes `cfg.agents?.defaults` as
`agentCfg`, so per-agent values were stored but never read on actual
replies. The reasoning/fastMode paths already consult `agentEntry` first;
verbose and elevated did not.

Wire the same agentEntry-first precedence for verbose and elevated:

- `src/auto-reply/reply/directive-handling.levels.ts`: extend the
  `agentEntry` parameter type with `verboseDefault`/`elevatedDefault`,
  and check `agentEntry?.verboseDefault` and `agentEntry?.elevatedDefault`
  before falling back to `agentCfg?.*`.
- `src/auto-reply/reply/get-reply-directives.ts`: same agentEntry-first
  fallback for `resolvedVerboseLevel` and `resolvedElevatedLevel`.
  Session and explicit-directive precedence preserved.

Add 6 regression tests in `directive-handling.levels.test.ts`:

- per-agent verboseDefault wins over agentCfg verboseDefault
- agentCfg verboseDefault still applies when agentEntry is absent
- session verboseLevel wins over per-agent verboseDefault
- per-agent elevatedDefault wins over agentCfg elevatedDefault
- agentCfg elevatedDefault still applies when agentEntry is absent
- session elevatedLevel wins over per-agent elevatedDefault

Refs openclaw#73680
@lonexreb lonexreb force-pushed the fix/73680-per-agent-verbose-elevated-defaults branch from f0fa64f to 46380ae Compare May 5, 2026 05:37
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling docs Improvements or additions to documentation gateway Gateway runtime size: M triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Per-agent verboseDefault / elevatedDefault rejected by config schema, despite resolver and SDK types supporting them

1 participant