SDK Guides
System Tools
Understand built-in web search, code execution, and reasoning tools.
#System Tools Guide
Some capabilities are useful to almost every agent — searching the web, running a quick calculation, drafting a long document, thinking through a hard problem. Rather than make you build and maintain those yourself, mAIvn ships them as built-in system tools your agent can reach for automatically, with privacy protections applied for free.
This guide explains what each system tool does, how the runtime keeps private data safe while they run, and how to control which ones are available.
#Overview
System tools are runtime-provided tools that extend agent capabilities:
| Tool | Description |
|---|---|
web_search |
Search the web for current information |
repl |
Execute Python code in a sandbox |
think |
Route to optimal LLM for complex reasoning |
compose_artifact |
Synthesize a substantial downstream artifact for a specific tool arg |
reevaluate |
Insert a planning checkpoint before continuing execution |
These tools are not defined in your SDK code - they're made available by the runtime when appropriate.
#Built-in Capabilities
#Datetime Awareness
The mAIvn runtime has built-in datetime awareness. Agents automatically know the current date and time without needing a custom tool. You do not need to create a get_current_time() tool - the system handles this natively.
# No need for this - the system already knows the time:# @agent.toolify()# def get_current_time() -> dict: ... # Just ask directlyresponse = agent.invoke([ HumanMessage(content='What day of the week is it?')])This applies to:
- Current date and time
- Timezone information
- Date calculations and comparisons
#Configuring Timezone
By default, the SDK auto-detects your system's timezone. You can explicitly configure the timezone using the Client:
from maivn import Agent, Client # Explicit timezone configurationclient = Client( api_key='your-api-key', client_timezone='America/New_York', # IANA timezone identifier) agent = Agent(name='scheduler', client=client)#Timezone Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
client_timezone |
str | None |
None |
IANA timezone (e.g., 'America/New_York', 'Europe/London') |
auto_detect_timezone |
bool |
True |
Auto-detect system timezone when client_timezone is not set |
#When to Configure Timezone
- Server applications: Set explicit timezone for consistent behavior across deployments
- User-facing apps: Set timezone based on user preferences
- Scheduled tasks: Ensure time-sensitive operations use the correct timezone
# Disable auto-detection, use UTCclient = Client( api_key='your-api-key', client_timezone='UTC', auto_detect_timezone=False,) # User-specific timezoneclient = Client( api_key='your-api-key', client_timezone=user_preferences.timezone,)The agent will use this timezone context when answering time-related questions or performing date calculations.
#Private Data Protection
System tools are designed with built-in privacy protections that automatically safeguard sensitive information:
#Privacy-First Architecture
All system tools follow a strict privacy model:
- Protected by default: raw private data stays behind the protected runtime boundary
- Schema-only awareness: planning and prompts use field names and placeholders, not raw values
- Automatic redaction: known private values are scrubbed from outbound payloads and outputs
- Audit logging: private-data access is tracked
#Web Search Privacy
# Private data is automatically excluded from search queriesagent.private_data = { 'user_email': 'john@example.com', 'api_key': 'sk-xxx-secret'} # When agent searches, private data stays within the runtimeresponse = agent.invoke([ HumanMessage(content='Search for information about this account')]) # Search query sent to external API:# "information about account" # Private data excludedHow the boundary behaves here:
- Private data is kept out of outbound search queries
- Search results are scanned and known private values redacted before returning
- Credentials and other secrets are not forwarded to search providers
- The activity is tracked so you have a record of what was searched
#REPL Code Execution Privacy
@agent.toolify()@depends_on_private_data(data_key='database_url', arg_name='db_url')def query_database(query: str, db_url: str) -> dict: # Code executes with injected database URL connection = connect(db_url) return connection.execute(query) # Agent sees: {'status': 'success', 'rows': 5}# Actual database URL never appears in outputHow the boundary behaves here:
- Private data is injected into the sandbox only during execution
- Output is scanned and known private values redacted
- Code and data are not persisted between executions
- The execution environment is isolated from your host
#Think Tool Privacy
The think tool operates with privacy by design:
- Receives only metadata about available private data
- Never sees actual private values
- Reasoning outputs automatically redacted if they reference sensitive data
- Ideal for complex logic involving private data concepts
#Automatic Redaction Flow
- Input filtering: Private data stripped before external calls
- Execution: Real values injected in isolated environment
- Output scanning: Results analyzed for sensitive data
- Redaction: Private data replaced with placeholders
- Audit: Access logged with compliance details
#Web Search
#Purpose
Search the web for current information, news, or facts.
#How It Works
- The agent determines it needs current information
- The runtime performs the web search
- Search results are returned to the agent
- Agent incorporates results into its response
#Example Use Case
agent = Agent( name='research_agent', system_prompt='''You are a research assistant. When asked about current events or recent information, use web search to find accurate data.''', api_key='...',) response = agent.invoke([ HumanMessage(content='What are the latest developments in AI?')])The agent will automatically use web_search when it determines current information is needed.
#REPL (Code Execution)
#Purpose
Execute Python code in a secure sandbox.
#How It Works
- Agent generates Python code to solve a problem
- The runtime executes code in an isolated sandbox
- Execution results (stdout, errors) are returned
- Agent interprets results and continues
#Example Use Case
agent = Agent( name='data_analyst', system_prompt='''You are a data analyst. When you need to perform calculations or data analysis, write Python code and execute it using the REPL.''', api_key='...',) response = agent.invoke([ HumanMessage(content='Calculate the compound interest on $10,000 at 5% for 10 years')])The agent might generate and execute:
principal = 10000rate = 0.05years = 10result = principal * (1 + rate) ** yearsprint(f"Final amount: ${result:.2f}")#Safety
- Code runs in an isolated sandbox
- No access to host system
- Time and resource limits applied
- Output is captured and returned
#Compose Artifact
#Purpose
Use compose_artifact when the agent needs to synthesize a substantial artifact for a downstream tool argument, such as a SQL query, HTML template, policy document, or other long-form structured payload.
#How It Works
- A downstream tool declares whether a specific argument may use
compose_artifact - The planner sees that policy in tool metadata and arg schema
- The runtime checks the policy again when
compose_artifactis invoked - The downstream tool execution also validates whether the argument actually did or did not come from
compose_artifact
#Declaring Arg Policy in the SDK
from maivn import Agent, compose_artifact_policy agent = Agent(name='artifact_agent', api_key='...') @compose_artifact_policy('query', mode='require', approval='explicit')@agent.toolify(description='Validate a SQL query artifact')def validate_query_artifact(query: str) -> dict: return {'validated': True, 'query': query}Supported modes:
forbid: the arg must not consumecompose_artifactallow: the arg may consumecompose_artifactrequire: the arg must consumecompose_artifact
Supported approval values:
none: no additional approval metadata requiredexplicit: invocationsystem_tools_configmust explicitly approve that target arg
#Invocation System Tools Config
Use SystemToolsConfig to narrow which system tools are allowed for a run and whichcompose_artifact targets are explicitly approved:
from maivn import SystemToolsConfig response = agent.invoke( [HumanMessage(content='Draft and validate the SQL artifact')], force_final_tool=True, system_tools_config=SystemToolsConfig( allowed_tools=['compose_artifact'], approved_compose_artifact_targets=['validate_query_artifact.query'], ),)Approval matching supports:
tool_name.arg_nametool_name.**
#When to Use It
Use compose_artifact when:
- the downstream argument expects a large, reusable artifact
- you want clear provenance between synthesis and validation/execution
- you want policy enforcement at both planning time and runtime
Prefer direct tool args when the content is short and does not need a dedicated artifact synthesis step
If compose_artifact cannot produce a value, the runtime treats that as a tool
error instead of forwarding None into the downstream argument. The error message
includes the artifact summary when available, so downstream tools do not need to
defensively validate a missing artifact value before running.
#Think
#Purpose
Route higher-level analysis tasks to the optimal LLM.
#How It Works
- Agent encounters a complex reasoning task
- The runtime routes to the best model for the task type
- Reasoning is performed with appropriate capabilities
- Results are returned to the agent
#When It's Used
- Interpreting verification results, logs, traces, or conflicting tool outputs
- Evaluating code, architecture, or trade-offs after evidence has been gathered
- Complex mathematical reasoning or multi-step logical deduction
- Tasks requiring extended context or specialized capabilities
Do not use think for direct lookup, simple arithmetic, trivial summaries, or as
a substitute for a dedicated function tool. When think receives prior tool
results, its output should preserve failed checks, nonzero return codes, tool
errors, and unverified assumptions instead of summarizing them as success.
#System Prompt Guidance
Guide the agent to use system tools appropriately:
#For Research Tasks
agent = Agent( name='researcher', system_prompt='''You are a research assistant. For current information or recent events: - Use web search to find up-to-date data - Verify information from multiple sources For calculations or data analysis: - Write and execute Python code - Show your work and explain results''', api_key='...',)#For Analysis Tasks
agent = Agent( name='analyst', system_prompt='''You are a data analyst. When analyzing data: - Use Python code execution for calculations - Visualize results when helpful - Explain your methodology If you discover your initial approach won't work: - Adjust your analysis plan accordingly''', api_key='...',)#Controlling System Tools
You can guide when system tools should (or shouldn't) be used:
agent = Agent( name='calculator', system_prompt='''You are a simple calculator. Only use basic arithmetic - do NOT use web search or code execution. Provide quick mental math answers.''', api_key='...',)When you need hard runtime boundaries, pass invocation system-tool config:
from maivn import SystemToolsConfig response = agent.invoke( [HumanMessage(content='Validate the generated SQL artifact')], system_tools_config=SystemToolsConfig( allowed_tools=['compose_artifact'], approved_compose_artifact_targets=['validate_query_artifact.query'], ),)#Interaction with Your Tools
System tools work alongside your custom tools:
@agent.toolify(description='Get product catalog')def get_products() -> dict: return {'products': [...]} @agent.toolify(final_tool=True)class MarketReport(BaseModel): products: list[str] market_trends: str # May come from web_search price_analysis: str # May come from repl calculationsThe agent can:
- Call
get_products(your tool) - Use
web_searchfor market trends - Use
replfor price calculations - Combine all into
MarketReport
#Event Tracing
See system tool usage with the event builder:
response = agent.events().invoke( [HumanMessage(content='Research AI trends and analyze market data')],)Output might show:
[SYSTEM] Using web_search for: AI trends 2024[SYSTEM] Executing Python code in sandbox[TOOL] Calling get_products[FINAL] Generating MarketReport#Privacy Controls and Auditing
#Audit Trail
System-tool activity that touches private data is tracked, so you have a
record that a value was used or excluded without that record itself exposing
the protected values. Treat the audit surface as a record that access
happened, not as a place to read sensitive data back out.
#Final Privacy Boundary
Every system-tool invocation still passes through a final protected-data boundary
before anything leaves the runtime:
- Raw outbound
private_datais withheld by default - Known private values are substituted with safe references rather than being sent verbatim
- User-typed text that matches a known private value is scrubbed before it reaches a model-visible context
- Raw private data may leave the protected boundary only when you have explicitly authorized a supported system-tool flow
This boundary is a safety net layered on top of your own careful handling, not a
substitute for it.
#Compliance-oriented Behavior
- PII detection: NLP-based identification of sensitive information (a safety net, not a guarantee of complete coverage)
- Data minimization: Only the data a tool actually needs is exposed to it
- Access tracking: Private-data access is recorded
#Configuration
System tools are still provisioned by the runtime, but developers can influence use at the SDK layer:
- Deployment administrators control availability, quotas, and deployment policy
- Invocation
system_tools_config.allowed_toolscan narrow which system tools may run for a session @compose_artifact_policy(...)controls whether a specific argument can usecompose_artifactsystem_tools_config.approved_compose_artifact_targetsprovides explicit approval for args that require it
Contact your administrator for:
- Enabling/disabling specific system tools
- Rate limits and quotas
#Best Practices
#1. Design for Privacy
# GOOD: System tools automatically handle privacyagent = Agent( name='secure_analyst', system_prompt='''Use web search for public information. Use REPL for calculations. System tools will automatically protect sensitive data.''', api_key='...') # Private data configurationagent.private_data = { 'customer_id': '12345', 'api_key': 'sk-xxx-secret'}#2. Trust the Redaction System
# System tools automatically redact outputs@agent.toolify()@depends_on_private_data(data_key='secret_key', arg_name='key')def process_data(data: dict, key: str) -> dict: result = external_api_call(data, key) # Return can contain sensitive data - system will redact return { 'processed': True, 'auth_used': key, # This will be redacted 'result': result }#3. Combine Privacy Capabilities
# System tools work together while maintaining privacy@agent.toolify(description='Get user profile')def get_user_profile(user_id: str) -> dict: return {'user_id': user_id, 'preferences': [...]} # Agent can:# 1. Get profile (your tool)# 2. Use web_search for public info about preferences# 3. Use repl for analysis calculations# 4. All private data stays protected#4. Monitor Privacy Compliance
# Enable event tracing to verify privacy behaviorresponse = agent.events().invoke( [HumanMessage(content='Analyze this user\'s data')],) # Output shows:# [PRIVACY] Excluded 2 private fields from web search# [PRIVACY] Redacted 1 sensitive value from REPL output# [AUDIT] Private data access logged#5. Use Explicit Artifact Policies for Sensitive Downstream Args
from maivn import compose_artifact_policy @compose_artifact_policy('query', mode='require', approval='explicit')@agent.toolify(description='Run an approved SQL query artifact')def execute_query(query: str) -> dict: return {'executed': True}This keeps artifact synthesis intentional, reviewable, and enforceable at runtime.
#Next steps
- Agent API - Agent configuration
- Decorators API - Dependency and arg policy decorators
- Tools Guide - Custom tool patterns
- Structured Output Guide - Combining with final tools