agent0-sdk 0.2.2__py3-none-any.whl → 0.5__py3-none-any.whl
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.
- agent0_sdk/__init__.py +1 -1
- agent0_sdk/core/agent.py +303 -29
- agent0_sdk/core/contracts.py +93 -51
- agent0_sdk/core/feedback_manager.py +191 -162
- agent0_sdk/core/indexer.py +787 -37
- agent0_sdk/core/models.py +10 -21
- agent0_sdk/core/oasf_validator.py +98 -0
- agent0_sdk/core/sdk.py +238 -20
- agent0_sdk/core/subgraph_client.py +56 -17
- agent0_sdk/core/web3_client.py +184 -17
- agent0_sdk/taxonomies/all_domains.json +1565 -0
- agent0_sdk/taxonomies/all_skills.json +1030 -0
- {agent0_sdk-0.2.2.dist-info → agent0_sdk-0.5.dist-info}/METADATA +78 -6
- agent0_sdk-0.5.dist-info/RECORD +19 -0
- {agent0_sdk-0.2.2.dist-info → agent0_sdk-0.5.dist-info}/top_level.txt +0 -1
- agent0_sdk-0.2.2.dist-info/RECORD +0 -27
- tests/__init__.py +0 -1
- tests/config.py +0 -46
- tests/conftest.py +0 -22
- tests/test_feedback.py +0 -417
- tests/test_models.py +0 -224
- tests/test_real_public_servers.py +0 -103
- tests/test_registration.py +0 -267
- tests/test_registrationIpfs.py +0 -227
- tests/test_sdk.py +0 -240
- tests/test_search.py +0 -415
- tests/test_transfer.py +0 -255
- {agent0_sdk-0.2.2.dist-info → agent0_sdk-0.5.dist-info}/WHEEL +0 -0
- {agent0_sdk-0.2.2.dist-info → agent0_sdk-0.5.dist-info}/licenses/LICENSE +0 -0
tests/test_search.py
DELETED
|
@@ -1,415 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Test for Agent Search and Discovery using Subgraph
|
|
3
|
-
Tests various search and filtering capabilities for discovering agents and their reputation.
|
|
4
|
-
|
|
5
|
-
Flow:
|
|
6
|
-
1. Get a specific agent by ID
|
|
7
|
-
2. Search agents by name (partial match)
|
|
8
|
-
3. Search agents by capabilities (MCP tools)
|
|
9
|
-
4. Search agents by skills (A2A)
|
|
10
|
-
5. Search agents by ENS domain
|
|
11
|
-
6. Search agents by active status
|
|
12
|
-
7. Combine multiple filters (capabilities + skills)
|
|
13
|
-
8. Search agents by reputation with minimum average score
|
|
14
|
-
9. Search agents by reputation with specific tags
|
|
15
|
-
10. Search agents by reputation with capability filtering
|
|
16
|
-
11. Advanced: Find top-rated agents with specific skills
|
|
17
|
-
12. Advanced: Find agents with multiple requirements
|
|
18
|
-
13. Pagination test
|
|
19
|
-
14. Sort by activity test
|
|
20
|
-
15. Search agents by single owner address
|
|
21
|
-
16. Search agents by multiple owner addresses
|
|
22
|
-
17. Search agents by operator addresses
|
|
23
|
-
18. Combined search: owner + active status
|
|
24
|
-
19. Combined search: owner + name filter
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
import logging
|
|
28
|
-
import time
|
|
29
|
-
import random
|
|
30
|
-
import sys
|
|
31
|
-
|
|
32
|
-
# Configure logging: root logger at WARNING to suppress noisy dependencies
|
|
33
|
-
logging.basicConfig(
|
|
34
|
-
level=logging.WARNING,
|
|
35
|
-
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
36
|
-
datefmt='%Y-%m-%d %H:%M:%S',
|
|
37
|
-
handlers=[logging.StreamHandler(sys.stdout)]
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
# Set debug level ONLY for agent0_sdk
|
|
41
|
-
logging.getLogger('agent0_sdk').setLevel(logging.DEBUG)
|
|
42
|
-
logging.getLogger('agent0_sdk.core').setLevel(logging.DEBUG)
|
|
43
|
-
|
|
44
|
-
from agent0_sdk import SDK, SearchParams
|
|
45
|
-
from config import CHAIN_ID, RPC_URL, AGENT_PRIVATE_KEY, SUBGRAPH_URL, AGENT_ID, print_config
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def main():
|
|
49
|
-
print("🔍 Testing Agent Search and Discovery")
|
|
50
|
-
print_config()
|
|
51
|
-
print("=" * 60)
|
|
52
|
-
|
|
53
|
-
# Initialize SDK without signer (read-only operations)
|
|
54
|
-
sdk = SDK(
|
|
55
|
-
chainId=CHAIN_ID,
|
|
56
|
-
rpcUrl=RPC_URL
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
print(f"\n📍 Step 1: Get Agent by ID")
|
|
60
|
-
print("-" * 60)
|
|
61
|
-
try:
|
|
62
|
-
agent = sdk.getAgent(AGENT_ID)
|
|
63
|
-
print(f"✅ Agent found: {agent.name}")
|
|
64
|
-
print(f" Description: {agent.description[:80] if agent.description else 'N/A'}...")
|
|
65
|
-
print(f" Chain ID: {agent.chainId}")
|
|
66
|
-
print(f" Active: {agent.active}")
|
|
67
|
-
print(f" ENS: {agent.ens}")
|
|
68
|
-
print(f" Agent ID: {agent.agentId}")
|
|
69
|
-
# MCP and A2A support determined by endpoint presence
|
|
70
|
-
if hasattr(agent, 'mcpEndpoint') and agent.mcpEndpoint:
|
|
71
|
-
print(f" MCP: {agent.mcpEndpoint}")
|
|
72
|
-
if hasattr(agent, 'a2aEndpoint') and agent.a2aEndpoint:
|
|
73
|
-
print(f" A2A: {agent.a2aEndpoint}")
|
|
74
|
-
except Exception as e:
|
|
75
|
-
print(f"❌ Failed to get agent: {e}")
|
|
76
|
-
|
|
77
|
-
print(f"\n📍 Step 2: Search Agents by Name (Partial Match)")
|
|
78
|
-
print("-" * 60)
|
|
79
|
-
try:
|
|
80
|
-
results = sdk.searchAgents(name="Test")
|
|
81
|
-
agents = results.get('items', [])
|
|
82
|
-
print(f"✅ Found {len(agents)} agent(s) with name matching 'Test'")
|
|
83
|
-
for i, agent in enumerate(agents[:3], 1):
|
|
84
|
-
agent_id = agent.get('agentId', agent.get('id', 'N/A'))
|
|
85
|
-
print(f" {i}. {agent['name']} (ID: {agent_id})")
|
|
86
|
-
if agent.get('description'):
|
|
87
|
-
print(f" {agent['description'][:60]}...")
|
|
88
|
-
except Exception as e:
|
|
89
|
-
print(f"❌ Failed to search by name: {e}")
|
|
90
|
-
|
|
91
|
-
print(f"\n📍 Step 3: Search Agents by MCP Tools (Capabilities)")
|
|
92
|
-
print("-" * 60)
|
|
93
|
-
try:
|
|
94
|
-
# Using capabilities from test_feedback.py: data_analysis, code_generation, natural_language_understanding, problem_solving, communication
|
|
95
|
-
results = sdk.searchAgents(mcpTools=["data_analysis"])
|
|
96
|
-
agents = results.get('items', [])
|
|
97
|
-
print(f"✅ Found {len(agents)} agent(s) with 'data_analysis' capability")
|
|
98
|
-
for i, agent in enumerate(agents[:3], 1):
|
|
99
|
-
print(f" {i}. {agent['name']}")
|
|
100
|
-
if agent.get('mcpTools'):
|
|
101
|
-
print(f" Tools: {', '.join(agent['mcpTools'][:3])}...")
|
|
102
|
-
except Exception as e:
|
|
103
|
-
print(f"❌ Failed to search by capabilities: {e}")
|
|
104
|
-
|
|
105
|
-
print(f"\n📍 Step 4: Search Agents by A2A Skills")
|
|
106
|
-
print("-" * 60)
|
|
107
|
-
try:
|
|
108
|
-
# Using skills from test_feedback.py: python, javascript, machine_learning, web_development, cloud_computing
|
|
109
|
-
results = sdk.searchAgents(a2aSkills=["javascript"])
|
|
110
|
-
agents = results.get('items', [])
|
|
111
|
-
print(f"✅ Found {len(agents)} agent(s) with 'javascript' skill")
|
|
112
|
-
for i, agent in enumerate(agents[:3], 1):
|
|
113
|
-
print(f" {i}. {agent['name']}")
|
|
114
|
-
if agent.get('a2aSkills'):
|
|
115
|
-
print(f" Skills: {', '.join(agent['a2aSkills'][:3])}...")
|
|
116
|
-
except Exception as e:
|
|
117
|
-
print(f"❌ Failed to search by skills: {e}")
|
|
118
|
-
|
|
119
|
-
print(f"\n📍 Step 5: Search Agents by ENS Domain")
|
|
120
|
-
print("-" * 60)
|
|
121
|
-
try:
|
|
122
|
-
results = sdk.searchAgents(ens="test")
|
|
123
|
-
agents = results.get('items', [])
|
|
124
|
-
print(f"✅ Found {len(agents)} agent(s) with ENS matching 'test'")
|
|
125
|
-
for i, agent in enumerate(agents[:3], 1):
|
|
126
|
-
print(f" {i}. {agent['name']}")
|
|
127
|
-
if agent.get('ens'):
|
|
128
|
-
print(f" ENS: {agent['ens']}")
|
|
129
|
-
except Exception as e:
|
|
130
|
-
print(f"❌ Failed to search by ENS: {e}")
|
|
131
|
-
|
|
132
|
-
print(f"\n📍 Step 6: Search Only Active Agents")
|
|
133
|
-
print("-" * 60)
|
|
134
|
-
try:
|
|
135
|
-
results = sdk.searchAgents(active=True, page_size=10)
|
|
136
|
-
agents = results.get('items', [])
|
|
137
|
-
print(f"✅ Found {len(agents)} active agent(s)")
|
|
138
|
-
for i, agent in enumerate(agents[:3], 1):
|
|
139
|
-
print(f" {i}. {agent['name']} - {agent.get('totalFeedback', 0)} feedback")
|
|
140
|
-
except Exception as e:
|
|
141
|
-
print(f"❌ Failed to search active agents: {e}")
|
|
142
|
-
|
|
143
|
-
print(f"\n📍 Step 7: Search Agents with Multiple Filters (Capabilities + Skills)")
|
|
144
|
-
print("-" * 60)
|
|
145
|
-
try:
|
|
146
|
-
# Using capabilities and skills from test_feedback.py:
|
|
147
|
-
# Capabilities: data_analysis, code_generation, natural_language_understanding, problem_solving, communication
|
|
148
|
-
# Skills: python, javascript, machine_learning, web_development, cloud_computing
|
|
149
|
-
results = sdk.searchAgents(
|
|
150
|
-
mcpTools=["communication"],
|
|
151
|
-
a2aSkills=["python"]
|
|
152
|
-
)
|
|
153
|
-
agents = results.get('items', [])
|
|
154
|
-
print(f"✅ Found {len(agents)} agent(s) with 'communication' capability AND 'python' skill")
|
|
155
|
-
for i, agent in enumerate(agents[:3], 1):
|
|
156
|
-
print(f" {i}. {agent['name']}")
|
|
157
|
-
except Exception as e:
|
|
158
|
-
print(f"❌ Failed to search with multiple filters: {e}")
|
|
159
|
-
|
|
160
|
-
print(f"\n📍 Step 8: Search Agents by Reputation (Minimum Average Score)")
|
|
161
|
-
print("-" * 60)
|
|
162
|
-
try:
|
|
163
|
-
results = sdk.searchAgentsByReputation(minAverageScore=80)
|
|
164
|
-
agents = results.get('items', [])
|
|
165
|
-
print(f"✅ Found {len(agents)} agent(s) with average score >= 80")
|
|
166
|
-
for i, agent in enumerate(agents[:3], 1):
|
|
167
|
-
# AgentSummary object - use attributes, not dict.get()
|
|
168
|
-
avg_score = agent.extras.get('averageScore', 'N/A') if agent.extras else 'N/A'
|
|
169
|
-
print(f" {i}. {agent.name}")
|
|
170
|
-
print(f" Average Score: {avg_score}")
|
|
171
|
-
print(f" Agent ID: {agent.agentId}")
|
|
172
|
-
except Exception as e:
|
|
173
|
-
print(f"❌ Failed to search by reputation score: {e}")
|
|
174
|
-
|
|
175
|
-
print(f"\n📍 Step 9: Search Agents by Reputation with Specific Tags")
|
|
176
|
-
print("-" * 60)
|
|
177
|
-
try:
|
|
178
|
-
# Using tags that actually exist in feedback: "enterprise" appears frequently
|
|
179
|
-
# Note: GraphQL query has known issue with mixing filters, so using includeRevoked=True as workaround
|
|
180
|
-
# which may affect results, but at least the query will execute
|
|
181
|
-
results = sdk.searchAgentsByReputation(
|
|
182
|
-
tags=["enterprise"],
|
|
183
|
-
minAverageScore=0, # No threshold to see any results
|
|
184
|
-
includeRevoked=True # Workaround for GraphQL query builder issue
|
|
185
|
-
)
|
|
186
|
-
agents = results.get('items', [])
|
|
187
|
-
print(f"✅ Found {len(agents)} agent(s) with 'enterprise' tag")
|
|
188
|
-
for i, agent in enumerate(agents[:3], 1):
|
|
189
|
-
# AgentSummary object - use attributes
|
|
190
|
-
avg_score = agent.extras.get('averageScore', 'N/A') if agent.extras else 'N/A'
|
|
191
|
-
print(f" {i}. {agent.name} - Avg: {avg_score}")
|
|
192
|
-
except Exception as e:
|
|
193
|
-
print(f"❌ Failed to search by reputation tags: {e}")
|
|
194
|
-
|
|
195
|
-
print(f"\n📍 Step 10: Search Agents by Reputation with Capability Filtering")
|
|
196
|
-
print("-" * 60)
|
|
197
|
-
try:
|
|
198
|
-
# Using capabilities that actually exist in feedback: code_generation, problem_solving, data_analysis
|
|
199
|
-
results = sdk.searchAgentsByReputation(
|
|
200
|
-
capabilities=["code_generation"],
|
|
201
|
-
minAverageScore=0 # No threshold to see any results
|
|
202
|
-
)
|
|
203
|
-
agents = results.get('items', [])
|
|
204
|
-
print(f"✅ Found {len(agents)} agent(s) with 'code_generation' capability")
|
|
205
|
-
for i, agent in enumerate(agents[:3], 1):
|
|
206
|
-
avg_score = agent.extras.get('averageScore', 'N/A') if hasattr(agent, 'extras') and agent.extras else 'N/A'
|
|
207
|
-
print(f" {i}. {agent.name}")
|
|
208
|
-
print(f" Avg Score: {avg_score}")
|
|
209
|
-
except Exception as e:
|
|
210
|
-
print(f"❌ Failed to search by reputation with capabilities: {e}")
|
|
211
|
-
|
|
212
|
-
print(f"\n📍 Step 11: Advanced - Find Top-Rated Agents with Specific Skills")
|
|
213
|
-
print("-" * 60)
|
|
214
|
-
try:
|
|
215
|
-
# Using skills that actually exist in feedback: python, machine_learning, cloud_computing, web_development
|
|
216
|
-
results = sdk.searchAgentsByReputation(
|
|
217
|
-
skills=["python"],
|
|
218
|
-
minAverageScore=0 # No threshold to see any results
|
|
219
|
-
)
|
|
220
|
-
agents = results.get('items', [])
|
|
221
|
-
print(f"✅ Found {len(agents)} agent(s) with 'python' skill")
|
|
222
|
-
for i, agent in enumerate(agents[:3], 1):
|
|
223
|
-
# AgentSummary object - use attributes
|
|
224
|
-
avg_score = agent.extras.get('averageScore', 'N/A') if agent.extras else 'N/A'
|
|
225
|
-
print(f" {i}. {agent.name}")
|
|
226
|
-
print(f" Average Score: {avg_score}")
|
|
227
|
-
if agent.a2aSkills:
|
|
228
|
-
print(f" Skills: {', '.join(agent.a2aSkills[:3])}")
|
|
229
|
-
except Exception as e:
|
|
230
|
-
print(f"❌ Failed advanced skill search: {e}")
|
|
231
|
-
|
|
232
|
-
print(f"\n📍 Step 12: Advanced - Complex Multi-Criteria Search")
|
|
233
|
-
print("-" * 60)
|
|
234
|
-
try:
|
|
235
|
-
results = sdk.searchAgents(name="Test", active=True, page_size=10)
|
|
236
|
-
agents = results.get('items', [])
|
|
237
|
-
print(f"✅ Found {len(agents)} agent(s) matching multiple criteria")
|
|
238
|
-
for i, agent in enumerate(agents[:3], 1):
|
|
239
|
-
print(f" {i}. {agent['name']}")
|
|
240
|
-
print(f" Active: {agent.get('active', False)}, Feedback: {agent.get('totalFeedback', 0)}")
|
|
241
|
-
if agent.get('ens'):
|
|
242
|
-
print(f" ENS: {agent['ens']}")
|
|
243
|
-
except Exception as e:
|
|
244
|
-
print(f"❌ Failed complex search: {e}")
|
|
245
|
-
|
|
246
|
-
print(f"\n📍 Step 13: Pagination Test (First 5 Agents)")
|
|
247
|
-
print("-" * 60)
|
|
248
|
-
try:
|
|
249
|
-
results = sdk.searchAgents(page_size=5)
|
|
250
|
-
agents = results.get('items', [])
|
|
251
|
-
print(f"✅ Retrieved first page: {len(agents)} agent(s)")
|
|
252
|
-
for i, agent in enumerate(agents, 1):
|
|
253
|
-
agent_id = agent.get('agentId', agent.get('id', 'N/A'))
|
|
254
|
-
print(f" {i}. {agent['name']} (ID: {agent_id})")
|
|
255
|
-
except Exception as e:
|
|
256
|
-
print(f"❌ Failed pagination test: {e}")
|
|
257
|
-
|
|
258
|
-
print(f"\n📍 Step 14: Sort by Activity (Most Recent)")
|
|
259
|
-
print("-" * 60)
|
|
260
|
-
try:
|
|
261
|
-
results = sdk.searchAgents(page_size=10, sort=["updatedAt:desc"])
|
|
262
|
-
agents = results.get('items', [])
|
|
263
|
-
if agents:
|
|
264
|
-
print(f"✅ Retrieved {len(agents)} agents")
|
|
265
|
-
print(f" Most recent activity IDs:")
|
|
266
|
-
for i, agent in enumerate(agents[:5], 1):
|
|
267
|
-
agent_id = agent.get('agentId', agent.get('id', 'N/A'))
|
|
268
|
-
print(f" {i}. ID {agent_id}: {agent['name']}")
|
|
269
|
-
except Exception as e:
|
|
270
|
-
print(f"❌ Failed activity sort: {e}")
|
|
271
|
-
|
|
272
|
-
print(f"\n📍 Step 15: Search Agents by Single Owner Address")
|
|
273
|
-
print("-" * 60)
|
|
274
|
-
try:
|
|
275
|
-
# First, get an agent to extract its owner address for testing
|
|
276
|
-
test_agent = sdk.getAgent(AGENT_ID)
|
|
277
|
-
if hasattr(test_agent, 'owner') and test_agent.owner:
|
|
278
|
-
owner_address = test_agent.owner
|
|
279
|
-
print(f" Testing with owner address: {owner_address}")
|
|
280
|
-
|
|
281
|
-
results = sdk.searchAgents(owners=[owner_address])
|
|
282
|
-
agents = results.get('items', [])
|
|
283
|
-
print(f"✅ Found {len(agents)} agent(s) owned by {owner_address[:10]}...{owner_address[-8:]}")
|
|
284
|
-
|
|
285
|
-
for i, agent in enumerate(agents[:3], 1):
|
|
286
|
-
agent_id = agent.get('agentId', agent.get('id', 'N/A'))
|
|
287
|
-
agent_owner = agent.get('owner', 'N/A')
|
|
288
|
-
print(f" {i}. {agent['name']} (ID: {agent_id})")
|
|
289
|
-
print(f" Owner: {agent_owner[:10]}...{agent_owner[-8:] if len(agent_owner) > 18 else agent_owner}")
|
|
290
|
-
else:
|
|
291
|
-
print("⚠️ Test agent doesn't have owner information")
|
|
292
|
-
except Exception as e:
|
|
293
|
-
print(f"❌ Failed to search by single owner: {e}")
|
|
294
|
-
|
|
295
|
-
print(f"\n📍 Step 16: Search Agents by Multiple Owner Addresses")
|
|
296
|
-
print("-" * 60)
|
|
297
|
-
try:
|
|
298
|
-
# Get multiple agents to collect different owner addresses
|
|
299
|
-
results = sdk.searchAgents(page_size=5)
|
|
300
|
-
agents = results.get('items', [])
|
|
301
|
-
owner_addresses = []
|
|
302
|
-
|
|
303
|
-
for agent in agents:
|
|
304
|
-
if agent.get('owner') and agent['owner'] not in owner_addresses:
|
|
305
|
-
owner_addresses.append(agent['owner'])
|
|
306
|
-
if len(owner_addresses) >= 2:
|
|
307
|
-
break
|
|
308
|
-
|
|
309
|
-
if len(owner_addresses) >= 2:
|
|
310
|
-
print(f" Testing with {len(owner_addresses)} owner addresses")
|
|
311
|
-
results = sdk.searchAgents(owners=owner_addresses)
|
|
312
|
-
agents = results.get('items', [])
|
|
313
|
-
print(f"✅ Found {len(agents)} agent(s) owned by multiple addresses")
|
|
314
|
-
|
|
315
|
-
for i, agent in enumerate(agents[:5], 1):
|
|
316
|
-
agent_id = agent.get('agentId', agent.get('id', 'N/A'))
|
|
317
|
-
agent_owner = agent.get('owner', 'N/A')
|
|
318
|
-
print(f" {i}. {agent['name']} (Owner: {agent_owner[:10]}...{agent_owner[-8:] if len(agent_owner) > 18 else agent_owner})")
|
|
319
|
-
else:
|
|
320
|
-
print("⚠️ Not enough different owners found for multi-owner test")
|
|
321
|
-
except Exception as e:
|
|
322
|
-
print(f"❌ Failed to search by multiple owners: {e}")
|
|
323
|
-
|
|
324
|
-
print(f"\n📍 Step 17: Search Agents by Operator Addresses")
|
|
325
|
-
print("-" * 60)
|
|
326
|
-
try:
|
|
327
|
-
# First check if any agents have operators defined
|
|
328
|
-
results = sdk.searchAgents(page_size=10)
|
|
329
|
-
agents = results.get('items', [])
|
|
330
|
-
test_operators = []
|
|
331
|
-
|
|
332
|
-
for agent in agents:
|
|
333
|
-
if agent.get('operators') and len(agent['operators']) > 0:
|
|
334
|
-
test_operators = agent['operators'][:1] # Use first operator
|
|
335
|
-
print(f" Testing with operator: {test_operators[0][:10]}...{test_operators[0][-8:]}")
|
|
336
|
-
break
|
|
337
|
-
|
|
338
|
-
if test_operators:
|
|
339
|
-
results = sdk.searchAgents(operators=test_operators)
|
|
340
|
-
found_agents = results.get('items', [])
|
|
341
|
-
print(f"✅ Found {len(found_agents)} agent(s) with specified operator")
|
|
342
|
-
|
|
343
|
-
for i, agent in enumerate(found_agents[:3], 1):
|
|
344
|
-
agent_id = agent.get('agentId', agent.get('id', 'N/A'))
|
|
345
|
-
agent_operators = agent.get('operators', [])
|
|
346
|
-
print(f" {i}. {agent['name']} (ID: {agent_id})")
|
|
347
|
-
if agent_operators:
|
|
348
|
-
print(f" Operators: {len(agent_operators)} total")
|
|
349
|
-
else:
|
|
350
|
-
print("⚠️ No agents with operators found for testing")
|
|
351
|
-
except Exception as e:
|
|
352
|
-
print(f"❌ Failed to search by operators: {e}")
|
|
353
|
-
|
|
354
|
-
print(f"\n📍 Step 18: Combined Search - Owner + Active Status")
|
|
355
|
-
print("-" * 60)
|
|
356
|
-
try:
|
|
357
|
-
# Get an owner address from an active agent
|
|
358
|
-
results = sdk.searchAgents(active=True, page_size=5)
|
|
359
|
-
agents = results.get('items', [])
|
|
360
|
-
|
|
361
|
-
if agents and agents[0].get('owner'):
|
|
362
|
-
test_owner = agents[0]['owner']
|
|
363
|
-
print(f" Testing owner {test_owner[:10]}...{test_owner[-8:]} + active=True")
|
|
364
|
-
|
|
365
|
-
results = sdk.searchAgents(owners=[test_owner], active=True)
|
|
366
|
-
found_agents = results.get('items', [])
|
|
367
|
-
print(f"✅ Found {len(found_agents)} active agent(s) owned by specified address")
|
|
368
|
-
|
|
369
|
-
for i, agent in enumerate(found_agents[:3], 1):
|
|
370
|
-
agent_id = agent.get('agentId', agent.get('id', 'N/A'))
|
|
371
|
-
print(f" {i}. {agent['name']} (ID: {agent_id})")
|
|
372
|
-
print(f" Active: {agent.get('active', False)}, Owner: {agent.get('owner', 'N/A')[:10]}...")
|
|
373
|
-
else:
|
|
374
|
-
print("⚠️ No active agents with owner information found")
|
|
375
|
-
except Exception as e:
|
|
376
|
-
print(f"❌ Failed combined owner + active search: {e}")
|
|
377
|
-
|
|
378
|
-
print(f"\n📍 Step 19: Combined Search - Owner + Name Filter")
|
|
379
|
-
print("-" * 60)
|
|
380
|
-
try:
|
|
381
|
-
# Get agents and find one with both name and owner
|
|
382
|
-
results = sdk.searchAgents(page_size=10)
|
|
383
|
-
agents = results.get('items', [])
|
|
384
|
-
|
|
385
|
-
test_agent = None
|
|
386
|
-
for agent in agents:
|
|
387
|
-
if agent.get('owner') and agent.get('name'):
|
|
388
|
-
test_agent = agent
|
|
389
|
-
break
|
|
390
|
-
|
|
391
|
-
if test_agent:
|
|
392
|
-
test_owner = test_agent['owner']
|
|
393
|
-
# Use partial name for search
|
|
394
|
-
name_part = test_agent['name'][:4] if len(test_agent['name']) > 4 else test_agent['name']
|
|
395
|
-
print(f" Testing owner filter + name contains '{name_part}'")
|
|
396
|
-
|
|
397
|
-
results = sdk.searchAgents(owners=[test_owner], name=name_part)
|
|
398
|
-
found_agents = results.get('items', [])
|
|
399
|
-
print(f"✅ Found {len(found_agents)} agent(s) matching both criteria")
|
|
400
|
-
|
|
401
|
-
for i, agent in enumerate(found_agents[:3], 1):
|
|
402
|
-
agent_id = agent.get('agentId', agent.get('id', 'N/A'))
|
|
403
|
-
print(f" {i}. {agent['name']} (ID: {agent_id})")
|
|
404
|
-
else:
|
|
405
|
-
print("⚠️ No suitable test agent found")
|
|
406
|
-
except Exception as e:
|
|
407
|
-
print(f"❌ Failed combined owner + name search: {e}")
|
|
408
|
-
|
|
409
|
-
print("\n" + "=" * 60)
|
|
410
|
-
print("✅ Search Tests Completed!")
|
|
411
|
-
print("=" * 60)
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
if __name__ == "__main__":
|
|
415
|
-
main()
|
tests/test_transfer.py
DELETED
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Test agent transfer functionality.
|
|
4
|
-
|
|
5
|
-
This script demonstrates:
|
|
6
|
-
1. Creating and registering an agent with owner A
|
|
7
|
-
2. Transferring agent from owner A to owner B
|
|
8
|
-
3. Verifying ownership changed on-chain
|
|
9
|
-
4. Attempting to transfer from non-owner (should fail)
|
|
10
|
-
5. Verifying agent metadata remains unchanged after transfer
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
import logging
|
|
14
|
-
import time
|
|
15
|
-
import sys
|
|
16
|
-
|
|
17
|
-
# Configure logging: root logger at WARNING to suppress noisy dependencies
|
|
18
|
-
logging.basicConfig(
|
|
19
|
-
level=logging.WARNING,
|
|
20
|
-
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
21
|
-
datefmt='%Y-%m-%d %H:%M:%S',
|
|
22
|
-
handlers=[logging.StreamHandler(sys.stdout)]
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
# Set debug level ONLY for agent0_sdk
|
|
26
|
-
logging.getLogger('agent0_sdk').setLevel(logging.DEBUG)
|
|
27
|
-
logging.getLogger('agent0_sdk.core').setLevel(logging.DEBUG)
|
|
28
|
-
|
|
29
|
-
from config import (
|
|
30
|
-
CHAIN_ID, RPC_URL, AGENT_PRIVATE_KEY, PINATA_JWT, SUBGRAPH_URL,
|
|
31
|
-
print_config
|
|
32
|
-
)
|
|
33
|
-
from agent0_sdk import SDK, EndpointType, TrustModel
|
|
34
|
-
|
|
35
|
-
def main():
|
|
36
|
-
print("=" * 60)
|
|
37
|
-
print("🔄 AGENT TRANSFER TEST")
|
|
38
|
-
print("=" * 60)
|
|
39
|
-
|
|
40
|
-
print_config()
|
|
41
|
-
|
|
42
|
-
# Configuration for SDK
|
|
43
|
-
sdkConfig_pinata = {
|
|
44
|
-
"chainId": CHAIN_ID,
|
|
45
|
-
"rpcUrl": RPC_URL,
|
|
46
|
-
"signer": AGENT_PRIVATE_KEY,
|
|
47
|
-
"ipfs": "pinata",
|
|
48
|
-
"pinataJwt": PINATA_JWT
|
|
49
|
-
# Subgraph URL auto-defaults from DEFAULT_SUBGRAPH_URLS
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
# Initialize SDK with Pinata
|
|
53
|
-
print("\n📡 Initializing SDK with Pinata...")
|
|
54
|
-
agentSdk = SDK(**sdkConfig_pinata)
|
|
55
|
-
|
|
56
|
-
# Create a second private key for testing transfer
|
|
57
|
-
# In a real scenario, this would be a different wallet
|
|
58
|
-
# For testing, we'll use a different address derived from the same key
|
|
59
|
-
print("\n🔑 Setting up test accounts...")
|
|
60
|
-
ownerA_address = agentSdk.web3_client.account.address
|
|
61
|
-
print(f"Owner A address: {ownerA_address}")
|
|
62
|
-
|
|
63
|
-
# For testing purposes, we'll use a different address
|
|
64
|
-
# In practice, this would be a completely different private key
|
|
65
|
-
ownerB_address = "0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6" # Example address
|
|
66
|
-
print(f"Owner B address: {ownerB_address}")
|
|
67
|
-
|
|
68
|
-
print("\n" + "=" * 60)
|
|
69
|
-
print("STEP 1: CREATE AND REGISTER AGENT WITH OWNER A")
|
|
70
|
-
print("=" * 60)
|
|
71
|
-
|
|
72
|
-
# Create agent
|
|
73
|
-
agent = agentSdk.createAgent(
|
|
74
|
-
name="Transfer Test Agent",
|
|
75
|
-
description="An agent for testing transfer functionality",
|
|
76
|
-
image="https://example.com/transfer-test-agent.png"
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
# Configure agent details
|
|
80
|
-
agent.setAgentWallet(ownerA_address, CHAIN_ID)
|
|
81
|
-
agent.setENS("transfer-test-agent.eth")
|
|
82
|
-
agent.setMetadata({
|
|
83
|
-
"version": "1.0",
|
|
84
|
-
"category": "test",
|
|
85
|
-
"transfer_test": True
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
# Add endpoints
|
|
89
|
-
agent.setMCP("https://mcp.example.com/transfer-test", auto_fetch=False)
|
|
90
|
-
agent.setA2A("https://a2a.example.com/transfer-test-agent.json", auto_fetch=False)
|
|
91
|
-
|
|
92
|
-
print(f"✅ Agent created with ID: {agent.agentId}")
|
|
93
|
-
print(f"📄 Registration file prepared")
|
|
94
|
-
|
|
95
|
-
# Register agent on-chain
|
|
96
|
-
print("\n📝 Registering agent on-chain...")
|
|
97
|
-
registration_result = agent.registerIPFS()
|
|
98
|
-
|
|
99
|
-
print(f"✅ Agent registered successfully!")
|
|
100
|
-
print(f" Agent ID: {registration_result.agentId}")
|
|
101
|
-
print(f" IPFS URI: {registration_result.agentURI}")
|
|
102
|
-
|
|
103
|
-
# Verify initial ownership using utility function
|
|
104
|
-
print("\n🔍 Verifying initial ownership...")
|
|
105
|
-
current_owner = agentSdk.getAgentOwner(registration_result.agentId)
|
|
106
|
-
print(f"✅ Current owner: {current_owner}")
|
|
107
|
-
print(f"✅ Matches Owner A: {current_owner.lower() == ownerA_address.lower()}")
|
|
108
|
-
|
|
109
|
-
print("\n" + "=" * 60)
|
|
110
|
-
print("STEP 2: TRANSFER AGENT TO OWNER B")
|
|
111
|
-
print("=" * 60)
|
|
112
|
-
|
|
113
|
-
# Transfer agent using Agent.transfer() method
|
|
114
|
-
print(f"🔄 Transferring agent {registration_result.agentId} to {ownerB_address}...")
|
|
115
|
-
|
|
116
|
-
try:
|
|
117
|
-
transfer_result = agent.transfer(ownerB_address)
|
|
118
|
-
print(f"✅ Transfer successful!")
|
|
119
|
-
print(f" Transaction: {transfer_result['txHash']}")
|
|
120
|
-
print(f" From: {transfer_result['from']}")
|
|
121
|
-
print(f" To: {transfer_result['to']}")
|
|
122
|
-
print(f" Agent ID: {transfer_result['agentId']}")
|
|
123
|
-
except Exception as e:
|
|
124
|
-
print(f"❌ Transfer failed: {e}")
|
|
125
|
-
return
|
|
126
|
-
|
|
127
|
-
print("\n" + "=" * 60)
|
|
128
|
-
print("STEP 3: VERIFY OWNERSHIP CHANGE")
|
|
129
|
-
print("=" * 60)
|
|
130
|
-
|
|
131
|
-
# Verify ownership changed using utility function
|
|
132
|
-
print("🔍 Verifying ownership change...")
|
|
133
|
-
new_owner = agentSdk.getAgentOwner(registration_result.agentId)
|
|
134
|
-
print(f"✅ New owner: {new_owner}")
|
|
135
|
-
print(f"✅ Matches Owner B: {new_owner.lower() == ownerB_address.lower()}")
|
|
136
|
-
|
|
137
|
-
# Verify agent metadata remains unchanged
|
|
138
|
-
print("\n🔍 Verifying agent metadata remains unchanged...")
|
|
139
|
-
# Parse agentId to extract tokenId for contract call
|
|
140
|
-
agent_id_str = str(registration_result.agentId)
|
|
141
|
-
if ":" in agent_id_str:
|
|
142
|
-
token_id = int(agent_id_str.split(":")[-1])
|
|
143
|
-
else:
|
|
144
|
-
token_id = int(agent_id_str)
|
|
145
|
-
|
|
146
|
-
agent_uri = agentSdk.web3_client.call_contract(
|
|
147
|
-
agentSdk.identity_registry,
|
|
148
|
-
"tokenURI",
|
|
149
|
-
token_id
|
|
150
|
-
)
|
|
151
|
-
print(f"✅ Agent URI unchanged: {agent_uri}")
|
|
152
|
-
# Note: registration_result.agentURI may be None if not set in RegistrationFile
|
|
153
|
-
if registration_result.agentURI:
|
|
154
|
-
print(f"✅ Matches original: {agent_uri == registration_result.agentURI}")
|
|
155
|
-
else:
|
|
156
|
-
print(f"✅ Agent URI retrieved from blockchain: {agent_uri}")
|
|
157
|
-
|
|
158
|
-
print("\n" + "=" * 60)
|
|
159
|
-
print("STEP 4: TEST SDK.transferAgent() METHOD")
|
|
160
|
-
print("=" * 60)
|
|
161
|
-
|
|
162
|
-
# Test SDK-level transfer method (this will fail since we're not Owner B)
|
|
163
|
-
print("🔄 Testing SDK.transferAgent() method...")
|
|
164
|
-
print(" (This should fail since we're not the current owner)")
|
|
165
|
-
|
|
166
|
-
try:
|
|
167
|
-
# Try to transfer back to Owner A (should fail)
|
|
168
|
-
sdk_transfer_result = agentSdk.transferAgent(
|
|
169
|
-
registration_result.agentId,
|
|
170
|
-
ownerA_address
|
|
171
|
-
)
|
|
172
|
-
print(f"❌ Unexpected success: {sdk_transfer_result}")
|
|
173
|
-
except Exception as e:
|
|
174
|
-
print(f"✅ Expected failure: {e}")
|
|
175
|
-
|
|
176
|
-
print("\n" + "=" * 60)
|
|
177
|
-
print("STEP 5: TEST INVALID TRANSFER ATTEMPTS")
|
|
178
|
-
print("=" * 60)
|
|
179
|
-
|
|
180
|
-
# Test invalid transfer attempts
|
|
181
|
-
print("🔄 Testing invalid transfer attempts...")
|
|
182
|
-
|
|
183
|
-
# Test zero address
|
|
184
|
-
try:
|
|
185
|
-
agent.transfer("0x0000000000000000000000000000000000000000")
|
|
186
|
-
print("❌ Zero address transfer should have failed")
|
|
187
|
-
except ValueError as e:
|
|
188
|
-
print(f"✅ Zero address correctly rejected: {e}")
|
|
189
|
-
|
|
190
|
-
# Test self-transfer
|
|
191
|
-
try:
|
|
192
|
-
agent.transfer(ownerB_address) # Try to transfer to same address
|
|
193
|
-
print("❌ Self-transfer should have failed")
|
|
194
|
-
except ValueError as e:
|
|
195
|
-
print(f"✅ Self-transfer correctly rejected: {e}")
|
|
196
|
-
|
|
197
|
-
# Test invalid address format
|
|
198
|
-
try:
|
|
199
|
-
agent.transfer("invalid_address")
|
|
200
|
-
print("❌ Invalid address should have failed")
|
|
201
|
-
except ValueError as e:
|
|
202
|
-
print(f"✅ Invalid address correctly rejected: {e}")
|
|
203
|
-
|
|
204
|
-
print("\n" + "=" * 60)
|
|
205
|
-
print("STEP 6: VERIFY AGENT DATA INTEGRITY")
|
|
206
|
-
print("=" * 60)
|
|
207
|
-
|
|
208
|
-
# Load agent and verify all data is intact
|
|
209
|
-
print("🔍 Loading agent and verifying data integrity...")
|
|
210
|
-
|
|
211
|
-
try:
|
|
212
|
-
loaded_agent = agentSdk.loadAgent(registration_result.agentId)
|
|
213
|
-
print(f"✅ Agent loaded successfully")
|
|
214
|
-
print(f" Name: {loaded_agent.name}")
|
|
215
|
-
print(f" Description: {loaded_agent.description}")
|
|
216
|
-
print(f" Image: {loaded_agent.image}")
|
|
217
|
-
print(f" Wallet Address: {loaded_agent.walletAddress}")
|
|
218
|
-
print(f" ENS: {loaded_agent.ensEndpoint}")
|
|
219
|
-
print(f" Metadata: {loaded_agent.metadata}")
|
|
220
|
-
print(f" MCP Endpoint: {loaded_agent.mcpEndpoint}")
|
|
221
|
-
print(f" A2A Endpoint: {loaded_agent.a2aEndpoint}")
|
|
222
|
-
print(f" Active: {loaded_agent.active}")
|
|
223
|
-
|
|
224
|
-
# Verify ownership is correctly reflected
|
|
225
|
-
print(f"\n🔍 Ownership verification:")
|
|
226
|
-
print(f" Current owner (on-chain): {new_owner}")
|
|
227
|
-
print(f" Expected owner: {ownerB_address}")
|
|
228
|
-
print(f" Match: {new_owner.lower() == ownerB_address.lower()}")
|
|
229
|
-
|
|
230
|
-
except Exception as e:
|
|
231
|
-
print(f"❌ Failed to load agent: {e}")
|
|
232
|
-
import traceback
|
|
233
|
-
traceback.print_exc()
|
|
234
|
-
|
|
235
|
-
print("\n" + "=" * 60)
|
|
236
|
-
print("🎉 TRANSFER TEST COMPLETED SUCCESSFULLY!")
|
|
237
|
-
print("=" * 60)
|
|
238
|
-
|
|
239
|
-
print("\n📋 Summary:")
|
|
240
|
-
print(f" ✅ Agent created and registered with Owner A")
|
|
241
|
-
print(f" ✅ Agent successfully transferred to Owner B")
|
|
242
|
-
print(f" ✅ Ownership change verified on-chain")
|
|
243
|
-
print(f" ✅ Invalid transfer attempts properly rejected")
|
|
244
|
-
print(f" ✅ Agent data integrity maintained")
|
|
245
|
-
print(f" ✅ Both Agent.transfer() and SDK.transferAgent() methods tested")
|
|
246
|
-
|
|
247
|
-
print(f"\n🔗 Agent Details:")
|
|
248
|
-
print(f" Agent ID: {registration_result.agentId}")
|
|
249
|
-
print(f" Current Owner: {new_owner}")
|
|
250
|
-
print(f" Agent URI: {agent_uri}")
|
|
251
|
-
if transfer_result and 'txHash' in transfer_result:
|
|
252
|
-
print(f" Transfer Transaction: {transfer_result['txHash']}")
|
|
253
|
-
|
|
254
|
-
if __name__ == "__main__":
|
|
255
|
-
main()
|
|
File without changes
|
|
File without changes
|