Toolbox¶
aigise.toolbox.decorators ¶
Decorators for declaring sandbox dependencies in AIgiSE tools and toolsets.
This module provides a unified decorator system for declaring which sandboxes are required by tools and toolsets. This enables static dependency analysis before actually creating any sandboxes.
F = TypeVar('F', bound=Callable) module-attribute ¶
logger = logging.getLogger(__name__) module-attribute ¶
_collect_dynamic_skill_dependencies(enabled_skills: Optional[Union[List[str], str]] = None) -> set[str] ¶
Scan all available bash skills for sandbox requirements defined in SKILL.md.
This manually scans the search paths (mirroring ToolLoader defaults) and parses the '## Requires Sandbox' section from SKILL.md files.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enabled_skills | Optional[Union[List[str], str]] | Optional filter to only collect dependencies from enabled tools. - None: Collect from no tools (returns empty set) - "all": Collect from all tools - List[str]: Only collect from specified tools | None |
collect_sandbox_dependencies(agent) -> set[str] ¶
Collect all sandbox dependencies from an agent and its tools.
This function performs static analysis on an agent's tools to determine which sandboxes are required. It checks for __sandbox_requirements__ metadata on: - Direct tool functions (decorated with @requires_sandbox) - Toolset instances (including MCP toolsets, returned by get_toolset() functions decorated with @requires_sandbox) - AgentTools (agents wrapped as tools, recursively) - Sub-agents (recursively)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent | An agent instance (LlmAgent, SequentialAgent, AigiseAgent, etc.) | required |
Returns:
| Type | Description |
|---|---|
set[str] | A set of sandbox type names required by the agent and all its sub-agents and mcp toolsets. |
requires_sandbox(*sandbox_types: str) -> Callable[[F], F] ¶
Universal decorator for declaring sandbox dependencies.
This decorator works for both: - Tool functions: Only marks the function with metadata - Toolset factories: Marks function AND injects metadata into returned instance
The decorator is purely declarative - it does not create or fetch sandboxes. It only adds __sandbox_requirements__ metadata for static analysis via collect_sandbox_dependencies().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*sandbox_types | str | Variable number of sandbox type names that the tool or toolset depends on (e.g., "main", "gdb_mcp", "neo4j"). | () |
Returns:
| Type | Description |
|---|---|
Callable[[F], F] | A decorator function that adds sandbox_requirements metadata. |
aigise.toolbox.general.agent_tools ¶
logger = logging.getLogger(__name__) module-attribute ¶
_build_full_instruction(instruction: str, include_history: bool, tool_context: ToolContext) -> str ¶
Build complete instruction with optional conversation history.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
instruction | str | The base instruction | required |
include_history | bool | Whether to include conversation history | required |
tool_context | ToolContext | Tool context containing session events | required |
Returns:
| Type | Description |
|---|---|
str | Complete instruction string with optional history context |
agent_ensemble(instruction: str, agent_name: str, model_name_to_count: dict[str, int], history_passed_in: bool, tool_context: ToolContext) async ¶
Agent ensemble is a tool that allows launching multiple agents, each with a different model, to perform a task. The agent will then aggregate the results from the agents and return the final result.
Before calling this tool, you must call get_available_agents_for_ensemble and get_available_models FIRST to get the allowed agents and models, as the allowed agents and models may change over time.
IMPORTANT
- "inherit" is a special model name meaning: reuse the current/root agent's model object from context.
- If get_available_models returns only ["inherit"], then you MUST pass model_name_to_count={"inherit": N}. This will run N ensemble agents using the same model object as the current/root agent.
Args: instruction: The specific instruction/task you want all agents to execute agent_name: The name of the agent to launch (must be in safe agents list) model_name_to_count: A dictionary of model names and the number of agents to launch with that model, where the key is the model name and the value is the number of agents to launch with that model, the total number of agents to launch is the sum of the values in the dictionary, it should be at least 2. history_passed_in: Whether to pass conversation history to agents for additional context tool_context: The tool context
Returns: The aggregated final result from all agents
agent_ensemble_pairwise(instructions: list[str], agent_name: str, model_names: list[str], history_passed_in: bool, tool_context: ToolContext) async ¶
Launch multiple agents in parallel, each with its own instruction and model. call this tool when you have multiple tasks to complete, for example, you have different approaches to solve the task, you can use this tool to try different approaches in parallel. - instructions: list of per-agent instructions - model_names: list of per-agent model names (same length as instructions) - agent_name: target agent to launch (must be in safe agents list) - history_passed_in: whether to include folded history in each instruction
Examples:
1) Two tasks on the same model instructions = [ "Summarize repo READMEs", "Extract CVEs from logs", ] model_names = [ "openai/gpt-5", "openai/gpt-5", ]
2) Three tasks with mixed models instructions = [ "Generate remediation plan", "List risky endpoints from code", "Draft incident report", ] model_names = [ "anthropic/claude-sonnet-4-20250514", "openai/gpt-5", "openai/gpt-5", ]
real instructions should be more specific and detailed, not just a general task description.
complain(complaint: str, tool_context: ToolContext) async ¶
If you have a complaint, you should call this tool to complain about it. E.g., if a tool is hard to use, if a file or folder is supposed to be there but is not, etc. We will take your complaint into consideration and improve the tooling. If there is a description that contradicts with the reality, you should call this tool to complain about it. Note that the task description is always correct, and there is definitely a way to complete it,you should not complain about it.
Returns:
| Type | Description |
|---|---|
| "Complained, we will take your complaint into consideration and improve the tooling." |
critique(tool_context: ToolContext) async ¶
Call this to query another model as a consultant to help you solve the task, you should call this frequently to get an idea of how to solve the task.
Returns:
| Type | Description |
|---|---|
| dict with 'idea' containing the other model's suggestion |
flag_unjustified_claims(tool_context: ToolContext) async ¶
Flag the unjustified claims in the history, this is done by another model
Returns:
| Type | Description |
|---|---|
| A natural language analysis of unjustified claims found in the conversation |
get_aigise_session(aigise_session_id: str, config_path: Optional[str] = None) -> AigiseSession ¶
Get or create an AigiseSession for the given session ID.
get_available_agents_for_ensemble(tool_context: ToolContext) async ¶
Get the available agents for the ensemble. Uses AgentEnsembleManager to discover static subagents, agent tools, and dynamic agents. Only agents whose tools are all covered by THREAD_SAFE_TOOLS are considered safe for ensemble.
Note that maybe there are no agents that are suitable for the current task, you should create a dynamic subagent that is suitable for the current task and then call it by agent_ensemble tool. Pick up thread-safe tools for dynamic agents if you want to create one for the current task.
Returns:
| Type | Description |
|---|---|
| Dictionary with safe_agents list, summary, and agent counts |
get_available_models(tool_context: ToolContext) async ¶
Get the available models configured for ensemble use.
Notes
- The special model name "inherit" means: reuse the current agent's model object from context (i.e., the root/current agent model).
Returns:
| Type | Description |
|---|---|
| Dictionary with available_models list and count |
note_suspicious_things(suspicious_things: str, tool_context: ToolContext) async ¶
If you have multiple intereting points or suspicious things to explore, you can call this tool to note them down so that you don't forget them.
Returns:
| Type | Description |
|---|---|
| "Noted" |
plan(plan: str, tool_context: ToolContext) async ¶
If you have want to do some planning, do not output the plan in plain text, call this tool to do the planning.
Returns:
| Type | Description |
|---|---|
| "Planning done" |
safe_tool_execution(func: F) -> F ¶
Decorator to wrap tool functions with error handling.
Catches all exceptions and returns a formatted error message with backtrace. Works for both sync and async functions.
Returns:
| Type | Description |
|---|---|
F | dict with "error" key containing failure message and backtrace |
think(thinking: str, tool_context: ToolContext) async ¶
If you have want to do some reasoning, do not output the reasoning in plain text, call this tool to do the reasoning.
Returns:
| Type | Description |
|---|---|
| "Thinking done" |
aigise.toolbox.general.dynamic_subagent ¶
_DEFAULT_SEARCH_LIMIT = 10 module-attribute ¶
AgentStatus ¶
Bases: Enum
Agent lifecycle status.
_extract_tool_names_from_agent(agent_instance) -> List[str] ¶
Extract tool names from agent instance
_extract_tool_names_from_metadata(metadata: Any) -> List[str] ¶
Extract tool names from agent metadata config
_keyword_score(*, keywords: List[str], name: str, description: str, match_all: bool) -> tuple[bool, int, List[str], List[str]] ¶
Return (matched, score, matched_keywords, matched_fields).
_normalize_keywords(keywords: Union[List[str], str]) -> List[str] ¶
Normalize keyword input into a list of non-empty strings.
call_subagent_as_tool(agent_name: str, task_message: str, tool_context: ToolContext) -> Dict[str, Any] async ¶
Call a sub-agent as a tool - Agent as a Tool pattern. You should first list the existing sub-agents before trying to call one.
This supports both dynamic agents and the current agent's subagents (only LlmAgent types).
This treats the sub-agent as a specialized tool that can process natural language requests and return structured results.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent_name | str | Name of the sub-agent to call | required |
task_message | str | Natural language task description | required |
Returns:
| Type | Description |
|---|---|
Dict[str, Any] | Result from the sub-agent execution |
complain(complaint: str, tool_context: ToolContext) async ¶
If you have a complaint, you should call this tool to complain about it. E.g., if a tool is hard to use, if a file or folder is supposed to be there but is not, etc. We will take your complaint into consideration and improve the tooling. If there is a description that contradicts with the reality, you should call this tool to complain about it. Note that the task description is always correct, and there is definitely a way to complete it,you should not complain about it.
Returns:
| Type | Description |
|---|---|
| "Complained, we will take your complaint into consideration and improve the tooling." |
create_subagent(agent_name: str, instruction: str, model_name: str, tools_list: List[str], tool_context: ToolContext, enabled_skills: Optional[List[str]] = None, description: Optional[str] = None) -> Dict[str, Any] async ¶
Dynamically create a sub-agent with specified tools and instructions. You should first list the existing sub-agents before creating a new one.
IMPORTANT: - A subagent's capabilities come from two sources: 1) Python tools/toolsets: determined by tools_list (plus a small set of default baseline tools injected automatically, see below). 2) Bash tools: determined by enabled_skills (which controls which bash_tools/* skills are loaded for the subagent). - enabled_skills can be empty. If it is empty/None, the subagent may not have any bash tools available. Choose it carefully based on what the subagent needs to do. - tools_list must NOT be empty. If it is empty, this tool will return an error and no subagent will be created. - Default baseline tools (always injected): run_terminal_command, list_background_tasks, get_background_task_output, wait_for_background, complain.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent_name | str | Custom name for the agent | required |
instruction | str | Custom instruction for the agent, this will be the system prompt for the agent, it should be a comprehensive instruction for the agent to follow and not task-specific. | required |
model_name | str | Model to use for the agent (e.g., "anthropic/claude-sonnet-4", "openai/gpt-5", or "inherit" to reuse the current agent's model) | required |
tools_list | List[str] | List of Python tool names to assign to the agent. This may also include toolset names (e.g. "gdb_mcp", "pdb_mcp") if the caller agent exposes a toolset instance with a stable | required |
enabled_skills | Optional[List[str]] | Controls which bash tools are loaded. - None: Load NO bash tools. - ["all"]: Load ONLY top-level skills: | None |
description | Optional[str] | Optional description for the agent | None |
Returns:
| Type | Description |
|---|---|
Dict[str, Any] | Dictionary with creation result and agent details |
get_aigise_session(aigise_session_id: str, config_path: Optional[str] = None) -> AigiseSession ¶
Get or create an AigiseSession for the given session ID.
get_background_task_output(task_id: str, *, tool_context: ToolContext) -> Dict[str, Any] ¶
Retrieve the output and exit code from a specific background task.
Use this tool after launching a command with background=True or a command has been sent to the background. If the command already finished the helper returns the full logs and cleans up the underlying temp files; otherwise, it streams the current log buffer without interrupting the running process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_id | str | The ID of the task (from list_background_tasks) | required |
tool_context | ToolContext | Tool context from the agent | required |
Returns:
| Name | Type | Description |
|---|---|---|
dict | Dict[str, Any] | Dictionary containing: - task_id: The task ID - status: Current status of the task - output: The output from the task - exit_code: The exit code (0 for success, non-zero for failure) - error: Error message if task not found - cleaned_up: Boolean indicating if cleanup was performed |
list_active_agents(tool_context: ToolContext) -> Dict[str, Any] async ¶
List all active sub-agents, loading persistent agents on demand.
This function: 1. Loads persisted agents on demand using caller's tools 2. Returns information about all dynamically created agents (both in-memory and restored)
list_background_tasks(tool_context: ToolContext) -> Dict[str, Any] ¶
List all background tasks and their current status.
This tool allows the agent to check the status of background tasks before making the next decision. It's particularly useful for: - Checking if fuzzing campaigns have completed - Monitoring long-running compilation or build processes - Verifying any task started with background=True parameter
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_context | ToolContext | Tool context from the agent | required |
Returns:
| Name | Type | Description |
|---|---|---|
dict | Dict[str, Any] | Dictionary containing: - tasks: List of task information dictionaries, each with: - id: Task ID - pid: Process ID - command: The command that was run - status: Current status (running/completed/failed/completed/unknown) - sandbox: The sandbox where the task is running - summary: Human-readable summary of task counts by status |
run_terminal_command(command: str, background: bool = False, timeout: int = 60, execution_timeout: Optional[int] = None, sandbox_name: str = 'main', *, tool_context: ToolContext) -> Dict[str, Any] ¶
Execute arbitrary bash inside the specified sandbox.
This behaves like a one-off terminal session: any bash syntax, pipes, or scripts listed via list_available_scripts can be invoked.
Command syntax and escaping rules (what the model should assume): - Write command exactly as you would type it in bash. Pipes (|), redirection (>, 2>&1), chaining (&&, ;), subshells ($(...)), and quoting all work normally. - Do NOT wrap your command in bash -c or bash -lc. The backend already executes your command via bash (and sources /shared/bashrc if present). Wrapping again usually adds unnecessary quoting/escaping pitfalls. - No extra escaping is required by the backend. The backend does NOT wrap your string into a fragile bash -c '...' one-liner; instead it writes your command verbatim into a temporary script and executes it with bash. This is newline-safe and preserves quotes as-is. - The command runs as a non-interactive process (no TTY, no persistent shell session). If you see output like mesg: ttyname failed: Inappropriate ioctl for device, it's a benign warning from shell init logic; the command can still succeed. - Stdout/stderr are captured and returned (and for background=True, you can retrieve them later via get_background_task_output).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
command | str | The full command line to execute (e.g., "python3 -c 'print(123)' | cat"). | required |
background | bool | Whether to run the command in the background (default: False) | False |
timeout | int | Timeout in seconds for foreground commands, after which they will be moved to background (default: 60) | 60 |
execution_timeout | Optional[int] | Timeout in seconds for the command itself, after which it will be terminated (default: None, meaning no timeout) | None |
sandbox_name | str | The name of the sandbox to run the command in (default: "main"). | 'main' |
tool_context | ToolContext | The tool context from the agent execution | required |
Returns:
| Type | Description |
|---|---|
Dict[str, Any] | Dict describing execution status. When |
Dict[str, Any] | response contains |
Dict[str, Any] |
|
safe_tool_execution(func: F) -> F ¶
Decorator to wrap tool functions with error handling.
Catches all exceptions and returns a formatted error message with backtrace. Works for both sync and async functions.
Returns:
| Type | Description |
|---|---|
F | dict with "error" key containing failure message and backtrace |
search_agent(keywords: Union[List[str], str], tool_context: ToolContext, limit: int = _DEFAULT_SEARCH_LIMIT, match_all: bool = False) -> Dict[str, Any] async ¶
Search sub-agent pool by keywords in name/description and return metadata.
This searches across: - Dynamic subagents in the current AIgiSE session (including persisted metadata) - ADK subagents attached to the current caller agent via sub_agents
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keywords | Union[List[str], str] | Search keywords. Accepts a whitespace-separated string or a list of strings. | required |
limit | int | Max number of results to return (sorted by relevance). | _DEFAULT_SEARCH_LIMIT |
match_all | bool | If True, require all keywords to match in (name or description). | False |
Returns:
| Type | Description |
|---|---|
Dict[str, Any] | dict with |
wait_for_background(task_id: str, timeout: int = 300, *, tool_context: ToolContext) -> Dict[str, Any] ¶
Block until a background task finishes or the wait times out.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_id | str | Identifier returned by | required |
timeout | int | Seconds to wait before returning with a timeout status. | 300 |
tool_context | ToolContext | Execution context used to locate session state. | required |
Returns:
| Type | Description |
|---|---|
Dict[str, Any] | Dict with keys such as |
Dict[str, Any] |
|