|
40 | 40 | from BaseAgent.config import default_config |
41 | 41 | from BaseAgent.resource_manager import ResourceManager |
42 | 42 | from BaseAgent.retriever import ToolRetriever |
43 | | -from BaseAgent.tools.support_tools import run_python_repl |
| 43 | +from BaseAgent.tools.support_tools import PlotCapture, run_python_repl |
44 | 44 | from BaseAgent.env_desc import data_lake_items, libraries |
45 | 45 | from BaseAgent.utils.tool_bridge import inject_custom_functions_to_repl |
46 | 46 | from BaseAgent.utils.formatting import pretty_print |
@@ -113,6 +113,10 @@ def __init__( |
113 | 113 | self._run_config: dict | None = None |
114 | 114 | self.state = AgentState(input=[], next_step=None, pending_code=None, pending_language=None) |
115 | 115 | self._usage_metrics = [] |
| 116 | + # Per-instance REPL namespace — isolates variables from other BaseAgent instances |
| 117 | + self._repl_namespace: dict = {} |
| 118 | + # Per-instance plot capture — isolates matplotlib output from other instances |
| 119 | + self._plot_capture = PlotCapture() |
116 | 120 | #TODO: add self-critic mode |
117 | 121 | self.self_critic = False |
118 | 122 |
|
@@ -1408,40 +1412,27 @@ def _map_langgraph_event(self, event: dict) -> "AgentEvent | None": |
1408 | 1412 | return None |
1409 | 1413 |
|
1410 | 1414 | def _clear_execution_plots(self): |
1411 | | - """ |
1412 | | - Clear execution plots before new execution. |
1413 | | -
|
1414 | | - This function clears any previously captured plots from the execution environment |
1415 | | - before starting a new execution. This prevents old plots from appearing in |
1416 | | - new execution results. |
1417 | | -
|
1418 | | - Note: |
1419 | | - This function calls the clear_captured_plots utility function and handles |
1420 | | - any exceptions gracefully to prevent execution failures. |
1421 | | - """ |
| 1415 | + """Clear the per-instance plot capture buffer before a new execution.""" |
1422 | 1416 | try: |
1423 | | - from BaseAgent.tools.support_tools import clear_captured_plots |
1424 | | - |
1425 | | - clear_captured_plots() |
| 1417 | + self._plot_capture.clear() |
1426 | 1418 | except Exception as e: |
1427 | 1419 | print(f"Warning: Could not clear execution plots: {e}") |
1428 | 1420 |
|
1429 | 1421 |
|
1430 | 1422 | def _inject_custom_functions_to_repl(self): |
| 1423 | + """Inject custom tools into the per-instance REPL namespace. |
| 1424 | +
|
| 1425 | + Makes custom tools added via ``add_tool()`` / ``add_mcp()`` callable |
| 1426 | + inside ``<execute>`` blocks. Uses ``self._repl_namespace`` so that |
| 1427 | + injected functions are isolated to this agent instance. |
1431 | 1428 | """ |
1432 | | - Inject custom functions into the Python REPL execution environment. |
1433 | | - This makes custom tools from ResourceManager available during code execution. |
1434 | | - """ |
1435 | | - # Get custom tools from ResourceManager |
1436 | 1429 | custom_tools = self.resource_manager.collection.custom_tools |
1437 | | - |
1438 | | - # Extract callable functions from CustomTool objects |
1439 | | - custom_functions = {} |
1440 | | - for tool in custom_tools: |
1441 | | - if tool.function is not None: |
1442 | | - custom_functions[tool.name] = tool.function |
1443 | | - |
1444 | | - inject_custom_functions_to_repl(custom_functions) |
| 1430 | + custom_functions = { |
| 1431 | + tool.name: tool.function |
| 1432 | + for tool in custom_tools |
| 1433 | + if tool.function is not None |
| 1434 | + } |
| 1435 | + inject_custom_functions_to_repl(custom_functions, namespace=self._repl_namespace) |
1445 | 1436 |
|
1446 | 1437 |
|
1447 | 1438 | def _record_usage(self, usage): |
|
0 commit comments