From e28a192a76095748d8bd0ed49a39b2298ab19573 Mon Sep 17 00:00:00 2001 From: aitbc Date: Mon, 25 May 2026 17:22:38 +0200 Subject: [PATCH] fix: resolve missing module imports for coordinator-api and blockchain-rpc Coordinator API (port 8011): - Install aitbc-agent-core package from local source - Fix agent_core_adapters import path in agent_integration_factory.py - Wrap hermes_enhanced router imports in try/except in routers/__init__.py Blockchain RPC (port 8006): - Rename models.py to base_models.py to allow models/ package - Create models/__init__.py re-exporting from base_models - Create models/dispute.py with all dispute Pydantic models - Fix disputes.py import path for dispute_resolution_service - Update database.py and sync.py to import from base_models - Wrap disputes, contracts, islands, bridge, staking imports in try/except in router.py - Add None checks in endpoint handlers for unavailable modules --- .../aitbc_chain/{models.py => base_models.py} | 0 .../src/aitbc_chain/database.py | 2 +- .../src/aitbc_chain/models/__init__.py | 4 + .../src/aitbc_chain/models/dispute.py | 89 ++++++++ .../src/aitbc_chain/rpc/disputes.py | 2 +- .../src/aitbc_chain/rpc/router.py | 202 ++++++++++++------ apps/blockchain-node/src/aitbc_chain/sync.py | 2 +- .../src/app/routers/__init__.py | 18 +- .../app/services/agent_integration_factory.py | 2 +- 9 files changed, 243 insertions(+), 78 deletions(-) rename apps/blockchain-node/src/aitbc_chain/{models.py => base_models.py} (100%) create mode 100644 apps/blockchain-node/src/aitbc_chain/models/__init__.py create mode 100644 apps/blockchain-node/src/aitbc_chain/models/dispute.py diff --git a/apps/blockchain-node/src/aitbc_chain/models.py b/apps/blockchain-node/src/aitbc_chain/base_models.py similarity index 100% rename from apps/blockchain-node/src/aitbc_chain/models.py rename to apps/blockchain-node/src/aitbc_chain/base_models.py diff --git a/apps/blockchain-node/src/aitbc_chain/database.py b/apps/blockchain-node/src/aitbc_chain/database.py index d5284e6f..44cc7403 100755 --- a/apps/blockchain-node/src/aitbc_chain/database.py +++ b/apps/blockchain-node/src/aitbc_chain/database.py @@ -12,7 +12,7 @@ from sqlalchemy import event from .config import settings # Import all models to ensure they are registered with SQLModel.metadata -from .models import Block, Transaction, Account, Receipt, Escrow # noqa: F401 +from .base_models import Block, Transaction, Account, Receipt, Escrow # noqa: F401 # Database encryption key (in production, this should come from HSM or secure key storage) _DB_ENCRYPTION_KEY = os.environ.get("AITBC_DB_KEY", "default_encryption_key_change_in_production") diff --git a/apps/blockchain-node/src/aitbc_chain/models/__init__.py b/apps/blockchain-node/src/aitbc_chain/models/__init__.py new file mode 100644 index 00000000..a50951e8 --- /dev/null +++ b/apps/blockchain-node/src/aitbc_chain/models/__init__.py @@ -0,0 +1,4 @@ +"""Blockchain chain models package.""" +# Re-export all models from base_models.py (the original models.py renamed) +# This package also contains sub-modules like dispute.py +from ..base_models import * # noqa: F403, E402 \ No newline at end of file diff --git a/apps/blockchain-node/src/aitbc_chain/models/dispute.py b/apps/blockchain-node/src/aitbc_chain/models/dispute.py new file mode 100644 index 00000000..0e705af9 --- /dev/null +++ b/apps/blockchain-node/src/aitbc_chain/models/dispute.py @@ -0,0 +1,89 @@ +"""Dispute-related Pydantic models for RPC endpoints.""" +from typing import Any, Dict, List, Optional +from pydantic import BaseModel, Field +from datetime import datetime + + +class FileDisputeRequest(BaseModel): + agreement_id: int + respondent: str + dispute_type: str + reason: str + evidence_hash: str + + +class FileDisputeResponse(BaseModel): + dispute_id: int + status: str + timestamp: str + + +class SubmitEvidenceRequest(BaseModel): + dispute_id: int + evidence_hash: str + evidence_type: str + description: str + + +class SubmitEvidenceResponse(BaseModel): + evidence_id: int + status: str + + +class VerifyEvidenceRequest(BaseModel): + dispute_id: int + evidence_id: int + verified: bool + + +class VerifyEvidenceResponse(BaseModel): + status: str + + +class SubmitArbitrationVoteRequest(BaseModel): + dispute_id: int + vote: str # "plaintiff" or "defendant" + reasoning: str + + +class SubmitArbitrationVoteResponse(BaseModel): + status: str + vote_id: int + + +class AuthorizeArbitratorRequest(BaseModel): + arbitrator_address: str + authorized: bool + + +class AuthorizeArbitratorResponse(BaseModel): + status: str + + +class GetDisputeResponse(BaseModel): + dispute_id: int + agreement_id: int + plaintiff: str + respondent: str + dispute_type: str + reason: str + status: str + created_at: str + evidence: List[Dict[str, Any]] = [] + votes: List[Dict[str, Any]] = [] + + +class GetEvidenceResponse(BaseModel): + evidence_id: int + dispute_id: int + evidence_hash: str + evidence_type: str + description: str + submitted_by: str + verified: bool + created_at: str + + +class GetArbitrationVotesResponse(BaseModel): + dispute_id: int + votes: List[Dict[str, Any]] = [] diff --git a/apps/blockchain-node/src/aitbc_chain/rpc/disputes.py b/apps/blockchain-node/src/aitbc_chain/rpc/disputes.py index e2b7e5f1..ef3a84ed 100644 --- a/apps/blockchain-node/src/aitbc_chain/rpc/disputes.py +++ b/apps/blockchain-node/src/aitbc_chain/rpc/disputes.py @@ -12,7 +12,7 @@ from .auth import get_authenticated_address _logger = get_logger(__name__) # Import dispute resolution service and models -from ..services.dispute_resolution import dispute_resolution_service +from ..rpc.dispute_resolution_service import dispute_resolution_service from ..models.dispute import ( FileDisputeRequest, FileDisputeResponse, diff --git a/apps/blockchain-node/src/aitbc_chain/rpc/router.py b/apps/blockchain-node/src/aitbc_chain/rpc/router.py index 6c03a94f..cae44601 100644 --- a/apps/blockchain-node/src/aitbc_chain/rpc/router.py +++ b/apps/blockchain-node/src/aitbc_chain/rpc/router.py @@ -31,6 +31,8 @@ from .utils import ( from aitbc.rate_limiting import rate_limit +_logger = get_logger(__name__) + # Import domain modules from .blocks import ( get_genesis_allocations, @@ -55,51 +57,60 @@ from .accounts import ( get_balance_breakdown, reconcile_balance, ) -from .disputes import ( - file_dispute, - submit_evidence, - verify_evidence, - submit_arbitration_vote, - authorize_arbitrator, - get_active_disputes, - get_authorized_arbitrators, - get_arbitrator_disputes, - get_user_disputes, - get_dispute, - get_dispute_evidence, - get_arbitration_votes, -) -from ..models.dispute import ( - FileDisputeRequest, - FileDisputeResponse, - SubmitEvidenceRequest, - SubmitEvidenceResponse, - VerifyEvidenceRequest, - VerifyEvidenceResponse, - SubmitArbitrationVoteRequest, - SubmitArbitrationVoteResponse, - AuthorizeArbitratorRequest, - AuthorizeArbitratorResponse, - GetDisputeResponse, - GetEvidenceResponse, - GetArbitrationVotesResponse, -) -from .contracts import ( - deploy_messaging_contract, - list_contracts, - deploy_contract, - call_contract, - verify_contract, - get_messaging_contract_state, - get_forum_topics, - create_forum_topic, - get_topic_messages, - post_message, - vote_message, - search_messages, - get_agent_reputation, - moderate_message, -) +try: + from .disputes import ( + file_dispute, + submit_evidence, + verify_evidence, + submit_arbitration_vote, + authorize_arbitrator, + get_active_disputes, + get_authorized_arbitrators, + get_arbitrator_disputes, + get_user_disputes, + get_dispute, + get_dispute_evidence, + get_arbitration_votes, + ) +except ImportError: + _logger.warning("Disputes module not available") +try: + from ..models.dispute import ( + FileDisputeRequest, + FileDisputeResponse, + SubmitEvidenceRequest, + SubmitEvidenceResponse, + VerifyEvidenceRequest, + VerifyEvidenceResponse, + SubmitArbitrationVoteRequest, + SubmitArbitrationVoteResponse, + AuthorizeArbitratorRequest, + AuthorizeArbitratorResponse, + GetDisputeResponse, + GetEvidenceResponse, + GetArbitrationVotesResponse, + ) +except ImportError: + _logger.warning("Dispute models not available") +try: + from .contracts import ( + deploy_messaging_contract, + list_contracts, + deploy_contract, + call_contract, + verify_contract, + get_messaging_contract_state, + get_forum_topics, + create_forum_topic, + get_topic_messages, + post_message, + vote_message, + search_messages, + get_agent_reputation, + moderate_message, + ) +except ImportError: + _logger.warning("Contracts module not available") from .sync import ( export_chain, import_chain, @@ -110,32 +121,57 @@ from .gossip import ( GetLogsRequest, GetLogsResponse, ) -from .islands import ( - join_island, - leave_island, - list_islands, - get_island, - request_bridge, - JoinIslandRequest, - JoinIslandResponse, - LeaveIslandRequest, - LeaveIslandResponse, - BridgeRequestRequest, - BridgeRequestResponse, -) -from .bridge import ( - bridge_lock, - bridge_confirm, - get_bridge_transfer, - list_pending_transfers, -) -from .staking import ( - stake_tokens, - unstake_tokens, - get_staking_info, -) - -_logger = get_logger(__name__) +try: + from .islands import ( + join_island, + leave_island, + list_islands, + get_island, + request_bridge, + JoinIslandRequest, + JoinIslandResponse, + LeaveIslandRequest, + LeaveIslandResponse, + BridgeRequestRequest, + BridgeRequestResponse, + ) +except ImportError: + _logger.warning("Islands module not available") + join_island = None + leave_island = None + list_islands = None + get_island = None + request_bridge = None + JoinIslandRequest = None + JoinIslandResponse = None + LeaveIslandRequest = None + LeaveIslandResponse = None + BridgeRequestRequest = None + BridgeRequestResponse = None +try: + from .bridge import ( + bridge_lock, + bridge_confirm, + get_bridge_transfer, + list_pending_transfers, + ) +except ImportError: + _logger.warning("Bridge module not available") + bridge_lock = None + bridge_confirm = None + get_bridge_transfer = None + list_pending_transfers = None +try: + from .staking import ( + stake_tokens, + unstake_tokens, + get_staking_info, + ) +except ImportError: + _logger.warning("Staking module not available") + stake_tokens = None + unstake_tokens = None + get_staking_info = None # Security scheme for authentication security = HTTPBearer(auto_error=False) @@ -588,12 +624,16 @@ async def get_logs_route( @router.post("/islands/join", summary="Join an island") async def join_island_route(request: JoinIslandRequest) -> JoinIslandResponse: """Join an island for edge compute operations""" + if join_island is None: + raise HTTPException(status_code=501, detail="Islands module not available") return await join_island(request) @router.post("/islands/leave", summary="Leave an island") async def leave_island_route(request: LeaveIslandRequest) -> LeaveIslandResponse: """Leave an island""" + if leave_island is None: + raise HTTPException(status_code=501, detail="Islands module not available") return await leave_island(request) @@ -601,6 +641,8 @@ async def leave_island_route(request: LeaveIslandRequest) -> LeaveIslandResponse @rate_limit(rate=100, per=60) async def list_islands_route() -> Dict[str, Any]: """List all islands that the node is a member of""" + if list_islands is None: + raise HTTPException(status_code=501, detail="Islands module not available") return await list_islands() @@ -608,12 +650,16 @@ async def list_islands_route() -> Dict[str, Any]: @rate_limit(rate=100, per=60) async def get_island_route(island_id: str) -> Dict[str, Any]: """Get details about a specific island""" + if get_island is None: + raise HTTPException(status_code=501, detail="Islands module not available") return await get_island(island_id) @router.post("/islands/bridge", summary="Request a bridge to another island") async def request_bridge_route(request: BridgeRequestRequest) -> BridgeRequestResponse: """Request a bridge to another island for cross-island communication""" + if request_bridge is None: + raise HTTPException(status_code=501, detail="Islands module not available") return await request_bridge(request) @@ -628,6 +674,8 @@ async def bridge_lock_route( lock_data: dict ) -> Dict[str, Any]: """Initiate a cross-chain bridge transfer by locking funds""" + if bridge_lock is None: + raise HTTPException(status_code=501, detail="Bridge module not available") return await bridge_lock(request, lock_data) @@ -638,6 +686,8 @@ async def bridge_confirm_route( confirm_data: dict ) -> Dict[str, Any]: """Confirm a cross-chain bridge transfer and release funds""" + if bridge_confirm is None: + raise HTTPException(status_code=501, detail="Bridge module not available") return await bridge_confirm(request, confirm_data) @@ -648,6 +698,8 @@ async def get_bridge_transfer_route( transfer_id: str ) -> Dict[str, Any]: """Get the status of a cross-chain transfer""" + if get_bridge_transfer is None: + raise HTTPException(status_code=501, detail="Bridge module not available") return await get_bridge_transfer(request, transfer_id) @@ -658,6 +710,8 @@ async def list_pending_transfers_route( chain_id: str = None ) -> List[Dict[str, Any]]: """List all pending cross-chain transfers""" + if list_pending_transfers is None: + raise HTTPException(status_code=501, detail="Bridge module not available") return await list_pending_transfers(request, chain_id) @@ -672,6 +726,8 @@ async def stake_tokens_route( stake_data: dict ) -> Dict[str, Any]: """Stake tokens for consensus participation""" + if stake_tokens is None: + raise HTTPException(status_code=501, detail="Staking module not available") return await stake_tokens(request, stake_data) @@ -682,6 +738,8 @@ async def unstake_tokens_route( unstake_data: dict ) -> Dict[str, Any]: """Unstake tokens after lock period expires""" + if unstake_tokens is None: + raise HTTPException(status_code=501, detail="Staking module not available") return await unstake_tokens(request, unstake_data) @@ -693,4 +751,6 @@ async def get_staking_info_route( chain_id: str = None ) -> Dict[str, Any]: """Get staking information for an address""" + if get_staking_info is None: + raise HTTPException(status_code=501, detail="Staking module not available") return await get_staking_info(request, address, chain_id) diff --git a/apps/blockchain-node/src/aitbc_chain/sync.py b/apps/blockchain-node/src/aitbc_chain/sync.py index 4eca2f9b..223e197e 100755 --- a/apps/blockchain-node/src/aitbc_chain/sync.py +++ b/apps/blockchain-node/src/aitbc_chain/sync.py @@ -16,7 +16,7 @@ from sqlmodel import Session, select from .config import settings from .metrics import metrics_registry -from .models import Block, Transaction as ChainTransaction, Account +from .base_models import Block, Transaction as ChainTransaction, Account from .logger import get_logger from .state.merkle_patricia_trie import StateManager from .state.state_transition import get_state_transition diff --git a/apps/coordinator-api/src/app/routers/__init__.py b/apps/coordinator-api/src/app/routers/__init__.py index 07094100..4af5114c 100755 --- a/apps/coordinator-api/src/app/routers/__init__.py +++ b/apps/coordinator-api/src/app/routers/__init__.py @@ -80,9 +80,21 @@ except ImportError: logger.warning("Trading router not available") # Hermes routers moved to contexts/hermes -from ..contexts.hermes.routers.hermes_enhanced import router as hermes_enhanced -from ..contexts.hermes.routers.hermes_enhanced_simple import router as hermes_enhanced_simple -from ..contexts.hermes.routers.hermes_enhanced_health import router as hermes_enhanced_health +try: + from ..contexts.hermes.routers.hermes_enhanced import router as hermes_enhanced +except ImportError: + hermes_enhanced = None # type: ignore[assignment] + logger.warning("Hermes enhanced router not available") +try: + from ..contexts.hermes.routers.hermes_enhanced_simple import router as hermes_enhanced_simple +except ImportError: + hermes_enhanced_simple = None # type: ignore[assignment] + logger.warning("Hermes enhanced simple router not available") +try: + from ..contexts.hermes.routers.hermes_enhanced_health import router as hermes_enhanced_health +except ImportError: + hermes_enhanced_health = None # type: ignore[assignment] + logger.warning("Hermes enhanced health router not available") from .hermes import router as hermes # Security router moved to contexts/security diff --git a/apps/coordinator-api/src/app/services/agent_integration_factory.py b/apps/coordinator-api/src/app/services/agent_integration_factory.py index a56916ac..7ad7e8b4 100644 --- a/apps/coordinator-api/src/app/services/agent_integration_factory.py +++ b/apps/coordinator-api/src/app/services/agent_integration_factory.py @@ -6,7 +6,7 @@ This enables gradual migration from duplicated code to shared implementation. from sqlmodel import Session from aitbc_agent_core import AgentIntegrationService -from .adapters.agent_core_adapters import ( +from ..adapters.agent_core_adapters import ( AgentSecurityManagerAdapter, AgentAuditorAdapter, AgentOrchestratorAdapter,