Skip to content

Managed Agents: wire compute provider, block host pip, clarify sandbox docs (safety)Β #1426

@MervinPraison

Description

@MervinPraison

Problem

LocalManagedAgent advertises a sandboxed execution story (compute="docker|e2b|modal|daytona|flyio|local", packages={"pip": [...]}, LocalManagedConfig.sandbox_type) but the actual code path runs tool calls in-process and installs pip packages into the caller's Python interpreter.

Concretely (evidence on main):

  1. praisonai/integrations/managed_local.py:463-478 β€” _install_packages() runs
    subprocess.run([sys.executable, "-m", "pip", "install", "-q", *pip_pkgs], ...)
    on the host Python, regardless of whether a compute provider is attached.
  2. praisonai/integrations/managed_local.py:548-577 β€” _execute_sync() calls self._ensure_agent() then agent.chat(prompt). It never touches self._compute. Tool calls (execute_command, read_file, etc.) run in-process.
  3. praisonai/integrations/managed_local.py:91 β€” LocalManagedConfig.sandbox_type: str = "subprocess" is declared but never read anywhere in the module (grep confirms).
  4. PraisonAIDocs/docs/concepts/managed-agents.mdx:8 claims "Managed Agents run on cloud infrastructure, automatically provisioning compute resources and managing execution environments" β€” true for AnthropicManagedAgent, false by default for LocalManagedAgent.

Consequence: a non-developer following the quickstart runs LLM-generated shell commands on their laptop, and arbitrary pip installs leak into their environment.

Acceptance criteria

  • LocalManagedAgent with packages=… and no compute=… raises ManagedSandboxRequired with actionable message. Opt-out available via explicit LocalManagedConfig(host_packages_ok=True) for developer workflows.
  • When compute=… is set, _install_packages runs inside the compute instance (compute.execute(instance_id, "pip install …")), never on the host.
  • When compute=… is set, every tool call routed through agent.chat(...) executes via compute.execute(instance_id, command) (for built-in tools that produce shell commands) β€” concretely: bridge execute_command / list_files / search_file / write_file tools to the compute provider by default.
  • LocalManagedConfig.sandbox_type is either honoured (e.g. selects compute provider) or removed with a short deprecation path.
  • Docs (managed-agents.mdx + managed-agents-local.mdx) make the host-vs-sandbox story explicit in the first paragraph and in every quickstart example.
  • Tests:
    • test_install_packages_without_compute_raises β€” assert ManagedSandboxRequired.
    • test_install_packages_with_compute_runs_in_sandbox β€” compute mock records pip install calls; host subprocess.run is not invoked.
    • test_tool_execution_routes_through_compute_when_attached β€” compute mock receives the tool's command.
    • Real agentic (gated by RUN_REAL_AGENTIC=1): Agent(backend=LocalManagedAgent(compute="docker", config=LocalManagedConfig(model="gpt-4o-mini", packages={"pip":["requests"]}))).start("Fetch https://example.com and print the title") β€” completes end-to-end; requests is installed in container, not host.

Implementation plan

  1. Add ManagedSandboxRequired exception in praisonai/integrations/managed_agents.py (shared).
  2. In LocalManagedAgent._install_packages, short-circuit to self._compute.execute(self._compute_instance_id, "pip install ...") when compute attached; else raise unless host_packages_ok=True.
  3. Add provision_compute() auto-call inside _ensure_agent() when self._compute is set and self._compute_instance_id is None.
  4. Introduce a thin _ComputeToolBridge that wraps the PraisonAI built-in shell-ish tools and delegates their exec step to compute.execute(...). Wire it in _resolve_tools() when compute is attached.
  5. Update LocalManagedConfig:
    • Add host_packages_ok: bool = False.
    • Either remove sandbox_type or make it a compute-provider alias (pick one, document once).
  6. Docs: rewrite "How it works" section of managed-agents.mdx to clearly state: Anthropic β†’ cloud; Local β†’ host unless compute=….
  7. Tests per acceptance criteria.

Files

Modify:

  • src/praisonai/praisonai/integrations/managed_local.py
  • src/praisonai/praisonai/integrations/managed_agents.py (new exception)
  • src/praisonai/praisonai/integrations/compute/*.py (ensure execute() accepts pip install ...)
  • PraisonAIDocs/docs/concepts/managed-agents.mdx
  • PraisonAIDocs/docs/concepts/managed-agents-local.mdx
  • src/praisonai-agents/tests/managed/test_managed_factory.py (add failing tests)

Create:

  • src/praisonai-agents/tests/managed/test_managed_sandbox_safety.py
  • src/praisonai/tests/integration/test_managed_compute_wiring.py (gated real agentic)

Invariants

  • Protocol-driven core untouched (changes live in wrapper).
  • Lazy imports preserved.
  • Backward-compatible: existing LocalManagedAgent(...) without compute= continues to work only when no packages=; opt-out flag available.

References

cc @claude β€” please pick this up per .windsurf/workflows/e2e-analysis-issue-pr-merge.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingclaudeAuto-trigger Claude analysisdocumentationImprovements or additions to documentationenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions