agent0-sdk 0.5__tar.gz → 0.31__tar.gz

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.
Files changed (39) hide show
  1. {agent0_sdk-0.5/agent0_sdk.egg-info → agent0_sdk-0.31}/PKG-INFO +6 -20
  2. {agent0_sdk-0.5 → agent0_sdk-0.31}/README.md +5 -19
  3. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/__init__.py +1 -1
  4. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/core/agent.py +30 -172
  5. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/core/contracts.py +58 -93
  6. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/core/feedback_manager.py +161 -90
  7. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/core/indexer.py +26 -54
  8. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/core/models.py +19 -6
  9. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/core/oasf_validator.py +1 -1
  10. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/core/sdk.py +16 -31
  11. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/core/subgraph_client.py +15 -34
  12. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/core/web3_client.py +17 -184
  13. {agent0_sdk-0.5 → agent0_sdk-0.31/agent0_sdk.egg-info}/PKG-INFO +6 -20
  14. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk.egg-info/SOURCES.txt +15 -2
  15. {agent0_sdk-0.5 → agent0_sdk-0.31}/pyproject.toml +1 -1
  16. agent0_sdk-0.31/tests/__init__.py +1 -0
  17. agent0_sdk-0.31/tests/config.py +46 -0
  18. agent0_sdk-0.31/tests/conftest.py +22 -0
  19. agent0_sdk-0.31/tests/discover_test_data.py +445 -0
  20. agent0_sdk-0.31/tests/test_feedback.py +417 -0
  21. agent0_sdk-0.31/tests/test_models.py +224 -0
  22. agent0_sdk-0.31/tests/test_multi_chain.py +588 -0
  23. agent0_sdk-0.31/tests/test_oasf_management.py +404 -0
  24. agent0_sdk-0.31/tests/test_real_public_servers.py +103 -0
  25. agent0_sdk-0.31/tests/test_registration.py +267 -0
  26. agent0_sdk-0.31/tests/test_registrationIpfs.py +227 -0
  27. agent0_sdk-0.31/tests/test_sdk.py +240 -0
  28. agent0_sdk-0.31/tests/test_search.py +415 -0
  29. agent0_sdk-0.31/tests/test_transfer.py +255 -0
  30. agent0_sdk-0.5/MANIFEST.in +0 -10
  31. {agent0_sdk-0.5 → agent0_sdk-0.31}/LICENSE +0 -0
  32. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/core/endpoint_crawler.py +0 -0
  33. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/core/ipfs_client.py +0 -0
  34. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/taxonomies/all_domains.json +0 -0
  35. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk/taxonomies/all_skills.json +0 -0
  36. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk.egg-info/dependency_links.txt +0 -0
  37. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk.egg-info/requires.txt +0 -0
  38. {agent0_sdk-0.5 → agent0_sdk-0.31}/agent0_sdk.egg-info/top_level.txt +0 -0
  39. {agent0_sdk-0.5 → agent0_sdk-0.31}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent0-sdk
3
- Version: 0.5
3
+ Version: 0.31
4
4
  Summary: Python SDK for agent portability, discovery and trust based on ERC-8004
5
5
  Author-email: Marco De Rossi <marco.derossi@consensys.net>
6
6
  License: MIT License
@@ -152,15 +152,12 @@ agent.setENS("myagent.eth")
152
152
 
153
153
  # Add OASF skills and domains (standardized taxonomies)
154
154
  agent.addSkill("data_engineering/data_transformation_pipeline", validate_oasf=True)
155
- agent.addSkill("natural_language_processing/natural_language_generation/summarization", validate_oasf=True)
155
+ agent.addSkill("natural_language_processing/summarization", validate_oasf=True)
156
156
  agent.addDomain("finance_and_business/investment_services", validate_oasf=True)
157
- agent.addDomain("technology/data_science/data_science", validate_oasf=True)
157
+ agent.addDomain("technology/data_science", validate_oasf=True)
158
158
 
159
159
  # Configure wallet and trust
160
- # Note: agentWallet is an on-chain verified attribute. setAgentWallet() is on-chain only.
161
- # EOAs: the NEW wallet must sign an EIP-712 message. If you pass new_wallet_signer, the SDK will
162
- # build + sign the typed data automatically.
163
- # If the current SDK signer address matches the new wallet, it can auto-sign without new_wallet_signer.
160
+ agent.setAgentWallet("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", chainId=11155111)
164
161
  agent.setTrust(reputation=True, cryptoEconomic=True)
165
162
 
166
163
  # Add metadata and set status
@@ -171,16 +168,6 @@ agent.setActive(True)
171
168
  agent.registerIPFS()
172
169
  print(f"Agent registered: {agent.agentId}") # e.g., "11155111:123"
173
170
  print(f"Agent URI: {agent.agentURI}") # e.g., "ipfs://Qm..."
174
-
175
- # (Optional) Change the agent wallet after registration
176
- # - On mint/registration, `agentWallet` defaults to the current owner address.
177
- # - Call this only if you want a DIFFERENT wallet (or after a transfer, since the wallet resets to zero).
178
- # - Transaction is sent by the SDK signer (agent owner), but the signature must be produced by the NEW wallet.
179
- agent.setAgentWallet(
180
- "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
181
- chainId=11155111,
182
- new_wallet_signer=os.getenv("NEW_WALLET_PRIVATE_KEY"),
183
- )
184
171
  ```
185
172
 
186
173
  ### 3. Load and Edit Agent
@@ -226,8 +213,7 @@ agent_summary = sdk.getAgent("11155111:123")
226
213
  feedback_file = sdk.prepareFeedback(
227
214
  agentId="11155111:123",
228
215
  score=85, # 0-100 (mandatory)
229
- tags=["data_analyst", "finance"], # Optional: tags are now strings (not bytes32)
230
- endpoint="https://example.com/endpoint", # Optional: endpoint URI associated with feedback
216
+ tags=["data_analyst", "finance"], # Optional
231
217
  capability="tools", # Optional: MCP capability
232
218
  name="code_generation", # Optional: MCP tool name
233
219
  skill="python" # Optional: A2A skill
@@ -321,7 +307,7 @@ OASF skills and domains appear in your agent's registration file:
321
307
  ],
322
308
  "domains": [
323
309
  "finance_and_business/investment_services",
324
- "technology/data_science/data_science"
310
+ "technology/data_science"
325
311
  ]
326
312
  }
327
313
  ]
@@ -82,15 +82,12 @@ agent.setENS("myagent.eth")
82
82
 
83
83
  # Add OASF skills and domains (standardized taxonomies)
84
84
  agent.addSkill("data_engineering/data_transformation_pipeline", validate_oasf=True)
85
- agent.addSkill("natural_language_processing/natural_language_generation/summarization", validate_oasf=True)
85
+ agent.addSkill("natural_language_processing/summarization", validate_oasf=True)
86
86
  agent.addDomain("finance_and_business/investment_services", validate_oasf=True)
87
- agent.addDomain("technology/data_science/data_science", validate_oasf=True)
87
+ agent.addDomain("technology/data_science", validate_oasf=True)
88
88
 
89
89
  # Configure wallet and trust
90
- # Note: agentWallet is an on-chain verified attribute. setAgentWallet() is on-chain only.
91
- # EOAs: the NEW wallet must sign an EIP-712 message. If you pass new_wallet_signer, the SDK will
92
- # build + sign the typed data automatically.
93
- # If the current SDK signer address matches the new wallet, it can auto-sign without new_wallet_signer.
90
+ agent.setAgentWallet("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", chainId=11155111)
94
91
  agent.setTrust(reputation=True, cryptoEconomic=True)
95
92
 
96
93
  # Add metadata and set status
@@ -101,16 +98,6 @@ agent.setActive(True)
101
98
  agent.registerIPFS()
102
99
  print(f"Agent registered: {agent.agentId}") # e.g., "11155111:123"
103
100
  print(f"Agent URI: {agent.agentURI}") # e.g., "ipfs://Qm..."
104
-
105
- # (Optional) Change the agent wallet after registration
106
- # - On mint/registration, `agentWallet` defaults to the current owner address.
107
- # - Call this only if you want a DIFFERENT wallet (or after a transfer, since the wallet resets to zero).
108
- # - Transaction is sent by the SDK signer (agent owner), but the signature must be produced by the NEW wallet.
109
- agent.setAgentWallet(
110
- "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
111
- chainId=11155111,
112
- new_wallet_signer=os.getenv("NEW_WALLET_PRIVATE_KEY"),
113
- )
114
101
  ```
115
102
 
116
103
  ### 3. Load and Edit Agent
@@ -156,8 +143,7 @@ agent_summary = sdk.getAgent("11155111:123")
156
143
  feedback_file = sdk.prepareFeedback(
157
144
  agentId="11155111:123",
158
145
  score=85, # 0-100 (mandatory)
159
- tags=["data_analyst", "finance"], # Optional: tags are now strings (not bytes32)
160
- endpoint="https://example.com/endpoint", # Optional: endpoint URI associated with feedback
146
+ tags=["data_analyst", "finance"], # Optional
161
147
  capability="tools", # Optional: MCP capability
162
148
  name="code_generation", # Optional: MCP tool name
163
149
  skill="python" # Optional: A2A skill
@@ -251,7 +237,7 @@ OASF skills and domains appear in your agent's registration file:
251
237
  ],
252
238
  "domains": [
253
239
  "finance_and_business/investment_services",
254
- "technology/data_science/data_science"
240
+ "technology/data_science"
255
241
  ]
256
242
  }
257
243
  ]
@@ -30,7 +30,7 @@ except ImportError:
30
30
  Agent = None
31
31
  _sdk_available = False
32
32
 
33
- __version__ = "0.5"
33
+ __version__ = "0.31"
34
34
  __all__ = [
35
35
  "SDK",
36
36
  "Agent",
@@ -176,14 +176,16 @@ class Agent:
176
176
  return self.registration_file
177
177
 
178
178
  def _collectMetadataForRegistration(self) -> List[Dict[str, Any]]:
179
- """Collect all metadata entries for registration.
180
-
181
- Note: agentWallet is now a reserved metadata key and cannot be set via setMetadata().
182
- It must be set separately using setAgentWallet() with EIP-712 signature verification.
183
- """
179
+ """Collect all metadata entries for registration."""
184
180
  metadata_entries = []
185
181
 
186
- # Note: agentWallet is no longer set via metadata - it's now reserved and managed via setAgentWallet()
182
+ # Add wallet address metadata
183
+ if self.walletAddress:
184
+ addr_bytes = bytes.fromhex(self.walletAddress[2:]) # Remove '0x' prefix
185
+ metadata_entries.append({
186
+ "key": "agentWallet",
187
+ "value": addr_bytes
188
+ })
187
189
 
188
190
  # Add ENS name metadata
189
191
  if self.ensEndpoint:
@@ -337,7 +339,7 @@ class Agent:
337
339
  Add a skill to the OASF endpoint.
338
340
 
339
341
  Args:
340
- slug: The skill slug to add (e.g., "natural_language_processing/natural_language_generation/summarization")
342
+ slug: The skill slug to add (e.g., "natural_language_processing/summarization")
341
343
  validate_oasf: If True, validate the slug against the OASF taxonomy (default: False)
342
344
 
343
345
  Returns:
@@ -490,55 +492,20 @@ class Agent:
490
492
  self.registration_file.updatedAt = int(time.time())
491
493
  return self
492
494
 
493
- def setAgentWallet(
494
- self,
495
- new_wallet: Address,
496
- chainId: Optional[int] = None,
497
- *,
498
- new_wallet_signer: Optional[Union[str, Any]] = None,
499
- deadline: Optional[int] = None,
500
- signature: Optional[bytes] = None,
501
- ) -> 'Agent':
502
- """Set agent wallet address on-chain (ERC-8004 agentWallet).
503
-
504
- This method is **on-chain only**. The `agentWallet` is a verified attribute and must be set via
505
- the IdentityRegistry `setAgentWallet` function.
506
-
507
- EOAs: provide `new_wallet_signer` (private key string or eth-account account) OR ensure the SDK
508
- signer address matches `new_wallet` so the SDK can auto-sign.\n
509
- Contract wallets (ERC-1271): provide `signature` bytes produced by the wallet’s signing mechanism.
510
- The SDK will build the correct EIP-712 typed data internally, but cannot produce the wallet signature.
511
-
512
- Args:
513
- new_wallet: New wallet address (must be controlled by the signer that produces the signature)
514
- chainId: Optional local bookkeeping for registration file (walletChainId). Defaults to agent chain.
515
- new_wallet_signer: EOA signer used to sign the EIP-712 message (private key string or eth-account account)
516
- deadline: Signature deadline timestamp. Defaults to now+60s (must be <= now+5min per contract).
517
- signature: Raw signature bytes (intended for ERC-1271 / external signing only)
518
- """
519
- # Breaking/clean: this API is only meaningful for already-registered agents.
520
- if not self.agentId:
521
- raise ValueError(
522
- "Cannot set agent wallet before the agent is registered on-chain. "
523
- "Call agent.register(...) / agent.registerIPFS() first to obtain agentId."
524
- )
525
-
526
- addr = new_wallet
527
-
528
- if not addr:
529
- raise ValueError("Wallet address cannot be empty. Use a non-zero address.")
530
-
531
- # Validate address format
532
- if not addr.startswith("0x") or len(addr) != 42:
533
- raise ValueError(f"Invalid Ethereum address format: {addr}. Must be 42 characters starting with '0x'")
534
-
535
- # Validate hexadecimal characters
536
- try:
537
- int(addr[2:], 16)
538
- except ValueError:
539
- raise ValueError(f"Invalid hexadecimal characters in address: {addr}")
495
+ def setAgentWallet(self, addr: Optional[Address], chainId: Optional[int] = None) -> 'Agent':
496
+ """Set agent wallet address in registration file (will be saved on-chain during next register call)."""
497
+ # Validate address format if provided
498
+ if addr:
499
+ if not addr.startswith("0x") or len(addr) != 42:
500
+ raise ValueError(f"Invalid Ethereum address format: {addr}. Must be 42 characters starting with '0x'")
501
+
502
+ # Validate hexadecimal characters
503
+ try:
504
+ int(addr[2:], 16)
505
+ except ValueError:
506
+ raise ValueError(f"Invalid hexadecimal characters in address: {addr}")
540
507
 
541
- # Determine chain ID to use (local bookkeeping)
508
+ # Determine chain ID to use
542
509
  if chainId is None:
543
510
  # Extract chain ID from agentId if available, otherwise use SDK's chain ID
544
511
  if self.agentId and ":" in self.agentId:
@@ -549,104 +516,14 @@ class Agent:
549
516
  else:
550
517
  chainId = self.sdk.chainId # Use SDK's chain ID as fallback
551
518
 
552
- # Parse agent ID
553
- agent_id_int = int(self.agentId.split(":")[-1]) if ":" in self.agentId else int(self.agentId)
554
-
555
- # Check if wallet is already set to this address (skip if same)
556
- try:
557
- current_wallet = self.sdk.web3_client.call_contract(
558
- self.sdk.identity_registry,
559
- "getAgentWallet",
560
- agent_id_int
561
- )
562
- if current_wallet and current_wallet.lower() == addr.lower():
563
- logger.debug(f"Agent wallet is already set to {addr}, skipping on-chain update")
564
- # Still update local registration file
565
- self.registration_file.walletAddress = addr
566
- self.registration_file.walletChainId = chainId
567
- self.registration_file.updatedAt = int(time.time())
568
- return self
569
- except Exception as e:
570
- logger.debug(f"Could not check current agent wallet: {e}, proceeding with update")
571
-
572
- # Set deadline (default to 60 seconds from now; contract max is now+5min)
573
- if deadline is None:
574
- deadline = int(time.time()) + 60
575
-
576
- # Resolve typed data + signature
577
- identity_registry_address = self.sdk.identity_registry.address
578
- owner_address = self.sdk.web3_client.call_contract(self.sdk.identity_registry, "ownerOf", agent_id_int)
579
-
580
- full_message = self.sdk.web3_client.build_agent_wallet_set_typed_data(
581
- agent_id=agent_id_int,
582
- new_wallet=addr,
583
- owner=owner_address,
584
- deadline=deadline,
585
- verifying_contract=identity_registry_address,
586
- chain_id=self.sdk.web3_client.chain_id,
587
- )
588
-
589
- if signature is None:
590
- # EOA signing paths
591
- if new_wallet_signer is not None:
592
- # Validate signer address matches addr (fail fast)
593
- try:
594
- from eth_account import Account as _Account
595
- if isinstance(new_wallet_signer, str):
596
- signer_addr = _Account.from_key(new_wallet_signer).address
597
- else:
598
- signer_addr = getattr(new_wallet_signer, "address", None)
599
- except Exception:
600
- signer_addr = getattr(new_wallet_signer, "address", None)
601
-
602
- if not signer_addr or signer_addr.lower() != addr.lower():
603
- raise ValueError(
604
- f"new_wallet_signer address ({signer_addr}) does not match new_wallet ({addr})."
605
- )
606
-
607
- signature = self.sdk.web3_client.sign_typed_data(full_message, new_wallet_signer) # type: ignore[arg-type]
608
- else:
609
- # Auto-sign only if SDK signer == new wallet
610
- current_address = self.sdk.web3_client.account.address if self.sdk.web3_client.account else None
611
- if current_address and current_address.lower() == addr.lower():
612
- signature = self.sdk.web3_client.sign_typed_data(full_message, self.sdk.web3_client.account)
613
- else:
614
- raise ValueError(
615
- f"New wallet must sign. Provide new_wallet_signer (EOA) or signature (ERC-1271/external). "
616
- f"SDK signer is {current_address}, new_wallet is {addr}."
617
- )
618
-
619
- # Optional: verify recover matches addr for EOA signatures
620
- recovered = self.sdk.web3_client.w3.eth.account.recover_message(
621
- __import__("eth_account.messages").messages.encode_typed_data(full_message=full_message),
622
- signature=signature,
623
- )
624
- if recovered.lower() != addr.lower():
625
- raise ValueError(f"Signature verification failed: recovered {recovered} but expected {addr}")
626
-
627
- # Call setAgentWallet on the contract
628
- try:
629
- txHash = self.sdk.web3_client.transact_contract(
630
- self.sdk.identity_registry,
631
- "setAgentWallet",
632
- agent_id_int,
633
- addr,
634
- deadline,
635
- signature
636
- )
637
-
638
- # Wait for transaction
639
- receipt = self.sdk.web3_client.wait_for_transaction(txHash)
640
- logger.debug(f"Agent wallet set on-chain: {txHash}")
641
-
642
- except Exception as e:
643
- raise ValueError(f"Failed to set agent wallet on-chain: {e}")
519
+ # Check if wallet changed
520
+ if addr != self._last_registered_wallet:
521
+ self._dirty_metadata.add("agentWallet")
644
522
 
645
523
  # Update local registration file
646
524
  self.registration_file.walletAddress = addr
647
525
  self.registration_file.walletChainId = chainId
648
526
  self.registration_file.updatedAt = int(time.time())
649
- self._last_registered_wallet = addr
650
527
 
651
528
  return self
652
529
 
@@ -759,7 +636,7 @@ class Agent:
759
636
  agentId = int(self.agentId.split(":")[-1])
760
637
  txHash = self.sdk.web3_client.transact_contract(
761
638
  self.sdk.identity_registry,
762
- "setAgentURI",
639
+ "setAgentUri",
763
640
  agentId,
764
641
  f"ipfs://{ipfsCid}"
765
642
  )
@@ -796,7 +673,7 @@ class Agent:
796
673
  agentId = int(self.agentId.split(":")[-1])
797
674
  txHash = self.sdk.web3_client.transact_contract(
798
675
  self.sdk.identity_registry,
799
- "setAgentURI",
676
+ "setAgentUri",
800
677
  agentId,
801
678
  f"ipfs://{ipfsCid}"
802
679
  )
@@ -838,7 +715,7 @@ class Agent:
838
715
  txHash = self.sdk.web3_client.transact_contract(
839
716
  self.sdk.identity_registry,
840
717
  "register",
841
- "", # Empty agentURI for now
718
+ "", # Empty tokenUri for now
842
719
  metadata_entries
843
720
  )
844
721
 
@@ -943,7 +820,7 @@ class Agent:
943
820
  agentId = int(self.registration_file.agentId.split(":")[-1])
944
821
  txHash = self.sdk.web3_client.transact_contract(
945
822
  self.sdk.identity_registry,
946
- "setAgentURI",
823
+ "setAgentUri",
947
824
  agentId,
948
825
  agentURI
949
826
  )
@@ -969,12 +846,7 @@ class Agent:
969
846
  approve_operator: bool = False,
970
847
  idem: Optional[IdemKey] = None,
971
848
  ) -> Dict[str, Any]:
972
- """Transfer agent ownership.
973
-
974
- Note: When an agent is transferred, the agentWallet is automatically reset
975
- to the zero address on-chain. The new owner must call setAgentWallet() to
976
- set a new wallet address with EIP-712 signature verification.
977
- """
849
+ """Transfer agent ownership."""
978
850
  if not self.registration_file.agentId:
979
851
  raise ValueError("Agent must be registered before transferring")
980
852
 
@@ -991,11 +863,6 @@ class Agent:
991
863
 
992
864
  receipt = self.sdk.web3_client.wait_for_transaction(txHash)
993
865
 
994
- # Note: agentWallet will be reset to zero address by the contract
995
- # Update local state to reflect this
996
- self.registration_file.walletAddress = None
997
- self._last_registered_wallet = None
998
-
999
866
  return {
1000
867
  "txHash": txHash,
1001
868
  "agentId": self.registration_file.agentId,
@@ -1040,10 +907,6 @@ class Agent:
1040
907
 
1041
908
  Only the current owner can transfer the agent.
1042
909
 
1043
- Note: When an agent is transferred, the agentWallet is automatically reset
1044
- to the zero address on-chain. The new owner must call setAgentWallet() to
1045
- set a new wallet address with EIP-712 signature verification.
1046
-
1047
910
  Args:
1048
911
  newOwnerAddress: Ethereum address of the new owner
1049
912
 
@@ -1101,11 +964,6 @@ class Agent:
1101
964
 
1102
965
  logger.debug(f"Agent {self.registration_file.agentId} successfully transferred to {checksum_address}")
1103
966
 
1104
- # Note: agentWallet will be reset to zero address by the contract
1105
- # Update local state to reflect this
1106
- self.registration_file.walletAddress = None
1107
- self._last_registered_wallet = None
1108
-
1109
967
  return {"txHash": txHash, "from": currentOwner, "to": checksum_address, "agentId": self.registration_file.agentId}
1110
968
 
1111
969
  def activate(self, idem: Optional[IdemKey] = None) -> RegistrationFile: