snowland-agent-core
Framework-agnostic agent engine shared by the snowland-aitool cloud web service and the local IDE MCP server.
This package contains the agent engine (AiderCore) and a lightweight
multi-agent orchestration layer (snowland_agent_core.orchestration). Framework-
specific concerns (configuration, persistence, credential lookup, audit logging)
are supplied through dependency-injected ports, so the engine also runs under a
plain CLI or inside unit tests with in-memory adapters. The orchestration layer
is built on LangGraph (langgraph.graph).
Features
- Ports & Adapters.
AiderCoretalks to abstract protocols (CredentialRepo,SessionRepo,InvocationLog). Concrete implementations are injected by the host (Django adapter or in-memory test doubles). - Single-agent engine.
AiderCore.chat(...)runs one aider turn with conversation persistence, skill injection, and tool-result plumbing. - Multi-agent orchestration.
AgentUnit/AgentRegistry/Router/Pipeline/Teamcompose agents. TheTeamcoordinator is built on a LangGraphStateGraphwith amax_stepscap. - Safety gates. Input prompt-injection checks (
check_input) and output secret-leak scans (check_output) wrap every run; the orchestration layer never bypasses the engine's gates. - Graph visualization.
Team.draw_mermaid()/export_graph_mermaid()render the LangGraphStateGraphvia LangGraph's native Mermaid export; the dependency-freeteam_to_mermaid()renderer provides the same Mermaid flowchart without importing LangGraph.
Architecture: three-repo topology
snowland-aitool-core/ # THIS repo — engine + orchestration
snowland_agent_core/
core/ # AiderCore, SessionManager, ports, config, safety, ...
orchestration/ # AgentUnit, Registry, Router, Pipeline, Team, ...
snowland-django-agent/ # Django adapter — implements the ports, reads settings
snowland_django_agent/
django_adapter/ # build_config(), get_core(), get_team(), repos
models.py / auth.py / views.py / ...
snowland-aitool/ # Host — Django web service + MCP server
mcp_server/server.py # bridges MCP tools to the Django adapter
aitool/settings.py # TEAM_DEFAULT_MAX_STEPS and other tunables
The engine is the single source of truth for execution and safety. The Django adapter and the MCP server are adapters that call into this package; they do not reimplement agent logic.
Installation
# Engine only (used by the cloud web service)
pip install .
# With the optional MCP extras (standalone MCP server)
pip install ".[mcp]"
Runtime dependencies: aider-chat, langgraph. The mcp extra adds
mcp, pydantic, anyio, uvicorn.
Package layout
snowland_agent_core/
__init__.py # __version__, VERSION
base/ # 与领域无关的抽象层:不依赖 Django / aider / 任何 LLM SDK
__init__.py # 公共 base API(BaseAgent / SkillRegistry / ContextManager / Verifier / Sandbox ...)
agent.py # BaseAgent / AgentResult / AgentCapability
ports.py # CredentialRepo / SessionRepo / InvocationLog protocols
context.py # ContextManager / MemoryStore / DictMemory
safety.py # check_input / check_output / check_command / safe_path
sandbox.py # Sandbox(路径与命令隔离)
verifier.py # Verifier(死循环护栏)
skill.py # Skill / SkillRegistry / SkillProvider
tools.py # ToolResult / ToolRegistry + 已注册的本地 hand 工具
utils.py # base 内部辅助函数(glob 匹配、纯 Python diff 应用等)
core/
__init__.py # public engine API
aider_core.py # AiderCore engine (wraps aider-chat)
session.py # SessionManager (caches per-session cores)
config.py # CoreConfig + default_config()
executor.py # bounded execution + error classification
planner.py # planning helper
toolcall.py # tool-result plumbing
capture_io.py # aider IO capture (pure, aider-only)
prompts.py # prompt templates (pure)
inmemory.py # in-memory port implementations + make_inmemory_core()
subagent.py # sub-agent execution helper
ports.py / safety.py / sandbox.py / context.py / verifier.py # 转发 shim,指向 base 对应模块(向后兼容旧导入路径)
orchestration/
__init__.py # public orchestration API
config.py # OrchestrationConfig
unit.py # AgentInput / AgentOutput / AgentUnit / AiderAgentUnit
registry.py # AgentRegistry (role name -> AgentUnit)
router.py # Router / RouteDecision / KeywordRouter / LLMRouter
pipeline.py # Pipeline (sequential AgentUnit composition)
team.py # Team coordinator (LangGraph StateGraph) + TeamResult + build_default_team()
visualization.py # team_to_mermaid / export_mermaid (no LangGraph import)
Quick start
Single agent
make_inmemory_core wires the engine with trivial in-memory ports so it can
run without a Django project (tests, CLI experiments):
from snowland_agent_core.core.inmemory import make_inmemory_core
core = make_inmemory_core("demo", workspace="/tmp/work")
result = core.chat("Refactor utils.py to use pathlib instead of os.path")
print(result["reply"])
print("edited:", result.get("edited_files"))
AiderCore.chat(message, context=None, skills=None, tool_results=None) returns
a dict with reply, edited_files, output, safety_warnings, and
gating flags (refused / terminated) when the safety gates fire.
Custom LLM endpoint (OpenAI-compatible vendors)
AiderCore routes requests through litellm. For OpenAI-compatible vendors
(zhipu / deepseek / moonshot / qwen / hunyuan) the model id is passed as-is
and custom_llm_provider is pinned to openai; the real host is selected by
api_base. Always pass api_base — an empty api_base makes litellm fall
back to https://api.openai.com/v1 and silently mis-route a zhipu call to
OpenAI. make_core_kwargs() (tests) and make_inmemory_core() forward
api_base to AiderCore.
core = make_inmemory_core(
"demo",
provider="zhipu",
model="glm-4.7-flash",
api_base="https://open.bigmodel.cn/api/paas/v4/",
api_key="<your-key>",
workspace="/tmp/work",
)
Multi-agent team
from snowland_agent_core.core.inmemory import make_inmemory_core
from snowland_agent_core.orchestration import build_default_team
# build_default_team accepts a make_core(session_id, **kwargs) -> AiderCore factory.
team = build_default_team(make_inmemory_core)
result = team.run("Implement a retry decorator with exponential backoff")
print(result.reply)
print("trace:", [step.role for step in result.trace])
The default team registers crafter, asker, and planner units plus an
implement pipeline (planner -> crafter), and routes the task with a
KeywordRouter. Set OrchestrationConfig(default_router="llm") and pass a
supervisor make_supervisor_core factory to use an LLMRouter instead.
Public API surface
Engine (snowland_agent_core.core):
AiderCore— the single-agent engine.SessionManager— caches per-sessionAiderCoreinstances.CoreConfig/default_config()— engine configuration.CredentialRepo,SessionRepo,InvocationLog— injection ports.make_inmemory_core()/make_inmemory_manager()— in-memory wiring.
Orchestration (snowland_agent_core.orchestration):
AgentInput,AgentOutput,AgentUnit,AiderAgentUnit.AgentRegistry,Router,RouteDecision,KeywordRouter,LLMRouter.Pipeline,Team,TeamResult,TeamTraceStep,build_default_team().OrchestrationConfig,team_to_mermaid(),export_mermaid().
Development & testing
# Run the test suite (standard-library unittest only; no pytest required)
python -m unittest discover -s test -t .
# Build the distribution
python -m build
License
BSD-3-Clause. See LICENSE.
Metadata
Release files for snowland-agent-core 0.2.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 |
|---|---|---|---|---|
| snowland_agent_core-0.2.0.tar.gz | 82.8 kB | Without provenance | Details for snowland_agent_core-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| snowland_agent_core-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for snowland_agent_core-0.2.0-py3-none-any.whl |
Total release size: 175.5 kB
Release files / snowland_agent_core-0.2.0.tar.gz
| Download URL | snowland_agent_core-0.2.0.tar.gz |
|---|---|
| Size | 82.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fca124b83d70f454cfe8808ee8e71cf437c1f2a34770842d00aa4a15887c2cd4
|
|
BLAKE2b-256 checksum How to use checksums |
678c5ebea8e951bd06a61348bf20590b7b0d4fea8424b592eeee96dd4823ab2d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / snowland_agent_core-0.2.0-py3-none-any.whl
| Download URL | snowland_agent_core-0.2.0-py3-none-any.whl |
|---|---|
| Size | 92.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
418920525a2fcaae1ac5bc47b4e0dd1c7de867224a6832ee8a45311e5a58e617
|
|
BLAKE2b-256 checksum How to use checksums |
0a71a08ad07804d4addd72abc0e80b4e8345fab2651b368cc1fb202e97480e32
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Security for snowland-agent-core 0.2.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.