Observed since 20 Oct, 22:49 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
[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
⚠️ Prototype — exploring the idea of a filesystem-first, durable agent framework built on 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 — 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
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.) |
# 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
cd demo-agent
agentopy chat --agent-dir agent
# Or HTTP server
agentopy dev --agent-dir agent --no-ui
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
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?"}'
┌─────────────────────────────────────────────────────────┐
│ 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) │ │ │ │ │ │
│ └──────────┘ └──────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────┘
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.
AgentiPy leverages pydantic-ai's battle-tested Agent class, tool system, streaming, and model abstraction:
run_stream(), run_stream_events(), and iter() supportThinking, WebSearch, MCP, etc. via YAMLPOST /agentopy/v1/session and GET /agentopy/v1/session/<id>/stream follow Eve.dev's NDJSON streaming protocol for familiarity.
In-memory session store with message history across turns. Pluggable — swap in SQLite/PostgreSQL for production.
| 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
Each tool is a Python file in agent/tools/. The filename (minus .py) becomes the tool name.
# 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 toolexecute() (sync/async): The tool function, with typed parametersSkills are markdown files in agent/skills/. They're appended to the system prompt.
# Be Concise
When asked for a skill, respond in exactly one sentence.
No greetings, no sign-offs, no explanations.
agent/agent.py:
model = "openai:gpt-4o"
description = "A friendly weather assistant"
Or agent/agent.yaml:
model: anthropic:claude-sonnet-4-20250514
description: A friendly weather assistant
instructions: "You are a concise weather bot."
MIT
pypistats · 53 observations shown. Missing days are unknown. Source category: overall: without mirrors.
| Date / source period | Value | Observed at |
|---|---|---|
| 2026-10-20 – 2026-10-20 | 4 | 2026-10-21T11:24:14.5505204Z |
| 2026-10-18 – 2026-10-18 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-10-17 – 2026-10-17 | 7 | 2026-10-21T11:24:14.5505204Z |
| 2026-10-16 – 2026-10-16 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-10-15 – 2026-10-15 | 5 | 2026-10-21T11:24:14.5505204Z |
| 2026-10-14 – 2026-10-14 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-10-13 – 2026-10-13 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-10-12 – 2026-10-12 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-10-11 – 2026-10-11 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-10-09 – 2026-10-09 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-10-06 – 2026-10-06 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-10-03 – 2026-10-03 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-10-02 – 2026-10-02 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-10-01 – 2026-10-01 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-30 – 2026-09-30 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-27 – 2026-09-27 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-26 – 2026-09-26 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-23 – 2026-09-23 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-22 – 2026-09-22 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-21 – 2026-09-21 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-20 – 2026-09-20 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-19 – 2026-09-19 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-16 – 2026-09-16 | 3 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-14 – 2026-09-14 | 3 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-13 – 2026-09-13 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-09 – 2026-09-09 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-07 – 2026-09-07 | 3 | 2026-10-21T11:24:14.5505204Z |
| 2026-09-01 – 2026-09-01 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-31 – 2026-08-31 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-28 – 2026-08-28 | 3 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-27 – 2026-08-27 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-26 – 2026-08-26 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-25 – 2026-08-25 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-24 – 2026-08-24 | 7 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-23 – 2026-08-23 | 3 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-21 – 2026-08-21 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-17 – 2026-08-17 | 6 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-15 – 2026-08-15 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-14 – 2026-08-14 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-09 – 2026-08-09 | 3 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-08 – 2026-08-08 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-06 – 2026-08-06 | 3 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-04 – 2026-08-04 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-03 – 2026-08-03 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-08-02 – 2026-08-02 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-07-31 – 2026-07-31 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-07-29 – 2026-07-29 | 6 | 2026-10-21T11:24:14.5505204Z |
| 2026-07-28 – 2026-07-28 | 2 | 2026-10-21T11:24:14.5505204Z |
| 2026-07-27 – 2026-07-27 | 7 | 2026-10-21T11:24:14.5505204Z |
| 2026-07-26 – 2026-07-26 | 1 | 2026-10-21T11:24:14.5505204Z |
| 2026-07-25 – 2026-07-25 | 3 | 2026-10-21T11:24:14.5505204Z |
| 2026-07-24 – 2026-07-24 | 16 | 2026-10-21T11:24:14.5505204Z |
| 2026-07-23 – 2026-07-23 | 96 | 2026-10-21T11:24:14.5505204Z |
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.0 | 23 Jul 2026 | 7 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 22:49 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:28bf49525a831db09d8aec6cfd04a0db6e501aab0939bb60ae7d7a4c66b8c615