Skip to content

feat(acp): Sonnet 5.5 auto-compaction window policy (#80) - #96

Merged
geeen-jp merged 4 commits into
mainfrom
issue-80
Oct 10, 2026
Merged

geeen-jp merged 4 commits into
mainfrom
issue-80

Conversation

@geeen-jp

Copy link
Copy Markdown
Owner

Summary

Apply Claude Code auto-compaction at 400,000 for managed Claude ACP sessions whose requested model is exactly claude-sonnet-5-5. The policy is applied to the spawned subprocess environment and is rebuilt on each start, so restarts and resumes re-evaluate it. Haiku, Opus, the sonnet alias, other providers, and other models are unchanged.

Design

The SDK sets CLAUDE_CODE_AUTO_COMPACT_WINDOW=400000 after merging inherited and ACP environment values, and only when both the command is Claude and the requested model is the exact Sonnet 5.5 identifier. This keeps the policy scoped to the Claude subprocess, overrides an inherited value for the qualifying model, and leaves access policy, exact-model proof, structured output, persisted settings, and host Claude configuration unchanged.

The selected environment variable was statically qualified on the runtime Claude CLI 2.1.293 and bundled Claude Code 2.1.280. Both also contain the autoCompactWindow setting surface. No settings file is written.

Files changed

  • AGENTS.md — document the exact-model policy and its lifecycle.
  • openhands-sdk/openhands/sdk/agent/acp_agent.py — apply the environment value to qualifying Claude ACP subprocesses.
  • tests/sdk/agent/test_acp_agent.py — cover model-switch restart behavior.
  • tests/sdk/agent/test_acp_claude_auth_isolation.py — cover model scoping, environment precedence, restart, concurrency, isolation, and credential coexistence.

Review and audit

Four review rounds (r1–r4) completed with zero MUST_FIX findings in each review. Four audit rounds completed; audit r4 reported zero MUST_FIX findings. Triage r4 returned OK with no needed changes. Four remediation rounds were used.

Resolved MUST_FIX findings:

  • A1 — stale policy after a live model switch. The initial implementation only set the environment at process start. Switching across exact claude-sonnet-5-5 now schedules a restart, so the new subprocess rebuilds its environment for the requested model. Review and audit r2 marked A1 fixed.
  • O1 — restart/resume coverage did not preserve one conversation or exercise load_session. The tests now drive a restart on one conversation state, seed a session ID, and assert that resume calls load_session with that ID while the resumed Sonnet subprocess receives 400000. Audit r4 marked O1 fixed.

Verification

Focused issue tests passed for auto-compaction, Sonnet 5.5, SetACPModel, and restart behavior. Scratch ACP verification also passed for the isolation test file and the focused ACP test set; pyright and ruff were clean.

The one live Claude probe used CLI 2.1.293 with Sonnet 5.5 and one turn; it returned ok. The probe did not set CLAUDE_CONFIG_DIR or CLAUDE_CODE_AUTO_COMPACT_WINDOW, so it confirms a bounded session only and does not demonstrate the 400K policy in an isolated config directory. Bundled CLI 2.1.280 was qualified by static inspection. No 400K-reaching run or threshold comparison was performed.

MAKE_VALIDATE: rc=0 on 3730d8a (log chain12-validate-try1.log, chain12)

Closes #80

@github-actions

Copy link
Copy Markdown

Endpoint audit

⚠️ 18 actionable Agent Server contract divergence(s) · report-only

Contract: pinned release artifact

Category Count
Actionable client-only calls 0
Actionable server-only operations 18
Documented non-divergences 13
Agent Server contract operations 129
Audited handwritten client endpoints 119

Actionable client-only calls (0)

none

Actionable server-only operations (18)

  • DELETE /api/canvas-extensions/installed/{}
  • DELETE /api/llm/provider-connections/{}
  • GET /api/canvas-extensions/installed
  • GET /api/canvas-extensions/installed/{}
  • GET /api/canvas-extensions/installed/{}/bundle
  • GET /api/conversations/{}/events
  • GET /api/file/archive
  • GET /api/git/commits
  • GET /api/git/commits/{}/changes
  • GET /api/init
  • GET /api/llm/provider-connections
  • PATCH /api/canvas-extensions/installed/{}
  • PATCH /api/llm/provider-connections/{}
  • POST /api/canvas-extensions/install
  • POST /api/conversations/{}/load_plugin
  • POST /api/file/create_directory
  • POST /api/init
  • POST /api/llm/provider-connections
Documented non-divergences (13)

Client calls intentionally absent from the filtered contract (11)

  • GET /
  • GET /alive
  • GET /health
  • GET /ready
  • GET /server_info

Reason: Operational Agent Server endpoints intentionally excluded from the filtered public release artifact.
Owner: OpenHands runtime maintainers

  • DELETE /api/meta-profiles/{}
  • GET /api/meta-profiles
  • GET /api/meta-profiles/{}
  • POST /api/meta-profiles/{}
  • POST /api/meta-profiles/{}/activate

Reason: Client-ahead API stacked on the pending Agent Server meta-profiles implementation.
Owner: OpenHands SDK maintainers
Tracking: OpenHands#3744

  • POST /api/profiles/{}/validate

Reason: Client-ahead API stacked on the pending Agent Server pre-flight LLM validation endpoint.
Owner: OpenHands TypeScript client maintainers
Tracking: OpenHands#4422

Server operations covered by an exposed browser URL (2)

  • GET /api/conversations/{}/workspace
  • GET /api/conversations/{}/workspace/{}

Reason: RemoteWorkspace.startWorkspaceSession exposes these authenticated URLs for browser iframe and file requests; they are not HttpClient method calls.
Owner: OpenHands TypeScript client maintainers

@github-actions

Copy link
Copy Markdown

Python API breakage checks — ✅ PASSED

Result: ✅ PASSED

Action log

@github-actions

Copy link
Copy Markdown

REST API breakage checks (OpenAPI) — ✅ PASSED

Result: ✅ PASSED

Action log

@github-actions

Copy link
Copy Markdown

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-sdk/openhands/sdk/agent
   acp_agent.py256133087%269, 339–342, 383, 415, 544, 551, 564, 589, 606, 609, 694, 701, 704–705, 803, 810, 830, 872, 875, 953, 1009, 1090–1091, 1095, 1105–1108, 1114–1117, 1120, 1127, 1141, 1147, 1153, 1160, 1162, 1203, 1291, 1405, 1453, 1573, 1577, 1579, 1581, 1610, 1613, 1615, 1619, 1622, 1631, 1714, 1720, 1743, 1801, 1811–1817, 1843–1845, 1856–1857, 1894, 1897, 1914–1918, 2136, 2140, 2176, 2182, 2190–2191, 2194, 2210–2211, 2227, 2230, 2233–2238, 2243, 2253, 2314–2324, 2333, 2373–2374, 2426, 2428, 2432, 2436, 2452, 2594, 2741, 2889, 2892–2893, 2910–2911, 2927, 2944, 2949, 2973, 3004, 3017, 3031, 3052, 3110, 3122, 3171, 3179, 3182, 3186–3189, 3200–3202, 3224, 3232–3233, 3236–3239, 3248–3250, 3256–3258, 3266–3267, 3279–3284, 3287–3289, 3296–3299, 3304–3308, 3320, 3346–3347, 3351–3352, 3360–3363, 3370, 3422, 3427, 3520–3521, 3544–3545, 3645, 3652–3653, 3745, 4005–4006, 4009, 4013–4015, 4018–4022, 4257, 4358, 4472, 4530, 4536, 4551–4552, 4563–4566, 4592, 4600, 4773–4775, 4787–4789, 4816, 4831–4832, 4835–4837, 4844, 4848, 4859–4860, 4868, 4873, 4885–4886, 4900, 4907, 4912–4915, 4917–4920, 4922–4925, 4947, 4959–4961, 4996–4997, 5000, 5008–5010, 5014, 5016, 5020, 5023, 5032–5034, 5038, 5072–5074, 5076, 5081–5083, 5092–5096, 5099, 5104–5106, 5109–5110, 5125–5127, 5182–5184, 5422–5424, 5463, 5467, 5478, 5488, 5496, 5508, 5534, 5555–5557, 5571, 5582–5585, 5672–5673, 5714–5715, 5730–5731, 5739, 5742–5743, 5748, 5750, 5784–5785, 5801–5802
TOTAL429131183372% 

@geeen-jp
geeen-jp merged commit 2b7c522 into main Oct 10, 2026
31 checks passed
@geeen-jp
geeen-jp deleted the issue-80 branch October 10, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

P1: Claude Sonnet 5.5 に auto-compaction 400K を限定適用する

1 participant