> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Local Managed Agents

> Run managed agents on local infrastructure with cloud management APIs

Local managed agents provide cloud-style APIs while running on your local infrastructure.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Local Managed Agent"
        A[📝 Request] --> B[🧠 Local LLM]
        B --> C[💻 Local Tools]
        C --> D[📁 Local Storage]
        D --> E[✅ Response]
    end
    
    classDef request fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef llm fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef tools fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef storage fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef response fill:#10B981,stroke:#7C90A0,color:#fff
    
    class A request
    class B llm
    class C tools
    class D storage
    class E response
```

## Quick Start

<Steps>
  <Step title="Basic Local Agent">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai.integrations.managed_agents import ManagedAgent, ManagedConfig

    managed = ManagedAgent(
        provider="local",
        config=ManagedConfig(model="gpt-4o-mini")
    )
    agent = Agent(name="local-assistant", backend=managed)
    result = agent.start("What is the capital of France?", stream=True)
    ```
  </Step>

  <Step title="With Secure Package Installation">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai.integrations.managed_agents import ManagedAgent, ManagedConfig

    managed = ManagedAgent(
        provider="local",
        config=ManagedConfig(
            model="gpt-4o-mini",
            packages={"pip": ["pandas", "numpy"]},
        ),
        compute="docker",   # required when packages are specified
    )
    agent = Agent(name="analyst", backend=managed)
    result = agent.start("Analyze this data: [1,2,3,4,5]", stream=True)
    ```
  </Step>
</Steps>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Agent
    participant LocalManaged
    participant LocalLLM
    participant LocalFS
    
    User->>Agent: Request
    Agent->>LocalManaged: Execute
    LocalManaged->>LocalLLM: Process
    LocalLLM-->>LocalManaged: Response
    LocalManaged->>LocalFS: Save Session
    LocalManaged-->>Agent: Result
    Agent-->>User: Output
```

Local managed agents provide the same APIs as cloud providers while keeping data on your infrastructure.

***

## Security: Sandboxed Package Installation

Local managed agents enforce sandbox-first security for package installation by default.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    A[📦 Package Request] --> B{Compute Provider?}
    B -->|Yes| C[🐳 Install in Sandbox]
    B -->|No| D{host_packages_ok?}
    D -->|True| E[⚠️ Install on Host]
    D -->|False| F[🚫 Raise ManagedSandboxRequired]
    
    C --> G[✅ Secure]
    E --> H[⚠️ Development Only]
    F --> I[❌ Error]
    
    classDef secure fill:#10B981,stroke:#7C90A0,color:#fff
    classDef warning fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef error fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef decision fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef input fill:#6366F1,stroke:#7C90A0,color:#fff
    
    class A input
    class B,D decision
    class C,G secure
    class E,H warning
    class F,I error
```

When `packages` are specified, three resolution paths exist:

1. **Compute Provider (Recommended)**: Attach `compute="docker"` to install packages in a sandbox
2. **Host Installation (Development Only)**: Set `host_packages_ok=True` for trusted environments
3. **No Packages**: Remove `packages` configuration to avoid installation

<Warning>
  Setting `host_packages_ok=True` installs packages directly on your host system, which can create security risks. Only use this in trusted developer environments where you control the package sources.
</Warning>

***

## Compute Tool Bridging

When a compute provider is attached, four shell-based tools automatically execute inside the compute instance instead of on the host:

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant Agent
    participant LocalManagedAgent
    participant Compute
    participant Result
    
    Agent->>LocalManagedAgent: execute_command("ls")
    LocalManagedAgent->>Compute: Bridge to compute.execute()
    Compute-->>LocalManagedAgent: Command output
    LocalManagedAgent-->>Agent: Bridged result
    
    Note over LocalManagedAgent,Compute: Also bridges: read_file, write_file, list_files
```

Bridged tools: `execute_command`, `read_file`, `write_file`, `list_files`

***

#### Tool Name Resolution

`LocalManagedAgent` resolves the strings in `tools=[...]` through the same canonical `ToolResolver` chain used by CLI `--tools`, YAML `agents.yaml`, recipes, and plain `Agent(tools=[...])`. A tool that resolves in one surface now resolves here too.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "LocalManagedAgent Tool Resolution"
        A[tools=...] --> Alias[TOOL_ALIAS_MAP + translate]
        Alias --> Resolver{ToolResolver}
        Resolver -->|1| L[local tools.py]
        Resolver -->|2| R[wrapper ToolRegistry]
        Resolver -->|3| C[praisonaiagents.tools]
        Resolver -->|4| P[praisonai-tools]
        Resolver -->|5| E[entry-point plugins]
        L --> Bridge{shell tool + compute?}
        R --> Bridge
        C --> Bridge
        P --> Bridge
        E --> Bridge
        Bridge -->|yes| Bridged[compute-bridged tool]
        Bridge -->|no| Direct[direct callable]
    end

    classDef input fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef process fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef resolve fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef output fill:#10B981,stroke:#7C90A0,color:#fff

    class A input
    class Alias,Bridge process
    class Resolver,L,R,C,P,E resolve
    class Bridged,Direct output
```

Resolution order (first match wins):

1. Local `tools.py` / `tools/` folder (requires `PRAISONAI_ALLOW_LOCAL_TOOLS=true`)
2. Wrapper `ToolRegistry` (`register_function`, `register_from_module`)
3. `praisonaiagents.tools` built-ins (e.g. `execute_command`, `read_file`)
4. `praisonai-tools` package
5. Entry-point plugins (`praisonai.tool_sources`)

When `praisonai-code` is not installed, the backend falls back to the historical `praisonaiagents.tools` lookup, so existing configs keep working unchanged.

Anthropic-style tool configs (`{"type": "agent_toolset_20260401", ...}`) and `TOOL_ALIAS_MAP` normalisation still run **before** resolution — the resolver only ever sees canonical tool names. Compute-bridge wrapping (`execute_command`, `read_file`, `write_file`, `list_files`) still runs **after** resolution regardless of the resolved source, so shell-based tools continue to execute inside the compute instance when one is attached.

***

## Configuration Options

### LocalManagedConfig Fields

| Option             | Type                   | Default                                 | Description                                                                                                                 |
| ------------------ | ---------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `model`            | `str`                  | `"gpt-4o"`                              | LLM model to use                                                                                                            |
| `system`           | `str`                  | `"You are a helpful coding assistant."` | System prompt                                                                                                               |
| `name`             | `str`                  | `"Agent"`                               | Agent display name                                                                                                          |
| `tools`            | `List[str]`            | Default tools                           | Enabled tool names. Resolved through the canonical `ToolResolver` chain (see [Tool Name Resolution](#tool-name-resolution)) |
| `packages`         | `Dict[str, List[str]]` | `None`                                  | Packages to install (e.g. `{"pip": ["pandas"]}`)                                                                            |
| `networking`       | `Dict[str, Any]`       | `{"type": "unrestricted"}`              | Network access policy                                                                                                       |
| `host_packages_ok` | `bool`                 | `False`                                 | Security opt-out. When `True`, permits pip install on host when no compute provider is attached                             |
| `working_dir`      | `str`                  | `""`                                    | Working directory inside the sandbox                                                                                        |
| `env`              | `Dict[str, str]`       | `{}`                                    | Extra environment variables                                                                                                 |

***

## Session Management

### Persistent Sessions

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai.integrations.managed_agents import ManagedAgent, ManagedConfig

# Create agent with session persistence
managed = ManagedAgent(
    provider="local",
    config=ManagedConfig(
        model="gpt-4o-mini",
        name="PersistentAgent"
    )
)
agent = Agent(name="persistent", backend=managed)

# First conversation
agent.start("Remember: my favorite color is blue")
session_info = managed.retrieve_session()
print(f"Session ID: {session_info['id']}")
print(f"Status: {session_info['status']}")

# Save session for later
ids = managed.save_ids()
# Store ids to file/database for persistence across restarts
```

<Note>
  Both `agent.start(..., stream=True)` and the non-streaming path persist the user prompt, the full assistant response, and token usage to the session store. Resume the session later and the full history is available — streaming does not drop messages.
</Note>

<Note>
  `retrieve_session()` **always** returns all 4 keys (`id`, `status`, `title`, `usage`) with sensible defaults when no session exists.
</Note>

### Resume Sessions

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# In another process/restart
managed2 = ManagedAgent(
    provider="local", 
    config=ManagedConfig(model="gpt-4o-mini")
)
managed2.restore_ids(ids)
managed2.resume_session(ids["session_id"])

agent2 = Agent(name="resumed", backend=managed2)
result = agent2.start("What is my favorite color?")  # Knows: blue
```

***

## Multi-turn Conversations

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai.integrations.managed_agents import ManagedAgent, ManagedConfig

managed = ManagedAgent(
    provider="local",
    config=ManagedConfig(
        model="gpt-4o-mini",
        system="You are a math tutor. Help students learn step by step.",
        name="MathTutor"
    )
)
agent = Agent(name="tutor", backend=managed)

# Multi-turn conversation in same session
response1 = agent.start("Explain what a derivative is", stream=True)
response2 = agent.start("Now show me how to find the derivative of x²", stream=True)
response3 = agent.start("What about x³?", stream=True)

# Session remembers all previous context
```

***

## Usage Tracking

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai.integrations.managed_agents import ManagedAgent, ManagedConfig

managed = ManagedAgent(
    provider="local",
    config=ManagedConfig(model="gpt-4o-mini")
)
agent = Agent(name="tracker", backend=managed)

# Execute some tasks
agent.start("Write a short poem")
agent.start("Explain quantum physics briefly")

# Check usage
session_info = managed.retrieve_session()
print(f"Session: {session_info['id']} (status: {session_info['status']})")
print(f"Input tokens:  {session_info['usage']['input_tokens']}")
print(f"Output tokens: {session_info['usage']['output_tokens']}")

# Also available on instance
print(f"Total input: {managed.total_input_tokens}")
print(f"Total output: {managed.total_output_tokens}")
```

***

## Best Practices

<AccordionGroup>
  <Accordion title="Configure Security Appropriately">
    Use compute providers like `compute="docker"` for package installation. Only set `host_packages_ok=True` in trusted developer environments. Packages require a sandbox by default to prevent security risks.
  </Accordion>

  <Accordion title="Handle ManagedSandboxRequired">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.integrations.managed_agents import ManagedSandboxRequired
    try:
        agent.start("Install pandas and analyze data")
    except ManagedSandboxRequired as e:
        # Either attach a compute provider, or set host_packages_ok=True
        print(f"Security error: {e}")
    ```
  </Accordion>

  <Accordion title="Session Persistence">
    Save session IDs using `save_ids()` for resuming conversations. Store IDs in a database or file system for persistence across application restarts.
  </Accordion>

  <Accordion title="Tool Configuration">
    Only enable tools your agent needs. When using compute providers, shell tools automatically execute in the sandbox for security.
  </Accordion>

  <Accordion title="Reference Tools by Name">
    Any tool that resolves via YAML/CLI/Python now resolves for `LocalManagedAgent` too. Reference your local `tools.py` function or your plugin tool by name in the `tools=[...]` list — no re-registration needed. Requires `PRAISONAI_ALLOW_LOCAL_TOOLS=true` for local `tools.py` loading.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Managed Agents" icon="cloud" href="/docs/concepts/managed-agents">
    Overview of managed agent concepts
  </Card>

  <Card title="Docker Compute" icon="docker" href="/docs/concepts/managed-agents-docker">
    Containerized execution environments
  </Card>

  <Card title="SessionInfo Schema" icon="circle-info" href="/docs/features/managed-agents-session-info">
    Unified session schema reference
  </Card>
</CardGroup>
