Skip to content

Commit d3a137b

Browse files
committed
update
1 parent 50f7c13 commit d3a137b

2 files changed

Lines changed: 56 additions & 175 deletions

File tree

examples/agents.py

Lines changed: 15 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -1,188 +1,40 @@
11
#!/usr/bin/env python3
2-
"""
3-
Robyn AI Agents Example
4-
=======================
5-
6-
This example demonstrates Robyn's AI capabilities including:
7-
1. OpenAI-powered conversational agents with memory
8-
2. REST API endpoints for chat interaction
9-
3. Memory management for conversation history
10-
11-
Run with: python examples/agents.py
12-
13-
Features:
14-
- Chat endpoint with persistent memory
15-
- Memory retrieval and clearing endpoints
16-
- Health check endpoint
17-
"""
2+
"""Simple Robyn AI Agents Example"""
183

194
import os
20-
from datetime import datetime
21-
225
from robyn import Robyn
236
from robyn.ai import agent, memory, configure
247

25-
268
app = Robyn(__file__)
27-
28-
# ============================================================================
29-
# AI Agent Configuration
30-
# ============================================================================
31-
32-
AGENT_CONFIG = {
33-
"openai_api_key": os.getenv("OPENAI_API_KEY", ""),
34-
"model": "gpt-4o-mini",
35-
"temperature": 0.7,
36-
"max_tokens": 500
37-
}
38-
39-
# Global agent instance
409
ai_agent = None
4110

42-
async def setup_agent():
43-
"""Initialize the AI agent with configuration"""
11+
@app.startup_handler
12+
async def startup():
4413
global ai_agent
4514

46-
if not AGENT_CONFIG["openai_api_key"]:
47-
print("⚠️ No OpenAI API key found. AI agent will not be available.")
48-
print(" Set OPENAI_API_KEY environment variable to enable chat.")
15+
if not os.getenv("OPENAI_API_KEY"):
16+
print("Set OPENAI_API_KEY to use AI features")
4917
return
5018

51-
try:
52-
user_memory = memory(provider="inmemory", user_id="default_user")
53-
54-
ai_config = configure(
55-
openai_api_key=AGENT_CONFIG["openai_api_key"],
56-
model=AGENT_CONFIG["model"],
57-
temperature=AGENT_CONFIG["temperature"],
58-
max_tokens=AGENT_CONFIG["max_tokens"]
59-
)
60-
61-
ai_agent = agent(runner="simple", memory=user_memory, config=ai_config)
62-
print("✓ AI agent initialized successfully")
63-
64-
except Exception as e:
65-
print(f"✗ Failed to initialize AI agent: {e}")
66-
ai_agent = None
67-
68-
@app.startup_handler
69-
async def startup():
70-
"""Setup agent on startup"""
71-
await setup_agent()
72-
73-
74-
75-
76-
# ============================================================================
77-
# AI Agent Endpoints
78-
# ============================================================================
19+
user_memory = memory(provider="inmemory", user_id="user")
20+
config = configure(openai_api_key=os.getenv("OPENAI_API_KEY"))
21+
ai_agent = agent(memory=user_memory, config=config)
7922

8023
@app.post("/chat")
8124
async def chat(request):
82-
"""Chat with the AI agent"""
8325
if not ai_agent:
84-
return {"error": "AI agent not available. Set OPENAI_API_KEY environment variable."}
85-
86-
try:
87-
data = request.json()
88-
query = data.get("query", "")
89-
use_history = data.get("history", True)
90-
91-
if not query:
92-
return {"error": "Query is required"}
93-
94-
result = await ai_agent.run(query, history=use_history)
95-
96-
return {
97-
"query": query,
98-
"response": result.get("response", "No response generated"),
99-
"model": AGENT_CONFIG["model"]
100-
}
101-
102-
except Exception as e:
103-
return {"error": f"Chat failed: {str(e)}"}
104-
105-
@app.get("/memory")
106-
async def get_memory():
107-
"""Get conversation memory"""
108-
if not ai_agent or not ai_agent.memory:
109-
return {"memory": [], "count": 0}
26+
return {"error": "AI not available"}
11027

111-
try:
112-
memory_data = await ai_agent.memory.get()
113-
return {"memory": memory_data, "count": len(memory_data)}
114-
except Exception as e:
115-
return {"error": f"Memory retrieval failed: {str(e)}"}
116-
117-
@app.delete("/memory")
118-
async def clear_memory():
119-
"""Clear conversation memory"""
120-
if not ai_agent or not ai_agent.memory:
121-
return {"message": "No memory to clear"}
28+
query = request.json().get("query")
29+
if not query:
30+
return {"error": "Query required"}
12231

123-
try:
124-
await ai_agent.memory.clear()
125-
return {"message": "Memory cleared successfully"}
126-
except Exception as e:
127-
return {"error": f"Memory clear failed: {str(e)}"}
128-
129-
# ============================================================================
130-
# Main Routes
131-
# ============================================================================
32+
result = await ai_agent.run(query)
33+
return {"response": result.get("response")}
13234

13335
@app.get("/")
13436
def home():
135-
"""AI Agent home page"""
136-
return {
137-
"name": "Robyn AI Agents Example",
138-
"description": "OpenAI-powered conversational agents with memory",
139-
"version": "1.0.0",
140-
"features": {
141-
"ai_agent": {
142-
"enabled": ai_agent is not None,
143-
"model": AGENT_CONFIG["model"] if ai_agent else None,
144-
"endpoints": ["/chat", "/memory"]
145-
}
146-
},
147-
"examples": {
148-
"chat": {
149-
"url": "POST /chat",
150-
"body": {"query": "Hello! What can you help me with?"}
151-
}
152-
}
153-
}
154-
155-
@app.get("/health")
156-
def health_check():
157-
"""Health check endpoint"""
158-
return {
159-
"status": "healthy",
160-
"timestamp": datetime.now().isoformat(),
161-
"ai_agent": "active" if ai_agent else "inactive"
162-
}
37+
return {"message": "Robyn AI Agent", "endpoint": "/chat"}
16338

16439
if __name__ == "__main__":
165-
print("🤖 Robyn AI Agents Example")
166-
print("=" * 50)
167-
print(f"🌐 Server: http://localhost:8080")
168-
print(f"💬 Chat Endpoint: http://localhost:8080/chat")
169-
print(f"❤️ Health Check: http://localhost:8080/health")
170-
print()
171-
172-
print("AI Agent:")
173-
if AGENT_CONFIG["openai_api_key"]:
174-
print(f" ✓ Model: {AGENT_CONFIG['model']}")
175-
print(" ✓ Memory: In-memory storage")
176-
print(" ✓ Chat endpoint available")
177-
else:
178-
print(" ⚠️ Disabled (no OPENAI_API_KEY)")
179-
print()
180-
181-
print("💬 Chat with the AI agent:")
182-
print(" curl -X POST http://localhost:8080/chat \\")
183-
print(" -H 'Content-Type: application/json' \\")
184-
print(" -d '{\"query\": \"Hello! What can you help me with?\"}'")
185-
print()
186-
print("🚀 Starting server...")
187-
18840
app.start(port=8080)

robyn/mcp.py

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -286,17 +286,34 @@ async def _handle_read_resource(self, params: Dict[str, Any]) -> Dict[str, Any]:
286286
template_uri, uri_params = match_result
287287
handler = self.resources[template_uri]
288288

289-
# Call the handler with extracted parameters
290-
if asyncio.iscoroutinefunction(handler):
291-
if uri_params:
292-
content = await handler(**uri_params)
293-
else:
294-
content = await handler(params)
295-
else:
296-
if uri_params:
297-
content = handler(**uri_params)
289+
# Call the handler with appropriate parameters based on its signature
290+
try:
291+
sig = inspect.signature(handler)
292+
handler_params = list(sig.parameters.keys())
293+
294+
if asyncio.iscoroutinefunction(handler):
295+
if uri_params:
296+
# Use URI parameters for templated resources
297+
content = await handler(**uri_params)
298+
elif handler_params:
299+
# Handler expects parameters, pass the full params dict
300+
content = await handler(params)
301+
else:
302+
# Handler expects no parameters
303+
content = await handler()
298304
else:
299-
content = handler(params)
305+
if uri_params:
306+
# Use URI parameters for templated resources
307+
content = handler(**uri_params)
308+
elif handler_params:
309+
# Handler expects parameters, pass the full params dict
310+
content = handler(params)
311+
else:
312+
# Handler expects no parameters
313+
content = handler()
314+
except TypeError as e:
315+
# Handle parameter mismatch errors
316+
raise MCPError(-32603, f"Handler parameter error: {str(e)}")
300317

301318
# Determine content type
302319
metadata = self.resource_metadata[template_uri]
@@ -392,8 +409,20 @@ def _setup_routes(self):
392409
async def handle_mcp_request(request):
393410
"""Handle MCP JSON-RPC requests"""
394411
try:
395-
# Parse JSON request
396-
request_data = request.json()
412+
# Parse JSON request - try multiple approaches
413+
try:
414+
request_data = request.json()
415+
except:
416+
# Fallback to parsing body as string
417+
body = request.body
418+
if isinstance(body, str):
419+
request_data = json.loads(body)
420+
else:
421+
request_data = json.loads(body.decode('utf-8'))
422+
423+
# Handle case where request.json() returns a string instead of dict
424+
if isinstance(request_data, str):
425+
request_data = json.loads(request_data)
397426

398427
# Handle the request
399428
response = await self.handler.handle_request(request_data)

0 commit comments

Comments
 (0)