A small-but-complete agent harness: ReAct loop, tool injection, three-tier memory, restricted-expression panels. Zero heavy deps.
Project description
🐦 sparrow
A small-but-complete agent harness.
Bring your own tools and a system prompt; sparrow wires them into a ReAct loop with citations, three-tier memory, and a restricted-expression engine for safe computed panels. Stdlib-only core, zero heavy dependencies — no LangChain, no LangGraph.
Why sparrow
Most agent frameworks are big. sparrow is the opposite: a single readable package you can fully understand in an afternoon, yet it has all the organs of a real agent:
- ReAct tool loop — the model decides what it needs; deterministic code decides how to get it.
- Tool injection — the engine assumes nothing about your domain. You inject plain functions as tools; finance, news, weather — all the same engine.
- Three-tier memory — conversations, materialized panels, and an append-only journal, all in one SQLite file, physically isolated from your business data.
- LLM emits declarations, not code — even custom panel columns are a restricted expression (AST allowlist: field names + numbers + arithmetic), so the model can compose derived metrics but never run arbitrary code.
- Citations by construction — every tool result carries a
source; final answers collect them automatically.
Install
pip install sparrow-agent # import name is `sparrow`
The core engine is stdlib-only. Point it at any OpenAI-compatible endpoint
(DeepSeek by default) via env or configure():
export SPARROW_LLM_API_KEY=sk-...
export SPARROW_LLM_BASE_URL=https://api.deepseek.com # optional
export SPARROW_LLM_MODEL=deepseek-chat # optional
Quickstart
from sparrow import tool, AgentConfig, Harness
@tool(description="Get current weather", source="demo-weather")
def get_weather(city: str) -> dict:
return {"city": city, "weather": "sunny, 24°C"}
config = AgentConfig(
system_prompt="You are a weather assistant. Always call a tool; never invent weather.",
tools=[get_weather],
)
for event in Harness(config).run([{"role": "user", "content": "Weather in Beijing?"}]):
print(event) # tool_call / tool_result / final / error
See examples/weather_agent.py for a full run.
Memory & panels (optional)
For dashboard-style apps, sparrow ships "panel as memory": the agent can persist a conversation insight as a live, declarative panel.
from sparrow import Memory, AgentConfig, panel_tools
mem = Memory("ui.db", transforms={"count": lambda d: {"value": len(next(iter(d.values()), []))}})
config = AgentConfig(
system_prompt="...",
tools=[*my_query_tools, *panel_tools(mem)], # adds create/archive/list_panels
recall_provider=mem.journal_summary_for_prompt, # inject episodic recall
)
Panels store recipes (a tool + transform/columns), not snapshots, so they recompute from live data every time. Custom table columns use the restricted expression engine:
{"title": "Market Value", "expr": "current_price * shares"} # safe
{"title": "x", "expr": "__import__('os')"} # rejected
Design principles
- LLM decides what, deterministic code decides how. The model only ever emits declarations (which tool, which transform, which column expression); real execution is plain Python. This prevents hallucinated data and confines the model to a read-only, validated surface.
- Read/write separation. Query tools read your business data; write tools only touch the agent's own memory db. The LLM can shape presentation, never the underlying truth.
- Memory covers every actor. The journal records what the user did, what the agent did, and what the system did — so the agent's worldview is complete.
Status
v0.1 — extracted from two production agents (a quant-trading assistant and an
AI-frontier tracker) and generalized. API may still move before 1.0.
MIT licensed.
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 sparrow_agent-0.2.0.tar.gz.
File metadata
- Download URL: sparrow_agent-0.2.0.tar.gz
- Upload date:
- Size: 29.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b1a518c86c9fda738fce5acbfa14a71957b2d30a069d4fc689ee891cce3ebd7
|
|
| MD5 |
6c04e825f2b010b6f51a263ce0b22eaa
|
|
| BLAKE2b-256 |
7c660538a2a95797a1a9a9844aee3ee909e13c04123330de6e0b276fea2ffdcb
|
Provenance
The following attestation bundles were made for sparrow_agent-0.2.0.tar.gz:
Publisher:
release.yml on nikefd/sparrow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sparrow_agent-0.2.0.tar.gz -
Subject digest:
0b1a518c86c9fda738fce5acbfa14a71957b2d30a069d4fc689ee891cce3ebd7 - Sigstore transparency entry: 1866904144
- Sigstore integration time:
-
Permalink:
nikefd/sparrow@751fa0f7ba96affceb6621f87b1fa6138ab3d24d -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/nikefd
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@751fa0f7ba96affceb6621f87b1fa6138ab3d24d -
Trigger Event:
push
-
Statement type:
File details
Details for the file sparrow_agent-0.2.0-py3-none-any.whl.
File metadata
- Download URL: sparrow_agent-0.2.0-py3-none-any.whl
- Upload date:
- Size: 26.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d436d14d072742b60d83546cd75906e6ec102280e15dfdde0a67150a96ca1b9
|
|
| MD5 |
212e691dd921252c9d22e383ec55ddf3
|
|
| BLAKE2b-256 |
603c72901fa82548c1beff05e7bd6b4fb3188306c8edcc55ee69f41e765196cc
|
Provenance
The following attestation bundles were made for sparrow_agent-0.2.0-py3-none-any.whl:
Publisher:
release.yml on nikefd/sparrow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sparrow_agent-0.2.0-py3-none-any.whl -
Subject digest:
1d436d14d072742b60d83546cd75906e6ec102280e15dfdde0a67150a96ca1b9 - Sigstore transparency entry: 1866904163
- Sigstore integration time:
-
Permalink:
nikefd/sparrow@751fa0f7ba96affceb6621f87b1fa6138ab3d24d -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/nikefd
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@751fa0f7ba96affceb6621f87b1fa6138ab3d24d -
Trigger Event:
push
-
Statement type: