Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions agents-sdk/templates/python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# AgentForge Python Agent Templates (LangGraph)

These templates provide LangGraph-powered agent workflows for all 6 AgentForge agent types.

## Prerequisites

```bash
pip install -r requirements.txt
```

Set environment variables in `.env`:
```
AGENTFORGE_API_URL=http://localhost:3000
OPENAI_API_KEY=your_key
ANTHROPIC_API_KEY=your_key
STELLAR_AGENT_SECRET=your_secret
ABLY_API_KEY=your_key
```

## Agents

| Template | Agent | Description |
|----------|-------|-------------|
| `mev_bot_agent.py` | MEV Bot | Front-running & sandwich detection |
| `arbitrage_tracker_agent.py` | Arbitrage Tracker | Triangular cross-path arbitrage |
| `trading_bot_agent.py` | Trading Bot | Grid, DCA, trend strategies |
| `mempool_monitor_agent.py` | Mempool Monitor | Real-time transaction stream analysis |
| `relayer_agent.py` | Relayer | Fee-bump relay with 0x402 charging |
| `liquidity_tracker_agent.py` | Liquidity Tracker | Order-book depth & slippage simulation |

## Multi-Agent (A2A) Example

```python
from base_agent import build_a2a_graph

# Chain MEV Bot → Trading Bot
app = build_a2a_graph(
agent1_id="mev_bot",
agent2_id="trading_bot",
system_prompt1="MEV detection prompt...",
system_prompt2="Trading execution prompt...",
)
result = app.invoke({"input": "Find and execute best MEV opportunity", ...})
```

## 0x402 Payment Flow

When an agent requires payment:
1. First call returns `payment_required=True` with `payment_amount` and `payment_address`
2. Use `stellar-sdk` to submit XLM payment to `payment_address`
3. Retry with `tx_hash` set to the transaction hash

## CLI Integration

```bash
agentforge agents run mev_bot --input "scan for opportunities" --secret $STELLAR_SECRET
agentforge a2a call mev_bot trading_bot --input "find and execute MEV" --secret $STELLAR_SECRET
```
31 changes: 31 additions & 0 deletions agents-sdk/templates/python/arbitrage_tracker_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""
AgentForge LangGraph Template — Arbitrage Tracker Agent
Triangular & cross-path arbitrage across Stellar DEX.
"""
import json
from base_agent import build_single_agent_graph, AgentState

SYSTEM_PROMPT = """You are an arbitrage tracking agent for the Stellar DEX.
Your tasks:
1. Monitor triangular arbitrage opportunities across XLM, USDC, BTC, ETH pairs
2. Calculate profit margins after transaction fees and slippage
3. Identify optimal arbitrage paths with lowest risk
4. Track historical arbitrage performance and success rates
5. Alert on opportunities above 0.5% profit threshold

Provide structured analysis with: pair paths, expected profit %, execution risk, and recommended action.
"""

def run_arbitrage_tracker(input_prompt: str, wallet_address: str = "", tx_hash: str = None):
app = build_single_agent_graph(agent_id="arb_tracker", system_prompt=SYSTEM_PROMPT)
state: AgentState = {
"input": input_prompt, "output": "", "agent_id": "arb_tracker",
"wallet_address": wallet_address, "tx_hash": tx_hash,
"payment_required": False, "payment_amount": 0.0, "payment_address": "",
"error": None, "steps": [],
}
return app.invoke(state)

if __name__ == "__main__":
result = run_arbitrage_tracker("Find arbitrage opportunities for XLM/USDC/BTC triangle")
print(json.dumps(result, indent=2))
164 changes: 164 additions & 0 deletions agents-sdk/templates/python/base_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
"""
AgentForge LangGraph Base Agent Template
Provides the common 0x402 payment-gated LangGraph workflow pattern.
"""

import os
import json
import time
from typing import TypedDict, Optional, List
from dotenv import load_dotenv
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from langchain.schema import HumanMessage, SystemMessage
import requests

load_dotenv()

AGENTFORGE_API_URL = os.getenv("AGENTFORGE_API_URL", "http://localhost:3000")
STELLAR_AGENT_SECRET = os.getenv("STELLAR_AGENT_SECRET", "")
ABLY_API_KEY = os.getenv("ABLY_API_KEY", "")


class AgentState(TypedDict):
input: str
output: str
agent_id: str
wallet_address: str
tx_hash: Optional[str]
payment_required: bool
payment_amount: float
payment_address: str
error: Optional[str]
steps: List[str]


def build_model(model_name: str = "openai-gpt4o-mini"):
"""Build a LangChain model from the model name."""
if model_name == "openai-gpt4o-mini":
return ChatOpenAI(model="gpt-4o-mini", api_key=os.getenv("OPENAI_API_KEY"))
elif model_name == "anthropic-claude-haiku":
return ChatAnthropic(model="claude-haiku-20240307", api_key=os.getenv("ANTHROPIC_API_KEY"))
else:
return ChatOpenAI(model="gpt-4o-mini", api_key=os.getenv("OPENAI_API_KEY"))


def create_run_node(agent_id: str, system_prompt: str, model_name: str = "openai-gpt4o-mini"):
"""Create a LangGraph node that runs an agent via the 0x402 API."""
model = build_model(model_name)

def run_node(state: AgentState) -> AgentState:
headers = {"Content-Type": "application/json"}
if state.get("wallet_address"):
headers["X-Payment-Wallet"] = state["wallet_address"]
if state.get("tx_hash"):
headers["X-Payment-Tx-Hash"] = state["tx_hash"]

try:
resp = requests.post(
f"{AGENTFORGE_API_URL}/api/agents/{agent_id}/run",
headers=headers,
json={"input": state["input"]},
timeout=30,
)
data = resp.json()

if resp.status_code == 402:
pd = data.get("payment_details", {})
return {
**state,
"payment_required": True,
"payment_amount": pd.get("amount_xlm", 0),
"payment_address": pd.get("address", ""),
"steps": state.get("steps", []) + ["payment_required"],
}

if not resp.ok or data.get("error"):
return {
**state,
"error": data.get("error", f"HTTP {resp.status_code}"),
"steps": state.get("steps", []) + [f"error:{resp.status_code}"],
}

return {
**state,
"output": data.get("output", ""),
"payment_required": False,
"steps": state.get("steps", []) + ["completed"],
}
except Exception as e:
return {**state, "error": str(e), "steps": state.get("steps", []) + ["exception"]}

return run_node


def should_retry_payment(state: AgentState) -> str:
if state.get("error"):
return "error"
if state.get("payment_required"):
return "payment_required"
return "completed"


def build_single_agent_graph(agent_id: str, system_prompt: str, model_name: str = "openai-gpt4o-mini") -> StateGraph:
"""Build a simple single-agent LangGraph workflow."""
run_node = create_run_node(agent_id, system_prompt, model_name)

graph = StateGraph(AgentState)
graph.add_node("run", run_node)
graph.set_entry_point("run")
graph.add_edge("run", END)

return graph.compile()


def build_a2a_graph(
agent1_id: str,
agent2_id: str,
system_prompt1: str,
system_prompt2: str,
model_name: str = "openai-gpt4o-mini",
) -> StateGraph:
"""Build a multi-agent A2A LangGraph workflow where agent1 feeds agent2."""
run1 = create_run_node(agent1_id, system_prompt1, model_name)
run2 = create_run_node(agent2_id, system_prompt2, model_name)

def bridge_node(state: AgentState) -> AgentState:
"""Pass agent1 output as agent2 input."""
return {
**state,
"input": f"[Agent 1 Output]: {state['output']}\n\n[Original Task]: {state['input']}",
}

graph = StateGraph(AgentState)
graph.add_node("run_agent1", run1)
graph.add_node("bridge", bridge_node)
graph.add_node("run_agent2", run2)
graph.set_entry_point("run_agent1")
graph.add_edge("run_agent1", "bridge")
graph.add_edge("bridge", "run_agent2")
graph.add_edge("run_agent2", END)

return graph.compile()


if __name__ == "__main__":
# Example: run a single agent
agent_app = build_single_agent_graph(
agent_id="1",
system_prompt="You are a DeFi analyst.",
)
result = agent_app.invoke({
"input": "Analyze current XLM/USDC liquidity",
"output": "",
"agent_id": "1",
"wallet_address": "",
"tx_hash": None,
"payment_required": False,
"payment_amount": 0.0,
"payment_address": "",
"error": None,
"steps": [],
})
print(json.dumps(result, indent=2))
32 changes: 32 additions & 0 deletions agents-sdk/templates/python/liquidity_tracker_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""
AgentForge LangGraph Template — Liquidity Slippage Tracker Agent
Order-book depth analysis with real-time slippage simulation.
"""
import json
from base_agent import build_single_agent_graph, AgentState

SYSTEM_PROMPT = """You are a liquidity and slippage tracking agent for the Stellar DEX.
Your analysis includes:
1. Real-time order book depth for all major Stellar trading pairs
2. Slippage simulation for trades of various sizes (100, 1000, 10000 XLM)
3. Liquidity concentration analysis (bid/ask spread, wall detection)
4. Yield opportunity detection in liquidity pools
5. Optimal trade routing to minimize market impact

Provide structured data: pair, bid depth, ask depth, slippage at each size tier,
recommended max trade size for <1% slippage, and yield APR if applicable.
"""

def run_liquidity_tracker(input_prompt: str, wallet_address: str = "", tx_hash: str = None):
app = build_single_agent_graph(agent_id="liquidity_tracker", system_prompt=SYSTEM_PROMPT)
state: AgentState = {
"input": input_prompt, "output": "", "agent_id": "liquidity_tracker",
"wallet_address": wallet_address, "tx_hash": tx_hash,
"payment_required": False, "payment_amount": 0.0, "payment_address": "",
"error": None, "steps": [],
}
return app.invoke(state)

if __name__ == "__main__":
result = run_liquidity_tracker("Analyze XLM/USDC liquidity depth and simulate 5000 XLM trade slippage")
print(json.dumps(result, indent=2))
31 changes: 31 additions & 0 deletions agents-sdk/templates/python/mempool_monitor_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""
AgentForge LangGraph Template — Mempool Monitor Agent
Real-time Stellar transaction stream analysis via Horizon SSE.
"""
import json
from base_agent import build_single_agent_graph, AgentState

SYSTEM_PROMPT = """You are a mempool monitoring agent for the Stellar network.
Your responsibilities:
1. Analyze pending Stellar transactions from the Horizon SSE stream
2. Detect unusually large transactions (>100,000 XLM)
3. Identify smart contract interactions with Soroban
4. Alert on potential wash trading or market manipulation
5. Track transaction fee trends and network congestion

Provide real-time alerts with: transaction hash, amount, type, risk level, and recommended action.
"""

def run_mempool_monitor(input_prompt: str, wallet_address: str = "", tx_hash: str = None):
app = build_single_agent_graph(agent_id="mempool_monitor", system_prompt=SYSTEM_PROMPT)
state: AgentState = {
"input": input_prompt, "output": "", "agent_id": "mempool_monitor",
"wallet_address": wallet_address, "tx_hash": tx_hash,
"payment_required": False, "payment_amount": 0.0, "payment_address": "",
"error": None, "steps": [],
}
return app.invoke(state)

if __name__ == "__main__":
result = run_mempool_monitor("Monitor Stellar mempool for large transactions in the last 5 minutes")
print(json.dumps(result, indent=2))
41 changes: 41 additions & 0 deletions agents-sdk/templates/python/mev_bot_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""
AgentForge LangGraph Template — MEV Bot Agent
Front-running & sandwich detection on Stellar DEX with A2A support.
"""
import json
from base_agent import build_single_agent_graph, build_a2a_graph, AgentState

SYSTEM_PROMPT = """You are an advanced MEV (Maximal Extractable Value) bot operating on the Stellar DEX.
Your tasks:
1. Detect front-running opportunities in the Stellar DEX order book
2. Identify sandwich attack vectors on large pending transactions
3. Calculate optimal trade sizes and slippage tolerances
4. Execute atomic arbitrage within a single ledger when profitable
5. Report all detected opportunities with risk/reward ratios

Always provide quantitative analysis with entry/exit prices, expected profit in XLM, and confidence levels.
"""

def run_mev_bot(input_prompt: str, wallet_address: str = "", tx_hash: str = None):
app = build_single_agent_graph(
agent_id="mev_bot",
system_prompt=SYSTEM_PROMPT,
)
state: AgentState = {
"input": input_prompt,
"output": "",
"agent_id": "mev_bot",
"wallet_address": wallet_address,
"tx_hash": tx_hash,
"payment_required": False,
"payment_amount": 0.0,
"payment_address": "",
"error": None,
"steps": [],
}
return app.invoke(state)


if __name__ == "__main__":
result = run_mev_bot("Scan Stellar DEX for MEV opportunities in the last 100 transactions")
print(json.dumps(result, indent=2))
31 changes: 31 additions & 0 deletions agents-sdk/templates/python/relayer_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""
AgentForge LangGraph Template — Relayer Agent
Fee-bump transaction relay with 0x402 micropayment charging.
"""
import json
from base_agent import build_single_agent_graph, AgentState

SYSTEM_PROMPT = """You are a transaction relayer agent for the Stellar network with 0x402 micropayment charging.
Your functions:
1. Accept unsigned transactions from users and fee-bump them to the network
2. Calculate optimal fee amounts based on network load
3. Queue multiple transactions for batch processing efficiency
4. Track relay success rates and failure reasons
5. Charge micropayments via 0x402 protocol for each relayed transaction

For each relay request provide: fee estimate, processing time, relay path, and cost breakdown.
"""

def run_relayer(input_prompt: str, wallet_address: str = "", tx_hash: str = None):
app = build_single_agent_graph(agent_id="relayer", system_prompt=SYSTEM_PROMPT)
state: AgentState = {
"input": input_prompt, "output": "", "agent_id": "relayer",
"wallet_address": wallet_address, "tx_hash": tx_hash,
"payment_required": False, "payment_amount": 0.0, "payment_address": "",
"error": None, "steps": [],
}
return app.invoke(state)

if __name__ == "__main__":
result = run_relayer("Relay a fee-bump transaction for a gasless user experience")
print(json.dumps(result, indent=2))
Loading
Loading