Math via python code with a single agent

The point of this example is to illustrate that for agents that have an AgentExecutor (which most frameworks have apart from Autogen), the approach from MathChat can be done with a single agent, as the second conversation partner there just plays the role of an AgentExecutor.

[1]:
%pip install sympy  # install sympy for the example
Requirement already satisfied: sympy in /Users/whimo/motleycrew/.venv/lib/python3.11/site-packages (1.14.0)
Requirement already satisfied: mpmath<1.4,>=1.1.0 in /Users/whimo/motleycrew/.venv/lib/python3.11/site-packages (from sympy) (1.3.0)

[notice] A new release of pip is available: 24.3.1 -> 25.1.1
[notice] To update, run: pip install --upgrade pip
Note: you may need to restart the kernel to use updated packages.
[2]:
import os, sys
from pathlib import Path
from dotenv import load_dotenv

WORKING_DIR = Path(os.path.realpath("."))


try:
    from motleycrew import MotleyCrew
except ImportError:
    # if we are running this from source
    motleycrew_location = os.path.realpath( "..")
    sys.path.append(motleycrew_location)

from motleycrew import MotleyCrew
from motleycrew.agents.langchain import ReActToolCallingMotleyAgent
from motleycrew.tools.code import PythonREPLTool
from motleycrew.common import configure_logging
from motleycrew.tasks import SimpleTask

configure_logging(verbose=True)
load_dotenv()
[2]:
True
[3]:
"""Main function of running the example."""

repl_tool = PythonREPLTool()

# Define your agents with roles and goals
solver = ReActToolCallingMotleyAgent(
    prompt="""You are a high school math teacher with a passion for problem-solving.
To solve a math problem, you first reason about it, step by step, then generate the code to solve it exactly,
using sympy, then use the REPL tool to evaluate that code, and then
use the output to generate a human-readable solution in LaTeX format.
Don't use dashes to indicate bullet points, don't output any backticks, just the LaTeX

{prompt}""",  # The {prompt} placeholder is where the task-specific prompt will go
    verbose=True,
    tools=[repl_tool],
)

problems = [
    "If $725x + 727y = 1500$ and $729x+ 731y = 1508$, "
    "what are the values of $x$, $y$, and $x - y$ ?",
]

# Create tasks for your agents
crew = MotleyCrew()
task = SimpleTask(
    crew=crew,
    name="solve math problem",
    description=f"""Create a nice human-readable solution to the following problem:
    {problems[0]}""",
    agent=solver,
)

# Get your crew to work!
crew.run()

display(task.output)
2025-07-30 20:00:05,275 - motleycrew.tools.code.python_repl - WARNING - Python REPL can execute arbitrary code from LLMs. Only use with trusted models and in secure environments. Consider using sandboxing or code review for production systems.
2025-07-30 20:00:06,745 - motleycrew - INFO - No db_path provided, creating temporary directory for database
2025-07-30 20:00:06,746 - motleycrew - INFO - Using Kuzu graph store with path: /var/folders/fv/tyhll76x0fn6l7j_q2nhvyg00000gn/T/tmpwkgrr68y/kuzu_db
2025-07-30 20:00:06,786 - motleycrew - INFO - Node table TaskNode does not exist in the database, creating
2025-07-30 20:00:06,804 - motleycrew - INFO - Property name not present in table for label TaskNode, creating
2025-07-30 20:00:06,806 - motleycrew - INFO - Property done not present in table for label TaskNode, creating
2025-07-30 20:00:06,808 - motleycrew - INFO - Node table SimpleTaskUnit does not exist in the database, creating
2025-07-30 20:00:06,810 - motleycrew - INFO - Property status not present in table for label SimpleTaskUnit, creating
2025-07-30 20:00:06,811 - motleycrew - INFO - Property output not present in table for label SimpleTaskUnit, creating
2025-07-30 20:00:06,812 - motleycrew - INFO - No known Cypher type matching annotation typing.Optional[typing.Any], will use JSON string
2025-07-30 20:00:06,813 - motleycrew - INFO - Property name not present in table for label SimpleTaskUnit, creating
2025-07-30 20:00:06,814 - motleycrew - INFO - Property prompt not present in table for label SimpleTaskUnit, creating
2025-07-30 20:00:06,815 - motleycrew - INFO - Property additional_params not present in table for label SimpleTaskUnit, creating
2025-07-30 20:00:06,815 - motleycrew - INFO - No known Cypher type matching annotation typing.Optional[dict[str, typing.Any]], will use JSON string
2025-07-30 20:00:06,817 - motleycrew - INFO - Relation table SimpleTaskUnit_belongs from SimpleTaskUnit to TaskNode does not exist in the database, creating
2025-07-30 20:00:06,820 - motleycrew - INFO - Inserting new node with label TaskNode: name='solve math problem' done=False
2025-07-30 20:00:06,830 - motleycrew - INFO - Node created OK
2025-07-30 20:00:06,832 - motleycrew - INFO - Relation table task_is_upstream from TaskNode to TaskNode does not exist in the database, creating
2025-07-30 20:00:06,864 - motleycrew - INFO - Available tasks: [SimpleTask(name=solve math problem, done=False)]
2025-07-30 20:00:06,867 - motleycrew - INFO - Processing task: SimpleTask(name=solve math problem, done=False)
2025-07-30 20:00:06,876 - motleycrew - INFO - Got a matching unit for task SimpleTask(name=solve math problem, done=False)
2025-07-30 20:00:06,877 - motleycrew - INFO - Processing unit: TaskUnit(status=pending)
2025-07-30 20:00:06,878 - motleycrew - INFO - Assigned unit TaskUnit(status=pending) to agent ReActToolCallingMotleyAgent(name=None), dispatching
2025-07-30 20:00:06,878 - motleycrew - INFO - Node TaskUnit(status=running) does not exist, creating
2025-07-30 20:00:06,880 - motleycrew - INFO - Inserting new node with label SimpleTaskUnit: TaskUnit(status=running)
2025-07-30 20:00:06,881 - motleycrew - INFO - No known Cypher type matching annotation typing.Optional[typing.Any], will use JSON string
2025-07-30 20:00:06,882 - motleycrew - INFO - No known Cypher type matching annotation typing.Optional[dict[str, typing.Any]], will use JSON string
2025-07-30 20:00:06,884 - motleycrew - INFO - Node created OK
2025-07-30 20:00:06,895 - motleycrew - INFO - Relation from TaskUnit(status=running) to name='solve math problem' done=False does not exist, creating
2025-07-30 20:00:06,900 - motleycrew - INFO - Creating relation SimpleTaskUnit_belongs from SimpleTaskUnit:0 to TaskNode:0
2025-07-30 20:00:06,906 - motleycrew - INFO - Relation created OK
2025-07-30 20:00:06,914 - motleycrew - INFO - Wrapping agent in RunnableWithMessageHistory


> Entering new AgentExecutor chain...
2025-07-30 20:00:12,001 - motleycrew - INFO - Reflecting exception in tool python_repl: MissingPrintStatementError: Command must contain at least one print statement. Remember to print the results you want to see using print(...).

Invoking: `python_repl` with `{'command': "from sympy import symbols, Eq, solve\n\n# Define the variables\nx, y = symbols('x y')\n\n# Define the equations\neq1 = Eq(725*x + 727*y, 1500)\neq2 = Eq(729*x + 731*y, 1508)\n\n# Solve the system of equations\nsolution = solve((eq1, eq2), (x, y))\n\n# Calculate x - y\nx_minus_y = solution[x] - solution[y]\n\nsolution, x_minus_y"}`
responded: Thought: To solve the system of linear equations given by \( 725x + 727y = 1500 \) and \( 729x + 731y = 1508 \), we can use sympy to find the values of \( x \) and \( y \). Once we have these values, we can also calculate \( x - y \). Let's use sympy to solve this system of equations.

I will write the code to solve these equations using sympy and execute it to find the values of \( x \), \( y \), and \( x - y \).

MissingPrintStatementError: Command must contain at least one print statement. Remember to print the results you want to see using print(...).
Invoking: `python_repl` with `{'command': "from sympy import symbols, Eq, solve\n\n# Define the variables\nx, y = symbols('x y')\n\n# Define the equations\neq1 = Eq(725*x + 727*y, 1500)\neq2 = Eq(729*x + 731*y, 1508)\n\n# Solve the system of equations\nsolution = solve((eq1, eq2), (x, y))\n\n# Calculate x - y\nx_minus_y = solution[x] - solution[y]\n\nprint('Solution:', solution)\nprint('x - y:', x_minus_y)"}`
responded: Thought: I need to add a print statement to display the results of the solution and the value of \( x - y \). I will modify the code to include print statements for these values.

Solution: {x: -23, y: 25}
x - y: -48

2025-07-30 20:00:21,691 - motleycrew - INFO - No known Cypher type matching annotation typing.Optional[typing.Any], will use JSON string
2025-07-30 20:00:21,696 - motleycrew - INFO - Task unit TaskUnit(status=running) completed, marking as done
2025-07-30 20:00:21,701 - motleycrew - INFO - Available tasks: []
2025-07-30 20:00:21,703 - motleycrew - INFO - Nothing left to do, exiting
Final Answer:
To solve the system of equations:

\[
\begin{align*}
725x + 727y &= 1500 \\
729x + 731y &= 1508
\end{align*}
\]

we find the values of \( x \) and \( y \) to be:

\[
x = -23, \quad y = 25
\]

Thus, the value of \( x - y \) is:

\[
x - y = -23 - 25 = -48
\]

Therefore, the solution is:

\[
x = -23, \quad y = 25, \quad x - y = -48
\]

> Finished chain.
'Final Answer: \nTo solve the system of equations:\n\n\\[\n\\begin{align*}\n725x + 727y &= 1500 \\\\\n729x + 731y &= 1508\n\\end{align*}\n\\]\n\nwe find the values of \\( x \\) and \\( y \\) to be:\n\n\\[\nx = -23, \\quad y = 25\n\\]\n\nThus, the value of \\( x - y \\) is:\n\n\\[\nx - y = -23 - 25 = -48\n\\]\n\nTherefore, the solution is:\n\n\\[\nx = -23, \\quad y = 25, \\quad x - y = -48\n\\]'
[4]:
from IPython.display import display, Math, Latex
display(Latex(task.output))
Final Answer: To solve the system of equations: \[ \begin{align*} 725x + 727y &= 1500 \\ 729x + 731y &= 1508 \end{align*} \] we find the values of \( x \) and \( y \) to be: \[ x = -23, \quad y = 25 \] Thus, the value of \( x - y \) is: \[ x - y = -23 - 25 = -48 \] Therefore, the solution is: \[ x = -23, \quad y = 25, \quad x - y = -48 \]