Skip to content

⚡ Optimize run_python tool to use asyncio subprocess#4

Open
mudcube wants to merge 1 commit intomainfrom
perf-optimize-run-python-11119271779874421824
Open

⚡ Optimize run_python tool to use asyncio subprocess#4
mudcube wants to merge 1 commit intomainfrom
perf-optimize-run-python-11119271779874421824

Conversation

@mudcube
Copy link
Copy Markdown
Contributor

@mudcube mudcube commented Jan 27, 2026

💡 What:
Optimized the run_python tool in src/matilda_brain/tools/builtins/code.py to be non-blocking. This involved:

  1. Changing run_python to be an async function.
  2. Replacing the synchronous subprocess.run call with asyncio.create_subprocess_exec.
  3. Replacing a subprocess call to which with shutil.which.
  4. Refactoring src/matilda_brain/tools/builtins/config.py to expose _safe_execute_async while reusing sanitization and error handling logic.
  5. Updating tests to support async execution.

🎯 Why:
The previous implementation blocked the entire event loop while waiting for the subprocess to finish. In an async application (like an AI agent server or CLI with multiple tasks), this prevents other operations (network requests, other tool calls, etc.) from progressing during code execution.

📊 Measured Improvement:
A benchmark running two run_python calls (each sleeping for 1 second) concurrently:

  • Baseline (Sync): ~2.06 seconds (sequential execution)
  • Optimized (Async): ~1.06 seconds (concurrent execution)
  • Improvement: ~2x speedup for concurrent calls (or strictly non-blocking behavior).

PR created automatically by Jules for task 11119271779874421824 started by @mudcube

- Replaced blocking `subprocess.run` with `asyncio.create_subprocess_exec` in `src/matilda_brain/tools/builtins/code.py`.
- Replaced `subprocess.run(["which", ...])` with `shutil.which` for faster python executable detection.
- Refactored `src/matilda_brain/tools/builtins/config.py` to support async safe execution (`_safe_execute_async`).
- Updated `tests/test_tools_builtin.py` to test `run_python` asynchronously using `pytest-asyncio`.

This change allows concurrent execution of `run_python` tool calls, significantly improving performance when multiple tools are running or when the event loop is busy. Benchmark showed 2 concurrent 1-second tasks taking ~1s instead of ~2s.

Co-authored-by: mudcube <101564+mudcube@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant