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"
@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"
)
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"]
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.1.tar.gz.
File metadata
- Download URL: picoflow-0.1.1.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a4a440a9f41e206f4e34780b970ab2c5a325b1c866bb8b37fee3a226ea46fc6
|
|
| MD5 |
40f274fc841182d7d20aba6eb1822770
|
|
| BLAKE2b-256 |
05ad2d6adf04a42c642e4dd09350bc261af675c232fa3a040b2c559180ca0a67
|
File details
Details for the file picoflow-0.1.1-py3-none-any.whl.
File metadata
- Download URL: picoflow-0.1.1-py3-none-any.whl
- Upload date:
- Size: 20.7 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 |
5246816676e6e47e0131a4d3251d5be55a8d7af34471b04ff0c482323c2446a7
|
|
| MD5 |
e62a8c23c8d5ddbbe32c9cd489fd5d1e
|
|
| BLAKE2b-256 |
97c532c1a123578f6a35eed24ae7e4b66ee794470ec87faf3c04071d9047b748
|