@@ -66,23 +66,45 @@ def _assemble_instructions(
6666def _assemble_compaction_provider (
6767 * ,
6868 disable_compaction : bool ,
69- max_context_window_tokens : int ,
70- max_output_tokens : int ,
69+ max_context_window_tokens : int | None ,
70+ max_output_tokens : int | None ,
7171 history_source_id : str ,
7272 before_compaction_strategy : CompactionStrategy | None ,
7373 after_compaction_strategy : CompactionStrategy | None ,
7474 tokenizer : TokenizerProtocol | None ,
7575) -> CompactionProvider | None :
76- """Build the compaction provider from parameters or defaults."""
76+ """Build the compaction provider from parameters or defaults.
77+
78+ The token-budget defaults (``ContextWindowCompactionStrategy`` for the before phase and
79+ ``ToolResultCompactionStrategy`` for the after phase) are only applied when the token
80+ params are provided. Caller-supplied strategies are always honored. Either phase may end
81+ up ``None``, which ``CompactionProvider`` interprets as "skip that phase".
82+
83+ Returns None when compaction is explicitly disabled, or when neither phase has a strategy
84+ (no custom strategies and no token budget to build the defaults).
85+ """
7786 if disable_compaction :
7887 return None
7988
80- before_strategy = before_compaction_strategy or ContextWindowCompactionStrategy (
81- max_context_window_tokens = max_context_window_tokens ,
82- max_output_tokens = max_output_tokens ,
83- tokenizer = tokenizer ,
84- )
85- after_strategy = after_compaction_strategy or ToolResultCompactionStrategy (keep_last_tool_call_groups = 2 )
89+ # Resolve the before-strategy: custom strategy wins; otherwise fall back to the
90+ # token-budget-aware default when token params are available.
91+ before_strategy = before_compaction_strategy
92+ if before_strategy is None and max_context_window_tokens is not None and max_output_tokens is not None :
93+ before_strategy = ContextWindowCompactionStrategy (
94+ max_context_window_tokens = max_context_window_tokens ,
95+ max_output_tokens = max_output_tokens ,
96+ tokenizer = tokenizer ,
97+ )
98+
99+ # Resolve the after-strategy: custom strategy wins; otherwise fall back to the default
100+ # when token params are available.
101+ after_strategy = after_compaction_strategy
102+ if after_strategy is None and max_context_window_tokens is not None and max_output_tokens is not None :
103+ after_strategy = ToolResultCompactionStrategy (keep_last_tool_call_groups = 2 )
104+
105+ # Nothing to compact in either phase: skip the provider entirely.
106+ if before_strategy is None and after_strategy is None :
107+ return None
86108
87109 return CompactionProvider (
88110 before_strategy = before_strategy ,
@@ -157,8 +179,8 @@ def create_harness_agent(
157179 harness_instructions : str | None = None ,
158180 agent_instructions : str | None = None ,
159181 tools : ToolTypes | Callable [..., Any ] | Sequence [ToolTypes | Callable [..., Any ]] | None = None ,
160- max_context_window_tokens : int ,
161- max_output_tokens : int ,
182+ max_context_window_tokens : int | None = None ,
183+ max_output_tokens : int | None = None ,
162184 history_provider : HistoryProvider | None = None ,
163185 disable_compaction : bool = False ,
164186 before_compaction_strategy : CompactionStrategy | None = None ,
@@ -206,8 +228,6 @@ def create_harness_agent(
206228
207229 agent = create_harness_agent(
208230 OpenAIChatClient(model="gpt-4o"),
209- max_context_window_tokens=128_000,
210- max_output_tokens=16_384,
211231 )
212232 session = agent.create_session()
213233 response = await agent.run("Plan a weekend trip to Seattle", session=session)
@@ -243,13 +263,21 @@ def create_harness_agent(
243263 (e.g., "You are a research assistant focused on academic sources.").
244264 tools: Additional tools to include in the agent's toolset.
245265 max_context_window_tokens: Maximum tokens the model's context window supports.
266+ Used to construct the default token-budget-aware compaction strategies. When None
267+ (default) and no custom ``before_compaction_strategy`` / ``after_compaction_strategy``
268+ is provided, compaction is automatically disabled.
246269 max_output_tokens: Maximum output tokens per response.
270+ Used to construct the default compaction strategies and sets a default max_tokens
271+ chat option. When None (default), no default max_tokens option is set, and unless a
272+ custom compaction strategy is provided, compaction is automatically disabled.
247273 history_provider: Custom history provider. When None, an InMemoryHistoryProvider is used.
248274 disable_compaction: When True, skip compaction provider setup.
249- before_compaction_strategy: Custom before-run compaction strategy.
250- Defaults to ContextWindowCompactionStrategy (token-budget aware).
251- after_compaction_strategy: Custom after-run compaction strategy.
252- Defaults to ToolResultCompactionStrategy.
275+ before_compaction_strategy: Custom before-run compaction strategy. When provided,
276+ compaction runs even if token params are omitted. Defaults to
277+ ContextWindowCompactionStrategy (token-budget aware) when token params are provided.
278+ after_compaction_strategy: Custom after-run compaction strategy. When provided,
279+ compaction runs even if token params are omitted. Defaults to
280+ ToolResultCompactionStrategy when token params are provided.
253281 tokenizer: Custom tokenizer for compaction strategies.
254282 disable_todo: When True, skip the TodoProvider.
255283 todo_provider: Custom TodoProvider instance. Ignored when disable_todo is True.
@@ -283,14 +311,19 @@ def create_harness_agent(
283311 A fully configured :class:`~agent_framework.Agent` instance.
284312
285313 Raises:
286- ValueError: If max_context_window_tokens <= 0 or max_output_tokens < 0
287- or max_output_tokens >= max_context_window_tokens.
314+ ValueError: If max_context_window_tokens is provided and <= 0, or
315+ max_output_tokens is provided and <= 0, or max_output_tokens >=
316+ max_context_window_tokens when both are provided.
288317 """
289- if max_context_window_tokens <= 0 :
318+ if max_context_window_tokens is not None and max_context_window_tokens <= 0 :
290319 raise ValueError ("max_context_window_tokens must be positive." )
291- if max_output_tokens < 0 :
292- raise ValueError ("max_output_tokens must be non-negative." )
293- if max_output_tokens >= max_context_window_tokens :
320+ if max_output_tokens is not None and max_output_tokens <= 0 :
321+ raise ValueError ("max_output_tokens must be positive." )
322+ if (
323+ max_context_window_tokens is not None
324+ and max_output_tokens is not None
325+ and max_output_tokens >= max_context_window_tokens
326+ ):
294327 raise ValueError ("max_output_tokens must be less than max_context_window_tokens." )
295328
296329 # Build history provider.
@@ -347,7 +380,8 @@ def create_harness_agent(
347380
348381 # Build default options dict.
349382 default_opts : dict [str , Any ] = dict (default_options ) if default_options else {}
350- default_opts .setdefault ("max_tokens" , max_output_tokens )
383+ if max_output_tokens is not None :
384+ default_opts .setdefault ("max_tokens" , max_output_tokens )
351385
352386 agent = Agent (
353387 client ,
0 commit comments