Skip to content

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.

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

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 name. Passing a toolset name injects the entire toolset into the subagent.

required
enabled_skills Optional[List[str]]

Controls which bash tools are loaded. - None: Load NO bash tools. - ["all"]: Load ONLY top-level skills: <root>/*/SKILL.md. - List[str]: Load skills by relative path/prefix under the skill root (e.g. ["fuzz"] or ["fuzz/simplified-python-fuzzer"]).

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 background is False the

Dict[str, Any]

response contains output and exit_code. Otherwise, it returns the

Dict[str, Any]

task_id needed to resume/inspect the background run.

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 matches listing matching agents and their metadata.

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 run_bash_tool_script or run_terminal_command when the task was launched.

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 success, output, exit_code, and

Dict[str, Any]

status. If the wait hits the timeout, timeout=True is included.