✨ Features
- 🎯 Minimalist - Clean design, only 12 core modules
- 📊 Stack-based Trace - Auto-track multi-agent interactions
- ⚡ Async-first - Full async I/O, concurrent tool execution
- 🔄 Auto-failover - ChaterPool switches models automatically
- 🧠 A-MEM - Self-evolving memory (arXiv:2502.12110)
- 🤖 ReAct - Complete reasoning-action loop
- 🛠️ MCP - Native Model Context Protocol support
- 🌐 Multi-agent - MsgHub broadcast, Pipeline orchestration
- 🔀 Flow - Lightweight workflow with loops, branches, parallel execution
🚀 Quick Start
import asyncio
from qagent import Agent, Memory, Chater, Runner, get_chater_cfg
agent = Agent(
name="Assistant",
chater=Chater(get_chater_cfg("ali")),
memory=Memory(),
system_prompt="You are helpful."
)
async def main():
result = await Runner.run(agent, "Hello!")
print(result.content)
asyncio.run(main())
Multi-Agent with Trace
from qagent import trace, Runner, Agent, Chater, Memory, get_chater_cfg
planner = Agent(name="Planner", chater=Chater(get_chater_cfg("ali")), memory=Memory())
executor = Agent(name="Executor", chater=Chater(get_chater_cfg("ali")), memory=Memory())
async def main():
with trace("workflow"):
result = await Runner.run_sequential(
[planner, executor],
"Plan and execute"
)
asyncio.run(main())
Flow Workflow
from qagent import Flow, END, Agent, Chater, Memory, get_chater_cfg
writer = Agent(name="Writer", chater=Chater(get_chater_cfg("ali")), memory=Memory())
reviewer = Agent(name="Reviewer", chater=Chater(get_chater_cfg("ali")), memory=Memory())
flow = Flow("write_review").add("write", writer).add("review", reviewer).max_loops(3)
flow.route("write").to("review")
flow.route("review").when(lambda r: "APPROVED" in r.content).to(END).default().to("write")
result = await flow.reply("Write a haiku about coding")
📐 Architecture
graph TB
subgraph Application["Application Layer"]
ReActAgent[ReActAgent]
AgenticMem[AgenticMemoryAgent]
CustomAgent[Custom Agents]
end
subgraph Core["Core Layer"]
Agent[Agent]
Runner[Runner]
Trace[Trace System]
end
subgraph Model["Model Layer"]
ChaterPool[ChaterPool]
Chater1[Model 1]
Chater2[Model 2]
ChaterN[Model N]
ChaterPool -->|auto switch| Chater1
ChaterPool -->|on failure| Chater2
ChaterPool -.->|backup| ChaterN
end
subgraph Tools["Tool Layer"]
ToolKit[ToolKit]
PythonFunc[Python Functions]
MCPTools[MCP Tools]
ToolKit --> PythonFunc
ToolKit --> MCPTools
end
subgraph Storage["Storage Layer"]
Memory[Memory]
VectorStore[VectorStore]
end
subgraph Orchestration["Orchestration Layer"]
MsgHub[MsgHub]
Pipeline[Pipeline]
FlowSystem[Flow]
end
ReActAgent --> Agent
AgenticMem --> Agent
CustomAgent --> Agent
Agent --> Runner
Agent --> ChaterPool
Agent --> ToolKit
Agent --> Memory
Runner --> Trace
AgenticMem --> VectorStore
MsgHub -.-> Agent
Pipeline -.-> Agent
FlowSystem -.-> Agent
style Trace fill:#e1f5ff
style Runner fill:#fff4e6
style ChaterPool fill:#99ccff
style MsgHub fill:#99ff99
style FlowSystem fill:#ffccff
Features:
- ✅ Stack-based - Auto parent-child management
- ✅ Concurrent-safe - contextvars isolation
- ✅ Zero-overhead - Fully disabled without trace
- ✅ Minimal data - Agent span: type/agent_id/input/output only
- ✅ Complete tracking - Generation/Tool/Custom spans
🔀 Flow System
Lightweight workflow with Agent-native interface:
from qagent import Flow, END, Agent, Chater, Memory, get_chater_cfg
planner = Agent(name="Planner", chater=Chater(get_chater_cfg("ali")), memory=Memory())
executor = Agent(name="Executor", chater=Chater(get_chater_cfg("ali")), memory=Memory())
reviewer = Agent(name="Reviewer", chater=Chater(get_chater_cfg("ali")), memory=Memory())
flow = Flow("plan_execute_review")
flow.add("plan", planner)
flow.add("execute", executor)
flow.add("review", reviewer)
flow.route("plan").to("execute")
flow.route("execute").to("review")
flow.route("review").when(lambda r: "APPROVED" in r.content).to(END).default().to("plan")
result = await flow.reply("Build a web app")
Loop Pattern
flow = Flow("review_loop").add("write", writer).add("review", reviewer).max_loops(5)
flow.route("write").to("review")
flow.route("review").when(lambda r: "APPROVED" in r.content).to(END).default().to("write")
Parallel Execution
flow = Flow("parallel").parallel("experts", [tech, biz, legal]).add("summarize", summarizer)
flow.route("experts").to("summarize")
Chain Helper
from qagent import chain
flow = chain(agent_a, agent_b, agent_c)
result = await flow.reply("Start")
🙏 Acknowledgments
Inspired by:
- OpenAI Agents SDK - Trace system, Runner pattern
- AgentScope - Hook decorators, MsgHub
📄 License
MIT License
Metadata
Release files for qagent 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| qagent-0.1.0.tar.gz | 1.4 MB | Without provenance | Details for qagent-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| qagent-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for qagent-0.1.0-py3-none-any.whl |
Total release size: 1.5 MB
Release files / qagent-0.1.0.tar.gz
| Download URL | qagent-0.1.0.tar.gz |
|---|---|
| Size | 1.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
11612ce17e53ae70884c2ceb9e9eef7302c0e36ddb711ed7c5f833a7ac511f4f
|
|
BLAKE2b-256 checksum How to use checksums |
fe99c57dfa669c1562ed84290eba60fe10034e65a82500029f1d8ceea05eb895
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / qagent-0.1.0-py3-none-any.whl
| Download URL | qagent-0.1.0-py3-none-any.whl |
|---|---|
| Size | 85.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9e58d40dd7c8ca6596334cab796cdeb73a75da8db055c4b1ae8f14812ff8b091
|
|
BLAKE2b-256 checksum How to use checksums |
7578785ef010ea9884b0a679cf46f787ab5c9e297a6ea89d9af27eebdf7996aa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Security for qagent 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.