agent0-sdk 0.31__py3-none-any.whl → 1.0.0__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.
@@ -1,404 +0,0 @@
1
- """
2
- Tests for OASF skills and domains management.
3
- """
4
-
5
- import pytest
6
- from unittest.mock import patch, MagicMock
7
-
8
- from agent0_sdk.core.sdk import SDK
9
- from agent0_sdk.core.models import EndpointType
10
- from agent0_sdk.core.oasf_validator import validate_skill, validate_domain
11
-
12
-
13
- class TestOASFManagement:
14
- """Test OASF skills and domains management."""
15
-
16
- def test_add_skill_without_validation(self):
17
- """Test adding a skill without validation."""
18
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
19
- # Create a mock instance with chain_id attribute
20
- mock_web3_instance = MagicMock()
21
- mock_web3_instance.chain_id = 11155111
22
- mock_web3_class.return_value = mock_web3_instance
23
-
24
- sdk = SDK(
25
- chainId=11155111,
26
- signer="0x1234567890abcdef1234567890abcdef12345678",
27
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
28
- )
29
-
30
- agent = sdk.createAgent("Test Agent", "A test agent")
31
-
32
- # Add skill without validation
33
- agent.addSkill("custom_skill/test_skill", validate_oasf=False)
34
-
35
- # Verify OASF endpoint was created
36
- oasf_endpoints = [ep for ep in agent.endpoints if ep.type == EndpointType.OASF]
37
- assert len(oasf_endpoints) == 1
38
-
39
- oasf_endpoint = oasf_endpoints[0]
40
- assert oasf_endpoint.value == "https://github.com/agntcy/oasf/"
41
- assert oasf_endpoint.meta["version"] == "v0.8.0"
42
- assert "custom_skill/test_skill" in oasf_endpoint.meta["skills"]
43
-
44
- def test_add_skill_with_validation_valid(self):
45
- """Test adding a valid skill with validation."""
46
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
47
- mock_web3_instance = MagicMock()
48
- mock_web3_instance.chain_id = 11155111
49
- mock_web3_class.return_value = mock_web3_instance
50
-
51
- sdk = SDK(
52
- chainId=11155111,
53
- signer="0x1234567890abcdef1234567890abcdef12345678",
54
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
55
- )
56
-
57
- agent = sdk.createAgent("Test Agent", "A test agent")
58
-
59
- # Add valid skill with validation
60
- agent.addSkill("advanced_reasoning_planning/strategic_planning", validate_oasf=True)
61
-
62
- # Verify skill was added
63
- oasf_endpoint = next(ep for ep in agent.endpoints if ep.type == EndpointType.OASF)
64
- assert "advanced_reasoning_planning/strategic_planning" in oasf_endpoint.meta["skills"]
65
-
66
- def test_add_skill_with_validation_invalid(self):
67
- """Test adding an invalid skill with validation raises ValueError."""
68
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
69
- mock_web3_instance = MagicMock()
70
- mock_web3_instance.chain_id = 11155111
71
- mock_web3_class.return_value = mock_web3_instance
72
-
73
- sdk = SDK(
74
- chainId=11155111,
75
- signer="0x1234567890abcdef1234567890abcdef12345678",
76
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
77
- )
78
-
79
- agent = sdk.createAgent("Test Agent", "A test agent")
80
-
81
- # Try to add invalid skill with validation
82
- with pytest.raises(ValueError, match="Invalid OASF skill slug"):
83
- agent.addSkill("invalid_skill/does_not_exist", validate_oasf=True)
84
-
85
- def test_add_skill_duplicate(self):
86
- """Test adding duplicate skill doesn't create duplicates."""
87
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
88
- mock_web3_instance = MagicMock()
89
- mock_web3_instance.chain_id = 11155111
90
- mock_web3_class.return_value = mock_web3_instance
91
-
92
- sdk = SDK(
93
- chainId=11155111,
94
- signer="0x1234567890abcdef1234567890abcdef12345678",
95
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
96
- )
97
-
98
- agent = sdk.createAgent("Test Agent", "A test agent")
99
-
100
- # Add same skill twice
101
- agent.addSkill("test_skill/slug", validate_oasf=False)
102
- agent.addSkill("test_skill/slug", validate_oasf=False)
103
-
104
- # Verify only one instance exists
105
- oasf_endpoint = next(ep for ep in agent.endpoints if ep.type == EndpointType.OASF)
106
- assert oasf_endpoint.meta["skills"].count("test_skill/slug") == 1
107
-
108
- def test_remove_skill_existing(self):
109
- """Test removing an existing skill."""
110
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
111
- mock_web3_instance = MagicMock()
112
- mock_web3_instance.chain_id = 11155111
113
- mock_web3_class.return_value = mock_web3_instance
114
-
115
- sdk = SDK(
116
- chainId=11155111,
117
- signer="0x1234567890abcdef1234567890abcdef12345678",
118
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
119
- )
120
-
121
- agent = sdk.createAgent("Test Agent", "A test agent")
122
-
123
- # Add skill
124
- agent.addSkill("test_skill/slug1", validate_oasf=False)
125
- agent.addSkill("test_skill/slug2", validate_oasf=False)
126
-
127
- # Remove one skill
128
- agent.removeSkill("test_skill/slug1")
129
-
130
- # Verify skill was removed
131
- oasf_endpoint = next(ep for ep in agent.endpoints if ep.type == EndpointType.OASF)
132
- assert "test_skill/slug1" not in oasf_endpoint.meta["skills"]
133
- assert "test_skill/slug2" in oasf_endpoint.meta["skills"]
134
-
135
- def test_remove_skill_non_existent(self):
136
- """Test removing a non-existent skill succeeds silently."""
137
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
138
- mock_web3_instance = MagicMock()
139
- mock_web3_instance.chain_id = 11155111
140
- mock_web3_class.return_value = mock_web3_instance
141
-
142
- sdk = SDK(
143
- chainId=11155111,
144
- signer="0x1234567890abcdef1234567890abcdef12345678",
145
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
146
- )
147
-
148
- agent = sdk.createAgent("Test Agent", "A test agent")
149
-
150
- # Remove skill when OASF endpoint doesn't exist (should succeed silently)
151
- agent.removeSkill("non_existent_skill")
152
-
153
- # Should not raise an error
154
-
155
- def test_remove_skill_when_endpoint_missing(self):
156
- """Test removing skill when OASF endpoint doesn't exist."""
157
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
158
- mock_web3_instance = MagicMock()
159
- mock_web3_instance.chain_id = 11155111
160
- mock_web3_class.return_value = mock_web3_instance
161
-
162
- sdk = SDK(
163
- chainId=11155111,
164
- signer="0x1234567890abcdef1234567890abcdef12345678",
165
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
166
- )
167
-
168
- agent = sdk.createAgent("Test Agent", "A test agent")
169
-
170
- # Remove skill when no OASF endpoint exists
171
- agent.removeSkill("some_skill")
172
-
173
- # Should succeed silently (idempotent)
174
-
175
- def test_add_domain_without_validation(self):
176
- """Test adding a domain without validation."""
177
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
178
- mock_web3_instance = MagicMock()
179
- mock_web3_instance.chain_id = 11155111
180
- mock_web3_class.return_value = mock_web3_instance
181
-
182
- sdk = SDK(
183
- chainId=11155111,
184
- signer="0x1234567890abcdef1234567890abcdef12345678",
185
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
186
- )
187
-
188
- agent = sdk.createAgent("Test Agent", "A test agent")
189
-
190
- # Add domain without validation
191
- agent.addDomain("custom_domain/test_domain", validate_oasf=False)
192
-
193
- # Verify OASF endpoint was created
194
- oasf_endpoints = [ep for ep in agent.endpoints if ep.type == EndpointType.OASF]
195
- assert len(oasf_endpoints) == 1
196
-
197
- oasf_endpoint = oasf_endpoints[0]
198
- assert "custom_domain/test_domain" in oasf_endpoint.meta["domains"]
199
-
200
- def test_add_domain_with_validation_valid(self):
201
- """Test adding a valid domain with validation."""
202
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
203
- mock_web3_instance = MagicMock()
204
- mock_web3_instance.chain_id = 11155111
205
- mock_web3_class.return_value = mock_web3_instance
206
-
207
- sdk = SDK(
208
- chainId=11155111,
209
- signer="0x1234567890abcdef1234567890abcdef12345678",
210
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
211
- )
212
-
213
- agent = sdk.createAgent("Test Agent", "A test agent")
214
-
215
- # Add valid domain with validation
216
- agent.addDomain("finance_and_business/investment_services", validate_oasf=True)
217
-
218
- # Verify domain was added
219
- oasf_endpoint = next(ep for ep in agent.endpoints if ep.type == EndpointType.OASF)
220
- assert "finance_and_business/investment_services" in oasf_endpoint.meta["domains"]
221
-
222
- def test_add_domain_with_validation_invalid(self):
223
- """Test adding an invalid domain with validation raises ValueError."""
224
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
225
- mock_web3_instance = MagicMock()
226
- mock_web3_instance.chain_id = 11155111
227
- mock_web3_class.return_value = mock_web3_instance
228
-
229
- sdk = SDK(
230
- chainId=11155111,
231
- signer="0x1234567890abcdef1234567890abcdef12345678",
232
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
233
- )
234
-
235
- agent = sdk.createAgent("Test Agent", "A test agent")
236
-
237
- # Try to add invalid domain with validation
238
- with pytest.raises(ValueError, match="Invalid OASF domain slug"):
239
- agent.addDomain("invalid_domain/does_not_exist", validate_oasf=True)
240
-
241
- def test_add_domain_duplicate(self):
242
- """Test adding duplicate domain doesn't create duplicates."""
243
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
244
- mock_web3_instance = MagicMock()
245
- mock_web3_instance.chain_id = 11155111
246
- mock_web3_class.return_value = mock_web3_instance
247
-
248
- sdk = SDK(
249
- chainId=11155111,
250
- signer="0x1234567890abcdef1234567890abcdef12345678",
251
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
252
- )
253
-
254
- agent = sdk.createAgent("Test Agent", "A test agent")
255
-
256
- # Add same domain twice
257
- agent.addDomain("test_domain/slug", validate_oasf=False)
258
- agent.addDomain("test_domain/slug", validate_oasf=False)
259
-
260
- # Verify only one instance exists
261
- oasf_endpoint = next(ep for ep in agent.endpoints if ep.type == EndpointType.OASF)
262
- assert oasf_endpoint.meta["domains"].count("test_domain/slug") == 1
263
-
264
- def test_remove_domain_existing(self):
265
- """Test removing an existing domain."""
266
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
267
- mock_web3_instance = MagicMock()
268
- mock_web3_instance.chain_id = 11155111
269
- mock_web3_class.return_value = mock_web3_instance
270
-
271
- sdk = SDK(
272
- chainId=11155111,
273
- signer="0x1234567890abcdef1234567890abcdef12345678",
274
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
275
- )
276
-
277
- agent = sdk.createAgent("Test Agent", "A test agent")
278
-
279
- # Add domains
280
- agent.addDomain("test_domain/slug1", validate_oasf=False)
281
- agent.addDomain("test_domain/slug2", validate_oasf=False)
282
-
283
- # Remove one domain
284
- agent.removeDomain("test_domain/slug1")
285
-
286
- # Verify domain was removed
287
- oasf_endpoint = next(ep for ep in agent.endpoints if ep.type == EndpointType.OASF)
288
- assert "test_domain/slug1" not in oasf_endpoint.meta["domains"]
289
- assert "test_domain/slug2" in oasf_endpoint.meta["domains"]
290
-
291
- def test_remove_domain_non_existent(self):
292
- """Test removing a non-existent domain succeeds silently."""
293
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
294
- mock_web3_instance = MagicMock()
295
- mock_web3_instance.chain_id = 11155111
296
- mock_web3_class.return_value = mock_web3_instance
297
-
298
- sdk = SDK(
299
- chainId=11155111,
300
- signer="0x1234567890abcdef1234567890abcdef12345678",
301
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
302
- )
303
-
304
- agent = sdk.createAgent("Test Agent", "A test agent")
305
-
306
- # Remove domain when OASF endpoint doesn't exist (should succeed silently)
307
- agent.removeDomain("non_existent_domain")
308
-
309
- # Should not raise an error
310
-
311
- def test_method_chaining(self):
312
- """Test method chaining."""
313
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
314
- mock_web3_instance = MagicMock()
315
- mock_web3_instance.chain_id = 11155111
316
- mock_web3_class.return_value = mock_web3_instance
317
-
318
- sdk = SDK(
319
- chainId=11155111,
320
- signer="0x1234567890abcdef1234567890abcdef12345678",
321
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
322
- )
323
-
324
- agent = sdk.createAgent("Test Agent", "A test agent")
325
-
326
- # Chain multiple operations
327
- agent.addSkill("skill1", validate_oasf=False)\
328
- .addDomain("domain1", validate_oasf=False)\
329
- .addSkill("skill2", validate_oasf=False)\
330
- .removeSkill("skill1")
331
-
332
- # Verify results
333
- oasf_endpoint = next(ep for ep in agent.endpoints if ep.type == EndpointType.OASF)
334
- assert "skill1" not in oasf_endpoint.meta["skills"]
335
- assert "skill2" in oasf_endpoint.meta["skills"]
336
- assert "domain1" in oasf_endpoint.meta["domains"]
337
-
338
- def test_serialization_deserialization(self):
339
- """Test that OASF data persists through serialization/deserialization."""
340
- with patch('agent0_sdk.core.sdk.Web3Client') as mock_web3_class:
341
- mock_web3_instance = MagicMock()
342
- mock_web3_instance.chain_id = 11155111
343
- mock_web3_class.return_value = mock_web3_instance
344
-
345
- sdk = SDK(
346
- chainId=11155111,
347
- signer="0x1234567890abcdef1234567890abcdef12345678",
348
- rpcUrl="https://eth-sepolia.g.alchemy.com/v2/test"
349
- )
350
-
351
- agent = sdk.createAgent("Test Agent", "A test agent")
352
-
353
- # Add skills and domains
354
- agent.addSkill("test_skill/slug1", validate_oasf=False)
355
- agent.addSkill("test_skill/slug2", validate_oasf=False)
356
- agent.addDomain("test_domain/slug1", validate_oasf=False)
357
-
358
- # Serialize to dict
359
- reg_file_dict = agent.registration_file.to_dict()
360
-
361
- # Find OASF endpoint in serialized data
362
- oasf_endpoint_dict = next(
363
- ep for ep in reg_file_dict["endpoints"]
364
- if ep["name"] == "OASF"
365
- )
366
-
367
- # Verify data is present
368
- assert "test_skill/slug1" in oasf_endpoint_dict["skills"]
369
- assert "test_skill/slug2" in oasf_endpoint_dict["skills"]
370
- assert "test_domain/slug1" in oasf_endpoint_dict["domains"]
371
-
372
- # Deserialize back
373
- from agent0_sdk.core.models import RegistrationFile
374
- new_reg_file = RegistrationFile.from_dict(reg_file_dict)
375
-
376
- # Verify OASF endpoint was restored
377
- oasf_endpoints = [ep for ep in new_reg_file.endpoints if ep.type == EndpointType.OASF]
378
- assert len(oasf_endpoints) == 1
379
-
380
- oasf_endpoint = oasf_endpoints[0]
381
- assert "test_skill/slug1" in oasf_endpoint.meta["skills"]
382
- assert "test_skill/slug2" in oasf_endpoint.meta["skills"]
383
- assert "test_domain/slug1" in oasf_endpoint.meta["domains"]
384
-
385
-
386
- class TestOASFValidator:
387
- """Test OASF validator utilities."""
388
-
389
- def test_validate_skill_valid(self):
390
- """Test validating a valid skill."""
391
- assert validate_skill("advanced_reasoning_planning/strategic_planning") is True
392
-
393
- def test_validate_skill_invalid(self):
394
- """Test validating an invalid skill."""
395
- assert validate_skill("invalid_skill/does_not_exist") is False
396
-
397
- def test_validate_domain_valid(self):
398
- """Test validating a valid domain."""
399
- assert validate_domain("finance_and_business/investment_services") is True
400
-
401
- def test_validate_domain_invalid(self):
402
- """Test validating an invalid domain."""
403
- assert validate_domain("invalid_domain/does_not_exist") is False
404
-
@@ -1,103 +0,0 @@
1
- """
2
- Test Endpoint Crawler with Real Public MCP and A2A Servers
3
- Tests against actual public servers provided by the user.
4
- """
5
-
6
- import logging
7
- import sys
8
- import os
9
-
10
- # Configure logging: root logger at WARNING to suppress noisy dependencies
11
- logging.basicConfig(
12
- level=logging.WARNING,
13
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
14
- datefmt='%Y-%m-%d %H:%M:%S',
15
- handlers=[logging.StreamHandler(sys.stdout)]
16
- )
17
-
18
- # Set debug level ONLY for agent0_sdk
19
- logging.getLogger('agent0_sdk').setLevel(logging.DEBUG)
20
- logging.getLogger('agent0_sdk.core').setLevel(logging.DEBUG)
21
-
22
- sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
23
-
24
- from agent0_sdk.core.endpoint_crawler import EndpointCrawler
25
- import json
26
-
27
- def main():
28
- print("🧪 Testing Endpoint Crawler with Real Public Servers")
29
- print("=" * 70)
30
-
31
- crawler = EndpointCrawler(timeout=10) # Longer timeout for real servers
32
-
33
- # Real public endpoints
34
- test_cases = [
35
- {
36
- "type": "A2A",
37
- "endpoint": "https://hello-world-gxfr.onrender.com",
38
- "description": "Real A2A Hello World Server"
39
- },
40
- {
41
- "type": "MCP",
42
- "endpoint": "https://mcp.atlassian.com/v1/forge/mcp",
43
- "description": "Atlassian MCP Server (requires authentication, will fail gracefully)"
44
- }
45
- ]
46
-
47
- successful_tests = []
48
- failed_tests = []
49
-
50
- for i, test_case in enumerate(test_cases, 1):
51
- print(f"\n📍 Test {i}: {test_case['type']} Endpoint")
52
- print("-" * 70)
53
- print(f"URL: {test_case['endpoint']}")
54
- print(f"Description: {test_case['description']}")
55
- print()
56
-
57
- if test_case['type'] == 'A2A':
58
- capabilities = crawler.fetch_a2a_capabilities(test_case['endpoint'])
59
- if capabilities:
60
- print("✅ SUCCESS! Fetched A2A capabilities:")
61
- print(json.dumps(capabilities, indent=2))
62
- successful_tests.append(test_case)
63
- else:
64
- print("❌ Failed to fetch A2A capabilities")
65
- failed_tests.append(test_case)
66
-
67
- elif test_case['type'] == 'MCP':
68
- capabilities = crawler.fetch_mcp_capabilities(test_case['endpoint'])
69
- if capabilities:
70
- print("✅ SUCCESS! Fetched MCP capabilities:")
71
- print(json.dumps(capabilities, indent=2))
72
- successful_tests.append(test_case)
73
- else:
74
- print("❌ Failed to fetch MCP capabilities")
75
- failed_tests.append(test_case)
76
-
77
- # Summary
78
- print("\n" + "=" * 70)
79
- print("📊 Summary")
80
- print("-" * 70)
81
- print(f"✅ Successful: {len(successful_tests)}")
82
- print(f"❌ Failed: {len(failed_tests)}")
83
-
84
- if successful_tests:
85
- print("\n✅ Successfully tested endpoints:")
86
- for test in successful_tests:
87
- print(f" - {test['type']}: {test['endpoint']}")
88
-
89
- if failed_tests:
90
- print("\n⚠️ Failed endpoints:")
91
- for test in failed_tests:
92
- print(f" - {test['type']}: {test['endpoint']}")
93
-
94
- print("\n" + "=" * 70)
95
- if successful_tests:
96
- print("🎉 Endpoint crawler is working with real public servers!")
97
- else:
98
- print("⚠️ No capabilities fetched. Check endpoints or network connection.")
99
- print("=" * 70)
100
-
101
- if __name__ == "__main__":
102
- main()
103
-