A lightweight multi-agent framework with ReAct reasoning, tool dispatch, and MCP integration
Project description
SimAgentPlg
A lightweight multi-agent framework with ReAct reasoning, tool dispatch, and MCP integration.
Features
- ReAct Agent — ReAct (Reasoning + Acting) loop with multi-turn tool calling
- Chat Agent — simple conversational agent with multi-turn history support
- Tool Dispatch — convention-over-configuration: define
do_{tool_name}methods, auto-routed via reflection - MCP Integration — pluggable MCP server manager for external tool providers
- Skill System — skill-based prompt injection for domain-specific behaviors
- Built-in Bash Executor — async sandboxed bash execution with timeout, output truncation, and blacklist filtering
- Stateless Execution — each
runtime()call starts with a clean context; history is caller-managed - OpenAI-compatible — works with any OpenAI-compatible API (DeepSeek, etc.)
Installation
pip install simagentplg
Or with uv:
uv pip install simagentplg
Quick Start
Set up your environment variables (.env):
CHAT_MODEL=deepseek-chat
MODEL_API_KEY=sk-xxxxxxxx
MODEL_URL=https://api.deepseek.com
LLM_TIMEOUT=30
Chat Agent
from simagentplg import ChatLoop
loop = ChatLoop()
result = await loop.runtime(task="介绍一下你自己")
# With multi-turn history
history = [
{"role": "user", "content": "今天天气不错"},
{"role": "assistant", "content": "是啊,适合出去走走"},
]
result = await loop.runtime(task="我们去哪", history=history)
ReAct Agent
from simagentplg import ReactLoop
loop = ReactLoop()
result = await loop.runtime(task="帮我写一个Python脚本打印当前时间")
The ReAct agent supports built-in tools (like bash_run) and any MCP tools configured in mcp_config.json.
MCP Configuration
Place an mcp_config.json alongside your ReactLoop:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-playwright"]
}
}
}
Architecture
LLMConfig (BaseHandler, ABC)
├── ChatLoop — stateless conversational agent
├── ReactLoop — ReAct reasoning + tool dispatch
│ ├── MCP tools — external tools via MCP protocol
│ ├── Skill system — domain-specific prompt injection
│ └── Local tools — built-in bash_run, extensible
└── (future) PlanLoop / ExecuteLoop
Tool Dispatch Flow
LLM calls "bash_run"
→ BaseHandler.dispatch("bash_run", args)
→ hasattr(self, "do_bash_run")? YES
→ await self.do_bash_run(args) ← local tool
→ NO
→ "未知工具" → MCP fallback ← external tool
Adding a Local Tool
- Define the tool schema in
tool_schema.py:
LOCAL_TOOLS = [
{
"type": "function",
"function": {
"name": "calculator",
"description": "Evaluate a math expression",
"parameters": {
"type": "object",
"properties": {
"expression": {"type": "string", "description": "Math expression"}
},
"required": ["expression"]
}
}
}
]
- Add the
do_calculatormethod inLLMConfig:
async def do_calculator(self, args: dict) -> StepOutcome:
result = eval(args["expression"])
return StepOutcome(data=result, next_prompt="\n")
All agents automatically inherit the new tool.
API
ChatLoop
loop = ChatLoop(temperature=0.7)
await loop.runtime(*, task, system_prompt=None, history=None) -> str | None
ReactLoop
loop = ReactLoop()
await loop.runtime(*, task, system_prompt=None, history=None) -> str | None
StepOutcome
@dataclass
class StepOutcome:
data: Any # tool return value
next_prompt: str | None # None = task complete
should_exit: bool # True = force exit
Requirements
- Python >= 3.12
- fastmcp >= 3.4.2
- openai >= 2.41.0
- python-dotenv >= 1.2.2
License
MIT
Project details
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 simagentplg-0.1.1.tar.gz.
File metadata
- Download URL: simagentplg-0.1.1.tar.gz
- Upload date:
- Size: 81.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d4b68ba34a4fce7049db4434c6b8f3f67e1454052363ec4f0253c3f07722974c
|
|
| MD5 |
fa1d6b762357a1ffea5c44990a9e4277
|
|
| BLAKE2b-256 |
2ef3036e0d0e2ac3c7c7f91ad87021268485c7147297895ce7497283cb730ea9
|
File details
Details for the file simagentplg-0.1.1-py3-none-any.whl.
File metadata
- Download URL: simagentplg-0.1.1-py3-none-any.whl
- Upload date:
- Size: 19.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7dcbfd1078694c3797784eb57a6a67bb85c334be707a57499aba5bbb49e371f6
|
|
| MD5 |
8a66117ae22c0764026d94d6b282624c
|
|
| BLAKE2b-256 |
9d7839c1cb41eed24dc0405ade51b7484b48dc6eb50bc32040700dba0125a372
|