ugarapi-mcp-server 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEPLOYMENT_GUIDE.md +343 -0
- package/GITHUB_SETUP_GUIDE.md +189 -0
- package/MARKETING_STRATEGY.md +418 -0
- package/OPENNODE_DEPLOY_GUIDE.md +191 -0
- package/OPENNODE_MANUAL_INTEGRATION.md +185 -0
- package/README.md +165 -0
- package/ai_service_business_plan.md +200 -0
- package/claude_desktop_config.json +14 -0
- package/main-v1.2-opennode.cpython-312.pyc +0 -0
- package/main-v1.2-opennode.py +588 -0
- package/main.py +395 -0
- package/package.json +29 -0
- package/requirements.txt +9 -0
- package/test_agent_simulator.py +296 -0
- package/ugarapi-banner.html +441 -0
- package/ugarapi-complete-package.zip +0 -0
- package/ugarapi-mcp-server.js +335 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AI Agent Simulator - Test Your AgentHub Services
|
|
3
|
+
This simulates how an AI agent would discover and use your services
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import asyncio
|
|
7
|
+
import httpx
|
|
8
|
+
import json
|
|
9
|
+
from typing import Dict, List
|
|
10
|
+
|
|
11
|
+
class AIAgentSimulator:
|
|
12
|
+
"""
|
|
13
|
+
Simulates an autonomous AI agent that:
|
|
14
|
+
1. Discovers your services
|
|
15
|
+
2. Creates payment
|
|
16
|
+
3. Uses the services
|
|
17
|
+
4. Evaluates results
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, base_url: str):
|
|
21
|
+
self.base_url = base_url
|
|
22
|
+
self.discovered_services = {}
|
|
23
|
+
self.payment_proofs = {}
|
|
24
|
+
|
|
25
|
+
async def discover_services(self):
|
|
26
|
+
"""
|
|
27
|
+
Step 1: AI agents discover services via .well-known manifest
|
|
28
|
+
"""
|
|
29
|
+
print("🤖 AI Agent: Discovering available services...")
|
|
30
|
+
|
|
31
|
+
async with httpx.AsyncClient() as client:
|
|
32
|
+
try:
|
|
33
|
+
response = await client.get(f"{self.base_url}/.well-known/ai-services.json")
|
|
34
|
+
manifest = response.json()
|
|
35
|
+
|
|
36
|
+
self.discovered_services = {
|
|
37
|
+
service["id"]: service
|
|
38
|
+
for service in manifest["services"]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
print(f"✅ Discovered {len(self.discovered_services)} services:")
|
|
42
|
+
for service_id, service in self.discovered_services.items():
|
|
43
|
+
print(f" - {service['name']}: {service['price_sats']} sats")
|
|
44
|
+
|
|
45
|
+
return True
|
|
46
|
+
|
|
47
|
+
except Exception as e:
|
|
48
|
+
print(f"❌ Failed to discover services: {e}")
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
async def create_payment(self, service_id: str) -> str:
|
|
52
|
+
"""
|
|
53
|
+
Step 2: Create a Lightning invoice for the service
|
|
54
|
+
"""
|
|
55
|
+
if service_id not in self.discovered_services:
|
|
56
|
+
raise ValueError(f"Unknown service: {service_id}")
|
|
57
|
+
|
|
58
|
+
service = self.discovered_services[service_id]
|
|
59
|
+
print(f"
|
|
60
|
+
💰 Creating payment for {service['name']}...")
|
|
61
|
+
|
|
62
|
+
async with httpx.AsyncClient() as client:
|
|
63
|
+
try:
|
|
64
|
+
response = await client.post(
|
|
65
|
+
f"{self.base_url}/api/v1/payment/create",
|
|
66
|
+
json={
|
|
67
|
+
"service": service_id,
|
|
68
|
+
"amount_sats": service["price_sats"]
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
payment_data = response.json()
|
|
72
|
+
|
|
73
|
+
invoice_id = payment_data["invoice_id"]
|
|
74
|
+
self.payment_proofs[service_id] = invoice_id
|
|
75
|
+
|
|
76
|
+
print(f"✅ Payment created: {invoice_id}")
|
|
77
|
+
print(f" Lightning Invoice: {payment_data['payment_request'][:50]}...")
|
|
78
|
+
print(f" Amount: {payment_data['amount_sats']} sats")
|
|
79
|
+
|
|
80
|
+
# Simulate payment (in production, AI agent would actually pay)
|
|
81
|
+
await self._simulate_payment(invoice_id)
|
|
82
|
+
|
|
83
|
+
return invoice_id
|
|
84
|
+
|
|
85
|
+
except Exception as e:
|
|
86
|
+
print(f"❌ Payment creation failed: {e}")
|
|
87
|
+
raise
|
|
88
|
+
|
|
89
|
+
async def _simulate_payment(self, invoice_id: str):
|
|
90
|
+
"""
|
|
91
|
+
Simulate Lightning payment (for testing)
|
|
92
|
+
In production, AI agent would actually send Bitcoin
|
|
93
|
+
"""
|
|
94
|
+
print("⚡ Simulating Lightning payment...")
|
|
95
|
+
|
|
96
|
+
# Mark payment as paid in the system
|
|
97
|
+
async with httpx.AsyncClient() as client:
|
|
98
|
+
await client.post(
|
|
99
|
+
f"{self.base_url}/api/v1/payment/webhook",
|
|
100
|
+
json={
|
|
101
|
+
"invoiceId": invoice_id,
|
|
102
|
+
"status": "paid"
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
print("✅ Payment confirmed!")
|
|
107
|
+
await asyncio.sleep(1) # Simulate network delay
|
|
108
|
+
|
|
109
|
+
async def test_web_extraction(self):
|
|
110
|
+
"""
|
|
111
|
+
Test Service 1: Web Data Extraction
|
|
112
|
+
"""
|
|
113
|
+
print("
|
|
114
|
+
🔍 Testing Web Extraction Service...")
|
|
115
|
+
|
|
116
|
+
# Create payment
|
|
117
|
+
invoice_id = await self.create_payment("web_extraction")
|
|
118
|
+
|
|
119
|
+
# Use service
|
|
120
|
+
async with httpx.AsyncClient() as client:
|
|
121
|
+
try:
|
|
122
|
+
response = await client.post(
|
|
123
|
+
f"{self.base_url}/api/v1/extract",
|
|
124
|
+
json={
|
|
125
|
+
"url": "https://example.com",
|
|
126
|
+
"selectors": {
|
|
127
|
+
"title": "h1",
|
|
128
|
+
"paragraphs": "p"
|
|
129
|
+
},
|
|
130
|
+
"payment_proof": invoice_id
|
|
131
|
+
}
|
|
132
|
+
)
|
|
133
|
+
result = response.json()
|
|
134
|
+
|
|
135
|
+
if result["success"]:
|
|
136
|
+
print("✅ Extraction successful!")
|
|
137
|
+
print(f" Extracted data: {json.dumps(result['data'], indent=2)}")
|
|
138
|
+
else:
|
|
139
|
+
print(f"❌ Extraction failed: {result.get('error')}")
|
|
140
|
+
|
|
141
|
+
return result
|
|
142
|
+
|
|
143
|
+
except Exception as e:
|
|
144
|
+
print(f"❌ Service call failed: {e}")
|
|
145
|
+
raise
|
|
146
|
+
|
|
147
|
+
async def test_document_timestamp(self):
|
|
148
|
+
"""
|
|
149
|
+
Test Service 2: Document Timestamping
|
|
150
|
+
"""
|
|
151
|
+
print("
|
|
152
|
+
📝 Testing Document Timestamp Service...")
|
|
153
|
+
|
|
154
|
+
# Create payment
|
|
155
|
+
invoice_id = await self.create_payment("document_timestamp")
|
|
156
|
+
|
|
157
|
+
# Create a document hash
|
|
158
|
+
import hashlib
|
|
159
|
+
document = "This is a test document for timestamping"
|
|
160
|
+
doc_hash = hashlib.sha256(document.encode()).hexdigest()
|
|
161
|
+
|
|
162
|
+
# Use service
|
|
163
|
+
async with httpx.AsyncClient() as client:
|
|
164
|
+
try:
|
|
165
|
+
response = await client.post(
|
|
166
|
+
f"{self.base_url}/api/v1/timestamp",
|
|
167
|
+
json={
|
|
168
|
+
"document_hash": doc_hash,
|
|
169
|
+
"metadata": {
|
|
170
|
+
"title": "Test Document",
|
|
171
|
+
"author": "AI Agent"
|
|
172
|
+
},
|
|
173
|
+
"payment_proof": invoice_id
|
|
174
|
+
}
|
|
175
|
+
)
|
|
176
|
+
result = response.json()
|
|
177
|
+
|
|
178
|
+
if result["success"]:
|
|
179
|
+
print("✅ Timestamp successful!")
|
|
180
|
+
print(f" Blockchain TX: {result['proof']['blockchain_tx']}")
|
|
181
|
+
print(f" Verification URL: {result['proof']['verification_url']}")
|
|
182
|
+
else:
|
|
183
|
+
print(f"❌ Timestamp failed")
|
|
184
|
+
|
|
185
|
+
return result
|
|
186
|
+
|
|
187
|
+
except Exception as e:
|
|
188
|
+
print(f"❌ Service call failed: {e}")
|
|
189
|
+
raise
|
|
190
|
+
|
|
191
|
+
async def test_api_aggregator(self):
|
|
192
|
+
"""
|
|
193
|
+
Test Service 3: API Aggregator
|
|
194
|
+
"""
|
|
195
|
+
print("
|
|
196
|
+
🌐 Testing API Aggregator Service...")
|
|
197
|
+
|
|
198
|
+
# Create payment
|
|
199
|
+
invoice_id = await self.create_payment("api_aggregator")
|
|
200
|
+
|
|
201
|
+
# Use service (test with exchange rate API - it's free)
|
|
202
|
+
async with httpx.AsyncClient() as client:
|
|
203
|
+
try:
|
|
204
|
+
response = await client.post(
|
|
205
|
+
f"{self.base_url}/api/v1/aggregate",
|
|
206
|
+
json={
|
|
207
|
+
"service": "exchange_rate",
|
|
208
|
+
"endpoint": "USD",
|
|
209
|
+
"params": {},
|
|
210
|
+
"payment_proof": invoice_id
|
|
211
|
+
}
|
|
212
|
+
)
|
|
213
|
+
result = response.json()
|
|
214
|
+
|
|
215
|
+
if result["success"]:
|
|
216
|
+
print("✅ API call successful!")
|
|
217
|
+
print(f" Service: {result['service']}")
|
|
218
|
+
print(f" Data sample: {str(result['data'])[:100]}...")
|
|
219
|
+
else:
|
|
220
|
+
print(f"❌ API call failed: {result.get('error')}")
|
|
221
|
+
|
|
222
|
+
return result
|
|
223
|
+
|
|
224
|
+
except Exception as e:
|
|
225
|
+
print(f"❌ Service call failed: {e}")
|
|
226
|
+
raise
|
|
227
|
+
|
|
228
|
+
async def evaluate_services(self):
|
|
229
|
+
"""
|
|
230
|
+
AI agent evaluates service quality and decides if it will use again
|
|
231
|
+
"""
|
|
232
|
+
print("
|
|
233
|
+
📊 Evaluating Service Quality...")
|
|
234
|
+
|
|
235
|
+
async with httpx.AsyncClient() as client:
|
|
236
|
+
response = await client.get(f"{self.base_url}/api/v1/stats")
|
|
237
|
+
stats = response.json()
|
|
238
|
+
|
|
239
|
+
print(f" Total requests processed: {stats['total_requests']}")
|
|
240
|
+
print(f" Advertised uptime: {stats['uptime']}")
|
|
241
|
+
|
|
242
|
+
# AI decision logic
|
|
243
|
+
if stats['total_requests'] > 0:
|
|
244
|
+
print("
|
|
245
|
+
✅ DECISION: Will add to preferred service list")
|
|
246
|
+
print(" Reasoning: Service is functional and has processing history")
|
|
247
|
+
else:
|
|
248
|
+
print("
|
|
249
|
+
⚠️ DECISION: Will monitor but not add yet")
|
|
250
|
+
print(" Reasoning: No processing history, need more data")
|
|
251
|
+
|
|
252
|
+
async def main():
|
|
253
|
+
"""
|
|
254
|
+
Run full AI agent simulation
|
|
255
|
+
"""
|
|
256
|
+
# Replace with your actual domain when deployed
|
|
257
|
+
BASE_URL = "http://localhost:8000" # Change to https://yourdomain.com when live
|
|
258
|
+
|
|
259
|
+
print("=" * 60)
|
|
260
|
+
print("AI AGENT SIMULATOR - AgentHub Services Test")
|
|
261
|
+
print("=" * 60)
|
|
262
|
+
|
|
263
|
+
agent = AIAgentSimulator(BASE_URL)
|
|
264
|
+
|
|
265
|
+
try:
|
|
266
|
+
# Step 1: Discover services
|
|
267
|
+
if not await agent.discover_services():
|
|
268
|
+
print("❌ Cannot proceed without service discovery")
|
|
269
|
+
return
|
|
270
|
+
|
|
271
|
+
# Step 2: Test each service
|
|
272
|
+
await agent.test_web_extraction()
|
|
273
|
+
await asyncio.sleep(2)
|
|
274
|
+
|
|
275
|
+
await agent.test_document_timestamp()
|
|
276
|
+
await asyncio.sleep(2)
|
|
277
|
+
|
|
278
|
+
await agent.test_api_aggregator()
|
|
279
|
+
await asyncio.sleep(2)
|
|
280
|
+
|
|
281
|
+
# Step 3: Evaluate
|
|
282
|
+
await agent.evaluate_services()
|
|
283
|
+
|
|
284
|
+
print("
|
|
285
|
+
" + "=" * 60)
|
|
286
|
+
print("✅ All tests completed successfully!")
|
|
287
|
+
print("=" * 60)
|
|
288
|
+
|
|
289
|
+
except Exception as e:
|
|
290
|
+
print(f"
|
|
291
|
+
❌ Test failed: {e}")
|
|
292
|
+
import traceback
|
|
293
|
+
traceback.print_exc()
|
|
294
|
+
|
|
295
|
+
if __name__ == "__main__":
|
|
296
|
+
asyncio.run(main())
|