Skip to main content

mAIvn Python SDK for building agentic systems with typed tools and dependencies

Project description

maivn

Python SDK for building agentic systems with typed tools and dependencies.

The maivn SDK provides a clean, declarative interface for creating AI agents with:

  • Typed tool definitions using decorators and Pydantic models
  • Dependency injection between tools, agents, and external data
  • Structured outputs with guaranteed schema conformance
  • Multi-agent orchestration via Swarms
  • Concurrent batch invocation for independent Agent and Swarm requests
  • MCP integration for external tool servers

Features

  • Declarative Tools: Define tools with @agent.toolify(), agent.add_tool(...), or Agent(..., tools=[...]) - functions or Pydantic models
  • Dependency Graph: Chain tools with @depends_on_tool, inject secrets with @depends_on_private_data
  • Structured Output: Use final_tool=True for guaranteed typed responses
  • Multi-Agent: Coordinate agents with Swarm and @depends_on_agent
  • Batch Invocation: Run multiple independent invoke() calls with batch() or abatch()
  • Scheduled Invocation: Run any agent or swarm on a cron(...), every(...), or at(...) schedule with bounded jitter, retry/backoff, misfire and overlap policies
  • Async Surface: ainvoke() / astream() mirror invoke() / stream() for native asyncio code
  • MCP Support: Connect external MCP servers (stdio/HTTP) as tool providers
  • Interrupts: Collect user input mid-execution with @depends_on_interrupt
  • System Tools: Built-in web_search, repl, think

Requirements

  • Python 3.10+

Installation

pip install maivn

maivn depends on the public maivn-shared package and will install it automatically from PyPI.

To install the public Studio companion and enable maivn studio from a normal shell:

pip install "maivn[studio]"

If you prefer to install the companion package directly, pip install maivn-studio also works.

Quick Start

Basic Agent with Tools

from maivn import Agent
from maivn.messages import HumanMessage

agent = Agent(
    name='weather_agent',
    description='Provides weather information',
    system_prompt='You are a helpful weather assistant.',
    api_key='your-api-key',  # or set MAIVN_API_KEY env var
)

@agent.toolify(description='Get current weather for a city')
def get_weather(city: str) -> dict:
    return {'city': city, 'temp': 72, 'condition': 'sunny'}

response = agent.invoke([HumanMessage(content='What is the weather in Austin?')])
print(response.content)

You can also register tools without decorators:

def get_weather(city: str) -> dict:
    """Get current weather for a city."""
    return {'city': city, 'temp': 72, 'condition': 'sunny'}

agent = Agent(
    name='weather_agent',
    description='Provides weather information',
    system_prompt='You are a helpful weather assistant.',
    api_key='your-api-key',
    tools=[get_weather],
)

# Or add tools after construction.
agent.add_tool(get_weather)

Fast Structured Output

Use .structured_output() to bypass the orchestrator for faster responses:

from pydantic import BaseModel, Field

class SentimentAnalysis(BaseModel):
    sentiment: str = Field(..., description='positive, negative, or neutral')
    confidence: float = Field(..., ge=0, le=1)

# Fast path - bypasses orchestrator, tools still execute as needed
response = agent.structured_output(SentimentAnalysis).invoke(
    [HumanMessage(content='Analyze: "I love this product!"')]
)

Structured Output with Full Orchestration

Use final_tool pattern when you need full orchestration for complex workflows:

from pydantic import BaseModel, Field

@agent.toolify(final_tool=True)
class WeatherReport(BaseModel):
    """Structured weather report."""
    city: str = Field(..., description='City name')
    temperature: int = Field(..., description='Temperature in Fahrenheit')
    summary: str = Field(..., description='Human-readable weather summary')

# Full orchestration for complex workflows
response = agent.invoke(
    [HumanMessage(content='Weather report for Austin')],
    force_final_tool=True,
)

Concurrent Batch Invocation

Use batch() when you have multiple independent requests for the same agent or swarm. The SDK runs the underlying invoke() calls concurrently and returns responses in the same order as the inputs.

batch_inputs = [
    [HumanMessage(content='Summarize ticket A')],
    [HumanMessage(content='Summarize ticket B')],
    [HumanMessage(content='Summarize ticket C')],
]

responses = agent.batch(
    batch_inputs,
    max_concurrency=3,
    force_final_tool=True,
)

# Async variant
responses = await agent.abatch(batch_inputs, max_concurrency=3)

Scheduled Invocation

Run any agent or swarm on a cadence with optional jitter and retry. The builder mirrors invoke / stream / batch and the async variants:

from datetime import timedelta
from maivn import JitterSpec, Retry

job = agent.cron(
    '0 9 * * MON-FRI',                  # weekdays at 09:00
    tz='America/New_York',
    jitter=JitterSpec.symmetric(timedelta(minutes=10)),  # ±10 min uniform
    retry=Retry(max_attempts=3, backoff='exponential', base=timedelta(seconds=30)),
).invoke([HumanMessage(content='Compose the daily ops briefing.')])

job.on_fire(lambda r: print(f'fired at {r.fired_at}, jitter={r.jitter_offset}'))
job.on_error(lambda r: alert(r.error))

# ... later
job.stop(drain=True)

scope.every(timedelta(minutes=15)) and scope.at(when) are also available. See the Scheduled Invocation guide and Scheduling reference for the full surface.

Tool Dependencies

from maivn import depends_on_tool

@agent.toolify(description='Fetch raw sensor data')
def fetch_sensor_data(sensor_id: str) -> dict:
    return {'sensor_id': sensor_id, 'readings': [72, 73, 71]}

@agent.toolify(description='Analyze sensor readings')
@depends_on_tool(fetch_sensor_data, arg_name='sensor_data')
def analyze_readings(sensor_data: dict) -> dict:
    readings = sensor_data['readings']
    return {'average': sum(readings) / len(readings)}

Private Data Injection

from maivn import depends_on_private_data

@agent.toolify(description='Call external API')
@depends_on_private_data(data_key='api_secret', arg_name='secret')
def call_api(query: str, secret: str) -> dict:
    # 'secret' is injected server-side, never exposed to LLM
    return {'result': f'Called API with query: {query}'}

# Set private data (stays server-side)
agent.private_data = {'api_secret': 'sk-xxx'}

Multi-Agent with Swarm

from maivn import Agent, Swarm, depends_on_agent

researcher = Agent(
    name='researcher',
    description='Research specialist',
    system_prompt='You research topics thoroughly.',
    api_key='your-api-key',
)

writer = Agent(
    name='writer',
    description='Content writer',
    system_prompt='You write clear, engaging content.',
    api_key='your-api-key',
    use_as_final_output=True,  # This agent produces final output
    included_nested_synthesis='auto',  # default: orchestrator/runtime decides
)

@researcher.toolify(description='Research a topic')
def research_topic(topic: str) -> dict:
    return {'findings': f'Research findings about {topic}'}

@writer.toolify(description='Write article')
@depends_on_agent(researcher, arg_name='research')
def write_article(research: dict) -> dict:
    return {'article': f'Article based on: {research["findings"]}'}

swarm = Swarm(
    name='content_team',
    agents=[researcher, writer],
)

response = swarm.invoke(
    HumanMessage(content='Write about AI agents'),
    force_final_tool=True,
)

Security

Your code stays local. All function tools and MCP tools execute in your environment - code is never transferred to or executed on maivn servers.

The maivn server only receives tool schemas (names, descriptions, parameters) and orchestrates execution. The actual tool code runs locally in your environment, ensuring:

  • Your business logic remains private
  • Sensitive data processed by tools stays local
  • You have full control over tool access and permissions

Scalability

Thousands of tools, no problem. The maivn system provides high-performance tool management for agents and swarms with large tool catalogs. Tool selection and orchestration remain fast and accurate regardless of how many tools you register.

Core Concepts

Concept Description
Agent Container for tools, configuration, and invocation logic
Swarm Coordinates multiple agents with shared tool access
Tool Function or Pydantic model exposed to the LLM
Dependency Declares data flow between tools/agents
Final Tool Marked tool that produces the structured output
Private Data Server-side secrets injected at execution time

Public API

Core Classes

Class Description
Agent Main agent class with tools and invocation
Swarm Multi-agent orchestration container
Client HTTP connection manager (usually auto-created)
ClientBuilder Factory for creating Client instances
BaseScope Base class for Agent/Swarm
MCPServer MCP server configuration
MCPAutoSetup Auto-setup for uvx-based MCP servers
ScheduledJob Lifecycle handle returned by cron/every/at
JitterSpec Bounded randomness for scheduled fires
Retry Retry policy with constant/linear/exp backoff
RunRecord Outcome of a single scheduled fire

Decorators

Decorator Description
@agent.toolify() Register a function/model as a tool
@depends_on_tool(tool, arg) Inject output from another tool
@depends_on_agent(agent, arg) Inject output from another agent
@depends_on_private_data(key, arg) Inject server-side secret
@depends_on_interrupt(arg, prompt, handler) Collect user input

Configuration

Function Description
ConfigurationBuilder.from_environment() Load config from env vars
get_configuration() Get current configuration
MaivnConfiguration Configuration model

Logging

Function Description
configure_logging(log_file) Initialize SDK logging
get_logger() Get SDK logger instance

Messages

Import from maivn.messages:

Class Description
HumanMessage User input message
AIMessage Assistant response
SystemMessage System prompt
RedactedMessage Message with sensitive data redacted

Environment Variables

Variable Description Default
MAIVN_API_KEY API key for authentication Required
MAIVN_TIMEOUT HTTP request timeout (seconds) 600
MAIVN_TOOL_EXECUTION_TIMEOUT Per-tool timeout (seconds) 900
MAIVN_DEPENDENCY_WAIT_TIMEOUT Dependency resolution timeout 300
MAIVN_TOTAL_EXECUTION_TIMEOUT Total session timeout 7200
MAIVN_ENABLE_BACKGROUND_EXECUTION Background tool execution True
MAIVN_LOG_LEVEL Logging level INFO
MAIVN_DEPLOYMENT_TIMEZONE Server timezone UTC

MAIVN_ENABLE_BACKGROUND_EXECUTION controls whether tool calls are dispatched via a background thread pool. Set it to false to force inline, sequential execution for more deterministic runs.

Documentation

API Reference

Guides

Reference

Development

Setup

cd libraries/maivn
uv sync

Testing

uv run pytest
uv run pytest --cov=maivn --cov-report=term-missing

Coverage gate: 80% line coverage, excluding terminal reporter UI modules and MCP integration modules as defined in pyproject.toml under tool.coverage.

Linting

uv run ruff check .
uv run ruff format .
uv run pyright

Releases

  • CI runs on pull requests and pushes to the default branch (master today).
  • Publish PyPI runs on version tags that match v*.
  • Configure PyPI Trusted Publishing for this repository before the first release.
  • See DEPLOYMENT.md for the full GitHub and PyPI release procedure.

For standalone repo verification before maivn-shared is published, use a local checkout of maivn-shared. The GitHub Actions workflow injects that temporary uv source override automatically.

License

See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

maivn-0.2.0.tar.gz (526.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

maivn-0.2.0-py3-none-any.whl (372.3 kB view details)

Uploaded Python 3

File details

Details for the file maivn-0.2.0.tar.gz.

File metadata

  • Download URL: maivn-0.2.0.tar.gz
  • Upload date:
  • Size: 526.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for maivn-0.2.0.tar.gz
Algorithm Hash digest
SHA256 6207c00fec77c184d4b3c3bd3a45454dbe9172dc24839e476973842304a697fd
MD5 a6193256331834dfcb36e2daaeb391e9
BLAKE2b-256 5c0afde20f708c45d8ed5c5b2b69dfeb88fd57e3cbafc2cef132a4b112f53273

See more details on using hashes here.

Provenance

The following attestation bundles were made for maivn-0.2.0.tar.gz:

Publisher: publish-pypi.yml on mAIvn-developer/maivn

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file maivn-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: maivn-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 372.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for maivn-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e0eea73489294ede30f252796aee4c31da57b7840e2377be178a54663363a532
MD5 9788b2df73fabfd768bab74618b7fe5f
BLAKE2b-256 4b1b823304bc3771c92c70003b0e06abc42aee493b5fde57c90889137adcc77c

See more details on using hashes here.

Provenance

The following attestation bundles were made for maivn-0.2.0-py3-none-any.whl:

Publisher: publish-pypi.yml on mAIvn-developer/maivn

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page