Health Universe A2A SDK for Python
# Health Universe A2A SDK for Python # Quick reference for LLM agents (Claude Code, Cursor, Copilot, etc.) # Version: 0.2.0 ## Overview Python SDK for building agents on the Health Universe platform. All agents use async processing with progress updates stored in database. ## Installation ```bash pip install health-universe-a2a ``` ## Quick Start - Minimal Agent ```python from health_universe_a2a import Agent, AgentContext class MyAgent(Agent): def get_agent_name(self) -> str: …
Unclaimed Agent
Are you the maintainer? Claim this agent to manage its listing and increase its trust score.
# Health Universe A2A SDK for Python # Quick reference for LLM agents (Claude Code, Cursor, Copilot, etc.) # Version: 0.2.0 ## Overview Python SDK for building agents on the Health Universe platform. All agents use async processing with progress updates stored in database. ## Installation ```bash pip install health-universe-a2a ``` ## Quick Start - Minimal Agent ```python from health_universe_a2a import Agent, AgentContext class MyAgent(Agent): def get_agent_name(self) -> str: return "My Agent" def get_agent_description(self) -> str: return "Does something useful" async def process_message(self, message: str, context: AgentContext) -> str: return f"Processed: {message}" if __name__ == "__main__": agent = MyAgent() agent.serve() ``` ## Required Methods - `get_agent_name() -> str` - Agent display name - `get_agent_description() -> str` - What the agent does - `process_message(message: str, context: AgentContext) -> str` - Main logic ## Optional Methods - `validate_message(message: str, metadata: dict) -> ValidationResult` - Pre-validation - `get_max_duration_seconds() -> int` - Max task duration (default: 3600) - `on_startup() -> None` - Called at server start - `on_shutdown() -> None` - Called at server stop ## Document Operations (via context.document_client) ```python async def process_message(self, message: str, context: AgentContext) -> str: # List all documents in thread docs = await context.document_client.list_documents() # Filter documents by name protocols = await context.document_client.filter_by_name("protocol") # Read document content content = await context.document_client.download_text(doc_id) binary = await context.document_client.download(doc_id) # Write new document (handles 3-step S3 upload) await context.document_client.write( "Analysis Results", json.dumps({"score": 0.95}), filename="results.json" ) # Update existing document (creates new version) await context.document_client.update(doc_id, new_content) return "Done!" ``` ## Progress Updates ```python async def process_message(self, message: str, context: AgentContext) -> str: await context.update_progress("Loading data...", 0.2) # ... work ... await context.update_progress("Processing...", 0.5) # ... work ... await context.update_progress("Complete!", 1.0) return "Done!" ``` ## Validation ```python from health_universe_a2a import ValidationAccepted, ValidationRejected async def validate_message(self, message: str, metadata: dict): if not message: return ValidationRejected(reason="Empty message") return ValidationAccepted(estimated_duration_seconds=60) ``` ## Inter-Agent Communication ```python async def process_message(self, message: str, context: AgentContext) -> str: # Call another agent with JWT propagation response = await self.call_other_agent("/other-agent", message, context) return response.text # Or with structured data response = await self.call_other_agent_with_data( "/processor", {"query": message}, context ) return json.dumps(response.data) ``` ## Multi-Agent Server ```python from health_universe_a2a import serve_multi_agents serve_multi_agents({ "/analyzer": AnalyzerAgent(), "/processor": ProcessorAgent(), }, port=8000) ``` ## Key Classes - `Agent` (alias: AsyncAgent) - Base class for agents - `AgentContext` (alias: BackgroundContext) - Context passed to process_message - `Document` - Document metadata (id, name, filename, document_type, latest_version) - `DocumentClient` - Client for document operations (via context.document_client) - `ValidationAccepted` - Return from validate_message on success - `ValidationRejected` - Return from validate_message on failure ## AgentContext Properties - `context.user_id: str | None` - User ID from request - `context.thread_id: str | None` - Thread/conversation ID - `context.file_access_token: str | None` - Token for document operations - `context.auth_token: str | None` - JWT for inter-agent calls - `context.document_client: DocumentClient` - Document operations client ## DocumentClient Methods - `list_documents(include_hidden=False) -> list[Document]` - `filter_by_name(query: str) -> list[Document]` - `get_document(document_id: str) -> Document` - `download(document_id: str) -> bytes` - `download_text(document_id: str) -> str` - `write(name, content, filename=None, ...) -> Document` - `update(document_id, content, comment=None) -> Document` ## Document Properties - `doc.id: str` - Document UUID - `doc.name: str` - Display name - `doc.filename: str` - Storage filename - `doc.document_type: str` - "user_upload" or "agent_output" - `doc.latest_version: int | None` - Version number - `doc.user_visible: bool` - Visible to users ## Environment Variables - `HU_APP_URL` or `A2A_BASE_URL` - Agent base URL - `HU_NESTJS_URL` - Document API URL (default: https://apps.healthuniverse.com/api/v1) - `BACKGROUND_UPDATE_URL` - Update API URL (default: https://apps.healthuniverse.com/api/v1) - `LOCAL_AGENT_BASE_URL` - Local agent URL (default: http://localhost:8501) - `HOST` - Server host (default: 0.0.0.0) - `PORT` or `AGENT_PORT` - Server port (default: 8000) ## Example Agents See `examples/` directory: - `simple_agent.py` - Minimal echo agent - `medical_classifier.py` - Symptom classification (no documents) - `document_inventory.py` - List documents and metadata - `protocol_analyzer.py` - Find, read, and analyze documents - `multi_agent_orchestration.py` - Inter-agent communication ## Common Patterns ### Healthcare Data Agent ```python class DataAnalyzer(Agent): def get_agent_name(self) -> str: return "Clinical Data Analyzer" def get_agent_description(self) -> str: return "Analyzes clinical datasets" async def process_message(self, message: str, context: AgentContext) -> str: # Find CSV files csvs = await context.document_client.filter_by_name(".csv") if not csvs: return "No CSV files found" # Read and analyze content = await context.document_client.download_text(csvs[0].id) results = analyze_csv(content) # Save results await context.document_client.write( "Analysis Results", json.dumps(results), filename="analysis.json" ) return f"Analyzed {csvs[0].name}" ``` ### Validation Agent ```python class ValidatedAgent(Agent): async def validate_message(self, message: str, metadata: dict): try: data = json.loads(message) if "required_field" not in data: return ValidationRejected(reason="Missing required_field") return ValidationAccepted(estimated_duration_seconds=120) except json.JSONDecodeError: return ValidationRejected(reason="Invalid JSON") ``` ### Orchestrator Agent ```python class Orchestrator(Agent): async def process_message(self, message: str, context: AgentContext) -> str: # Call analyzer analysis = await self.call_other_agent("/analyzer", message, context) # Call processor with analysis results result = await self.call_other_agent_with_data( "/processor", {"input": message, "analysis": analysis.text}, context ) return result.text ```