The Problem

Developers building autonomous agents need a repeatable way to combine prompt‑driven logic, file‑system sandboxing, and typed output validation. Without a framework, each project re‑implements sandbox policies, session persistence, and deployment scaffolding, leading to duplicated effort and security gaps.

What This Does

pyflue supplies a lightweight “harness” that glues together:

  • CLI scaffoldingpyflue/cli.py implements pyflue init, run, and dev.
  • Server runtimepyflue/server.py exposes prompt_events via an SSE endpoint.
  • Sandbox layerpyflue/sandboxes/ (base, virtual, daytona, e2b, modal, remote, runloop) implements file‑read/write, shell execution, and policy enforcement.
  • Core orchestrationpyflue/core.py creates agents, sessions, and routes skill calls.
  • Typed contractspyflue/types.py defines PyFlueConfig, PyFlueEvent, and result models used across the codebase.

The repository ships with example agents (examples/agents/*.py) and full Markdown‑based skill definitions (.agents/skills/*.md).

How It Is Wired

Entry points

  • CLIpyflue/cli.py:run (line 98) is the top‑level command invoked by pyflue run. It reaches 42 functions and calls _run, which eventually invokes _run_local.
  • Serverpyflue/server.py:prompt_events (line 93) starts the HTTP event stream, reaching 30 functions.

Core flow (CLI)

  1. run → _run (cli) → load_config (core) reads pyflue.toml from the filesystem.
  2. load_config → resolve (core) resolves configuration values (called 19 times across the repo).
  3. init → session (core) creates a PyFlueAgent (instantiated 14 times) and a VirtualSandbox (instantiated 11 times).
  4. session.shell or session.run_python eventually reaches SandboxPolicy (imported by 19 callers) and executes a subprocess via subprocess.run (e.g., run → _run_local).

The only external effect is a subprocess launch (subprocess.run) and file I/O (e.g., write_file, read_file in pyflue/sandboxes/base.py). No network calls are present in the static call graph.

Core flow (Server)

prompt_events creates a PyFlueAgent via init, then streams events through stream → PyFlueEvent (8 calls). The same sandbox and config paths as the CLI are used.

Hub modules

  • pyflue/types.py is imported by 12 modules (high blast radius).
  • pyflue/sandboxes/base.py is imported by 14 modules and contains the primary file‑helper API (read_file, write_file, edit_file).
  • pyflue/__init__ is imported by 10 modules and re‑exports public symbols.

Hot spots

  • pyflue/core.py is the largest file (650 LOC) and is called from 17 other files, making it a change‑impact hotspot.
  • Deep nesting (max indentation depth 6) appears in pyflue/core.py, pyflue/harnesses/deepagents.py, and pyflue/deploy.py, increasing cognitive load.
  • Repeated 6‑line code blocks span 16 files (cli.py, deploy.py, code/base.py, code/monty.py, …), indicating a DRY violation.

How To Use It

# Install (uv is recommended)
uv add pyflue               # or: pip install pyflue

# Optional extras for sandbox backends
uv add "pyflue[sandboxes]"  # installs Daytona, E2B, Modal, etc.

Initialize a new agent project:

pyflue init my-agent
cd my-agent

Run an interactive prompt (CLI) or start the HTTP server:

pyflue run --prompt "Review this project"
# or
pyflue dev --port 2024   # starts prompt_events server

Configuration lives in pyflue.toml (created by init). No environment variables are required out‑of‑the‑box; backends such as Daytona may need their own credentials, which are loaded by the respective sandbox provider modules.

Real‑World Use

A CI/CD pipeline can invoke pyflue run on pull‑request diffs to automatically suggest code fixes. The agent reads the repository via the virtual sandbox, generates a FixResult Pydantic model, and the CI script can apply the changes if fix_applied is true.

from pyflue import init

async def ci_fix():
    agent = await init(sandbox="virtual", allow_write=True)
    sess = await agent.session("pr-123")
    res = await sess.skill("triage", args={"issue_number": 42}, result=FixResult)
    if res.fix_applied:
        await sess.shell("git apply suggestions.patch")

Code Health & Issues

  • HIGH – GitHub Actions use a mutable tag (astral-sh/setup-uv@v5). Pin to a commit SHA to avoid supply‑chain drift.
  • MEDIUM – No dependency‑vulnerability scan in CI. Add dependency-review-action or osv-scanner.
  • LOW – Workflow jobs lack timeout-minutes; set explicit limits to prevent overlapping runs.
  • LOW/RISK – No lockfile; builds are non‑reproducible (pyproject.toml only).
  • MEDIUM – Deep nesting in three files makes control flow hard to follow.
  • MEDIUM – Broad except clauses swallow errors; replace with specific exception handling.
  • MEDIUM – Hub modules (types.py, sandboxes/base.py) have high import counts; keep them stable.
  • HIGH – Repeated 6‑line blocks across 16 files; extract shared helpers to reduce duplication.
  • MEDIUM – Oversized core.py (650 LOC) should be split by responsibility.

The Bottom Line

pyflue delivers a coherent, extensible harness for building sandboxed agents, with clear entry points and a modest external footprint. However, the codebase suffers from duplicated logic, deep nesting, and a few CI hygiene gaps that should be addressed before using it in production‑critical environments. It is best suited for teams comfortable tweaking Python internals and willing to invest in modest refactoring.