polyrob 0.5.0__py3-none-any.whl
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.
- agents/README.md +453 -0
- agents/__init__.py +164 -0
- agents/base_agent.py +743 -0
- agents/personality/character.py +119 -0
- agents/personality/character_manager.py +309 -0
- agents/personality/characters/rob.character.json +56 -0
- agents/personality/characters/trump.character.json +63 -0
- agents/personality/persona_render.py +78 -0
- agents/personality/persona_resolver.py +115 -0
- agents/prompt/__init__.py +58 -0
- agents/prompt/base_prompt.py +92 -0
- agents/prompt/system.py +417 -0
- agents/task/README_PATH_MANAGEMENT.md +141 -0
- agents/task/__init__.py +162 -0
- agents/task/agent/__init__.py +70 -0
- agents/task/agent/agent_state.py +408 -0
- agents/task/agent/async_delegation.py +274 -0
- agents/task/agent/autonomy_state.py +275 -0
- agents/task/agent/conversation.py +75 -0
- agents/task/agent/core/__init__.py +6 -0
- agents/task/agent/core/aux_metering.py +61 -0
- agents/task/agent/core/background_review.py +157 -0
- agents/task/agent/core/construction.py +1179 -0
- agents/task/agent/core/conversational_exit.py +49 -0
- agents/task/agent/core/correspondent_gate.py +227 -0
- agents/task/agent/core/curator.py +246 -0
- agents/task/agent/core/episodic_digest.py +103 -0
- agents/task/agent/core/error_recovery.py +480 -0
- agents/task/agent/core/history_io.py +257 -0
- agents/task/agent/core/llm_provisioning.py +287 -0
- agents/task/agent/core/llm_runner.py +547 -0
- agents/task/agent/core/logging_io.py +276 -0
- agents/task/agent/core/loop_detection.py +262 -0
- agents/task/agent/core/memory_prefetch.py +325 -0
- agents/task/agent/core/memory_writer.py +667 -0
- agents/task/agent/core/model_introspection.py +82 -0
- agents/task/agent/core/model_swap.py +177 -0
- agents/task/agent/core/next_action_internal.py +1331 -0
- agents/task/agent/core/output_validation.py +303 -0
- agents/task/agent/core/project_context.py +272 -0
- agents/task/agent/core/resources.py +93 -0
- agents/task/agent/core/result_processing.py +389 -0
- agents/task/agent/core/run_loop.py +661 -0
- agents/task/agent/core/safety_lifecycle.py +228 -0
- agents/task/agent/core/secret_guard.py +293 -0
- agents/task/agent/core/self_wake.py +280 -0
- agents/task/agent/core/session_metadata.py +104 -0
- agents/task/agent/core/step.py +781 -0
- agents/task/agent/core/step_execution.py +398 -0
- agents/task/agent/core/step_telemetry.py +222 -0
- agents/task/agent/core/test_aux_metering.py +50 -0
- agents/task/agent/core/test_billing_failover.py +68 -0
- agents/task/agent/core/test_fatal_error_classifier.py +38 -0
- agents/task/agent/core/test_judge_validation.py +275 -0
- agents/task/agent/core/test_model_swap.py +190 -0
- agents/task/agent/core/test_reflection_offload.py +54 -0
- agents/task/agent/core/turn_input.py +8 -0
- agents/task/agent/core/untrusted_wrap.py +103 -0
- agents/task/agent/core/user_ingress.py +228 -0
- agents/task/agent/hitl_manager.py +396 -0
- agents/task/agent/log_sanitize.py +36 -0
- agents/task/agent/message_manager/config.py +97 -0
- agents/task/agent/message_manager/service.py +758 -0
- agents/task/agent/message_manager/tests.py +305 -0
- agents/task/agent/message_manager/tool_call_builder.py +539 -0
- agents/task/agent/message_manager/tool_message_repair.py +364 -0
- agents/task/agent/message_manager/views.py +143 -0
- agents/task/agent/messages/__init__.py +8 -0
- agents/task/agent/messages/builders.py +309 -0
- agents/task/agent/messages/compactor.py +611 -0
- agents/task/agent/messages/context_references.py +271 -0
- agents/task/agent/messages/filters.py +333 -0
- agents/task/agent/messages/guidance.py +328 -0
- agents/task/agent/messages/persistence.py +448 -0
- agents/task/agent/messages/retrieval.py +506 -0
- agents/task/agent/messages/sqlite_persistence.py +85 -0
- agents/task/agent/messages/test_compaction_upgrade.py +349 -0
- agents/task/agent/messages/test_persistence_subdir_fix.py +28 -0
- agents/task/agent/messages/test_sqlite_persistence.py +54 -0
- agents/task/agent/messages/token_counter.py +532 -0
- agents/task/agent/orchestrator.py +776 -0
- agents/task/agent/profile_manager.py +105 -0
- agents/task/agent/profile_registry.py +173 -0
- agents/task/agent/prompts.py +1090 -0
- agents/task/agent/scenario_registry.py +226 -0
- agents/task/agent/service.py +509 -0
- agents/task/agent/session.py +984 -0
- agents/task/agent/skill_discovery.py +110 -0
- agents/task/agent/skill_frontmatter.py +94 -0
- agents/task/agent/skill_manager.py +1201 -0
- agents/task/agent/skill_store.py +627 -0
- agents/task/agent/skill_validation.py +56 -0
- agents/task/agent/skill_writer.py +492 -0
- agents/task/agent/sub_agent_manager.py +1137 -0
- agents/task/agent/test_session_disk_recovery.py +34 -0
- agents/task/agent/tests.py +513 -0
- agents/task/agent/tool_call_tracker.py +511 -0
- agents/task/agent/views.py +469 -0
- agents/task/config.py +432 -0
- agents/task/constants.py +1384 -0
- agents/task/flag_defaults.py +63 -0
- agents/task/goals/__init__.py +1 -0
- agents/task/goals/autonomy_marker.py +28 -0
- agents/task/goals/board.py +690 -0
- agents/task/goals/completion_judge.py +247 -0
- agents/task/goals/context.py +62 -0
- agents/task/goals/dispatcher.py +848 -0
- agents/task/goals/escalation.py +102 -0
- agents/task/goals/planner.py +114 -0
- agents/task/logging_config.py +155 -0
- agents/task/path.py +991 -0
- agents/task/robust_parse_config.py +400 -0
- agents/task/runtime/__init__.py +0 -0
- agents/task/runtime/run_as_session.py +130 -0
- agents/task/runtime_safety.py +308 -0
- agents/task/session/__init__.py +5 -0
- agents/task/session/browser_pool.py +130 -0
- agents/task/session/cleanup.py +612 -0
- agents/task/session/execution.py +397 -0
- agents/task/session/feed.py +200 -0
- agents/task/session/hitl_ingress.py +201 -0
- agents/task/session/hooks.py +83 -0
- agents/task/session/multi_agent.py +243 -0
- agents/task/session/workspace.py +91 -0
- agents/task/session_registry.py +91 -0
- agents/task/session_route.py +35 -0
- agents/task/sqlite_session_registry.py +261 -0
- agents/task/surface_config.py +185 -0
- agents/task/telemetry/__init__.py +58 -0
- agents/task/telemetry/event_log.py +180 -0
- agents/task/telemetry/formatters.py +642 -0
- agents/task/telemetry/manager.py +571 -0
- agents/task/telemetry/memory_events.py +66 -0
- agents/task/telemetry/self_events.py +53 -0
- agents/task/telemetry/sequence.py +160 -0
- agents/task/telemetry/service.py +1265 -0
- agents/task/telemetry/views.py +882 -0
- agents/task/templates.py +98 -0
- agents/task/test_aux_chain.py +151 -0
- agents/task/test_aux_router.py +41 -0
- agents/task/tests/test_parse_robustness.py +170 -0
- agents/task/tool_defaults.py +110 -0
- agents/task/utils.py +762 -0
- agents/task/utils_json.py +768 -0
- agents/task/utils_webview.py +86 -0
- agents/task/workspace_context.py +229 -0
- agents/task_agent_lite.py +2398 -0
- api/README.md +683 -0
- api/TASK_API_DOCS.md +151 -0
- api/__init__.py +0 -0
- api/a2a/__init__.py +37 -0
- api/a2a/agent_card.py +337 -0
- api/a2a/client.py +657 -0
- api/a2a/endpoints.py +375 -0
- api/a2a/models.py +268 -0
- api/a2a/streaming.py +419 -0
- api/a2a/task_handler.py +929 -0
- api/admin_endpoints.py +1584 -0
- api/app.py +923 -0
- api/auth_constants.py +28 -0
- api/auth_endpoints.py +402 -0
- api/auth_state.py +36 -0
- api/chat_via_task.py +42 -0
- api/conversation_manager.py +231 -0
- api/dependencies.py +186 -0
- api/eip8004_endpoints.py +452 -0
- api/hyperliquid_models.py +174 -0
- api/hyperliquid_routes.py +450 -0
- api/interfaces.py +207 -0
- api/jwt_middleware.py +83 -0
- api/kb/__init__.py +1 -0
- api/kb/endpoints.py +314 -0
- api/mcp_models.py +279 -0
- api/mcp_routes.py +438 -0
- api/middleware.py +526 -0
- api/models.py +176 -0
- api/openai_compat/__init__.py +0 -0
- api/openai_compat/model_map.py +25 -0
- api/openai_compat/models.py +59 -0
- api/openai_compat/router.py +140 -0
- api/payment_endpoints.py +444 -0
- api/payment_verification.py +138 -0
- api/polymarket_models.py +155 -0
- api/polymarket_routes.py +501 -0
- api/pricing_endpoints.py +89 -0
- api/session_routing.py +54 -0
- api/skill_endpoints.py +453 -0
- api/task_http_api.py +1856 -0
- api/webhooks.py +52 -0
- api/x402_endpoints.py +280 -0
- avatar/README.md +44 -0
- avatar/__init__.py +1 -0
- avatar/config/rob.json +7 -0
- avatar/mindprint.js +395 -0
- avatar/renders/rob.meta.json +20 -0
- avatar/renders/rob.png +0 -0
- avatar/studio.html +373 -0
- avatar/webview/avatar-live.js +44 -0
- cli/README.md +89 -0
- cli/__init__.py +0 -0
- cli/cli_surface.py +67 -0
- cli/commands/__init__.py +0 -0
- cli/commands/_bootstrap.py +49 -0
- cli/commands/_errors.py +53 -0
- cli/commands/chat.py +973 -0
- cli/commands/config.py +100 -0
- cli/commands/dashboard.py +103 -0
- cli/commands/doctor.py +222 -0
- cli/commands/email.py +174 -0
- cli/commands/gateway.py +346 -0
- cli/commands/goals.py +509 -0
- cli/commands/init.py +276 -0
- cli/commands/journey.py +30 -0
- cli/commands/kb.py +280 -0
- cli/commands/model.py +107 -0
- cli/commands/owner.py +431 -0
- cli/commands/pfp.py +232 -0
- cli/commands/run.py +414 -0
- cli/commands/serve.py +41 -0
- cli/commands/session.py +684 -0
- cli/commands/skill_install.py +786 -0
- cli/commands/skills.py +128 -0
- cli/commands/subagents.py +100 -0
- cli/commands/surface.py +81 -0
- cli/commands/telegram.py +185 -0
- cli/commands/todos.py +209 -0
- cli/commands/tools.py +102 -0
- cli/commands/update.py +316 -0
- cli/commands/whatsapp.py +175 -0
- cli/config_store.py +276 -0
- cli/gitignore.py +43 -0
- cli/inventory.py +46 -0
- cli/keys.py +101 -0
- cli/persona.py +17 -0
- cli/polyrob.py +137 -0
- cli/ui/__init__.py +64 -0
- cli/ui/activity.py +141 -0
- cli/ui/app.py +538 -0
- cli/ui/banner.py +233 -0
- cli/ui/blocks.py +534 -0
- cli/ui/bootstrap_notice.py +47 -0
- cli/ui/commands/__init__.py +41 -0
- cli/ui/commands/h_cron.py +64 -0
- cli/ui/commands/h_journey.py +164 -0
- cli/ui/commands/h_kb.py +121 -0
- cli/ui/commands/h_learn.py +100 -0
- cli/ui/commands/h_mcp.py +215 -0
- cli/ui/commands/h_self.py +113 -0
- cli/ui/commands/h_skills.py +314 -0
- cli/ui/commands/handlers.py +1672 -0
- cli/ui/commands/registry.py +426 -0
- cli/ui/dialog.py +425 -0
- cli/ui/event_registry.py +110 -0
- cli/ui/event_specs.py +45 -0
- cli/ui/events.py +433 -0
- cli/ui/identity.py +15 -0
- cli/ui/lifecycle.py +159 -0
- cli/ui/live_hooks.py +43 -0
- cli/ui/model_selector.py +532 -0
- cli/ui/persistent_loop.py +181 -0
- cli/ui/pick.py +113 -0
- cli/ui/plain_renderer.py +351 -0
- cli/ui/renderer.py +384 -0
- cli/ui/rich_renderer.py +533 -0
- cli/ui/secrets.py +115 -0
- cli/ui/state.py +376 -0
- cli/ui/statusbar.py +231 -0
- cli/ui/streaming.py +254 -0
- cli/ui/terminal_render.py +105 -0
- cli/ui/theme.py +132 -0
- cli/update/__init__.py +6 -0
- cli/update/context.py +121 -0
- cli/update/detect.py +176 -0
- cli/update/engine.py +95 -0
- cli/update/migrate_guarded.py +55 -0
- cli/update/process_guard.py +215 -0
- cli/update/runners.py +78 -0
- cli/update/snapshot.py +270 -0
- cli/update/versions.py +205 -0
- core/README.md +377 -0
- core/__init__.py +174 -0
- core/assets.py +87 -0
- core/async_bridge.py +76 -0
- core/autonomy_runtime.py +259 -0
- core/base_component.py +302 -0
- core/bootstrap.py +681 -0
- core/bot.py +310 -0
- core/config.py +833 -0
- core/constants.py +126 -0
- core/container.py +462 -0
- core/db_manifest.py +101 -0
- core/embedding.py +57 -0
- core/env.py +39 -0
- core/exceptions.py +287 -0
- core/flags.py +144 -0
- core/flags_catalog.py +345 -0
- core/home_migration.py +62 -0
- core/identity.py +118 -0
- core/initialization.py +1004 -0
- core/instance.py +537 -0
- core/interactive_gate.py +96 -0
- core/logging.py +436 -0
- core/owner_doc_writer.py +176 -0
- core/pairing.py +193 -0
- core/path_safety.py +20 -0
- core/paths.py +27 -0
- core/payment_config.py +21 -0
- core/permissions.py +322 -0
- core/runtime_config.py +96 -0
- core/runtime_paths.py +135 -0
- core/seams.py +35 -0
- core/secret_scan.py +25 -0
- core/secret_scrub.py +71 -0
- core/secrets.py +35 -0
- core/security_logging_filter.py +148 -0
- core/self_context_writer.py +333 -0
- core/self_evolution.py +294 -0
- core/session_context.py +47 -0
- core/sqlite_util.py +59 -0
- core/surfaces/__init__.py +16 -0
- core/surfaces/access.py +118 -0
- core/surfaces/binding.py +88 -0
- core/surfaces/bootstrap.py +78 -0
- core/surfaces/circuit.py +168 -0
- core/surfaces/continuity.py +77 -0
- core/surfaces/correspondents.py +228 -0
- core/surfaces/dispatcher.py +216 -0
- core/surfaces/envelopes.py +75 -0
- core/surfaces/gc.py +30 -0
- core/surfaces/idempotency.py +57 -0
- core/surfaces/inbound_webhook.py +124 -0
- core/surfaces/media.py +32 -0
- core/surfaces/message_router.py +91 -0
- core/surfaces/outbound_allowlist.py +80 -0
- core/surfaces/outbound_dispatcher.py +110 -0
- core/surfaces/outbound_mirror.py +37 -0
- core/surfaces/outbound_queue.py +107 -0
- core/surfaces/outbound_target.py +12 -0
- core/surfaces/owner_admin.py +29 -0
- core/surfaces/proactive.py +78 -0
- core/surfaces/progress.py +108 -0
- core/surfaces/rate_bucket.py +21 -0
- core/surfaces/registry.py +51 -0
- core/surfaces/rendering.py +53 -0
- core/surfaces/send_policy.py +14 -0
- core/surfaces/serialize.py +24 -0
- core/surfaces/session_chat_registry.py +112 -0
- core/surfaces/session_policy.py +60 -0
- core/surfaces/surface.py +288 -0
- core/surfaces/transcription.py +88 -0
- core/surfaces/voice_echo.py +26 -0
- core/surfaces/voice_guard.py +23 -0
- core/tickers.py +174 -0
- core/tool_catalog.py +192 -0
- core/version.py +75 -0
- core/wallet/__init__.py +5 -0
- core/wallet/agent_wallet.py +59 -0
- core/wallet/audit_sink.py +61 -0
- core/wallet/config.py +70 -0
- core/wallet/factory.py +87 -0
- core/wallet/policy.py +104 -0
- core/wallet/signer.py +51 -0
- cron/README.md +65 -0
- cron/__init__.py +0 -0
- cron/delivery.py +277 -0
- cron/digest.py +124 -0
- cron/jobs.py +207 -0
- cron/runner.py +297 -0
- cron/schedule.py +194 -0
- cron/scheduler.py +201 -0
- cron/service.py +57 -0
- cron/wake_gate.py +223 -0
- data/__init__.py +1 -0
- data/prompts/autov2_prompts.json +87 -0
- data/prompts/skills/browser-automation/SKILL.md +43 -0
- data/prompts/skills/coding-workflow/SKILL.md +36 -0
- data/prompts/skills/crypto-trading-safety/SKILL.md +53 -0
- data/prompts/skills/document-writing/SKILL.md +33 -0
- data/prompts/skills/email-comms/SKILL.md +33 -0
- data/prompts/skills/file-data-ops/SKILL.md +35 -0
- data/prompts/skills/hyperliquid-account-review/SKILL.md +48 -0
- data/prompts/skills/hyperliquid-market-data/SKILL.md +52 -0
- data/prompts/skills/hyperliquid-trading/SKILL.md +59 -0
- data/prompts/skills/lead-research/SKILL.md +86 -0
- data/prompts/skills/market-research-brief/SKILL.md +104 -0
- data/prompts/skills/person-analyzer/SKILL.md +124 -0
- data/prompts/skills/polymarket-market-research/SKILL.md +54 -0
- data/prompts/skills/polymarket-portfolio-review/SKILL.md +50 -0
- data/prompts/skills/polymarket-trading/SKILL.md +55 -0
- data/prompts/skills/presentation-creator/SKILL.md +36 -0
- data/prompts/skills/project-analyzer/SKILL.md +169 -0
- data/prompts/skills/rules.json +268 -0
- data/prompts/skills/secret-handling/SKILL.md +20 -0
- data/prompts/skills/skill-authoring/SKILL.md +31 -0
- data/prompts/skills/skill-security-review/SKILL.md +27 -0
- data/prompts/skills/social-discovery/SKILL.md +57 -0
- data/prompts/skills/task-planning/SKILL.md +33 -0
- data/prompts/skills/web-research/SKILL.md +39 -0
- data/prompts/skills/web-scraping/SKILL.md +73 -0
- data/prompts/skills/x-engagement/SKILL.md +69 -0
- data/prompts/system_prompts.json +4 -0
- data/subscription_channels.json +5 -0
- modules/README.md +503 -0
- modules/__init__.py +124 -0
- modules/auth/__init__.py +13 -0
- modules/auth/api_key_manager.py +157 -0
- modules/auth/identity_mapper.py +380 -0
- modules/auth/siwe_auth.py +273 -0
- modules/auth/tier_manager.py +173 -0
- modules/base_module.py +190 -0
- modules/credits/__init__.py +29 -0
- modules/credits/balance_manager.py +237 -0
- modules/credits/cost_utils.py +129 -0
- modules/credits/pricing.py +139 -0
- modules/credits/unified_ledger.py +148 -0
- modules/credits/usage_meter.py +310 -0
- modules/credits/usage_tracker.py +674 -0
- modules/database/__init__.py +33 -0
- modules/database/audit_log.py +322 -0
- modules/database/auth_tables.py +276 -0
- modules/database/connection.py +644 -0
- modules/database/connection_pool.py +305 -0
- modules/database/conversation_contexts.py +446 -0
- modules/database/database_manager.py +237 -0
- modules/database/hyperliquid.py +375 -0
- modules/database/polymarket.py +574 -0
- modules/database/user_mcp_servers.py +728 -0
- modules/database/user_profiles.py +562 -0
- modules/database/utils.py +107 -0
- modules/database/x402_tables.py +92 -0
- modules/eip8004/README.md +1069 -0
- modules/eip8004/__init__.py +65 -0
- modules/eip8004/contracts.py +498 -0
- modules/eip8004/models.py +271 -0
- modules/eip8004/registration.py +148 -0
- modules/eip8004/reputation.py +367 -0
- modules/eip8004/validation.py +277 -0
- modules/llm/__init__.py +97 -0
- modules/llm/adapters.py +963 -0
- modules/llm/anthropic_client.py +831 -0
- modules/llm/available_models.py +106 -0
- modules/llm/brain_scrubber.py +137 -0
- modules/llm/cache_hints.py +162 -0
- modules/llm/deepseek_client.py +562 -0
- modules/llm/gemini_client.py +1367 -0
- modules/llm/llm_client.py +1139 -0
- modules/llm/llm_client_registry.py +188 -0
- modules/llm/llm_factory.py +237 -0
- modules/llm/llm_manager.py +1036 -0
- modules/llm/messages.py +374 -0
- modules/llm/model_registry.py +1935 -0
- modules/llm/nvidia_client.py +125 -0
- modules/llm/openai_client.py +800 -0
- modules/llm/openrouter_client.py +969 -0
- modules/llm/profiles.py +178 -0
- modules/llm/test_anthropic_cache_capture.py +35 -0
- modules/llm/test_cached_pricing_derivation.py +24 -0
- modules/llm/think_scrubber.py +444 -0
- modules/llm/token_counter.py +268 -0
- modules/memory/__init__.py +35 -0
- modules/memory/backend_factory.py +83 -0
- modules/memory/cache_manager.py +186 -0
- modules/memory/episodic.py +108 -0
- modules/memory/local_vector_memory_provider.py +552 -0
- modules/memory/memory_manager.py +225 -0
- modules/memory/models.py +312 -0
- modules/memory/provider.py +210 -0
- modules/memory/registry.py +205 -0
- modules/memory/sqlite_memory_provider.py +767 -0
- modules/memory/task/__init__.py +52 -0
- modules/memory/task/compaction_manager.py +157 -0
- modules/memory/task/context_retriever.py +809 -0
- modules/memory/task/hierarchical_memory.py +1002 -0
- modules/memory/task/lexical_retriever.py +71 -0
- modules/memory/task/null_context_manager.py +213 -0
- modules/memory/task/phase_manager.py +625 -0
- modules/memory/task/reflection_service.py +157 -0
- modules/memory/task/semantic_retriever.py +218 -0
- modules/memory/task/task_context_manager.py +1165 -0
- modules/memory/task/test_forgetting_engages.py +24 -0
- modules/memory/task/test_reflection_llm.py +39 -0
- modules/memory/task/test_threat_scan.py +53 -0
- modules/memory/task/threat_scan.py +90 -0
- modules/memory/test_sqlite_memory_provider.py +106 -0
- modules/memory/user_profile_manager.py +527 -0
- modules/payments/__init__.py +11 -0
- modules/payments/deposit_monitor.py +478 -0
- modules/payments/price_oracle.py +70 -0
- modules/payments/treasury_sweeper.py +401 -0
- modules/payments/wallet_generator.py +145 -0
- modules/pfp/__init__.py +1 -0
- modules/pfp/config.py +92 -0
- modules/pfp/mesh.py +565 -0
- modules/pfp/push.py +69 -0
- modules/pfp/renderer.py +85 -0
- modules/pfp/store.py +82 -0
- modules/skills/__init__.py +1 -0
- modules/skills/skill_usage.py +248 -0
- modules/transcription/__init__.py +24 -0
- modules/transcription/base.py +20 -0
- modules/transcription/faster_whisper_transcriber.py +55 -0
- modules/x402/README.md +249 -0
- modules/x402/__init__.py +22 -0
- modules/x402/invoicing.py +416 -0
- modules/x402/middleware.py +364 -0
- modules/x402/settlement_watcher.py +145 -0
- modules/x402/x402_integration.py +344 -0
- polyrob-0.5.0.dist-info/METADATA +482 -0
- polyrob-0.5.0.dist-info/RECORD +745 -0
- polyrob-0.5.0.dist-info/WHEEL +5 -0
- polyrob-0.5.0.dist-info/entry_points.txt +2 -0
- polyrob-0.5.0.dist-info/licenses/LICENSE +21 -0
- polyrob-0.5.0.dist-info/top_level.txt +12 -0
- surfaces/README.md +70 -0
- surfaces/__init__.py +0 -0
- surfaces/email/__init__.py +0 -0
- surfaces/email/dedup.py +44 -0
- surfaces/email/harness.py +187 -0
- surfaces/email/inbound.py +159 -0
- surfaces/email/seed.py +60 -0
- surfaces/email/surface.py +105 -0
- surfaces/telegram/__init__.py +0 -0
- surfaces/telegram/dedup.py +83 -0
- surfaces/telegram/harness.py +886 -0
- surfaces/telegram/inbound.py +145 -0
- surfaces/telegram/interactive_tools.py +49 -0
- surfaces/telegram/markdown.py +347 -0
- surfaces/telegram/rate_limit.py +167 -0
- surfaces/telegram/surface.py +187 -0
- surfaces/telegram/voice.py +52 -0
- surfaces/whatsapp/__init__.py +0 -0
- surfaces/whatsapp/client.py +51 -0
- surfaces/whatsapp/harness.py +62 -0
- surfaces/whatsapp/inbound.py +132 -0
- surfaces/whatsapp/surface.py +64 -0
- surfaces/whatsapp/window.py +34 -0
- tools/README.md +578 -0
- tools/__init__.py +424 -0
- tools/alchemy/__init__.py +5 -0
- tools/alchemy/alchemy_tool.py +389 -0
- tools/anysite/__init__.py +17 -0
- tools/anysite/client.py +88 -0
- tools/anysite/tool.py +89 -0
- tools/base_tool.py +468 -0
- tools/browser/__init__.py +22 -0
- tools/browser/actions.py +118 -0
- tools/browser/browser.py +1457 -0
- tools/browser/browser_manager.py +690 -0
- tools/browser/context.py +1748 -0
- tools/browser/playwright_utils.py +137 -0
- tools/browser/views.py +56 -0
- tools/code_exec/SANDBOX_SECURITY.md +144 -0
- tools/code_exec/__init__.py +178 -0
- tools/code_exec/backend.py +73 -0
- tools/code_exec/backends/__init__.py +1 -0
- tools/code_exec/backends/docker.py +779 -0
- tools/code_exec/backends/local_subprocess.py +154 -0
- tools/code_exec/env_policy.py +45 -0
- tools/code_exec/result.py +42 -0
- tools/code_exec/sandbox_guard.py +59 -0
- tools/code_exec/tool.py +227 -0
- tools/coding/__init__.py +50 -0
- tools/coding/edit.py +107 -0
- tools/coding/search.py +113 -0
- tools/coding/tool.py +353 -0
- tools/collabland/__init__.py +5 -0
- tools/collabland/collabland_tool.py +471 -0
- tools/controller/__init__.py +0 -0
- tools/controller/_helpers.py +165 -0
- tools/controller/action_registration.py +1765 -0
- tools/controller/approval.py +244 -0
- tools/controller/approval_interactive.py +90 -0
- tools/controller/delegation.py +195 -0
- tools/controller/execution.py +797 -0
- tools/controller/execution_context.py +141 -0
- tools/controller/hooks.py +135 -0
- tools/controller/introspection.py +344 -0
- tools/controller/mcp_registrar.py +190 -0
- tools/controller/message_send.py +31 -0
- tools/controller/registry/__init__.py +4 -0
- tools/controller/registry/schema_generators.py +395 -0
- tools/controller/registry/schema_sanitizer.py +406 -0
- tools/controller/registry/service.py +1266 -0
- tools/controller/registry/views.py +151 -0
- tools/controller/service.py +409 -0
- tools/controller/tool_management.py +334 -0
- tools/controller/types.py +28 -0
- tools/controller/views.py +450 -0
- tools/cronjob_tools.py +166 -0
- tools/crypto_trade_gate.py +59 -0
- tools/descriptors.py +452 -0
- tools/dom/__init__.py +0 -0
- tools/dom/history_tree_processor/service.py +244 -0
- tools/dom/history_tree_processor/view.py +99 -0
- tools/dom/service.py +471 -0
- tools/dom/views.py +346 -0
- tools/email_tool.py +403 -0
- tools/exceptions.py +169 -0
- tools/filesystem.py +1038 -0
- tools/filesystem_docproc.py +331 -0
- tools/filesystem_pdf.py +755 -0
- tools/git/__init__.py +42 -0
- tools/git/tool.py +258 -0
- tools/github/__init__.py +33 -0
- tools/github/client.py +94 -0
- tools/github/tool.py +237 -0
- tools/goal_tools.py +309 -0
- tools/hyperliquid/__init__.py +56 -0
- tools/hyperliquid/models.py +233 -0
- tools/hyperliquid/service.py +1680 -0
- tools/knowledge_ingest.py +950 -0
- tools/mcp/README.md +535 -0
- tools/mcp/__init__.py +52 -0
- tools/mcp/catalog.py +115 -0
- tools/mcp/config.py +337 -0
- tools/mcp/mcp_tool.py +1415 -0
- tools/mcp/param_coercion.py +289 -0
- tools/mcp/protocol.py +1520 -0
- tools/mcp/rate_limit.py +50 -0
- tools/mcp/security.py +424 -0
- tools/mcp/self_install.py +111 -0
- tools/mcp/server_manager.py +829 -0
- tools/mcp/subscriptions.py +72 -0
- tools/mcp/user_mcp_service.py +899 -0
- tools/mcp/validation_tracker.py +89 -0
- tools/mcp/views.py +346 -0
- tools/oauth/__init__.py +17 -0
- tools/oauth/manager.py +75 -0
- tools/oauth/provider.py +69 -0
- tools/oauth/providers/__init__.py +1 -0
- tools/oauth/providers/generic_oauth2.py +96 -0
- tools/perplexity_tool.py +280 -0
- tools/polymarket/__init__.py +41 -0
- tools/polymarket/clob_adapter.py +76 -0
- tools/polymarket/models.py +182 -0
- tools/polymarket/service.py +2082 -0
- tools/self_env/__init__.py +61 -0
- tools/self_env/tool.py +274 -0
- tools/shell/__init__.py +80 -0
- tools/shell/backend_pool.py +118 -0
- tools/shell/discipline.py +62 -0
- tools/shell/executor.py +157 -0
- tools/shell/loopback_allow.py +87 -0
- tools/shell/process_registry.py +113 -0
- tools/shell/process_tool.py +131 -0
- tools/shell/state.py +129 -0
- tools/shell/tool.py +151 -0
- tools/task_tool.py +637 -0
- tools/twitter_tool.py +2086 -0
- tools/user_directory.py +179 -0
- tools/web_fetch/__init__.py +3 -0
- tools/web_fetch/fetcher.py +144 -0
- tools/web_fetch/render.py +44 -0
- tools/web_fetch/tool.py +60 -0
- tools/x402/__init__.py +60 -0
- tools/x402/client.py +47 -0
- tools/x402/invoice_tool.py +143 -0
- tools/x402/real_client.py +250 -0
- tools/x402/service.py +131 -0
- utils/README.md +498 -0
- utils/__init__.py +46 -0
- utils/auth_utils.py +114 -0
- utils/bounded_collections.py +162 -0
- utils/circuit_breaker.py +389 -0
- utils/gif_utils.py +435 -0
- utils/markdown_utils.py +291 -0
- utils/message_utils.py +147 -0
- utils/metrics.py +36 -0
- utils/path_validator.py +227 -0
- utils/rate_limit_manager.py +399 -0
- utils/result_size.py +296 -0
- utils/time_utils.py +206 -0
- utils/user_utils.py +188 -0
- webview/README.md +111 -0
- webview/RENAME_AND_ALIGN_HANDOFF.md +200 -0
- webview/__init__.py +8 -0
- webview/activity.py +636 -0
- webview/owner_auth.py +108 -0
- webview/pages.py +448 -0
- webview/repair_sessions.py +399 -0
- webview/server.py +4323 -0
- webview/server_launcher.py +112 -0
- webview/static/css/activity.css +89 -0
- webview/static/css/chat.css +1772 -0
- webview/static/css/components.css +1190 -0
- webview/static/css/config-panel.css +651 -0
- webview/static/css/pages/admin.css +766 -0
- webview/static/css/pages/profile.css +231 -0
- webview/static/css/pages/settings.css +297 -0
- webview/static/css/pages/signin.css +316 -0
- webview/static/css/style.css +4250 -0
- webview/static/css/variables.css +147 -0
- webview/static/css/workspace-fullwidth-fix.css +109 -0
- webview/static/img/favicon.ico +0 -0
- webview/static/js/activity.js +394 -0
- webview/static/js/admin/activity.js +186 -0
- webview/static/js/admin/dashboard.js +163 -0
- webview/static/js/admin/user_detail.js +400 -0
- webview/static/js/admin/users.js +174 -0
- webview/static/js/admin/utils.js +214 -0
- webview/static/js/chat.js +3178 -0
- webview/static/js/config-panel.js +522 -0
- webview/static/js/constants.js +20 -0
- webview/static/js/error-handler.js +226 -0
- webview/static/js/ethers.min.js +1 -0
- webview/static/js/event-filter.js +137 -0
- webview/static/js/event-store.js +351 -0
- webview/static/js/file-attachments.js +374 -0
- webview/static/js/file-loader.js +163 -0
- webview/static/js/index.js +103 -0
- webview/static/js/performance-utils.js +196 -0
- webview/static/js/profile.js +396 -0
- webview/static/js/screenshot.js +386 -0
- webview/static/js/session.js +1527 -0
- webview/static/js/settings.js +1288 -0
- webview/static/js/sidebar-data.js +766 -0
- webview/static/js/sidebar-toggle.js +296 -0
- webview/static/js/socket.io.min.js +7 -0
- webview/static/js/stats.js +355 -0
- webview/static/js/ui-utils.js +420 -0
- webview/static/js/workspace.js +966 -0
- webview/stats_service.py +613 -0
- webview/templates/__init__.py +1 -0
- webview/templates/__pycache__/__init__.cpython-311.pyc +0 -0
- webview/templates/activity.html +36 -0
- webview/templates/admin/activity.html +122 -0
- webview/templates/admin/dashboard.html +112 -0
- webview/templates/admin/user_detail.html +228 -0
- webview/templates/admin/users.html +105 -0
- webview/templates/autonomy.html +60 -0
- webview/templates/error.html +133 -0
- webview/templates/finance.html +90 -0
- webview/templates/identity.html +73 -0
- webview/templates/index.html +42 -0
- webview/templates/layout.html +125 -0
- webview/templates/memory.html +59 -0
- webview/templates/owner_login.html +15 -0
- webview/templates/profile.html +121 -0
- webview/templates/session.html +312 -0
- webview/templates/settings.html +534 -0
- webview/templates/sidebar.html +112 -0
- webview/templates/signin.html +213 -0
- webview/templates/status.html +14 -0
- webview/templates/system.html +45 -0
- webview/webgate.py +196 -0
api/a2a/endpoints.py
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
"""A2A Protocol Endpoints - JSON-RPC over HTTP.
|
|
2
|
+
|
|
3
|
+
Implements the A2A JSON-RPC 2.0 interface for task management.
|
|
4
|
+
All methods follow the A2A specification naming convention.
|
|
5
|
+
|
|
6
|
+
Supported Methods:
|
|
7
|
+
- message/send: Create new task or continue existing
|
|
8
|
+
- tasks/get: Get task status
|
|
9
|
+
- tasks/list: List tasks with pagination
|
|
10
|
+
- tasks/cancel: Cancel a task
|
|
11
|
+
- tasks/resubscribe: Resubscribe to streaming events
|
|
12
|
+
- tasks/pushNotificationConfig/*: Push notification management
|
|
13
|
+
|
|
14
|
+
Reference: https://a2a-protocol.org/latest/specification/
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import logging
|
|
18
|
+
from typing import Optional
|
|
19
|
+
from fastapi import APIRouter, Request, HTTPException, Depends
|
|
20
|
+
from fastapi.responses import JSONResponse
|
|
21
|
+
|
|
22
|
+
from api.a2a.models import (
|
|
23
|
+
JSONRPCRequest, JSONRPCResponse, JSONRPCError, A2AErrorCode,
|
|
24
|
+
SendMessageRequest, GetTaskRequest, ListTasksRequest,
|
|
25
|
+
CancelTaskRequest, TaskResubscriptionRequest,
|
|
26
|
+
SetPushNotificationConfigRequest, PushNotificationConfig,
|
|
27
|
+
A2AMessage, A2ATask, ListTasksResponse
|
|
28
|
+
)
|
|
29
|
+
from api.a2a.task_handler import A2ATaskHandler
|
|
30
|
+
from api.payment_verification import verify_payment_for_request, payment_required_response
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger(__name__)
|
|
33
|
+
router = APIRouter(prefix="/a2a", tags=["a2a"])
|
|
34
|
+
|
|
35
|
+
# A2A-specific error code for payment required
|
|
36
|
+
A2A_ERROR_PAYMENT_REQUIRED = -32402
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_task_handler(request: Request) -> A2ATaskHandler:
|
|
40
|
+
"""Get A2A task handler from container."""
|
|
41
|
+
from core.container import DependencyContainer
|
|
42
|
+
container = DependencyContainer.get_instance()
|
|
43
|
+
return A2ATaskHandler(container)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# Permissive auth policy (accepts x402, JWT, and API-key auth).
|
|
47
|
+
# Delegates to the canonical implementation in api.dependencies.
|
|
48
|
+
from api.dependencies import get_user_permissive as get_authenticated_user
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@router.post("/rpc")
|
|
52
|
+
async def a2a_rpc_endpoint(
|
|
53
|
+
rpc_request: JSONRPCRequest,
|
|
54
|
+
request: Request,
|
|
55
|
+
handler: A2ATaskHandler = Depends(get_task_handler)
|
|
56
|
+
):
|
|
57
|
+
"""A2A JSON-RPC 2.0 endpoint.
|
|
58
|
+
|
|
59
|
+
Handles all A2A protocol methods via JSON-RPC.
|
|
60
|
+
"""
|
|
61
|
+
request_id = rpc_request.id
|
|
62
|
+
|
|
63
|
+
try:
|
|
64
|
+
user_id = await get_authenticated_user(request)
|
|
65
|
+
method = rpc_request.method
|
|
66
|
+
params = rpc_request.params or {}
|
|
67
|
+
|
|
68
|
+
logger.info(f"A2A RPC: {method} from user {user_id}")
|
|
69
|
+
|
|
70
|
+
# Route to appropriate handler (pass request for payment verification)
|
|
71
|
+
result = await _handle_rpc_method(
|
|
72
|
+
method=method,
|
|
73
|
+
params=params,
|
|
74
|
+
user_id=user_id,
|
|
75
|
+
handler=handler,
|
|
76
|
+
request=request
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
return JSONRPCResponse(
|
|
80
|
+
id=request_id,
|
|
81
|
+
result=result.dict() if hasattr(result, 'dict') else result
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
except HTTPException as e:
|
|
85
|
+
# Handle 402 Payment Required specially for JSON-RPC
|
|
86
|
+
if e.status_code == 402:
|
|
87
|
+
return JSONRPCResponse(
|
|
88
|
+
id=request_id,
|
|
89
|
+
error=JSONRPCError(
|
|
90
|
+
code=A2A_ERROR_PAYMENT_REQUIRED,
|
|
91
|
+
message="Payment required",
|
|
92
|
+
data=e.detail if isinstance(e.detail, dict) else {"message": e.detail}
|
|
93
|
+
)
|
|
94
|
+
)
|
|
95
|
+
return JSONRPCResponse(
|
|
96
|
+
id=request_id,
|
|
97
|
+
error=JSONRPCError(
|
|
98
|
+
code=A2AErrorCode.AUTHENTICATION_REQUIRED if e.status_code == 401 else A2AErrorCode.INTERNAL_ERROR,
|
|
99
|
+
message=e.detail
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
except ValueError as e:
|
|
103
|
+
return JSONRPCResponse(
|
|
104
|
+
id=request_id,
|
|
105
|
+
error=JSONRPCError(
|
|
106
|
+
code=A2AErrorCode.INVALID_PARAMS,
|
|
107
|
+
message=str(e)
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
except Exception as e:
|
|
111
|
+
logger.error(f"A2A RPC error: {e}", exc_info=True)
|
|
112
|
+
return JSONRPCResponse(
|
|
113
|
+
id=request_id,
|
|
114
|
+
error=JSONRPCError(
|
|
115
|
+
code=A2AErrorCode.INTERNAL_ERROR,
|
|
116
|
+
message="Internal error",
|
|
117
|
+
data=str(e)
|
|
118
|
+
)
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
async def _handle_rpc_method(
|
|
123
|
+
method: str,
|
|
124
|
+
params: dict,
|
|
125
|
+
user_id: str,
|
|
126
|
+
handler: A2ATaskHandler,
|
|
127
|
+
request: Request
|
|
128
|
+
):
|
|
129
|
+
"""Handle individual RPC methods with payment verification.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
method: RPC method name
|
|
133
|
+
params: Method parameters
|
|
134
|
+
user_id: Authenticated user
|
|
135
|
+
handler: A2A task handler
|
|
136
|
+
request: FastAPI request for payment verification
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
Method result
|
|
140
|
+
|
|
141
|
+
Raises:
|
|
142
|
+
ValueError: Invalid params
|
|
143
|
+
HTTPException: Method not found or payment required
|
|
144
|
+
"""
|
|
145
|
+
# Message operations
|
|
146
|
+
if method == "message/send":
|
|
147
|
+
message = A2AMessage(**params.get("message", {}))
|
|
148
|
+
config = params.get("configuration")
|
|
149
|
+
msg_request = SendMessageRequest(message=message, configuration=config)
|
|
150
|
+
|
|
151
|
+
# Check if this is a new task or continuation
|
|
152
|
+
if message.taskId:
|
|
153
|
+
# Continuation of existing task - already paid
|
|
154
|
+
return await handler.send_message(message.taskId, message, user_id)
|
|
155
|
+
else:
|
|
156
|
+
# NEW TASK: Verify payment before creation
|
|
157
|
+
try:
|
|
158
|
+
payment_method, details = await verify_payment_for_request(
|
|
159
|
+
request=request,
|
|
160
|
+
cost_credits=1 # Session creation = 1 credit
|
|
161
|
+
)
|
|
162
|
+
logger.info(f"A2A RPC task payment verified via {payment_method}: {details}")
|
|
163
|
+
except HTTPException as e:
|
|
164
|
+
if e.status_code == 402:
|
|
165
|
+
# Return 402 with payment options
|
|
166
|
+
raise HTTPException(
|
|
167
|
+
status_code=402,
|
|
168
|
+
detail=payment_required_response(request, cost_credits=1)
|
|
169
|
+
)
|
|
170
|
+
raise
|
|
171
|
+
|
|
172
|
+
return await handler.create_task(msg_request, user_id, message.contextId)
|
|
173
|
+
|
|
174
|
+
# Task operations
|
|
175
|
+
elif method == "tasks/get":
|
|
176
|
+
task_id = params.get("id")
|
|
177
|
+
if not task_id:
|
|
178
|
+
raise ValueError("Missing task id")
|
|
179
|
+
history_length = params.get("historyLength")
|
|
180
|
+
return await handler.get_task(task_id, history_length, user_id=user_id)
|
|
181
|
+
|
|
182
|
+
elif method == "tasks/list":
|
|
183
|
+
context_id = params.get("contextId")
|
|
184
|
+
page_token = params.get("pageToken")
|
|
185
|
+
page_size = params.get("pageSize", 20)
|
|
186
|
+
tasks, next_token = await handler.list_tasks(
|
|
187
|
+
user_id, context_id, page_token, page_size
|
|
188
|
+
)
|
|
189
|
+
return ListTasksResponse(tasks=tasks, nextPageToken=next_token)
|
|
190
|
+
|
|
191
|
+
elif method == "tasks/cancel":
|
|
192
|
+
task_id = params.get("id")
|
|
193
|
+
if not task_id:
|
|
194
|
+
raise ValueError("Missing task id")
|
|
195
|
+
return await handler.cancel_task(task_id, user_id)
|
|
196
|
+
|
|
197
|
+
# Push notification operations
|
|
198
|
+
elif method == "tasks/pushNotificationConfig/set":
|
|
199
|
+
task_id = params.get("taskId")
|
|
200
|
+
config_data = params.get("config", {})
|
|
201
|
+
config = PushNotificationConfig(**config_data)
|
|
202
|
+
await handler.set_push_notification_config(task_id, config, user_id=user_id)
|
|
203
|
+
return {"success": True}
|
|
204
|
+
|
|
205
|
+
elif method == "tasks/pushNotificationConfig/get":
|
|
206
|
+
task_id = params.get("taskId")
|
|
207
|
+
config = await handler.get_push_notification_config(task_id, user_id=user_id)
|
|
208
|
+
return config.dict() if config else None
|
|
209
|
+
|
|
210
|
+
elif method == "tasks/pushNotificationConfig/delete":
|
|
211
|
+
task_id = params.get("taskId")
|
|
212
|
+
success = await handler.delete_push_notification_config(task_id, user_id=user_id)
|
|
213
|
+
return {"success": success}
|
|
214
|
+
|
|
215
|
+
else:
|
|
216
|
+
raise HTTPException(
|
|
217
|
+
status_code=400,
|
|
218
|
+
detail=f"Method '{method}' not found"
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
# =============================================================================
|
|
223
|
+
@router.post("/tasks")
|
|
224
|
+
async def create_task(
|
|
225
|
+
request_body: SendMessageRequest,
|
|
226
|
+
request: Request,
|
|
227
|
+
handler: A2ATaskHandler = Depends(get_task_handler)
|
|
228
|
+
):
|
|
229
|
+
"""Create a new A2A task with payment verification.
|
|
230
|
+
|
|
231
|
+
RESTful convenience endpoint for task creation.
|
|
232
|
+
Equivalent to message/send RPC method.
|
|
233
|
+
"""
|
|
234
|
+
user_id = await get_authenticated_user(request)
|
|
235
|
+
|
|
236
|
+
# Verify payment for new task creation
|
|
237
|
+
try:
|
|
238
|
+
payment_method, details = await verify_payment_for_request(
|
|
239
|
+
request=request,
|
|
240
|
+
cost_credits=1
|
|
241
|
+
)
|
|
242
|
+
logger.info(f"A2A REST task payment verified via {payment_method}")
|
|
243
|
+
except HTTPException as e:
|
|
244
|
+
if e.status_code == 402:
|
|
245
|
+
return JSONResponse(
|
|
246
|
+
status_code=402,
|
|
247
|
+
content=payment_required_response(request, cost_credits=1)
|
|
248
|
+
)
|
|
249
|
+
raise
|
|
250
|
+
|
|
251
|
+
return await handler.create_task(
|
|
252
|
+
request_body,
|
|
253
|
+
user_id,
|
|
254
|
+
request_body.message.contextId
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
@router.get("/tasks/{task_id}")
|
|
259
|
+
async def get_task(
|
|
260
|
+
task_id: str,
|
|
261
|
+
historyLength: Optional[int] = None,
|
|
262
|
+
request: Request = None,
|
|
263
|
+
handler: A2ATaskHandler = Depends(get_task_handler)
|
|
264
|
+
):
|
|
265
|
+
"""Get A2A task status.
|
|
266
|
+
|
|
267
|
+
RESTful convenience endpoint for getting task status.
|
|
268
|
+
Equivalent to tasks/get RPC method.
|
|
269
|
+
"""
|
|
270
|
+
# Authenticate and enforce ownership (was previously unauthenticated — IDOR).
|
|
271
|
+
user_id = await get_authenticated_user(request)
|
|
272
|
+
try:
|
|
273
|
+
return await handler.get_task(task_id, historyLength, user_id=user_id)
|
|
274
|
+
except ValueError as e:
|
|
275
|
+
raise HTTPException(status_code=404, detail=str(e))
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
@router.post("/tasks/{task_id}/send")
|
|
279
|
+
async def send_to_task(
|
|
280
|
+
task_id: str,
|
|
281
|
+
message: A2AMessage,
|
|
282
|
+
request: Request,
|
|
283
|
+
handler: A2ATaskHandler = Depends(get_task_handler)
|
|
284
|
+
):
|
|
285
|
+
"""Send a message to an existing A2A task.
|
|
286
|
+
|
|
287
|
+
RESTful convenience endpoint for continuing tasks.
|
|
288
|
+
Equivalent to message/send RPC method with taskId.
|
|
289
|
+
"""
|
|
290
|
+
user_id = await get_authenticated_user(request)
|
|
291
|
+
message.taskId = task_id # Ensure ID matches path
|
|
292
|
+
try:
|
|
293
|
+
return await handler.send_message(task_id, message, user_id)
|
|
294
|
+
except ValueError as e:
|
|
295
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
@router.post("/tasks/{task_id}/cancel")
|
|
299
|
+
async def cancel_task(
|
|
300
|
+
task_id: str,
|
|
301
|
+
request: Request,
|
|
302
|
+
handler: A2ATaskHandler = Depends(get_task_handler)
|
|
303
|
+
):
|
|
304
|
+
"""Cancel an A2A task.
|
|
305
|
+
|
|
306
|
+
RESTful convenience endpoint for task cancellation.
|
|
307
|
+
Equivalent to tasks/cancel RPC method.
|
|
308
|
+
"""
|
|
309
|
+
user_id = await get_authenticated_user(request)
|
|
310
|
+
try:
|
|
311
|
+
return await handler.cancel_task(task_id, user_id)
|
|
312
|
+
except ValueError as e:
|
|
313
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
@router.get("/tasks")
|
|
317
|
+
async def list_tasks(
|
|
318
|
+
contextId: Optional[str] = None,
|
|
319
|
+
pageToken: Optional[str] = None,
|
|
320
|
+
pageSize: int = 20,
|
|
321
|
+
request: Request = None,
|
|
322
|
+
handler: A2ATaskHandler = Depends(get_task_handler)
|
|
323
|
+
):
|
|
324
|
+
"""List A2A tasks with pagination.
|
|
325
|
+
|
|
326
|
+
RESTful convenience endpoint for listing tasks.
|
|
327
|
+
Equivalent to tasks/list RPC method.
|
|
328
|
+
"""
|
|
329
|
+
user_id = await get_authenticated_user(request)
|
|
330
|
+
tasks, next_token = await handler.list_tasks(
|
|
331
|
+
user_id, contextId, pageToken, pageSize
|
|
332
|
+
)
|
|
333
|
+
return ListTasksResponse(tasks=tasks, nextPageToken=next_token)
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
# =============================================================================
|
|
337
|
+
@router.post("/tasks/{task_id}/push-config")
|
|
338
|
+
async def set_push_config(
|
|
339
|
+
task_id: str,
|
|
340
|
+
config: PushNotificationConfig,
|
|
341
|
+
request: Request,
|
|
342
|
+
handler: A2ATaskHandler = Depends(get_task_handler)
|
|
343
|
+
):
|
|
344
|
+
"""Set push notification config for a task."""
|
|
345
|
+
user_id = await get_authenticated_user(request)
|
|
346
|
+
await handler.set_push_notification_config(task_id, config, user_id=user_id)
|
|
347
|
+
return {"success": True, "taskId": task_id}
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
@router.get("/tasks/{task_id}/push-config")
|
|
351
|
+
async def get_push_config(
|
|
352
|
+
task_id: str,
|
|
353
|
+
request: Request,
|
|
354
|
+
handler: A2ATaskHandler = Depends(get_task_handler)
|
|
355
|
+
):
|
|
356
|
+
"""Get push notification config for a task."""
|
|
357
|
+
user_id = await get_authenticated_user(request)
|
|
358
|
+
config = await handler.get_push_notification_config(task_id, user_id=user_id)
|
|
359
|
+
if not config:
|
|
360
|
+
raise HTTPException(status_code=404, detail="No push config found")
|
|
361
|
+
return config
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
@router.delete("/tasks/{task_id}/push-config")
|
|
365
|
+
async def delete_push_config(
|
|
366
|
+
task_id: str,
|
|
367
|
+
request: Request,
|
|
368
|
+
handler: A2ATaskHandler = Depends(get_task_handler)
|
|
369
|
+
):
|
|
370
|
+
"""Delete push notification config for a task."""
|
|
371
|
+
user_id = await get_authenticated_user(request)
|
|
372
|
+
success = await handler.delete_push_notification_config(task_id, user_id=user_id)
|
|
373
|
+
if not success:
|
|
374
|
+
raise HTTPException(status_code=404, detail="No push config found")
|
|
375
|
+
return {"success": True, "taskId": task_id}
|
api/a2a/models.py
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"""A2A Protocol Models - Pydantic models for A2A communication.
|
|
2
|
+
|
|
3
|
+
Based on Google's A2A Protocol Specification:
|
|
4
|
+
https://a2a-protocol.org/latest/specification/
|
|
5
|
+
|
|
6
|
+
All models follow the official A2A schema definitions.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Optional, List, Dict, Any, Union, Literal
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
from enum import Enum
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
import uuid
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class A2ATaskState(str, Enum):
|
|
17
|
+
"""A2A Task lifecycle states.
|
|
18
|
+
|
|
19
|
+
Non-terminal (active) states:
|
|
20
|
+
- submitted: Initial state, typically transitions immediately to working
|
|
21
|
+
- working: Agent actively processing the task
|
|
22
|
+
|
|
23
|
+
Interrupted states (can resume):
|
|
24
|
+
- input-required: Awaiting client information
|
|
25
|
+
- auth-required: Awaiting external authentication
|
|
26
|
+
|
|
27
|
+
Terminal states (immutable):
|
|
28
|
+
- completed: Task finished successfully
|
|
29
|
+
- failed: Task processing failed
|
|
30
|
+
- canceled: User-initiated cancellation
|
|
31
|
+
- rejected: Agent declined execution
|
|
32
|
+
- unknown: Unknown/undefined terminal state
|
|
33
|
+
"""
|
|
34
|
+
SUBMITTED = "submitted"
|
|
35
|
+
WORKING = "working"
|
|
36
|
+
INPUT_REQUIRED = "input-required"
|
|
37
|
+
AUTH_REQUIRED = "auth-required"
|
|
38
|
+
COMPLETED = "completed"
|
|
39
|
+
FAILED = "failed"
|
|
40
|
+
CANCELED = "canceled"
|
|
41
|
+
REJECTED = "rejected"
|
|
42
|
+
UNKNOWN = "unknown"
|
|
43
|
+
|
|
44
|
+
@classmethod
|
|
45
|
+
def is_terminal(cls, state: 'A2ATaskState') -> bool:
|
|
46
|
+
"""Check if state is terminal (no further transitions allowed)."""
|
|
47
|
+
return state in [
|
|
48
|
+
cls.COMPLETED, cls.FAILED, cls.CANCELED,
|
|
49
|
+
cls.REJECTED, cls.UNKNOWN
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def is_interrupted(cls, state: 'A2ATaskState') -> bool:
|
|
54
|
+
"""Check if state is interrupted (awaiting input)."""
|
|
55
|
+
return state in [cls.INPUT_REQUIRED, cls.AUTH_REQUIRED]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class TextPart(BaseModel):
|
|
59
|
+
"""Text content part."""
|
|
60
|
+
kind: Literal['text'] = 'text'
|
|
61
|
+
text: str
|
|
62
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class FileWithBytes(BaseModel):
|
|
66
|
+
"""File content with inline bytes."""
|
|
67
|
+
bytes: str # base64-encoded content
|
|
68
|
+
name: Optional[str] = None
|
|
69
|
+
mimeType: Optional[str] = None
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class FileWithUri(BaseModel):
|
|
73
|
+
"""File content with URI reference."""
|
|
74
|
+
uri: str
|
|
75
|
+
name: Optional[str] = None
|
|
76
|
+
mimeType: Optional[str] = None
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class FilePart(BaseModel):
|
|
80
|
+
"""File content part."""
|
|
81
|
+
kind: Literal['file'] = 'file'
|
|
82
|
+
file: Union[FileWithBytes, FileWithUri]
|
|
83
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class DataPart(BaseModel):
|
|
87
|
+
"""Structured JSON data part."""
|
|
88
|
+
kind: Literal['data'] = 'data'
|
|
89
|
+
data: Dict[str, Any]
|
|
90
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# Part union type
|
|
94
|
+
Part = Union[TextPart, FilePart, DataPart]
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class A2AMessage(BaseModel):
|
|
98
|
+
"""A2A Message - Communication payload.
|
|
99
|
+
|
|
100
|
+
Messages represent a single turn of communication between
|
|
101
|
+
user/client and agent.
|
|
102
|
+
"""
|
|
103
|
+
messageId: str = Field(default_factory=lambda: str(uuid.uuid4()))
|
|
104
|
+
role: Literal["user", "agent"]
|
|
105
|
+
parts: List[Dict[str, Any]] # Mixed parts (text, file, data)
|
|
106
|
+
kind: Literal['message'] = 'message'
|
|
107
|
+
taskId: Optional[str] = None
|
|
108
|
+
contextId: Optional[str] = None
|
|
109
|
+
referenceTaskIds: Optional[List[str]] = None
|
|
110
|
+
extensions: Optional[List[str]] = None
|
|
111
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class A2AArtifact(BaseModel):
|
|
115
|
+
"""A2A Artifact - Output produced by agent.
|
|
116
|
+
|
|
117
|
+
Artifacts represent outputs/results of task execution.
|
|
118
|
+
Can contain mixed content types via parts array.
|
|
119
|
+
"""
|
|
120
|
+
artifactId: str = Field(default_factory=lambda: str(uuid.uuid4()))
|
|
121
|
+
parts: List[Dict[str, Any]]
|
|
122
|
+
name: Optional[str] = None
|
|
123
|
+
description: Optional[str] = None
|
|
124
|
+
extensions: Optional[List[str]] = None
|
|
125
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
126
|
+
|
|
127
|
+
# Streaming support
|
|
128
|
+
index: Optional[int] = None # Index within owning task
|
|
129
|
+
append: Optional[bool] = None # For streaming: append to existing?
|
|
130
|
+
lastChunk: Optional[bool] = None # For streaming: final chunk?
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class A2ATaskStatus(BaseModel):
|
|
134
|
+
"""Task status and related messages."""
|
|
135
|
+
state: A2ATaskState
|
|
136
|
+
message: Optional[A2AMessage] = None
|
|
137
|
+
timestamp: Optional[str] = Field(default_factory=lambda: datetime.now().isoformat())
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class A2ATask(BaseModel):
|
|
141
|
+
"""A2A Task - Fundamental unit of work.
|
|
142
|
+
|
|
143
|
+
Tasks encapsulate the entire lifecycle of an agent interaction,
|
|
144
|
+
from initial request to final result.
|
|
145
|
+
"""
|
|
146
|
+
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
|
|
147
|
+
contextId: str = Field(default_factory=lambda: str(uuid.uuid4()))
|
|
148
|
+
status: A2ATaskStatus
|
|
149
|
+
kind: Literal['task'] = 'task'
|
|
150
|
+
history: Optional[List[A2AMessage]] = None
|
|
151
|
+
artifacts: Optional[List[A2AArtifact]] = None
|
|
152
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class SendMessageRequest(BaseModel):
|
|
156
|
+
"""Request to send a message (create or continue task)."""
|
|
157
|
+
message: A2AMessage
|
|
158
|
+
configuration: Optional[Dict[str, Any]] = None # pushNotificationConfig, etc.
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class SendMessageResponse(BaseModel):
|
|
162
|
+
"""Response from sending a message."""
|
|
163
|
+
task: Optional[A2ATask] = None
|
|
164
|
+
message: Optional[A2AMessage] = None
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class GetTaskRequest(BaseModel):
|
|
168
|
+
"""Request to get task status."""
|
|
169
|
+
id: str
|
|
170
|
+
historyLength: Optional[int] = None # None = all, 0 = none, >0 = last N
|
|
171
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class ListTasksRequest(BaseModel):
|
|
175
|
+
"""Request to list tasks."""
|
|
176
|
+
contextId: Optional[str] = None
|
|
177
|
+
pageToken: Optional[str] = None
|
|
178
|
+
pageSize: Optional[int] = 20
|
|
179
|
+
includeArtifacts: Optional[bool] = False
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class ListTasksResponse(BaseModel):
|
|
183
|
+
"""Response for listing tasks."""
|
|
184
|
+
tasks: List[A2ATask]
|
|
185
|
+
nextPageToken: Optional[str] = None
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class CancelTaskRequest(BaseModel):
|
|
189
|
+
"""Request to cancel a task."""
|
|
190
|
+
id: str
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class TaskResubscriptionRequest(BaseModel):
|
|
194
|
+
"""Request to resubscribe to task events."""
|
|
195
|
+
id: str
|
|
196
|
+
historyLength: Optional[int] = None
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class AuthenticationInfo(BaseModel):
|
|
200
|
+
"""Authentication info for webhook callbacks."""
|
|
201
|
+
schemes: List[str] # e.g., ["Bearer"]
|
|
202
|
+
credentials: Optional[str] = None
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class PushNotificationConfig(BaseModel):
|
|
206
|
+
"""Configuration for webhook push notifications."""
|
|
207
|
+
url: str # HTTPS webhook endpoint
|
|
208
|
+
token: Optional[str] = None # Client-generated validation token
|
|
209
|
+
authentication: Optional[AuthenticationInfo] = None
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
class SetPushNotificationConfigRequest(BaseModel):
|
|
213
|
+
"""Request to set push notification config."""
|
|
214
|
+
taskId: str
|
|
215
|
+
config: PushNotificationConfig
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class TaskStatusUpdateEvent(BaseModel):
|
|
219
|
+
"""Task status update event in streaming response."""
|
|
220
|
+
task: A2ATask
|
|
221
|
+
final: bool = False # True if this is the final update
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class TaskArtifactUpdateEvent(BaseModel):
|
|
225
|
+
"""Artifact update event in streaming response."""
|
|
226
|
+
taskId: str
|
|
227
|
+
artifact: A2AArtifact
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
class JSONRPCRequest(BaseModel):
|
|
231
|
+
"""JSON-RPC 2.0 Request."""
|
|
232
|
+
jsonrpc: str = "2.0"
|
|
233
|
+
method: str
|
|
234
|
+
params: Optional[Dict[str, Any]] = None
|
|
235
|
+
id: Optional[Union[str, int]] = None
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class JSONRPCError(BaseModel):
|
|
239
|
+
"""JSON-RPC 2.0 Error."""
|
|
240
|
+
code: int
|
|
241
|
+
message: str
|
|
242
|
+
data: Optional[Any] = None
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class JSONRPCResponse(BaseModel):
|
|
246
|
+
"""JSON-RPC 2.0 Response."""
|
|
247
|
+
jsonrpc: str = "2.0"
|
|
248
|
+
result: Optional[Any] = None
|
|
249
|
+
error: Optional[JSONRPCError] = None
|
|
250
|
+
id: Optional[Union[str, int]] = None
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
class A2AErrorCode:
|
|
254
|
+
"""A2A-specific error codes (JSON-RPC server error range)."""
|
|
255
|
+
# Standard JSON-RPC errors
|
|
256
|
+
PARSE_ERROR = -32700
|
|
257
|
+
INVALID_REQUEST = -32600
|
|
258
|
+
METHOD_NOT_FOUND = -32601
|
|
259
|
+
INVALID_PARAMS = -32602
|
|
260
|
+
INTERNAL_ERROR = -32603
|
|
261
|
+
|
|
262
|
+
# A2A-specific errors (-32000 to -32099)
|
|
263
|
+
TASK_NOT_FOUND = -32000
|
|
264
|
+
TASK_NOT_CANCELABLE = -32001
|
|
265
|
+
PUSH_NOTIFICATION_NOT_SUPPORTED = -32002
|
|
266
|
+
UNSUPPORTED_OPERATION = -32003
|
|
267
|
+
AUTHENTICATION_REQUIRED = -32004
|
|
268
|
+
PAYMENT_REQUIRED = -32005
|