Commit ff4b312
authored
feat(providers): always-on client-side context compaction for pydantic-ai providers (claude, openai) (#503)
* build(deps): add pydantic-ai-harness and bump pydantic-ai-slim floor
* feat(providers): add context-window and output-limit resolution cascades for compaction
* feat(providers): assemble tiered compaction capability for pydantic-ai agents
* feat(providers): enable always-on tiered compaction for claude and openai providers
* feat(providers): emit compaction lifecycle events for pydantic-ai agents
* feat(cli): render compaction lifecycle events in console output
- Add ConsoleEventSubscriber branches for agent_compaction_config, start, and complete.
- Use styled()/join() for markup-safe interpolation per AGENTS.md rules.
- Extend test_logging.py with config/start/success/failure render tests.
- Add JSONL verbatim round-trip test and replay skip-list guard.
* feat(dashboard): show compaction lifecycle events in the activity stream
- Add agent_compaction_config/start/complete to the EventType union and payload interfaces.
- Append activity-log entries for compaction lifecycle events on the active node.
- Add Vitest coverage for config/start/complete/success/error and replay-state neutrality.
- Regenerate static/ assets via make build-frontend.
* docs: document automatic context compaction for pydantic-ai providers
* feat(providers): unify default max_tokens at 16384 for claude and openai
* feat(providers): resolve effective anthropic max_tokens and read model output cap for compaction
* fix(providers): additive compaction reserve from effective max_tokens and tool-output config
* docs: align compaction reserve docs with effective-max-tokens formula
* feat(providers): add vendor model-listing token-limit parser for compaction
* refactor(providers): drop the global compaction context-window env override
* fix(providers): paginate the full Anthropic model listing for token-limit metadata
* feat(providers): read vendor-advertised model token limits in the OpenAI provider
* fix(providers): handle OpenAI SDK AsyncPaginator in model metadata fetch
* test(providers): pin compaction cascade behavior with provider-advertised limits
* docs: document provider-advertised token limits and drop the window env override
* fix(providers): harden compaction metadata parsing and close lifecycle
Defensive model-listing parser for hostile Mapping/property access.
Broad exception handling in Claude metadata cache population.
Reset Claude unavailable-listing latches in close().
Restore OpenAI get_model_capabilities token fields to None and plain in membership.
Add regression tests for parser hostility, proxy-prefix negative pin, and close reset.
* fix(providers): emit compaction start event before the inner strategy runs
The fail-open wrapper emitted agent_compaction_start only after the inner
tiered strategy (including the summarizer's network call) had already
returned, and hardcoded elapsed to 0.0, so console/JSONL/dashboard showed
an instant start/complete pair instead of a live lifecycle. Emit start
immediately before delegating when the estimate crosses the trigger, and
measure the real elapsed time.
* fix(providers): warn only for explicit models and single-flight model listing
The available-models warning fired for the hardcoded provider default
(e.g. gpt-5-mini) even when every agent overrides it with its own model:,
producing a misleading warning on proxies that don't list the default.
Warn only when the model was explicitly requested via the constructor.
Also move the models.list() fetch under the cache lock with a
double-checked pattern so concurrent first-callers issue exactly one
round-trip instead of a stampede, and honor a per-agent max_tokens
attribute (issue #471 groundwork) when resolving the compaction output
limit in both providers.
* test(providers): pin explicit-model warning, listing single-flight, per-agent compaction limit
Cover the companion provider fixes: no warning for the hardcoded default
model when agents override it (warning retained for an explicitly
requested model), exactly one models.list() call under concurrent
first-callers, and the compaction output limit honoring a per-agent
max_tokens attribute with source "settings".
* fix(providers): address PR #503 review findings on context compaction
Blocking:
- measure post-compaction tokens via heuristic reclaim (mirroring
TieredCompaction._escalate) so tokens_saved is non-zero on real
compactions instead of always reporting before == after
- replace the degenerate trigger=1 floor with resolve_compaction_plan:
the tool buffer is clamped to 25% of the window, the target keeps a
window-scaled 5% hysteresis margin below the trigger, and a plan with
no viable headroom is disabled (reported on agent_compaction_config
via enabled/disabled_reason) instead of compacting on every request
- keep max_tokens off the OpenAI wire when unset; the compaction reserve
still falls back to the 16384 default internally, so reasoning models
keep the server's full output allowance
Recommended:
- fold ANTHROPIC_BASE_URL into ClaudeProvider._base_url so
has_custom_base_url gates registry lookups for env-configured proxies
- bound Anthropic/OpenAI model-listing drains at 2000 entries, handle
partial listings explicitly, never cache an empty listing, and narrow
the catch to transport errors so parser bugs surface
- pin pydantic-ai-harness (<0.25) and pydantic-ai-slim (<3), and declare
genai-prices as a direct dependency
- delete the dead _ThresholdGatedCompaction gate (its branches were
identical and duplicated the wrapper's own estimate)
- split the wrapper's failure handling into three zones so a telemetry
failure no longer latches compaction off or reports false failure, and
name degraded tiers / still-over-trigger on agent_compaction_complete
- implement AgentProvider.get_max_output_tokens on the Copilot provider
- style the four compaction activity types in the dashboard, render
tokens_saved, and surface disabled/degraded states
- rebuild examples/compaction.yaml around a multi-turn MCP tool loop
(loop-back iterations never accumulated provider history) and fix the
inverted trigger-direction comment
- correct docs claiming ModelInfo.max_tokens caps the wire value, the
dashboard-bar refresh timing, and split the CHANGELOG entry into
Added/Changed (dropping the nonexistent 64k-fallback removal note)1 parent ead6c76 commit ff4b312
48 files changed
Lines changed: 6370 additions & 221 deletions
File tree
- docs
- providers
- examples
- plugins/conductor/skills/conductor/references
- src/conductor
- cli
- config
- providers
- _pydantic_ai
- web
- frontend/src
- components
- detail
- layout
- stores
- types
- static
- assets
- tests
- test_cli
- test_config
- test_engine
- test_integration
- test_providers
- test_web
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
228 | 228 | | |
229 | 229 | | |
230 | 230 | | |
| 231 | + | |
| 232 | + | |
231 | 233 | | |
232 | 234 | | |
233 | 235 | | |
| |||
389 | 391 | | |
390 | 392 | | |
391 | 393 | | |
| 394 | + | |
392 | 395 | | |
393 | 396 | | |
394 | 397 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
108 | 108 | | |
109 | 109 | | |
110 | 110 | | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
111 | 121 | | |
112 | 122 | | |
113 | 123 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
436 | 436 | | |
437 | 437 | | |
438 | 438 | | |
439 | | - | |
| 439 | + | |
440 | 440 | | |
441 | 441 | | |
442 | 442 | | |
443 | 443 | | |
444 | | - | |
| 444 | + | |
445 | 445 | | |
446 | 446 | | |
447 | 447 | | |
| |||
496 | 496 | | |
497 | 497 | | |
498 | 498 | | |
499 | | - | |
500 | | - | |
501 | | - | |
| 499 | + | |
502 | 500 | | |
503 | | - | |
504 | | - | |
505 | | - | |
506 | | - | |
507 | | - | |
508 | | - | |
| 501 | + | |
509 | 502 | | |
510 | 503 | | |
511 | 504 | | |
| |||
790 | 783 | | |
791 | 784 | | |
792 | 785 | | |
793 | | - | |
| 786 | + | |
794 | 787 | | |
795 | 788 | | |
796 | 789 | | |
| |||
0 commit comments