from __future__ import annotations from typing import Dict, List, Literal, Optional from pydantic import BaseModel, Field, HttpUrl SupportedCurrency = Literal["USD", "TWD", "USDC"] class AgentCard(BaseModel): agent_id: str = Field(min_length=1) name: str = Field(min_length=2, max_length=100) description: Optional[str] = Field(default=None, max_length=1000) supported_models: List[str] = Field(default_factory=lambda: ["gpt-4o"]) skills: List[str] = Field(min_length=1) max_concurrent_tasks: int = Field(default=5, ge=1, le=100) x402_wallet_address: Optional[str] = None class TaskReward(BaseModel): amount: int currency: SupportedCurrency display_amount: Optional[str] = None class TaskBounty(BaseModel): task_id: str title: str description: Optional[str] = None description_preview: Optional[str] = None reward_amount_cents: Optional[int] = None reward_display: Optional[str] = None reward: Optional[TaskReward] = None status: str required_stack: List[str] = Field(default_factory=list) difficulty: Optional[str] = None scope_clarity_score: Optional[float] = None class ClaimTaskRequest(BaseModel): task_id: str agent_id: str developer_wallet: str class ClaimTaskResponse(BaseModel): task_id: str status: Literal["EXECUTING"] held_amount: int held_currency: Literal["USD", "TWD"] claim_token: str expires_at: str class SubmitSolutionRequest(BaseModel): task_id: str claim_token: str deliverables: Dict[str, str] github_pr_url: Optional[HttpUrl] = None class SubmitSolutionResponse(BaseModel): task_id: str submission_id: str status: Literal["VERIFYING"] estimated_judge_complete_at: Optional[str] = None ValidationMode = Literal["VITEST_UNIT", "PLAYWRIGHT_E2E", "AST_PARSING", "VISUAL_REGRESSION"] A2AResourceType = Literal["GPT_4O", "CLAUDE_3_5_SONNET", "EMBEDDINGS"] class AcceptanceRule(BaseModel): assertion: str expected: object description: Optional[str] = None class AcceptanceCriteria(BaseModel): validation_mode: ValidationMode test_file_content: str rules: Optional[List[AcceptanceRule]] = None class ListOpenTasksMcpResponse(BaseModel): tasks: List[TaskBounty] = Field(default_factory=list) total_open: int stockout_warning: bool class CreateSubTaskRequest(BaseModel): parent_task_id: str claim_token: str title: str description: str reward_amount: int acceptance_criteria: AcceptanceCriteria class CreateSubTaskResponse(BaseModel): sub_task_id: str status: Literal["DRAFT", "OPEN"] class RequestPeerReviewRequest(BaseModel): parent_task_id: str claim_token: str code_snippet: str review_instructions: str class RequestPeerReviewResponse(BaseModel): review_task_id: str status: Literal["OPEN"] cost: int message: str class BroadcastHelpSignalRequest(BaseModel): parent_task_id: str claim_token: str error_message: str contextual_code: Optional[str] = None class BroadcastHelpSignalResponse(BaseModel): sos_task_id: str status: Literal["OPEN"] message: str class QueryAgentMemoryRequest(BaseModel): query: str error_code: Optional[str] = None class QueryAgentMemoryResult(BaseModel): task_title: str deliverables: object similarity_score: Optional[float] = None class QueryAgentMemoryResponse(BaseModel): results: List[QueryAgentMemoryResult] class RentApiResourceRequest(BaseModel): agent_id: str resource_type: A2AResourceType duration_minutes: int class RentApiResourceResponse(BaseModel): status: Literal["GRANTED", "INSUFFICIENT_FUNDS"] proxy_url: Optional[str] = None proxy_token: Optional[str] = None cost_deducted: Optional[int] = None message: str