Skip to content

Commit

Permalink
Pass monitoring tests
Browse files Browse the repository at this point in the history
  • Loading branch information
aymeric-roucher committed Jan 10, 2025
1 parent 110652c commit 6f2ce4f
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 81 deletions.
9 changes: 4 additions & 5 deletions docs/source/en/guided_tour.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,7 @@ The Python interpreter also doesn't allow imports by default outside of a safe l
You can authorize additional imports by passing the authorized modules as a list of strings in argument `additional_authorized_imports` upon initialization of your [`CodeAgent`]:

```py
from smolagents import CodeAgent

model = HfApiModel()
agent = CodeAgent(tools=[], model=model, additional_authorized_imports=['requests', 'bs4'])
agent.run("Could you get me the title of the page at url 'https://huggingface.co/blog'?")
```
Expand Down Expand Up @@ -164,12 +163,12 @@ Transformers comes with a default toolbox for empowering agents, that you can ad
- **Python code interpreter**: runs your the LLM generated Python code in a secure environment. This tool will only be added to [`ToolCallingAgent`] if you initialize it with `add_base_tools=True`, since code-based agent can already natively execute Python code
- **Transcriber**: a speech-to-text pipeline built on Whisper-Turbo that transcribes an audio to text.

You can manually use a tool by calling the [`load_tool`] function and a task to perform.
You can manually use a tool by calling it with its arguments.

```python
from smolagents import load_tool
from smolagents import DuckDuckGoSearchTool

search_tool = load_tool("web_search")
search_tool = DuckDuckGoSearchTool()
print(search_tool("Who's the current president of Russia?"))
```

Expand Down
123 changes: 90 additions & 33 deletions tests/test_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
ChatCompletionOutputFunctionDefinition,
)


def get_new_path(suffix="") -> str:
directory = tempfile.mkdtemp()
return os.path.join(directory, str(uuid.uuid4()) + suffix)
Expand Down Expand Up @@ -88,7 +89,8 @@ def __call__(
id="call_0",
type="function",
function=ChatCompletionOutputFunctionDefinition(
name="fake_image_generation_tool", arguments={"prompt": "An image of a cat"}
name="fake_image_generation_tool",
arguments={"prompt": "An image of a cat"},
),
)
],
Expand All @@ -108,30 +110,39 @@ def __call__(
],
)


def fake_code_model(messages, stop_sequences=None, grammar=None) -> str:
prompt = str(messages)
if "special_marker" not in prompt:
return ChatCompletionOutputMessage(role="assistant", content="""
return ChatCompletionOutputMessage(
role="assistant",
content="""
Thought: I should multiply 2 by 3.6452. special_marker
Code:
```py
result = 2**3.6452
```<end_code>
""")
""",
)
else: # We're at step 2
return ChatCompletionOutputMessage(role="assistant", content="""
return ChatCompletionOutputMessage(
role="assistant",
content="""
Thought: I can now answer the initial question
Code:
```py
final_answer(7.2904)
```<end_code>
""")
""",
)


def fake_code_model_error(messages, stop_sequences=None) -> str:
prompt = str(messages)
if "special_marker" not in prompt:
return ChatCompletionOutputMessage(role="assistant", content="""
return ChatCompletionOutputMessage(
role="assistant",
content="""
Thought: I should multiply 2 by 3.6452. special_marker
Code:
```py
Expand All @@ -140,21 +151,27 @@ def fake_code_model_error(messages, stop_sequences=None) -> str:
print = 2
print("Ok, calculation done!")
```<end_code>
""")
""",
)
else: # We're at step 2
return ChatCompletionOutputMessage(role="assistant", content="""
return ChatCompletionOutputMessage(
role="assistant",
content="""
Thought: I can now answer the initial question
Code:
```py
final_answer("got an error")
```<end_code>
""")
""",
)


def fake_code_model_syntax_error(messages, stop_sequences=None) -> str:
prompt = str(messages)
if "special_marker" not in prompt:
return ChatCompletionOutputMessage(role="assistant", content="""
return ChatCompletionOutputMessage(
role="assistant",
content="""
Thought: I should multiply 2 by 3.6452. special_marker
Code:
```py
Expand All @@ -163,32 +180,41 @@ def fake_code_model_syntax_error(messages, stop_sequences=None) -> str:
print("Failing due to unexpected indent")
print("Ok, calculation done!")
```<end_code>
""")
""",
)
else: # We're at step 2
return ChatCompletionOutputMessage(role="assistant", content="""
return ChatCompletionOutputMessage(
role="assistant",
content="""
Thought: I can now answer the initial question
Code:
```py
final_answer("got an error")
```<end_code>
""")
""",
)


def fake_code_model_import(messages, stop_sequences=None) -> str:
return ChatCompletionOutputMessage(role="assistant", content="""
return ChatCompletionOutputMessage(
role="assistant",
content="""
Thought: I can answer the question
Code:
```py
import numpy as np
final_answer("got an error")
```<end_code>
""")
""",
)


def fake_code_functiondef(messages, stop_sequences=None) -> str:
prompt = str(messages)
if "special_marker" not in prompt:
return ChatCompletionOutputMessage(role="assistant", content="""
return ChatCompletionOutputMessage(
role="assistant",
content="""
Thought: Let's define the function. special_marker
Code:
```py
Expand All @@ -197,39 +223,49 @@ def fake_code_functiondef(messages, stop_sequences=None) -> str:
def moving_average(x, w):
return np.convolve(x, np.ones(w), 'valid') / w
```<end_code>
""")
""",
)
else: # We're at step 2
return ChatCompletionOutputMessage(role="assistant", content="""
return ChatCompletionOutputMessage(
role="assistant",
content="""
Thought: I can now answer the initial question
Code:
```py
x, w = [0, 1, 2, 3, 4, 5], 2
res = moving_average(x, w)
final_answer(res)
```<end_code>
""")
""",
)


def fake_code_model_single_step(messages, stop_sequences=None, grammar=None) -> str:
return ChatCompletionOutputMessage(role="assistant", content="""
return ChatCompletionOutputMessage(
role="assistant",
content="""
Thought: I should multiply 2 by 3.6452. special_marker
Code:
```py
result = python_interpreter(code="2*3.6452")
final_answer(result)
```
""")
""",
)


def fake_code_model_no_return(messages, stop_sequences=None, grammar=None) -> str:
return ChatCompletionOutputMessage(role="assistant", content="""
return ChatCompletionOutputMessage(
role="assistant",
content="""
Thought: I should multiply 2 by 3.6452. special_marker
Code:
```py
result = python_interpreter(code="2*3.6452")
print(result)
```
""")
""",
)


class AgentTests(unittest.TestCase):
Expand Down Expand Up @@ -406,7 +442,13 @@ def test_code_agent_missing_import_triggers_advice_in_error_log(self):

def test_multiagents(self):
class FakeModelMultiagentsManagerAgent:
def __call__(self, messages, stop_sequences=None, grammar=None, tools_to_call_from=None):
def __call__(
self,
messages,
stop_sequences=None,
grammar=None,
tools_to_call_from=None,
):
if tools_to_call_from is not None:
if len(messages) < 3:
return ChatCompletionOutputMessage(
Expand All @@ -417,7 +459,8 @@ def __call__(self, messages, stop_sequences=None, grammar=None, tools_to_call_fr
id="call_0",
type="function",
function=ChatCompletionOutputFunctionDefinition(
name="search_agent", arguments="Who is the current US president?"
name="search_agent",
arguments="Who is the current US president?",
),
)
],
Expand All @@ -439,28 +482,38 @@ def __call__(self, messages, stop_sequences=None, grammar=None, tools_to_call_fr
)
else:
if len(messages) < 3:
return ChatCompletionOutputMessage(role="assistant", content="""
return ChatCompletionOutputMessage(
role="assistant",
content="""
Thought: Let's call our search agent.
Code:
```py
result = search_agent("Who is the current US president?")
```<end_code>
""")
""",
)
else:
assert "Report on the current US president" in str(messages)
return ChatCompletionOutputMessage(role="assistant", content="""
return ChatCompletionOutputMessage(
role="assistant",
content="""
Thought: Let's return the report.
Code:
```py
final_answer("Final report.")
```<end_code>
""")
""",
)

manager_model = FakeModelMultiagentsManagerAgent()

class FakeModelMultiagentsManagedAgent:
def __call__(
self, messages, tools_to_call_from=None, stop_sequences=None, grammar=None
self,
messages,
tools_to_call_from=None,
stop_sequences=None,
grammar=None,
):
return ChatCompletionOutputMessage(
role="assistant",
Expand All @@ -470,7 +523,8 @@ def __call__(
id="call_0",
type="function",
function=ChatCompletionOutputFunctionDefinition(
name="final_answer", arguments="Report on the current US president"
name="final_answer",
arguments="Report on the current US president",
),
)
],
Expand Down Expand Up @@ -511,13 +565,16 @@ def __call__(

def test_code_nontrivial_final_answer_works(self):
def fake_code_model_final_answer(messages, stop_sequences=None, grammar=None):
return ChatCompletionOutputMessage(role="assistant", content="""Code:
return ChatCompletionOutputMessage(
role="assistant",
content="""Code:
```py
def nested_answer():
final_answer("Correct!")
nested_answer()
```<end_code>""")
```<end_code>""",
)

agent = CodeAgent(tools=[], model=fake_code_model_final_answer)

Expand Down
11 changes: 8 additions & 3 deletions tests/test_all_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ def setup_class(cls):
raise ValueError(f"Docs directory not found at {cls.docs_dir}")

load_dotenv()
cls.hf_token = os.getenv("HF_TOKEN")

cls.md_files = list(cls.docs_dir.rglob("*.md"))
if not cls.md_files:
Expand All @@ -115,6 +114,7 @@ def test_single_doc(self, doc_path: Path):
"from_langchain", # Langchain is not a dependency
"while llm_should_continue(memory):", # This is pseudo code
"ollama_chat/llama3.2", # Exclude ollama building in guided tour
"model = TransformersModel(model_id=model_id)", # Exclude testing with transformers model
]
code_blocks = [
block
Expand All @@ -131,10 +131,15 @@ def test_single_doc(self, doc_path: Path):
ast.parse(block)

# Create and execute test script
print("\n\nCollected code block:==========\n".join(code_blocks))
try:
code_blocks = [
block.replace("<YOUR_HUGGINGFACEHUB_API_TOKEN>", self.hf_token).replace(
"{your_username}", "m-ric"
(
block.replace(
"<YOUR_HUGGINGFACEHUB_API_TOKEN>", os.getenv("HF_TOKEN")
)
.replace("YOUR_ANTHROPIC_API_KEY", os.getenv("ANTHROPIC_API_KEY"))
.replace("{your_username}", "m-ric")
)
for block in code_blocks
]
Expand Down
Loading

0 comments on commit 6f2ce4f

Please sign in to comment.