Metadata-Version: 2.4
Name: flyagent
Version: 0.1.0
Summary: The lightweight, fast, and powerful Python framework for building AI agents
Project-URL: Homepage, https://github.com/TokenFlyAI/FlyAgent
Project-URL: Repository, https://github.com/TokenFlyAI/FlyAgent
Project-URL: Issues, https://github.com/TokenFlyAI/FlyAgent/issues
License: MIT
Keywords: agent,ai,anthropic,automation,llm,mcp,openai
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Requires-Dist: openai>=1.0.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.0.0
Provides-Extra: all
Requires-Dist: anthropic>=0.20.0; extra == 'all'
Requires-Dist: mcp>=1.0.0; extra == 'all'
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.20.0; extra == 'anthropic'
Provides-Extra: mcp
Requires-Dist: mcp>=1.0.0; extra == 'mcp'
Description-Content-Type: text/markdown

# FlyAgent

**The lightweight, fast, and powerful Python framework for building AI agents.**

```python
from flyagent import run
result = run("find all TODO comments in this codebase and summarize them")
```

---

## Why FlyAgent?

Most agentic frameworks are either **too simple** (just prompt chaining) or **too heavy** (hundreds of dependencies, steep learning curve). FlyAgent hits the sweet spot:

| | FlyAgent | LangChain | AutoGPT |
|--|--|--|--|
| Lines to first agent | **3** | ~30 | config files |
| Parallel tool execution | ✅ DAG-based | ❌ sequential | ❌ |
| Built-in TUI | ✅ rich terminal | ❌ | ❌ |
| Task harness (plan→execute→review) | ✅ | manual | manual |
| Multi-API (OpenAI + Anthropic) | ✅ auto-detect | ✅ | ❌ |
| Config-driven (`agent.yaml`) | ✅ composable | ❌ | ✅ |
| MCP server support | ✅ | partial | ❌ |
| Core dependencies | **2** (`openai`, `pyyaml`) | 50+ | 20+ |

### Key strengths

**🚀 Fast to start** — `pip install flyagent`, set an API key, call `run()`. No boilerplate.

**⚡ Parallel execution** — Under the hood, a DAG scheduler runs independent tool calls concurrently. If an agent decides to read 5 files at once, all 5 run in parallel threads.

**🎯 Harness keeps agents on track** — The `Harness` enforces a structured workflow: agents must write a plan first, execute step by step, then self-review. This dramatically reduces hallucination and missed steps.

**🔧 Everything is a tool** — Agents, skills, and sub-agents are all `Tool` objects. They compose naturally. A sub-agent IS a tool — pass it to another agent and it just works.

**📺 Beautiful TUI included** — Load any config and get a Claude Code-style terminal UI instantly, with live tool call rendering, spinners, and markdown output.

**🔌 MCP native** — Add any MCP server in two lines of YAML. Its tools appear alongside your built-in tools automatically.

---

## Install

```bash
# pip
pip install flyagent

# uv (faster)
uv add flyagent

# With Anthropic (Claude) support
pip install "flyagent[anthropic]"
uv add "flyagent[anthropic]"

# With MCP server support
pip install "flyagent[mcp]"
uv add "flyagent[mcp]"

# Everything
pip install "flyagent[all]"
uv add "flyagent[all]"

# From source
git clone https://github.com/TokenFlyAI/Agentic_System
cd Agentic_System
pip install -e .        # pip editable install
uv pip install -e .     # uv editable install
```

```bash
export OPENAI_API_KEY=sk-...        # OpenAI (GPT-4o)
export ANTHROPIC_API_KEY=sk-ant-... # Anthropic (Claude)
```

---

## API Reference

### `run()` — One-liner

```python
from flyagent import run

result = run("list all Python files modified today")
result = run("summarize README.md", model="claude-opus-4-6")
result = run("fix the bug in utils.py", tools=["bash", "read_file", "edit_file"])
```

---

### `Agent` — Core class

```python
from flyagent import Agent
from flyagent.tools import BashTool, ReadFileTool, WriteFileTool, GlobTool

agent = Agent(
    tools=[BashTool, ReadFileTool, WriteFileTool, GlobTool],
    model="gpt-4o",                          # or "claude-opus-4-6"
    system="You are a senior Python dev.",   # custom system prompt
    name="my_agent",                         # optional
)

# Block until done, print progress live
result = agent.run("refactor utils.py to use dataclasses")

# Stream structured events (for custom UIs)
for event in agent.events("run the tests and fix failures"):
    if event["type"] == "tool_start":
        print(f"Running {event['tool']}...")
    elif event["type"] == "result":
        print(event["text"])
```

---

### `@tool` — Custom tools

Turn any Python function into an agent tool. Type hints auto-build the JSON schema.

```python
from flyagent import Agent, tool

@tool(description="Get current UTC time")
def get_time() -> str:
    from datetime import datetime, timezone
    return datetime.now(timezone.utc).isoformat()

@tool(description="Add two numbers")
def add(a: int, b: int) -> str:
    return str(a + b)

@tool(description="Look up a stock price")
def stock_price(ticker: str) -> str:
    # your real implementation here
    return f"{ticker}: $150.00"

agent = Agent(tools=[get_time, add, stock_price, BashTool])
result = agent.run("What time is it and what is 42 + 58?")
```

For full schema control:

```python
from flyagent import create_tool
from flyagent.core.schema import JS

weather = create_tool(
    name="get_weather",
    description="Get weather for a city",
    func=lambda city, units="celsius": f"{city}: 22°{units[0].upper()}",
    input_schema=JS.object(
        properties={
            "city":  JS.string(description="City name"),
            "units": JS.string(description="celsius or fahrenheit", enum=["celsius", "fahrenheit"]),
        },
        required=["city"],
    ),
)
```

---

### `Harness` — Structured task execution

A `Harness` enforces **plan → execute → review** on every task. The agent must:
1. Write a numbered TODO plan before acting
2. Check off each step as it completes
3. Self-review the output against the original goal

This keeps agents focused, reduces errors, and makes output predictable.

```python
from flyagent import Harness
from flyagent.tools import BashTool, ReadFileTool, WriteFileTool, EditFileTool

# Custom harness
harness = Harness(
    tools=[BashTool, ReadFileTool, WriteFileTool, EditFileTool],
    model="gpt-4o",
    system="You are a senior software engineer.",
    workflow=["plan", "execute", "review"],
    max_steps=25,
)
result = harness.run("add input validation to the signup endpoint")
```

**Preset harnesses** — batteries included:

```python
from flyagent import CodingHarness, ResearchHarness, DataHarness, ShellHarness

# All file/bash/search tools + coding-focused prompt
CodingHarness().run("fix all failing tests")

# WebFetch + bash + files + research-focused prompt
ResearchHarness().run("research the top 5 Python web frameworks in 2025")

# Bash (python/pandas/matplotlib) + files + data-focused prompt
DataHarness().run("analyze sales.csv and generate a summary report")

# Bash only + DevOps-focused prompt
ShellHarness().run("check system disk usage and clean up logs older than 30 days")
```

---

### `skill` — Reusable capabilities

A skill is a named, reusable combination of instructions + tools that can be activated at runtime.

```python
from flyagent import skill, Agent
from flyagent.tools import ReadFileTool, GrepTool, BashTool

@skill(tools=["read_file", "grep"], description="Review Python code quality")
def code_review() -> str:
    return (
        "Review the given code for: bugs, edge cases, style issues (PEP 8), "
        "performance problems, and missing error handling."
    )

@skill(tools=["bash"], description="Run and interpret test results")
def test_runner() -> str:
    return "Run pytest with verbose output. Explain any failures clearly."

agent = Agent(
    tools=[ReadFileTool, GrepTool, BashTool],
    skills=[code_review, test_runner],
)
result = agent.run("review auth.py and then run its tests")
```

---

### `SubAgent` — Multi-agent systems

Sub-agents are agents that act as tools for a parent (coordinator) agent.

```python
from flyagent import Agent, SubAgent
from flyagent.tools import ReadFileTool, WriteFileTool, EditFileTool, BashTool, GrepTool

# Specialist agents
researcher = SubAgent(
    name="researcher",
    tools=[ReadFileTool, GrepTool],
    system="You find and analyze relevant code. Report findings clearly.",
)
implementer = SubAgent(
    name="implementer",
    tools=[WriteFileTool, EditFileTool, BashTool],
    system="You implement code changes based on a specification.",
)
reviewer = SubAgent(
    name="reviewer",
    tools=[ReadFileTool, BashTool],
    system="You review code changes and run tests to verify correctness.",
)

# Coordinator delegates to specialists
coordinator = Agent(
    tools=[researcher, implementer, reviewer],
    system="Break down tasks and delegate to the right specialist.",
    model="gpt-4o",
)

result = coordinator.run(
    "Add rate limiting to the API — research the codebase, implement it, then review"
)
```

---

### Config-driven agents (YAML)

Define agents as YAML files — no code needed.

```yaml
# agents/coding_agent.yaml
name: coding_agent
model: claude-opus-4-6
tools: [bash, read_file, write_file, edit_file, glob, grep]
harness: coding
system: "You are a senior Python developer. Write clean, tested code."

skills:
  - name: code_review
    tools: [read_file, grep]
    prompt: "Review code for bugs, style issues, and performance."

sub_agents:
  - !config agents/tester.yaml   # import from another file
```

```yaml
# agents/tester.yaml
name: tester
tools: [bash, read_file]
system: "Run tests and report results with clear explanations."
```

```yaml
# With MCP servers
mcp_servers:
  - name: github
    command: npx
    args: ["-y", "@modelcontextprotocol/server-github"]
    env:
      GITHUB_TOKEN: "${GITHUB_TOKEN}"
  - name: postgres
    command: npx
    args: ["-y", "@modelcontextprotocol/server-postgres", "${DB_URL}"]
```

```python
from flyagent import Agent
agent = Agent.from_config("agents/coding_agent.yaml")
result = agent.run("add pagination to the users endpoint")
```

---

### Multi-API support

FlyAgent auto-detects the provider from the model name and available env vars.

```python
from flyagent import Agent
from flyagent.providers import OpenAIProvider, AnthropicProvider

# Auto-detect (recommended)
agent = Agent(model="gpt-4o")            # uses OPENAI_API_KEY
agent = Agent(model="claude-opus-4-6")   # uses ANTHROPIC_API_KEY

# Explicit provider
agent = Agent(provider=OpenAIProvider(model="gpt-4o", api_key="sk-..."))
agent = Agent(provider=AnthropicProvider(model="claude-opus-4-6"))
```

---

### MCP servers

Connect to any MCP server — its tools appear alongside your built-in tools.

```python
from flyagent import Agent
from flyagent.mcp_client import load_mcp_tools
from flyagent.tools import BashTool

mcp_tools = load_mcp_tools([{
    "name": "github",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-github"],
    "env": {"GITHUB_TOKEN": "ghp_..."},
}])

agent = Agent(tools=[BashTool] + mcp_tools)
result = agent.run("list the open PRs in my repo")
```

---

## Built-in Tools

| Class | Name (YAML) | Description |
|-------|-------------|-------------|
| `BashTool` | `bash` | Run shell commands, get stdout/stderr/exit code |
| `ReadFileTool` | `read_file` | Read file contents, optional line range |
| `WriteFileTool` | `write_file` | Write/create files, auto-creates parent dirs |
| `EditFileTool` | `edit_file` | Find-and-replace edit (exact string match) |
| `ListDirTool` | `list_dir` | Directory tree with configurable depth |
| `GlobTool` | `glob` | Find files by glob pattern (`**/*.py`) |
| `GrepTool` | `grep` | Regex search across files, returns file:line matches |
| `WebFetchTool` | `web_fetch` | Fetch a URL, returns stripped plain text |

YAML shorthand aliases:
- `files` → expands to `read_file, write_file, edit_file, list_dir`
- `search` → expands to `glob, grep`

---

## TUI — Beautiful terminal interface

FlyAgent ships with a rich terminal UI that works with **any config file**.

```bash
# Load any config
python -m flyagent --config agents/coding_agent.yaml

# Preset harnesses
python -m flyagent --harness coding
python -m flyagent --harness research
python -m flyagent --harness data
python -m flyagent --harness shell

# One-shot task
python -m flyagent --config my_agent.yaml "fix failing tests"
python -m flyagent "list Python files here"

# Different model
python -m flyagent --model claude-opus-4-6
```

Embed the TUI in your own app:

```python
from flyagent.tui_rich import AgentTUI
from flyagent import Agent

# From config
tui = AgentTUI.from_config("my_agent.yaml")
tui.run()

# From code
agent = Agent(tools=[...], model="gpt-4o")
tui = AgentTUI(agent, title="My Agent", subtitle="coding · bash · files")
tui.run()

# One-shot with TUI
tui.run(initial_task="summarize the codebase")
```

---

## Examples

```bash
# Minimal hello world
python examples/hello.py

# Custom tools
python examples/custom_tool.py

# Tiny Claude Code — coding assistant
python examples/tiny_claude_code/main.py
python examples/tiny_claude_code/main.py "refactor utils.py"

# Chatbot with agent abilities
python examples/chatbot_with_agent/main.py
```

---

## Architecture

FlyAgent has a clean two-layer design — you only touch the surface layer:

```
┌─────────────────────────────────────────────────────────┐
│                    SURFACE LAYER                        │
│  (what you use)                                         │
│                                                         │
│  Agent   SubAgent   Harness   @tool   @skill   run()    │
│  AgentTUI   providers   mcp_client   tools/             │
│  Agent.from_config()   YAML composition                 │
└──────────────────────────┬──────────────────────────────┘
                           │ thin bridge
┌──────────────────────────▼──────────────────────────────┐
│                    ENGINE LAYER                         │
│  (high-performance core, rarely touched)                │
│                                                         │
│  core/executor/   ← parallel DAG scheduler              │
│    ToolExecutor      ThreadPoolExecutor                 │
│    TaskScheduler     dependency tracking                │
│                                                         │
│  core/impl/agent/  ← LLM orchestrator                  │
│    AgentV3           tool-call loop                     │
│    builtin_tools     sub-agents, skills                 │
│                                                         │
│  core/llm/         ← LLM API integration               │
│  core/context/     ← state management                  │
│  core/schema/      ← JSON schema types                  │
└─────────────────────────────────────────────────────────┘
```

### How a task executes

```
agent.run("fix the failing tests")
    │
    ▼
AgentV3 calls LLM
    │  "I'll run pytest first, then read failing test files"
    ▼
ToolExecutionPlan (DAG)
    ├─ bash("pytest -v")           ← runs in parallel
    └─ read_file("test_utils.py")  ← runs in parallel
    │
    ▼
Results fed back to LLM
    │  "Test X failed because of Y — I'll edit utils.py"
    ▼
ToolExecutionPlan
    └─ edit_file("utils.py", ...)
    │
    ▼
LLM calls complete() → result returned
```

### Core concepts

**Everything is a Tool** — `Agent`, `SubAgent`, and skills all implement the `Tool` interface. This makes composition trivial: pass an agent as a tool to another agent.

**Generator-based execution** — Tools are generators that yield `ToolExecutionUpdate` objects. This lets the executor control scheduling without threads inside tools.

**DAG scheduling** — When an agent yields a `ToolExecutionPlan`, the executor builds a dependency graph and runs independent tasks concurrently via `ThreadPoolExecutor`.

**Three-layer context** — Each tool gets `local_context` (its own state), `parent_context` (caller's state), and `global_context` (session-wide). Sub-agents can read parent context naturally.

---

## Requirements

```
openai>=1.0.0      # required (OpenAI provider)
pyyaml>=6.0        # required (config files)
anthropic>=0.20.0  # optional (Anthropic/Claude provider)
mcp>=1.0.0         # optional (MCP server support)
rich               # optional (TUI — usually pre-installed)
```

---

## Quick reference

```python
from flyagent import (
    Agent,          # core agent class
    SubAgent,       # agent-as-tool for multi-agent systems
    Harness,        # structured plan→execute→review workflow
    run,            # one-liner shortcut
    tool,           # @tool decorator for custom tools
    skill,          # @skill decorator for reusable capabilities
    create_tool,    # function → Tool with manual schema
    SkillRegistry,  # global skill registry

    # Built-in tools
    BashTool, ReadFileTool, WriteFileTool, EditFileTool,
    ListDirTool, GlobTool, GrepTool, WebFetchTool, ALL_TOOLS,

    # Providers
    OpenAIProvider, AnthropicProvider,

    # Preset harnesses
    CodingHarness, ResearchHarness, DataHarness, ShellHarness,
)

from flyagent.tui_rich import AgentTUI     # rich terminal UI
from flyagent.mcp_client import load_mcp_tools  # MCP integration
```
