Skip to content

feat(config): support per-agent compaction overrides#69987

Closed
scottgl9 wants to merge 1 commit into
openclaw:mainfrom
scottgl9:scottgl9/per-agent-compaction-config
Closed

feat(config): support per-agent compaction overrides#69987
scottgl9 wants to merge 1 commit into
openclaw:mainfrom
scottgl9:scottgl9/per-agent-compaction-config

Conversation

@scottgl9

Copy link
Copy Markdown
Contributor

Summary

  • Problem: compaction overrides were supported only at agents.defaults.compaction, so all agents had to share the same compaction instructions and runtime settings.
  • Why it matters: specialized agents need different compaction guidance to preserve the right context during long-running sessions.
  • What changed: added optional agents.list[].compaction support, merged it over defaults, and threaded effective per-agent compaction config through embedded runtime compaction paths.
  • What did NOT change (scope boundary): default-only behavior remains unchanged when per-agent overrides are omitted; this PR does not redesign the broader config resolution model beyond compaction.

Change Type (select all)

  • Feature
  • Refactor required for the fix

Scope (select all touched areas)

  • Gateway / orchestration
  • API / contracts
  • UI / DX

Linked Issue/PR

Root Cause (if applicable)

  • Root cause: compaction config existed only on the agent defaults surface, and runtime compaction paths read only agents.defaults.compaction.
  • Missing detection / guardrail: there was no config/runtime path for agent-scoped compaction resolution.
  • Contributing context (if known): upstream already had a mature compaction config shape, so the missing behavior was override placement and runtime wiring rather than compaction capability itself.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
    • src/agents/agent-scope.test.ts
    • src/agents/pi-settings.test.ts
    • src/agents/pi-embedded-runner/extensions.test.ts
  • Scenario the test should lock in:
    • per-agent compaction config merges over defaults
    • per-agent customInstructions wins over default customInstructions
    • runtime compaction setup consumes the effective agent-specific config
  • Why this is the smallest reliable guardrail:
    • these tests cover both config resolution and the embedded runtime handoff where compaction instructions are actually consumed
  • Existing test that already covers this (if any): config schema and runtime-config suites cover the broader config surface
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • OpenClaw now accepts optional agents.list[].compaction entries.
  • Per-agent compaction fields inherit from agents.defaults.compaction and override defaults when set.
  • agents.list[].compaction.customInstructions now lets each agent provide its own compaction guidance.

Diagram (if applicable)

Before:
[agent run] -> [agents.defaults.compaction only] -> [shared compaction behavior for every agent]

After:
[agent run] -> [agents.list[].compaction if present] -> [fallback to agents.defaults.compaction] -> [agent-specific compaction behavior]

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: Linux
  • Runtime/container: local OpenClaw dev environment
  • Model/provider: N/A (config/runtime path change)
  • Integration/channel (if any): N/A
  • Relevant config (redacted): multi-agent config with agents.defaults.compaction plus agents.list[].compaction

Steps

  1. Configure agents.defaults.compaction.customInstructions.
  2. Add agents.list[].compaction.customInstructions for a specific agent.
  3. Run config validation and embedded compaction/runtime tests.

Expected

  • Config validates.
  • Effective compaction settings for that agent use the per-agent override.
  • Other agents continue inheriting defaults.

Actual

  • Verified locally.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
    • staged typecheck/lint/import-cycle guards passed
    • generated schema baseline updated and validated
    • runtime-config and agents test suites passed in the changed-file gate
    • per-agent compaction merge and runtime precedence covered by added tests
  • Edge cases checked:
    • per-agent override with inherited default fields
    • no per-agent override preserves prior defaults-only behavior
    • shared schema extraction did not leave runtime import cycles
  • What you did not verify:
    • manual end-to-end interactive compaction against a live chat session

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: per-agent compaction schema could drift from defaults compaction schema over time.
    • Mitigation: this PR extracts the shared compaction schema into a dedicated config schema module and reuses it in both places.
  • Risk: runtime compaction paths could accidentally keep reading defaults-only config.
    • Mitigation: this PR threads agentId through the affected embedded runtime setup paths and adds tests around the effective runtime behavior.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: M r: too-many-prs Auto-close: author has more than twenty active PRs. labels Apr 22, 2026
@openclaw-barnacle

Copy link
Copy Markdown

Closing this PR because the author has more than 10 active PRs in this repo. Please reduce the active PR queue and reopen or resubmit once it is back under the limit. You can close your own PRs to get back under the limit.

@greptile-apps

greptile-apps Bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds optional per-agent compaction overrides that merge over agents.defaults.compaction, threads agentId through the embedded runtime compaction paths, and extracts the shared compaction Zod schema into a dedicated module — a clean, well-scoped change with good test coverage.

  • P1 — silent config loss when agent entry is absent: Both resolveCompactionConfig in pi-settings.ts and the inline resolution in extensions.ts call resolveAgentConfig(cfg, agentId)?.compaction without a ?? agents.defaults.compaction fallback. When agentId is non-null but has no matching entry in agents.list (e.g. DEFAULT_AGENT_ID with an empty list), the entire defaults compaction config is silently dropped — a regression from prior behavior. The existing resolveAgentContextLimits shows the correct pattern: resolveAgentConfig(cfg, agentId)?.contextLimits ?? defaults.
  • P2 — CI runner bump: The testbox job was scaled from 8 vCPU/5 min to 32 vCPU/30 min; this appears unrelated to the feature and should be confirmed intentional.

Confidence Score: 4/5

Not safe to merge as-is due to a silent config regression on the no-list-entry path.

Two callers that resolve compaction config when an agentId is provided both lack the ?? defaults fallback present in the analogous resolveAgentContextLimits function, causing the defaults compaction config to be silently dropped whenever the agentId has no matching agents.list entry. This is a present behavioral regression, not a theoretical risk.

src/agents/pi-settings.ts (resolveCompactionConfig) and src/agents/pi-embedded-runner/extensions.ts (inline compactionCfg resolution) both need the ?? agents.defaults.compaction fallback.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/pi-settings.ts
Line: 44-48

Comment:
**Missing fallback to defaults when agent entry is absent**

When `agentId` is provided but `resolveAgentConfig` returns `undefined` (no matching entry in `agents.list`), this function returns `undefined` instead of `agents.defaults.compaction`. Before this PR those callers always received the defaults config; now a non-null `agentId` without a matching list entry silently drops the entire defaults compaction configuration — a regression for any deployment that has `agents.defaults.compaction` set but uses a session whose agentId isn't in `agents.list` (including the DEFAULT_AGENT_ID path when the list is empty).

Compare the existing `resolveAgentContextLimits`, which correctly falls back:
```ts
return resolveAgentConfig(cfg, agentId)?.contextLimits ?? defaults;
```

The fix:
```ts
function resolveCompactionConfig(params: { cfg?: OpenClawConfig; agentId?: string }) {
  if (params.cfg && params.agentId) {
    return (
      resolveAgentConfig(params.cfg, params.agentId)?.compaction ??
      params.cfg?.agents?.defaults?.compaction
    );
  }
  return params.cfg?.agents?.defaults?.compaction;
}
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/extensions.ts
Line: 92-95

Comment:
**Same missing-fallback bug as in `pi-settings.ts`**

When `agentId` is set but has no entry in `agents.list`, `resolveAgentConfig` returns `undefined` and `compactionCfg` becomes `undefined`, so no compaction extension is registered even if `agents.defaults.compaction.mode` is `"safeguard"`. The same fallback fix applies here:

```ts
const compactionCfg =
  params.cfg && params.agentId
    ? (resolveAgentConfig(params.cfg, params.agentId)?.compaction ??
        params.cfg?.agents?.defaults?.compaction)
    : params.cfg?.agents?.defaults?.compaction;
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: .github/workflows/ci-check-testbox.yml
Line: 24-25

Comment:
**Large CI resource bump included in feature PR**

The runner was scaled from `blacksmith-8vcpu-ubuntu-2404` (5 min timeout) to `blacksmith-32vcpu-ubuntu-2404` (30 min timeout) — 4× CPU and 6× time. The PR description doesn't mention this change. If this is intentional (e.g., new tests are slower), it's worth a brief note; if it's leftover from local debugging, it should be reverted to avoid unnecessary compute cost on every CI run.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "feat(config): support per-agent compacti..." | Re-trigger Greptile

Comment thread src/agents/pi-settings.ts
Comment on lines +44 to +48
function resolveCompactionConfig(params: { cfg?: OpenClawConfig; agentId?: string }) {
if (params.cfg && params.agentId) {
return resolveAgentConfig(params.cfg, params.agentId)?.compaction;
}
return params.cfg?.agents?.defaults?.compaction;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Missing fallback to defaults when agent entry is absent

When agentId is provided but resolveAgentConfig returns undefined (no matching entry in agents.list), this function returns undefined instead of agents.defaults.compaction. Before this PR those callers always received the defaults config; now a non-null agentId without a matching list entry silently drops the entire defaults compaction configuration — a regression for any deployment that has agents.defaults.compaction set but uses a session whose agentId isn't in agents.list (including the DEFAULT_AGENT_ID path when the list is empty).

Compare the existing resolveAgentContextLimits, which correctly falls back:

return resolveAgentConfig(cfg, agentId)?.contextLimits ?? defaults;

The fix:

function resolveCompactionConfig(params: { cfg?: OpenClawConfig; agentId?: string }) {
  if (params.cfg && params.agentId) {
    return (
      resolveAgentConfig(params.cfg, params.agentId)?.compaction ??
      params.cfg?.agents?.defaults?.compaction
    );
  }
  return params.cfg?.agents?.defaults?.compaction;
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/pi-settings.ts
Line: 44-48

Comment:
**Missing fallback to defaults when agent entry is absent**

When `agentId` is provided but `resolveAgentConfig` returns `undefined` (no matching entry in `agents.list`), this function returns `undefined` instead of `agents.defaults.compaction`. Before this PR those callers always received the defaults config; now a non-null `agentId` without a matching list entry silently drops the entire defaults compaction configuration — a regression for any deployment that has `agents.defaults.compaction` set but uses a session whose agentId isn't in `agents.list` (including the DEFAULT_AGENT_ID path when the list is empty).

Compare the existing `resolveAgentContextLimits`, which correctly falls back:
```ts
return resolveAgentConfig(cfg, agentId)?.contextLimits ?? defaults;
```

The fix:
```ts
function resolveCompactionConfig(params: { cfg?: OpenClawConfig; agentId?: string }) {
  if (params.cfg && params.agentId) {
    return (
      resolveAgentConfig(params.cfg, params.agentId)?.compaction ??
      params.cfg?.agents?.defaults?.compaction
    );
  }
  return params.cfg?.agents?.defaults?.compaction;
}
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +92 to +95
const compactionCfg =
params.cfg && params.agentId
? resolveAgentConfig(params.cfg, params.agentId)?.compaction
: params.cfg?.agents?.defaults?.compaction;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Same missing-fallback bug as in pi-settings.ts

When agentId is set but has no entry in agents.list, resolveAgentConfig returns undefined and compactionCfg becomes undefined, so no compaction extension is registered even if agents.defaults.compaction.mode is "safeguard". The same fallback fix applies here:

const compactionCfg =
  params.cfg && params.agentId
    ? (resolveAgentConfig(params.cfg, params.agentId)?.compaction ??
        params.cfg?.agents?.defaults?.compaction)
    : params.cfg?.agents?.defaults?.compaction;
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/extensions.ts
Line: 92-95

Comment:
**Same missing-fallback bug as in `pi-settings.ts`**

When `agentId` is set but has no entry in `agents.list`, `resolveAgentConfig` returns `undefined` and `compactionCfg` becomes `undefined`, so no compaction extension is registered even if `agents.defaults.compaction.mode` is `"safeguard"`. The same fallback fix applies here:

```ts
const compactionCfg =
  params.cfg && params.agentId
    ? (resolveAgentConfig(params.cfg, params.agentId)?.compaction ??
        params.cfg?.agents?.defaults?.compaction)
    : params.cfg?.agents?.defaults?.compaction;
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +24 to +25
runs-on: blacksmith-32vcpu-ubuntu-2404
timeout-minutes: 30

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Large CI resource bump included in feature PR

The runner was scaled from blacksmith-8vcpu-ubuntu-2404 (5 min timeout) to blacksmith-32vcpu-ubuntu-2404 (30 min timeout) — 4× CPU and 6× time. The PR description doesn't mention this change. If this is intentional (e.g., new tests are slower), it's worth a brief note; if it's leftover from local debugging, it should be reverted to avoid unnecessary compute cost on every CI run.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/ci-check-testbox.yml
Line: 24-25

Comment:
**Large CI resource bump included in feature PR**

The runner was scaled from `blacksmith-8vcpu-ubuntu-2404` (5 min timeout) to `blacksmith-32vcpu-ubuntu-2404` (30 min timeout) — 4× CPU and 6× time. The PR description doesn't mention this change. If this is intentional (e.g., new tests are slower), it's worth a brief note; if it's leftover from local debugging, it should be reverted to avoid unnecessary compute cost on every CI run.

How can I resolve this? If you propose a fix, please make it concise.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 230a78ea14

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +93 to +95
params.cfg && params.agentId
? resolveAgentConfig(params.cfg, params.agentId)?.compaction
: params.cfg?.agents?.defaults?.compaction;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fall back to defaults when agent compaction is unresolved

This lookup drops agents.defaults.compaction whenever an agentId is present but no matching agents.list[] entry exists. That now happens in normal defaults-only configs (no agents.list) because runtime paths pass sessionAgentId, so resolveAgentConfig(...) returns undefined and safeguard mode/custom instructions from defaults are silently ignored. The result is that sessions stop loading the safeguard extension even though defaults are configured.

Useful? React with 👍 / 👎.

Comment thread src/agents/pi-settings.ts
Comment on lines +45 to +47
if (params.cfg && params.agentId) {
return resolveAgentConfig(params.cfg, params.agentId)?.compaction;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep default compaction settings when agent entry is absent

This helper has the same missing-fallback pattern: with a truthy agentId and no matching agents.list[] entry, it returns undefined instead of default compaction config. Since the run path now passes sessionAgentId, defaults-only setups lose configured reserveTokens, keepRecentTokens, and reserveTokensFloor, changing runtime compaction behavior from prior releases.

Useful? React with 👍 / 👎.

Comment on lines +131 to +133
typeof entry.compaction === "object" && entry.compaction
? { ...agentDefaults?.compaction, ...entry.compaction }
: agentDefaults?.compaction,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Deep-merge nested compaction overrides from agent defaults

This merge is only shallow, so nested objects like qualityGuard and memoryFlush are replaced wholesale instead of inheriting unspecified fields from defaults. For example, setting only agents.list[].compaction.qualityGuard.maxRetries drops default qualityGuard.enabled, which then evaluates to false in runtime and unexpectedly disables the guard.

Useful? React with 👍 / 👎.

@prtags

prtags Bot commented Apr 23, 2026

Copy link
Copy Markdown

Related work from PRtags group creative-gnat-d23p

Title: Open PR duplicate: per-agent compaction overrides config support

Number Title
#69987* feat(config): support per-agent compaction overrides
#69988 feat(config): support per-agent compaction overrides

* This PR

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

Labels

agents Agent runtime and tooling r: too-many-prs Auto-close: author has more than twenty active PRs. size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: support per-agent compaction overrides

1 participant