from supplygraphai_a2a_sdk import AgentClient
client = AgentClient(
api_key="YOUR_API_KEY",
base_url="https://agent.supplygraph.ai/api/v1/agents"
)from supplygraphai_a2a_sdk import USTariffCalculationAgent
agent = USTariffCalculationAgent(client)
resp = agent.run("Importing 100kg of ice cream from China")
print(resp)Every agent response follows this envelope:
{
"success": true,
"code": "WAITING_USER",
"message": "Please provide the country of origin.",
"data": {
"task_id": "tsk_xxx",
"stage": "interpreting",
"code": "WAITING_USER",
"content": "Please specify the country."
}
}Developer essentials:
code→ Primary state (WAITING_USER,TASK_ACCEPTED,TASK_RUNNING,TASK_COMPLETED, etc.)data.task_id→ Used to continue the same taskdata.content→ Response content (text or structured JSON)message→ Always safe to show to user
A2A tasks often require:
- Initial run
- Agent requests more info (
WAITING_USER) - Continue with
task_id - Agent accepts task (
TASK_ACCEPTED) - Task runs (
TASK_RUNNING) - Complete (
TASK_COMPLETED) → callresults()
Here is the full recommended implementation:
resp = agent.run("Import 100kg ice cream")
task_id = resp["data"]["task_id"]
code = resp["code"]
while True:
# --- Interpreting Stage ---
if code == "WAITING_USER":
print(resp["message"])
user_reply = input("> ")
resp = agent.run(text=user_reply, task_id=task_id)
code = resp["code"]
continue
if code == "INVALID_REQUEST":
print("Invalid:", resp["message"])
break
if code == "UNAUTHORIZED":
print("API key invalid.")
break
# --- Executing Stage ---
if code == "TASK_ACCEPTED":
resp = agent.status(task_id)
code = resp["code"]
continue
if code == "TASK_RUNNING":
import time; time.sleep(1)
resp = agent.status(task_id)
code = resp["code"]
continue
# --- Completed Stage ---
if code == "TASK_COMPLETED":
result = agent.results(task_id)
print("Final:", result["data"]["content"])
break
if code == "TASK_FAILED":
print("Task failed:", resp["message"])
breakcontent = resp["data"]["content"]
if isinstance(content, str):
print("Text:", content)
elif isinstance(content, dict) and content.get("type") == "result":
print("Structured:", content["data"])SSE frames:
{
"event": "stream",
"data": {
"code": "THINKING",
"reasoning": ["..."]
}
}Developer usage:
events = agent.run("Import 100kg citrus", stream=True)
for ev in events:
for r in ev["data"]["reasoning"]:
print("> ", r)manifest = client.manifest("tariff_classification")
print(manifest["pricing"])
print(manifest["input_schema"])from supplygraphai_a2a_sdk.client.base_agent import BaseAgent
class MyCustomAgent(BaseAgent):
def __init__(self, client):
super().__init__(client, agent_id="my_custom_agent")
agent = MyCustomAgent(client)
print(agent.run("Hello"))The SDK includes first-class adapters for popular agent and tooling ecosystems. These adapters are optional and only needed when you integrate with a specific framework.
Supported ecosystems include (non-exhaustive):
- Google A2A
- AutoGen
- LangChain
- LangGraph
- Semantic Kernel
- CrewAI
- DSPy
- Flowise
- LlamaIndex
- MCP (ChatGPT, Cursor, Zed, etc.)
- BentoML
- Haystack
- Airflow
Each adapter:
- Wraps a SupplyGraph A2A Agent as a native tool / node / skill / runner
- Has no hard dependency inside the SDK (you install the framework in your own project)
- Uses the same A2A lifecycle:
run → status → resultswithtask_idand streaming support
Adapter-specific usage examples and best practices are provided in the dedicated docs
(e.g. docs/adapters/langgraph_adapter.md, docs/adapters/crewai_adapter.md, etc.).
Explore more about the SupplyGraph AI ecosystem:
📘 Getting Started Guide
https://github.com/SupplyGraphAI/supplygraph-ai/blob/main/docs/getting-started.md
🤖 Agent Specifications & Library
https://github.com/SupplyGraphAI/supplygraph-ai/tree/main/docs/agents
🧠 SupplyGraph AI Documentation Hub
https://github.com/SupplyGraphAI/supplygraph-ai
📦 Python A2A SDK (Official Repository)
https://github.com/SupplyGraphAI/supplygraphai_a2a_sdk
🌐 Official Website & Use Cases
https://www.supplygraph.ai