# tinker_cookbook.tool_use.AgentToolMessageEnv ## *class* [**tinker_cookbook.tool_use.AgentToolMessageEnv**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L37)(*[MessageEnv](https://tinker-docs.thinkingmachines.ai/cookbook/api-reference/rl/messageenv/index.md)*) Generic tool-use MessageEnv for agents. **Fields:** - [**tools**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L40) (*list\[[Tool](https://tinker-docs.thinkingmachines.ai/cookbook/api-reference/tool_use/types_tool/index.md)\]*) - [**initial_messages**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L41) (*list\[[Message](https://tinker-docs.thinkingmachines.ai/cookbook/api-reference/renderers/message/index.md)\]*) - [**max_turns**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L42) (*int*) - [**reward_fn**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L43) (*RewardFn*) - [**failed_parse_reward**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L44) (*float*, default: `-0.1`) - [**terminate_on_parse_error**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L45) (*bool*, default: `True`) - [**max_tool_calls**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L46) (*int | None*, default: `None`) - [**parse_error_policy**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L47) (*ParseErrorPolicy | None*, default: `None`) - [**tool_execution**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L48) (*ToolExecution*, default: `'parallel'`) - [**termination_policy**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L49) (*TerminationRewardPolicy | None*, default: `None`) - [**history**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L50) (*list\[[Message](https://tinker-docs.thinkingmachines.ai/cookbook/api-reference/renderers/message/index.md)\]*, default: `field(default_factory=list)`) ### [**set_max_tool_calls**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L75)(*max_tool_calls*) Apply a rollout-level tool-call limit (seam used by the rollout runner). When a limit is already configured on the env, the tighter cap wins. **Parameters:** - [**max_tool_calls**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L75) (*int*) **Returns:** *None* ### [**set_parse_error_policy**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L85)(*policy*) Apply a rollout-level parse-error policy (seam used by the rollout runner). **Parameters:** - [**policy**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L85) (*ParseErrorPolicy*) **Returns:** *None* ### [**observe_truncated_response**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L89)(*message*) Record a truncated assistant response (LENGTH-continue support). The message is appended to the history as-is; no tools run and the turn/tool-call counters are untouched. **Parameters:** - [**message**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L89) (*[Message](https://tinker-docs.thinkingmachines.ai/cookbook/api-reference/renderers/message/index.md)*) **Returns:** *list\[[Message](https://tinker-docs.thinkingmachines.ai/cookbook/api-reference/renderers/message/index.md)\]* ### [**add_messages**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L98)(*messages*) Append externally injected messages (rollout-hook support). **Parameters:** - [**messages**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L98) (*list\[[Message](https://tinker-docs.thinkingmachines.ai/cookbook/api-reference/renderers/message/index.md)\]*) **Returns:** *list\[[Message](https://tinker-docs.thinkingmachines.ai/cookbook/api-reference/renderers/message/index.md)\]* ### [**step**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L137)(*message*) Execute any tools and return next messages. **The episode ends when:** - no tool calls in message (model decided to stop) - every tool call in the message failed to parse and `terminate_on_parse_error` is True - a tool returns should_stop=True - max_turns reached - the tool-call budget (`max_tool_calls`, when configured) is exhausted — checked pre-dispatch and mid-batch, so a turn asking for more calls than the remaining budget executes only the allowed prefix and then stops Tool calls whose arguments failed to parse (e.g. malformed JSON) arrive in `message["unparsed_tool_calls"]`. When the message contains *only* unparsed tool calls, the turn is a parse failure: `failed_parse_reward` is applied, `metrics["parse_error"]` is set, the error details are recorded in `logs["parse_errors"]`, and `reward_fn` is skipped. When valid and unparsed tool calls are mixed, the valid ones execute and the episode proceeds normally with no failure reward (some tool progress happened), but the parse error is still surfaced via `metrics["parse_error"]` and `logs["parse_errors"]`. reward_fn is called once at episode end to grade the full trajectory. **Parameters:** - [**message**](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/tool_use/agent_tool_message_env.py#L137) (*[Message](https://tinker-docs.thinkingmachines.ai/cookbook/api-reference/renderers/message/index.md)*) **Returns:** *[MessageStepResult](https://tinker-docs.thinkingmachines.ai/cookbook/api-reference/rl/messagestepresult/index.md)*