Physarum Intelligence Network Python SDK — MCP tool routing, model selection, and cost optimization
Project description
physarum-sdk
Python SDK for the Physarum Intelligence Network — real-time MCP tool routing, model selection, and cost optimization powered by network-wide telemetry and Physarum-inspired conductivity algorithms.
What it does
- Routes tool calls to the best-performing implementation based on live success rates, latency, and quality signals collected across all tenants
- Tracks every tool execution with zero-overhead telemetry batching
- Works with any Python AI framework — LangChain, LlamaIndex, raw OpenAI/Anthropic calls
- Fails open — if the API is unavailable, falls back to your configured static priorities
Installation
pip install physarum-sdk
Quick start
from physarum import PhysarumClient, PhysarumConfig
client = PhysarumClient(PhysarumConfig(
api_key=os.environ["PHYSARUM_API_KEY"],
tenant_id=os.environ["PHYSARUM_TENANT_ID"],
ingestion_base_url="https://api.physarum.network",
recommendation_base_url="https://api.physarum.network",
mode="SHADOW", # Start with SHADOW, graduate to CONTROLLED
))
# Ask Physarum which tool to use
from physarum.types import RouteRequest
decision = client.select_tool(RouteRequest(
task_category="payment_flow",
candidate_tools=["stripe", "paypal", "razorpay"],
action_class="SIDE_EFFECT_CRITICAL",
))
print(decision["selected_tool"]) # e.g. "stripe"
print(decision["reason"]) # "controlled_mode" | "shadow_mode" | ...
client.shutdown()
Operating modes
| Mode | Behaviour |
|---|---|
SHADOW |
Observes only. Records telemetry but never changes which tool is called. Zero risk, full learning. |
ADVISORY |
Calls the recommendation API and logs the suggestion but still runs your default tool. |
CONTROLLED |
Physarum selects the tool. The network's best recommendation is used for every call. |
Start with SHADOW to accumulate signal, then graduate to CONTROLLED once you trust the data.
Manual tool wrapping
Wrap any function call to automatically record success, latency, and error telemetry:
from physarum.types import WrapToolCallInput
outcome = client.wrap_tool_call(WrapToolCallInput(
tool_id="stripe",
tool_name="stripe",
task_category="payment_flow",
action_class="SIDE_EFFECT_CRITICAL",
session_id_hash="hashed-session-id",
execute=lambda: stripe.charge(amount=9900, currency="usd"),
))
print(outcome.result) # whatever stripe.charge returned
print(outcome.telemetry) # full telemetry dict, already flushed to Physarum
LangChain integration
from langchain.tools import StructuredTool
from physarum.types import WrapToolCallInput
def make_physarum_tool(client, name, description, func, task_category, action_class):
def wrapped(**kwargs):
outcome = client.wrap_tool_call(WrapToolCallInput(
tool_id=name,
tool_name=name,
task_category=task_category,
action_class=action_class,
session_id_hash="your-session-hash",
execute=lambda: func(**kwargs),
))
return outcome.result
return StructuredTool.from_function(
func=wrapped,
name=name,
description=description,
)
search_tool = make_physarum_tool(
client,
name="search_products",
description="Search the product catalogue",
func=search_products_api,
task_category="product_search",
action_class="READ_ONLY",
)
Context enrichment
Pass context to improve routing accuracy. Physarum learns per-country, per-domain, and per-locale performance:
from physarum.types import RouteRequest, ContextInput
decision = client.select_tool(RouteRequest(
task_category="payment_flow",
candidate_tools=["stripe", "razorpay"],
action_class="SIDE_EFFECT_CRITICAL",
context=ContextInput(
country_code="IN", # India — Razorpay likely performs better
domain="e-commerce",
locale="en-IN",
model_id="claude-sonnet-4-6",
time_of_day_utc="14:30",
),
))
Model routing
from physarum.types import ModelRouteRequest
result = client.get_model_routes(ModelRouteRequest(
task_category="code_debug",
candidate_models=["claude-opus-4-6", "claude-sonnet-4-6", "gpt-4o"],
))
best_model = result.recommendations[0]["model_id"]
Cost optimization
from physarum.types import CostOptimizeRequest
result = client.get_cost_optimized_path(CostOptimizeRequest(
task_category="document_summarization",
candidate_tools=["gpt-4o", "claude-sonnet-4-6", "gemini-flash"],
quality_floor=0.8, # minimum acceptable quality score
budget_tokens=50_000, # max tokens to spend
))
MCP server discovery
# Get all MCP servers registered on the network
servers = client.get_mcp_servers()
# Filter by task category
payment_servers = client.get_mcp_servers(task_category="payment_flow")
Static fallback priorities
Configure a deterministic fallback order used when the recommendation API is unavailable:
client = PhysarumClient(PhysarumConfig(
# ...
local_static_priorities=["stripe", "paypal", "razorpay"],
local_static_priorities_by_task_category={
"payment_flow_india": ["razorpay", "stripe"],
},
))
Configuration reference
from physarum import PhysarumConfig
config = PhysarumConfig(
api_key="...",
tenant_id="...",
ingestion_base_url="https://api.physarum.network",
recommendation_base_url="https://api.physarum.network",
mode="SHADOW", # "SHADOW" | "ADVISORY" | "CONTROLLED"
request_timeout_ms=5000, # default: 5000
telemetry_batch_size=50, # events per flush, default: 50
telemetry_flush_interval_ms=2000, # default: 2000ms
local_static_priorities=[], # fallback tool order
local_static_priorities_by_task_category={},
)
Action classes
| Value | Use when |
|---|---|
READ_ONLY |
Tool only reads data — search, lookup, fetch |
IDEMPOTENT_WRITE |
Safe to retry — upsert, idempotent create |
SIDE_EFFECT_CRITICAL |
Must not be retried blindly — payment, email send, webhook |
Shutdown
Always call shutdown() before your process exits to flush buffered telemetry:
import atexit
atexit.register(client.shutdown)
Or use as a context manager pattern:
try:
result = client.wrap_tool_call(...)
finally:
client.shutdown()
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 physarum_sdk-0.2.0.tar.gz.
File metadata
- Download URL: physarum_sdk-0.2.0.tar.gz
- Upload date:
- Size: 10.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9b3587d186f47a557b8b8786a2dd8856dbe5ba40e0b8e562886b7045ac7f18b
|
|
| MD5 |
2006baa988e03c5ebd66c7fbb342ccf8
|
|
| BLAKE2b-256 |
26bb35062f3b8dbcfcd5b8aa5710ca90c3cb378a64f173816f80a670b2c57073
|
File details
Details for the file physarum_sdk-0.2.0-py3-none-any.whl.
File metadata
- Download URL: physarum_sdk-0.2.0-py3-none-any.whl
- Upload date:
- Size: 9.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5854a2a5782f226312c7341211b878f8cf88f96f4aa444caa262dc1cf7e86895
|
|
| MD5 |
4b177c3ed76de65bc1a3e2144c8b113c
|
|
| BLAKE2b-256 |
7c5594a8111457764cb73b0f77e07c46037f688a88ec27fad5eb8be1b5e58921
|