TokenPolicy per managed agent to observe usage, enforce budgets, or reduce model context. These controls are independent and off unless configured.
Start with observation
Add a policy to your existing agent definition:agent.py
TokenPolicy() observes without changing or blocking requests. Numeric reports go to harnest.tokens at INFO level or your observer; prompt and tool-result content is excluded.
You can set budgets while leaving enforce=False to observe which input, context-window, and model-call budgets would be exceeded. An output limit is passed to the provider only when enforcement is enabled.
Choose limits and reductions
Agent(token_policy=policy, ...). These numbers are examples, not defaults. Configure each graph agent or subagent independently; a parent’s policy does not automatically configure its children or native targets.
See TokenPolicy settings and defaults for every option. Start with observation, then enable only the limits and reductions your workload needs.
Reductions run when you explicitly configure them, even if enforce=False. To observe unchanged requests, leave all reductions and transforming callbacks unset.
The default counter estimates serialized input at four characters per token. Reports mark these counts as estimates. Provider framing, language, media, and generated tool schemas can change actual usage. Supply a model-aware
count_tokens callback when you need accurate admission checks. A count-based input budget is not a guaranteed billing cap.TokenBudgetExceeded. In a stream, earlier output may already have reached the caller.
Model-call counts are shared per agent within an invocation and reset on new or resumed invocations. Provider-internal retries are excluded; these are not durable spending limits.
Keep the original history
Reductions affect only the model request. Session history, checkpoints, and original tool results remain unchanged. The built-in history reduction removes complete earlier turns. It keeps the latest user turn and its ongoing tool exchanges together, and preserves system/developer instructions. It does not generate summaries. Tool-text reduction preserves identifiers and structured scalar types, and leaves LangGraph non-text media blocks intact. ADK JSON response string values are shortened individually. Compare task success, retries, latency, and token usage before enabling reductions. Use a custom transformation for summaries or selective retention.Override or disable for one invocation
Use a trusted Python scope around runtime calls:Agent(token_policy=TokenPolicy(enabled=False), ...) to install a disabled adapter for later activation. Agent(token_policy=None, ...), the default, installs no adapter at all.
Only trusted Python code can change token policy; HTTP metadata cannot. Authenticate callers before selecting a profile. Outside Harnest invocations, use token_policy_scope(...) for max_model_calls state.
Supply your own strategies
All strategy callbacks accept ordinary or asynchronous functions. Synchronous model calls require synchronous strategies. Harnest does not call an additional model unless your strategy does so. Choose a strategy callback when built-in counting, retention, or tool selection does not fit your workload. Harnest counts input, applies built-in reductions, runsrequest_transform and tool_selector, recounts, then checks budgets. Selection preserves tool order and cannot add permissions.
For example, restrict exposed tools using an application-owned set:
TokenRequest uses native message and system formats: Google Content dictionaries for ADK and LangChain messages_to_dict for LangGraph. Branch on framework when transforming native settings. See TokenRequest fields.
Transformations may edit messages, instructions, and generation settings. They must preserve tool-call/result pairing, required instructions, and native metadata. Use tool_selector to select tools; context_metadata is read-only counter input.
TokenReport separates counted input from provider-reported usage; unavailable usage stays None. Observer failures log a warning without interrupting execution. See report fields.
Framework coverage
Policies apply to configured managed agents in ordinary and streaming calls. Native targets and model calls inside your own Python need separate integration. Disable token policy for ADK live connections, which reject active policies. Configure provider caching and reasoning through model settings or your request transformation. See Agents and graphs, Lifecycle, and Telemetry for the surrounding runtime contracts.API reference
Reference:harnest.model.