Metadata-Version: 2.4
Name: agentopy
Version: 0.1.0
Summary: [Prototype] Filesystem-first durable agent framework built on pydantic-ai v2 — exploring ideas inspired by Eve.dev, fully open source with no vendor lock-in
Author: AgentiPy
License: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: pydantic-ai>=2.0.0
Requires-Dist: click>=8.0
Requires-Dist: uvicorn>=0.30.0
Requires-Dist: fastapi>=0.115.0
Requires-Dist: sse-starlette>=2.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: httpx>=0.27.0

# AgentiPy

**⚠️ Prototype — exploring the idea of a filesystem-first, durable agent framework built on [pydantic-ai](https://github.com/pydantic/pydantic-ai) v2.**

> This is an experimental prototype for research and exploration. It is not production-ready. The API, architecture, and implementation are all subject to change as the ideas are validated and iterated on.

Inspired by [Eve.dev](https://eve.dev/docs/introduction) — exploring how to replicate its filesystem-first developer experience in Python, entirely on open-source foundations with no vendor lock-in.

```
my-agent/
├── pyproject.toml
└── agent/
    ├── agent.py                # Model config
    ├── instructions.md         # System prompt
    ├── tools/
    │   └── get_weather.py      # Tool: filename = tool name
    ├── skills/
    │   └── be-concise.md       # On-demand procedures
    └── channels/               # Platform entrypoints
```

## Philosophy

**The filesystem IS the interface.** A file's location determines its role. No registry to maintain — add a file, and the agent discovers it.

| Path | What it defines |
|------|----------------|
| `agent/instructions.md` | Always-on system prompt |
| `agent/agent.py` | Runtime config (model, description) |
| `agent/tools/get_weather.py` | Tool named `get_weather` |
| `agent/skills/` | On-demand markdown procedures |
| `agent/channels/` | Platform entrypoints (HTTP, Slack, etc.) |

## Quick Start

```bash
# Install
pip install agentopy

# Scaffold a new agent
agentopy init my-agent

# Chat with it
cd my-agent && agentopy chat

# Or start the HTTP server
agentopy dev --no-ui
```

## Demo: Weather Agent

```bash
cd demo-agent
agentopy chat --agent-dir agent

# Or HTTP server
agentopy dev --agent-dir agent --no-ui
```

### HTTP API

```
POST /agentopy/v1/session                 — Start a session
GET  /agentopy/v1/session/<id>/stream     — NDJSON event stream
POST /agentopy/v1/session/<id>            — Continue a session
GET  /health                               — Health check
```

```bash
curl -X POST http://127.0.0.1:2000/agentopy/v1/session \
  -H 'content-type: application/json' \
  -d '{"message":"What is the weather in New York?"}'
```

## Architecture

```
┌─────────────────────────────────────────────────────────┐
│                    CLI / HTTP Client                     │
└──────────────────────┬──────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────┐
│                     EveAgent                             │
│  ┌─────────────┐  ┌──────────────────┐  ┌────────────┐  │
│  │  Loader     │  │  pydantic-ai     │  │  Sessions  │  │
│  │  (discovers │──►  Agent wrapper   │──►  (in-mem   │  │
│  │   files)    │  │  (tool reg,      │  │   store)   │  │
│  │             │  │   streaming)     │  │            │  │
│  └─────────────┘  └──────────────────┘  └────────────┘  │
└──────────────────────┬──────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────┐
│                   pydantic-ai v2                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────────────────┐   │
│  │ Agent    │  │ Tools    │  │ Capabilities          │   │
│  │ (loop,   │  │(typed fn)│  │ (Think, WebSearch, …) │   │
│  │  stream) │  │          │  │                       │   │
│  └──────────┘  └──────────┘  └──────────────────────┘   │
└─────────────────────────────────────────────────────────┘
```

## Key Design Decisions

### 1. Filesystem-first discovery
No registries, no imports. `loader.py` walks `agent/` and builds a config from file paths. A file at `agent/tools/get_weather.py` becomes tool `get_weather`.

### 2. Thin wrapper over pydantic-ai
AgentiPy leverages pydantic-ai's battle-tested `Agent` class, tool system, streaming, and model abstraction:
- **Provider-agnostic**: OpenAI, Anthropic, Gemini, DeepSeek, Ollama — everything pydantic-ai supports
- **Type-safe tools**: All tools get validated parameter schemas
- **Streaming**: Built-in `run_stream()`, `run_stream_events()`, and `iter()` support
- **Capabilities**: Plug in `Thinking`, `WebSearch`, `MCP`, etc. via YAML

### 3. API design
`POST /agentopy/v1/session` and `GET /agentopy/v1/session/<id>/stream` follow Eve.dev's NDJSON streaming protocol for familiarity.

### 4. Session management
In-memory session store with message history across turns. Pluggable — swap in SQLite/PostgreSQL for production.

## Comparison

| Feature | Eve.dev | AgentiPy | pydantic-ai alone |
|---------|---------|----------|-------------------|
| Language | TypeScript | Python | Python |
| Filesystem-first | ✅ | ✅ | ❌ (code-only) |
| YAML agent specs | ❌ | ✅ (via agent.yaml) | ✅ |
| Durable execution | ✅ (Workflow SDK) | 🔄 (via pydantic-ai caps) | ✅ (Temporal, DBOS, Prefect, Restate) |
| Open source | ✅ | ✅ | ✅ |
| Vendor lock-in | ❌ (Vercel ecosystem) | ✅ none | ✅ none |
| Provider-agnostic | ✅ (AI SDK) | ✅ (pydantic-ai) | ✅ |
| NDJSON streaming | ✅ | ✅ | ✅ |
| MCP support | ✅ | 🔄 (via pydantic-ai) | ✅ |
| Capabilities system | ❌ | 🔄 (leverages pydantic-ai) | ✅ |
| Platform | Intel Mac, Apple Silicon | Any (Python) | Any |

✅ = built-in | 🔄 = via pydantic-ai | ❌ = not available

## Writing Tools

Each tool is a Python file in `agent/tools/`. The filename (minus `.py`) becomes the tool name.

```python
# agent/tools/get_weather.py
from datetime import datetime

description = "Get the current weather for a city."


async def execute(city: str, units: str = "fahrenheit") -> dict:
    """Return weather data for the given city."""
    return {
        "city": city,
        "temp": 72,
        "condition": "Sunny",
        "unit": "F"[0],
        "reported_at": datetime.now().isoformat(),
    }
```

The file must define:
- `description` (str): What the model sees for this tool
- `execute()` (sync/async): The tool function, with typed parameters

## Writing Skills

Skills are markdown files in `agent/skills/`. They're appended to the system prompt.

```markdown
# Be Concise

When asked for a skill, respond in exactly one sentence.
No greetings, no sign-offs, no explanations.
```

## Configuration

`agent/agent.py`:
```python
model = "openai:gpt-4o"
description = "A friendly weather assistant"
```

Or `agent/agent.yaml`:
```yaml
model: anthropic:claude-sonnet-4-20250514
description: A friendly weather assistant
instructions: "You are a concise weather bot."
```

## Roadmap

- [x] Filesystem loader (tools, instructions, skills)
- [x] pydantic-ai Agent integration
- [x] Session management with message history
- [x] HTTP server with NDJSON streaming
- [x] CLI: init, dev, chat, run
- [x] YAML agent config support
- [ ] Durable execution (Temporal, DBOS capabilities)
- [ ] On-demand skill loading (not always in context)
- [ ] Subagents (nested agent directories)
- [ ] MCP connections
- [ ] Human-in-the-loop tool approval
- [ ] Slack/Discord channels
- [ ] Persistent session store (SQLite)
- [ ] OpenTelemetry/Logfire instrumentation

## License

MIT
