This fixes the issue where the original agent's model_settings was being directly modified during the tool choice reset process. The original implementation caused the agent's tool_choice to unintentionally reset to "auto" for subsequent runs, which could be unexpected behavior.
The fix creates new copies of the agent and model settings objects using dataclasses.replace() instead of modifying the original objects. This ensures that the tool choice reset is limited to the current run only, maintaining the expected behavior for sequential runs with the same agent.
Addresses feedback from @baderalfahad about the agent instance being modified when it should maintain its original state between runs.
- Refactor tool_choice reset to target only problematic edge cases
- Replace manual ModelSettings recreation with dataclasses.replace
- Fix line length and error handling lint issues in tests
## Context
By default, the outputs of tools are sent to the LLM again. The LLM gets
to read the outputs, and produce a new response. There are cases where
this is not desired:
1. Every tool results in another round trip, and sometimes the output of
the tool is enough.
2. If you force tool use (via model settings `tool_choice=required`),
then the agent will just infinite loop.
This enables you to have different behavior, e.g. use the first tool
output as the final output, or write a custom function to process tool
results and potentially produce an output.
## Test plan
Added new tests and ran existing tests
Also added examples.
Closes#117
`assert len(spans) == 12` is a very weak assertion. This PR asserts the
exported traces and spans more precisely in a readable tree format. And
when the format of an exported trace/span changes (e.g. a new key is
added to every span), you can use `pytest --inline-snapshot=fix` to
update all relevant tests automatically. See
https://15r10nk.github.io/inline-snapshot/latest/ for more info.
## Changes
- In this handoff example, we need to use `first_agent` with
`random_number_tool`, instead of `second_agent` without that tool, since
the user is asking to generate a random number.
- fixed typo in comments
# Summary
This adds the missing TracingProcessor export to __init__.py.
# Behavior
When trying to add a custom tracing processor, the TracingProcessor
importing fails with not found error when trying the example usage
proposed in issue #164
Specifically this line throws the error:
`add_trace_processor(MyTracingProcessor("output"))`
# Expected Behavior
Inspecting the init file, simply the import/export was missing. Adding
these made the example code work for me
# Test plan
Local dev of example code in #164
# Issue number
#164
# Checks
None
These classes print a really long, unreadable output by default. This
trims it to the main useful info (i.e. output, last agent, overview of
run).
---
[//]: # (BEGIN SAPLING FOOTER)
* __->__ #196
* #195