Spaces:
Sleeping
Sleeping
| import abc | |
| import time | |
| import uuid | |
| import hashlib | |
| import json | |
| from typing import Dict, Any, Optional | |
| class ToolConnector(abc.ABC): | |
| """ | |
| Abstract Base Class for all typed tool connectors exposed to the brain. | |
| Enforces input schema, output schema, error schema, timeouts, execution IDs, | |
| logging, and result hashes. | |
| """ | |
| def __init__(self, name: str, description: str, timeout_sec: float = 30.0): | |
| self.name = name | |
| self.description = description | |
| self.timeout_sec = timeout_sec | |
| self.execution_history = [] | |
| def input_schema(self) -> Dict[str, Any]: | |
| pass | |
| def output_schema(self) -> Dict[str, Any]: | |
| pass | |
| def error_schema(self) -> Dict[str, Any]: | |
| return { | |
| "type": "object", | |
| "properties": { | |
| "error_code": {"type": "string"}, | |
| "message": {"type": "string"}, | |
| "recoverable": {"type": "boolean"} | |
| }, | |
| "required": ["error_code", "message"] | |
| } | |
| def compute_hash(self, data: Any) -> str: | |
| if isinstance(data, (dict, list)): | |
| serialized = json.dumps(data, sort_keys=True) | |
| elif isinstance(data, bytes): | |
| serialized = data | |
| else: | |
| serialized = str(data) | |
| if isinstance(serialized, str): | |
| serialized = serialized.encode("utf-8") | |
| return hashlib.sha256(serialized).hexdigest() | |
| def run(self, params: Dict[str, Any], execution_id: Optional[str] = None) -> Dict[str, Any]: | |
| exec_id = execution_id or str(uuid.uuid4()) | |
| start_time = time.time() | |
| try: | |
| # Validate input params against schema keys | |
| req_keys = self.input_schema.get("required", []) | |
| for k in req_keys: | |
| if k not in params: | |
| raise ValueError(f"Missing required parameter '{k}' for connector '{self.name}'") | |
| result_payload = self._execute(params, exec_id) | |
| duration = time.time() - start_time | |
| res_hash = self.compute_hash(result_payload) | |
| record = { | |
| "execution_id": exec_id, | |
| "tool": self.name, | |
| "status": "SUCCESS", | |
| "duration_sec": round(duration, 4), | |
| "params": params, | |
| "result": result_payload, | |
| "result_hash": res_hash | |
| } | |
| self.execution_history.append(record) | |
| return record | |
| except Exception as e: | |
| duration = time.time() - start_time | |
| record = { | |
| "execution_id": exec_id, | |
| "tool": self.name, | |
| "status": "ERROR", | |
| "duration_sec": round(duration, 4), | |
| "params": params, | |
| "error": { | |
| "error_code": type(e).__name__, | |
| "message": str(e), | |
| "recoverable": True | |
| }, | |
| "result_hash": None | |
| } | |
| self.execution_history.append(record) | |
| return record | |
| def _execute(self, params: Dict[str, Any], execution_id: str) -> Dict[str, Any]: | |
| pass | |