Simple, flexible AI agent framework with a small DSL and explicit state
Project description
PicoFlow — Simple, Flexible AI Agent Framework
Build agents with explicit steps and a small DSL.
LLMs, tools, loops, and branches compose naturally.
A Minimal PicoFlow Application
from picoflow import flow, llm, create_agent
LLM_URL = "llm+openai://api.openai.com/v1/chat/completions?model=gpt-4.1-mini&api_key_env=OPENAI_API_KEY&insecure=1"
@flow
async def mem(ctx):
return ctx.add_memory("user", ctx.input)
agent = create_agent(
mem >> llm("Answer in one sentence: {input}", llm_adapter=LLM_URL)
)
print(agent.get_output("What is PicoFlow?", trace=True))
export OPENAI_API_KEY=sk-...
python minimal.py
Core Ideas
-
Flow = step
A flow is just a Python function that takes and returnsState. -
DSL = pipeline
Use>>to compose steps into readable execution graphs. -
Agent = runner
create_agent(flow)gives yourun / arun / get_output. -
State = context (Ctx)
Ctxis an alias ofState. It is immutable and explicit.
Quick Start (Step by Step)
1. Define Steps with @flow
from picoflow import flow, Ctx
@flow
async def normalize(ctx: Ctx) -> Ctx:
return ctx.update(input=ctx.input.strip().lower())
2. Call LLM as a Step
from picoflow import llm
ask = llm("Answer briefly: {input}")
3. Compose with DSL
pipeline = normalize >> ask
4. Run with Agent
from picoflow import create_agent
agent = create_agent(pipeline)
state = await agent.arun("Hello WORLD")
print(state.output)
DSL in One Minute
Sequential
flow = a >> b >> c
Loop
flow = step.repeat()
or:
flow = repeat(step, until=lambda s: s.done)
Parallel + Merge
flow = fork(a, b) >> merge()
Custom merge:
flow = fork(a, b) >> merge(
mode=MergeType.CUSTOM,
reducer=lambda branches, main: branches[0]
)
LLM URL
from picoflow.adapters.registry import from_url
adapter = from_url(
"llm+openai://api.openai.com/v1/chat/completions"
"?model=gpt-4.1-mini&api_key_env=OPENAI_API_KEY&insecure=1"
)
Then:
flow = llm("Explain: {input}", llm_adapter=adapter)
Custom Adapters
class MyAdapter(LLMAdapter):
def __call__(self, prompt: str, stream: bool):
...
from picoflow.adapters.registry import register
register("myllm", lambda url: MyAdapter(...))
Use:
llm+myllm://host/model?param=value
Runtime Options
Tracing
await agent.arun("hi", trace=True)
Timeout
await agent.arun("hi", timeout=10)
Streaming
async def on_chunk(text: str):
print(text, end="", flush=True)
await agent.arun("stream me", stream_callback=on_chunk)
Tools
from picoflow import tool
flow = tool("search", lambda q: {"result": "..."} )
Results:
state.tools["search"]
Troubleshooting: SSL certificate verify failed
Recommended (secure): set your CA bundle
export SSL_CERT_FILE=/path/to/ca.pem
# or
export PICO_CA_FILE=/path/to/ca.pem
Quick debug (insecure): disable verification temporarily
...&insecure=1
or
export PICO_SSL_VERIFY=0
Do not use this in production.
Note: Local Ollama usage (llm+ollama://localhost:11434/...) uses plain
HTTP and does not require SSL configuration.
📚 Cookbook (Examples)
The cookbook/ directory contains small, focused examples for common
patterns.
Each folder is runnable and demonstrates one specific feature or usage
style.
cookbook/
├─ minimal-demo # Smallest runnable PicoFlow example
├─ multiple-crew # Multi-agent / crew-style collaboration
├─ simple-chat # Basic chat agent
├─ simple-chat-stream # Streaming responses from LLM
├─ simple-tool # Tool calling and tool state
└─ trace # Tracing and execution visualization
How to run
All examples are standalone scripts:
export OPENAI_API_KEY=sk-...
cd cookbook/simple-chat
python main.py
When to use which example
-
Start here →
minimal-demo
Understand Flow, DSL (>>), and Agent execution. -
LLM interaction →
simple-chat,simple-chat-stream
Prompt → response, with and without streaming. -
Tool calling →
simple-tool
How tools are defined, executed, and stored instate.tools. -
Multi-step / multi-agent →
multiple-crew
Composition of multiple flows and roles. -
Debugging & observability →
trace
How tracing hooks and structured events work.
Cookbook examples are intentionally small and close to real usage.
They are recommended as the primary learning path after reading the Minimal Example.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file picoflow-0.1.6.tar.gz.
File metadata
- Download URL: picoflow-0.1.6.tar.gz
- Upload date:
- Size: 21.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26ba73b8f04b1b242acff8b7b7202880fed11afe7dc60a0ff8446b23c9f07e2b
|
|
| MD5 |
0c84e014c2ad640d1632c37082c7bc59
|
|
| BLAKE2b-256 |
c430eb9187dfa8b30ba324a210e35ee65d054c254fc8e4c713564c2f27624395
|
File details
Details for the file picoflow-0.1.6-py3-none-any.whl.
File metadata
- Download URL: picoflow-0.1.6-py3-none-any.whl
- Upload date:
- Size: 25.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54dc24fa18473c2e32e0243641408e469aa3ec76b2ec18f2e5684df8a8eb0e06
|
|
| MD5 |
f126fbbd5a0d1e64dfee9db8dcaa89db
|
|
| BLAKE2b-256 |
7b7a621929912b45ef4067a4e7e98caef00648d8fb8440c799c7458aabcb73a0
|