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/eip8004_endpoints.py
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
"""ERC-8004 Trustless Agents API Endpoints.
|
|
2
|
+
|
|
3
|
+
Implements the HTTP API for ERC-8004 integration:
|
|
4
|
+
- Registration file endpoint (for Identity Registry tokenURI)
|
|
5
|
+
- Reputation endpoints (feedback auth, submission, querying)
|
|
6
|
+
- Validation endpoints (request, response, status)
|
|
7
|
+
|
|
8
|
+
Reference: https://eips.ethereum.org/EIPS/eip-8004
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import logging
|
|
13
|
+
from typing import Optional, Dict, Any, List
|
|
14
|
+
from fastapi import APIRouter, Request, HTTPException, Depends
|
|
15
|
+
from pydantic import BaseModel, Field
|
|
16
|
+
|
|
17
|
+
from modules.eip8004 import (
|
|
18
|
+
build_registration_file,
|
|
19
|
+
ReputationManager,
|
|
20
|
+
ValidationManager,
|
|
21
|
+
EIP8004Config,
|
|
22
|
+
)
|
|
23
|
+
from modules.eip8004.registration import get_eip8004_config
|
|
24
|
+
from modules.eip8004.models import (
|
|
25
|
+
CreateFeedbackAuthRequest,
|
|
26
|
+
CreateFeedbackAuthResponse,
|
|
27
|
+
SubmitFeedbackRequest,
|
|
28
|
+
GetReputationRequest,
|
|
29
|
+
ReputationSummary,
|
|
30
|
+
RequestValidationRequest,
|
|
31
|
+
ValidationSummary,
|
|
32
|
+
ProofOfPayment,
|
|
33
|
+
FeedbackAuth,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
logger = logging.getLogger(__name__)
|
|
37
|
+
router = APIRouter(prefix="/eip8004", tags=["EIP-8004 Trustless Agents"])
|
|
38
|
+
|
|
39
|
+
# Singleton managers
|
|
40
|
+
_reputation_manager: Optional[ReputationManager] = None
|
|
41
|
+
_validation_manager: Optional[ValidationManager] = None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def require_eip8004_enabled() -> bool:
|
|
45
|
+
"""Gate write endpoints behind EIP8004_ENABLED (404 when off).
|
|
46
|
+
|
|
47
|
+
Discovery/read endpoints stay open; only the state-changing surface is hidden
|
|
48
|
+
unless an operator explicitly enables ERC-8004.
|
|
49
|
+
"""
|
|
50
|
+
if os.environ.get("EIP8004_ENABLED", "false").lower() != "true":
|
|
51
|
+
raise HTTPException(status_code=404, detail="ERC-8004 not enabled")
|
|
52
|
+
return True
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def require_owner_or_admin(request: Request) -> bool:
|
|
56
|
+
"""Require admin/owner for sensitive ERC-8004 writes.
|
|
57
|
+
|
|
58
|
+
/reputation/authorize signs an EIP-712 payload with the AGENT'S private key,
|
|
59
|
+
so it must never be callable anonymously (it would be a signing oracle).
|
|
60
|
+
"""
|
|
61
|
+
if not getattr(request.state, "is_admin", False):
|
|
62
|
+
raise HTTPException(status_code=403, detail="Admin access required")
|
|
63
|
+
return True
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def get_reputation_manager() -> ReputationManager:
|
|
67
|
+
"""Get or create reputation manager singleton."""
|
|
68
|
+
global _reputation_manager
|
|
69
|
+
if _reputation_manager is None:
|
|
70
|
+
_reputation_manager = ReputationManager()
|
|
71
|
+
return _reputation_manager
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def get_validation_manager() -> ValidationManager:
|
|
75
|
+
"""Get or create validation manager singleton."""
|
|
76
|
+
global _validation_manager
|
|
77
|
+
if _validation_manager is None:
|
|
78
|
+
_validation_manager = ValidationManager()
|
|
79
|
+
return _validation_manager
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# =============================================================================
|
|
83
|
+
# Registration / Discovery Endpoints
|
|
84
|
+
# =============================================================================
|
|
85
|
+
|
|
86
|
+
@router.get("/registration.json", response_model=Dict[str, Any])
|
|
87
|
+
async def get_registration_file(request: Request):
|
|
88
|
+
"""Get the ERC-8004 registration file.
|
|
89
|
+
|
|
90
|
+
This is what the Identity Registry tokenURI points to.
|
|
91
|
+
Contains all agent endpoints (A2A, MCP, wallets) and trust models.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
Registration file JSON per ERC-8004 spec
|
|
95
|
+
"""
|
|
96
|
+
# Determine base URL
|
|
97
|
+
scheme = request.headers.get("x-forwarded-proto", request.url.scheme)
|
|
98
|
+
host = request.headers.get("host", request.url.netloc)
|
|
99
|
+
base_url = f"{scheme}://{host}"
|
|
100
|
+
|
|
101
|
+
registration = build_registration_file(base_url)
|
|
102
|
+
return registration.model_dump(exclude_none=True)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@router.get("/config")
|
|
106
|
+
async def get_config():
|
|
107
|
+
"""Get ERC-8004 configuration status.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
Current configuration (addresses, chain, supported trust models)
|
|
111
|
+
"""
|
|
112
|
+
config = get_eip8004_config()
|
|
113
|
+
return {
|
|
114
|
+
"enabled": config.enabled,
|
|
115
|
+
"chainId": config.chain_id,
|
|
116
|
+
"agentId": config.agent_id,
|
|
117
|
+
"identityRegistry": config.identity_registry_address,
|
|
118
|
+
"reputationRegistry": config.reputation_registry_address,
|
|
119
|
+
"validationRegistry": config.validation_registry_address,
|
|
120
|
+
"supportedTrust": config.supported_trust,
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# =============================================================================
|
|
125
|
+
# Reputation Registry Endpoints
|
|
126
|
+
# =============================================================================
|
|
127
|
+
|
|
128
|
+
class FeedbackAuthRequest(BaseModel):
|
|
129
|
+
"""Request body for creating feedback authorization."""
|
|
130
|
+
clientAddress: str = Field(..., description="Client wallet address to authorize")
|
|
131
|
+
taskId: Optional[str] = Field(None, description="Optional A2A task ID")
|
|
132
|
+
expiresInSeconds: int = Field(default=86400, description="Validity period (default 24h)")
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class FeedbackAuthResponse(BaseModel):
|
|
136
|
+
"""Response with feedback authorization."""
|
|
137
|
+
agentId: int
|
|
138
|
+
clientAddress: str
|
|
139
|
+
expiresAt: int
|
|
140
|
+
nonce: str
|
|
141
|
+
signature: str
|
|
142
|
+
message: str = "Feedback authorization created"
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@router.post(
|
|
146
|
+
"/reputation/authorize",
|
|
147
|
+
response_model=FeedbackAuthResponse,
|
|
148
|
+
dependencies=[Depends(require_eip8004_enabled), Depends(require_owner_or_admin)],
|
|
149
|
+
)
|
|
150
|
+
async def create_feedback_authorization(
|
|
151
|
+
body: FeedbackAuthRequest,
|
|
152
|
+
manager: ReputationManager = Depends(get_reputation_manager),
|
|
153
|
+
):
|
|
154
|
+
"""Create a signed authorization for a client to submit feedback.
|
|
155
|
+
|
|
156
|
+
This endpoint is called by the agent after accepting a task.
|
|
157
|
+
The client uses the returned authorization when submitting feedback.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
body: Client address and optional task ID
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
Signed FeedbackAuth per ERC-8004 spec
|
|
164
|
+
"""
|
|
165
|
+
try:
|
|
166
|
+
auth = await manager.create_feedback_auth(
|
|
167
|
+
client_address=body.clientAddress,
|
|
168
|
+
task_id=body.taskId,
|
|
169
|
+
expires_in_seconds=body.expiresInSeconds,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
return FeedbackAuthResponse(
|
|
173
|
+
agentId=auth.agentId,
|
|
174
|
+
clientAddress=auth.clientAddress,
|
|
175
|
+
expiresAt=auth.expiresAt,
|
|
176
|
+
nonce=auth.nonce,
|
|
177
|
+
signature=auth.signature,
|
|
178
|
+
)
|
|
179
|
+
except ValueError as e:
|
|
180
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
181
|
+
except Exception as e:
|
|
182
|
+
logger.error(f"Failed to create feedback auth: {e}")
|
|
183
|
+
raise HTTPException(status_code=500, detail="Failed to create authorization")
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class SubmitFeedbackBody(BaseModel):
|
|
187
|
+
"""Request body for feedback submission."""
|
|
188
|
+
agentId: int = Field(..., description="Agent's on-chain ID")
|
|
189
|
+
score: int = Field(..., ge=0, le=100, description="Score 0-100")
|
|
190
|
+
|
|
191
|
+
# Authorization (from /reputation/authorize)
|
|
192
|
+
feedbackAuth: Dict[str, Any] = Field(..., description="Authorization from agent")
|
|
193
|
+
|
|
194
|
+
# Optional fields
|
|
195
|
+
tag1: Optional[str] = Field(None, description="Primary categorization tag")
|
|
196
|
+
tag2: Optional[str] = Field(None, description="Secondary tag")
|
|
197
|
+
skill: Optional[str] = Field(None, description="A2A skill identifier")
|
|
198
|
+
taskId: Optional[str] = Field(None, description="A2A task ID")
|
|
199
|
+
comment: Optional[str] = Field(None, description="Text feedback")
|
|
200
|
+
|
|
201
|
+
# x402 integration
|
|
202
|
+
proofOfPayment: Optional[Dict[str, str]] = Field(None, description="x402 payment proof")
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
@router.post("/reputation/feedback", dependencies=[Depends(require_eip8004_enabled)])
|
|
206
|
+
async def submit_feedback(
|
|
207
|
+
body: SubmitFeedbackBody,
|
|
208
|
+
manager: ReputationManager = Depends(get_reputation_manager),
|
|
209
|
+
):
|
|
210
|
+
"""Submit feedback for an agent.
|
|
211
|
+
|
|
212
|
+
Called by clients after completing a task. Requires valid authorization
|
|
213
|
+
from the agent (obtained via /reputation/authorize).
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
body: Feedback data including score, auth, and optional tags
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
Submission result with file hash
|
|
220
|
+
"""
|
|
221
|
+
try:
|
|
222
|
+
# Parse feedback auth
|
|
223
|
+
auth = FeedbackAuth(**body.feedbackAuth)
|
|
224
|
+
|
|
225
|
+
# Parse proof of payment if provided
|
|
226
|
+
pop = None
|
|
227
|
+
if body.proofOfPayment:
|
|
228
|
+
pop = ProofOfPayment(**body.proofOfPayment)
|
|
229
|
+
|
|
230
|
+
result = await manager.submit_feedback(
|
|
231
|
+
agent_id=body.agentId,
|
|
232
|
+
score=body.score,
|
|
233
|
+
feedback_auth=auth,
|
|
234
|
+
tag1=body.tag1,
|
|
235
|
+
tag2=body.tag2,
|
|
236
|
+
skill=body.skill,
|
|
237
|
+
task_id=body.taskId,
|
|
238
|
+
proof_of_payment=pop,
|
|
239
|
+
comment=body.comment,
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
return result
|
|
243
|
+
except ValueError as e:
|
|
244
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
245
|
+
except Exception as e:
|
|
246
|
+
logger.error(f"Failed to submit feedback: {e}")
|
|
247
|
+
raise HTTPException(status_code=500, detail="Failed to submit feedback")
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
class ReputationQuery(BaseModel):
|
|
251
|
+
"""Query parameters for reputation lookup."""
|
|
252
|
+
agentId: int
|
|
253
|
+
clientAddress: Optional[str] = None
|
|
254
|
+
tag1: Optional[str] = None
|
|
255
|
+
tag2: Optional[str] = None
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
@router.post("/reputation/query", response_model=ReputationSummary)
|
|
259
|
+
async def query_reputation(
|
|
260
|
+
body: ReputationQuery,
|
|
261
|
+
manager: ReputationManager = Depends(get_reputation_manager),
|
|
262
|
+
):
|
|
263
|
+
"""Query reputation for an agent.
|
|
264
|
+
|
|
265
|
+
Returns aggregated feedback statistics with optional filtering.
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
body: Query filters (agent ID, client, tags)
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
ReputationSummary with scores and stats
|
|
272
|
+
"""
|
|
273
|
+
return await manager.get_reputation(
|
|
274
|
+
agent_id=body.agentId,
|
|
275
|
+
client_address=body.clientAddress,
|
|
276
|
+
tag1=body.tag1,
|
|
277
|
+
tag2=body.tag2,
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
@router.get("/reputation/{agent_id}")
|
|
282
|
+
async def get_reputation(
|
|
283
|
+
agent_id: int,
|
|
284
|
+
limit: int = 50,
|
|
285
|
+
offset: int = 0,
|
|
286
|
+
manager: ReputationManager = Depends(get_reputation_manager),
|
|
287
|
+
):
|
|
288
|
+
"""Get reputation summary and feedback list for an agent.
|
|
289
|
+
|
|
290
|
+
Args:
|
|
291
|
+
agent_id: Agent's on-chain ID
|
|
292
|
+
limit: Max feedback entries to return
|
|
293
|
+
offset: Pagination offset
|
|
294
|
+
|
|
295
|
+
Returns:
|
|
296
|
+
Summary and list of feedback entries
|
|
297
|
+
"""
|
|
298
|
+
summary = await manager.get_reputation(agent_id=agent_id)
|
|
299
|
+
feedback_list = await manager.get_feedback_list(
|
|
300
|
+
agent_id=agent_id,
|
|
301
|
+
limit=limit,
|
|
302
|
+
offset=offset,
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
return {
|
|
306
|
+
"summary": summary.model_dump(),
|
|
307
|
+
"feedback": feedback_list,
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
# =============================================================================
|
|
312
|
+
# Validation Registry Endpoints
|
|
313
|
+
# =============================================================================
|
|
314
|
+
|
|
315
|
+
class ValidationRequestBody(BaseModel):
|
|
316
|
+
"""Request body for validation request."""
|
|
317
|
+
validatorAddress: str = Field(..., description="Validator contract address")
|
|
318
|
+
requestData: Dict[str, Any] = Field(..., description="Data to validate")
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
@router.post("/validation/request", dependencies=[Depends(require_eip8004_enabled)])
|
|
322
|
+
async def request_validation(
|
|
323
|
+
body: ValidationRequestBody,
|
|
324
|
+
manager: ValidationManager = Depends(get_validation_manager),
|
|
325
|
+
):
|
|
326
|
+
"""Request validation from a validator.
|
|
327
|
+
|
|
328
|
+
Submits data to be validated by a specific validator contract.
|
|
329
|
+
|
|
330
|
+
Args:
|
|
331
|
+
body: Validator address and request data
|
|
332
|
+
|
|
333
|
+
Returns:
|
|
334
|
+
Request result with hash for tracking
|
|
335
|
+
"""
|
|
336
|
+
try:
|
|
337
|
+
result = await manager.request_validation(
|
|
338
|
+
validator_address=body.validatorAddress,
|
|
339
|
+
request_data=body.requestData,
|
|
340
|
+
)
|
|
341
|
+
return result
|
|
342
|
+
except ValueError as e:
|
|
343
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
344
|
+
except Exception as e:
|
|
345
|
+
logger.error(f"Failed to request validation: {e}")
|
|
346
|
+
raise HTTPException(status_code=500, detail="Failed to request validation")
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
class ValidationResponseBody(BaseModel):
|
|
350
|
+
"""Request body for validation response."""
|
|
351
|
+
requestHash: str = Field(..., description="Hash of original request")
|
|
352
|
+
response: int = Field(..., ge=0, le=100, description="Result 0-100")
|
|
353
|
+
responseData: Optional[Dict[str, Any]] = Field(None, description="Evidence data")
|
|
354
|
+
tag: Optional[str] = Field(None, description="Categorization tag")
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
@router.post(
|
|
358
|
+
"/validation/respond",
|
|
359
|
+
dependencies=[Depends(require_eip8004_enabled), Depends(require_owner_or_admin)],
|
|
360
|
+
)
|
|
361
|
+
async def submit_validation_response(
|
|
362
|
+
body: ValidationResponseBody,
|
|
363
|
+
manager: ValidationManager = Depends(get_validation_manager),
|
|
364
|
+
):
|
|
365
|
+
"""Submit a validation response.
|
|
366
|
+
|
|
367
|
+
Called by validators after processing a request.
|
|
368
|
+
|
|
369
|
+
Args:
|
|
370
|
+
body: Request hash, response value, optional evidence
|
|
371
|
+
|
|
372
|
+
Returns:
|
|
373
|
+
Response submission result
|
|
374
|
+
"""
|
|
375
|
+
try:
|
|
376
|
+
result = await manager.submit_response(
|
|
377
|
+
request_hash=body.requestHash,
|
|
378
|
+
response=body.response,
|
|
379
|
+
response_data=body.responseData,
|
|
380
|
+
tag=body.tag,
|
|
381
|
+
)
|
|
382
|
+
return result
|
|
383
|
+
except ValueError as e:
|
|
384
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
385
|
+
except Exception as e:
|
|
386
|
+
logger.error(f"Failed to submit validation response: {e}")
|
|
387
|
+
raise HTTPException(status_code=500, detail="Failed to submit response")
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
@router.get("/validation/status/{request_hash}")
|
|
391
|
+
async def get_validation_status(
|
|
392
|
+
request_hash: str,
|
|
393
|
+
manager: ValidationManager = Depends(get_validation_manager),
|
|
394
|
+
):
|
|
395
|
+
"""Get status of a validation request.
|
|
396
|
+
|
|
397
|
+
Args:
|
|
398
|
+
request_hash: Hash of the validation request
|
|
399
|
+
|
|
400
|
+
Returns:
|
|
401
|
+
Validation status with response and timestamp
|
|
402
|
+
"""
|
|
403
|
+
status = await manager.get_validation_status(request_hash)
|
|
404
|
+
if status is None:
|
|
405
|
+
raise HTTPException(status_code=404, detail="Validation request not found")
|
|
406
|
+
|
|
407
|
+
return status.model_dump()
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
@router.get("/validation/summary/{agent_id}", response_model=ValidationSummary)
|
|
411
|
+
async def get_validation_summary(
|
|
412
|
+
agent_id: int,
|
|
413
|
+
manager: ValidationManager = Depends(get_validation_manager),
|
|
414
|
+
):
|
|
415
|
+
"""Get validation summary for an agent.
|
|
416
|
+
|
|
417
|
+
Args:
|
|
418
|
+
agent_id: Agent's on-chain ID
|
|
419
|
+
|
|
420
|
+
Returns:
|
|
421
|
+
ValidationSummary with aggregated stats
|
|
422
|
+
"""
|
|
423
|
+
return await manager.get_validation_summary(agent_id=agent_id)
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
@router.get("/validation/pending")
|
|
427
|
+
async def list_pending_validations(
|
|
428
|
+
agent_id: Optional[int] = None,
|
|
429
|
+
manager: ValidationManager = Depends(get_validation_manager),
|
|
430
|
+
):
|
|
431
|
+
"""List pending validation requests.
|
|
432
|
+
|
|
433
|
+
Args:
|
|
434
|
+
agent_id: Optional filter by agent ID
|
|
435
|
+
|
|
436
|
+
Returns:
|
|
437
|
+
List of pending validation requests
|
|
438
|
+
"""
|
|
439
|
+
return await manager.list_pending_validations(agent_id=agent_id)
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
@router.get("/validation/validators")
|
|
443
|
+
async def list_validators(
|
|
444
|
+
manager: ValidationManager = Depends(get_validation_manager),
|
|
445
|
+
):
|
|
446
|
+
"""List supported validator types.
|
|
447
|
+
|
|
448
|
+
Returns:
|
|
449
|
+
Dictionary of validator types and descriptions
|
|
450
|
+
"""
|
|
451
|
+
return manager.get_supported_validators()
|
|
452
|
+
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Hyperliquid API Models
|
|
3
|
+
|
|
4
|
+
Pydantic models for request/response validation.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
from typing import Optional, Dict, Any, List
|
|
9
|
+
from pydantic import BaseModel, Field, field_validator
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# =============================================================================
|
|
13
|
+
# Validation Patterns
|
|
14
|
+
# =============================================================================
|
|
15
|
+
|
|
16
|
+
WALLET_ADDRESS_PATTERN = re.compile(r"^0x[a-fA-F0-9]{40}$")
|
|
17
|
+
PRIVATE_KEY_PATTERN = re.compile(r"^(0x)?[a-fA-F0-9]{64}$")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# =============================================================================
|
|
21
|
+
# Request Models
|
|
22
|
+
# =============================================================================
|
|
23
|
+
|
|
24
|
+
class ConfigureHyperliquidRequest(BaseModel):
|
|
25
|
+
"""Request to configure Hyperliquid credentials"""
|
|
26
|
+
|
|
27
|
+
wallet_address: str = Field(..., description="Ethereum wallet address (0x...)")
|
|
28
|
+
private_key: str = Field(..., description="Wallet private key")
|
|
29
|
+
|
|
30
|
+
# Optional agent wallet for delegated trading
|
|
31
|
+
agent_wallet_address: Optional[str] = Field(None, description="Agent wallet address")
|
|
32
|
+
agent_wallet_private_key: Optional[str] = Field(None, description="Agent wallet private key")
|
|
33
|
+
agent_wallet_name: Optional[str] = Field(None, description="Agent wallet label")
|
|
34
|
+
|
|
35
|
+
# Network and mode
|
|
36
|
+
testnet: bool = Field(True, description="Use testnet (True) or mainnet (False)")
|
|
37
|
+
demo_mode: bool = Field(True, description="Read-only mode (True) or trading enabled (False)")
|
|
38
|
+
|
|
39
|
+
# Trading limits
|
|
40
|
+
max_order_size_usd: Optional[float] = Field(1000.0, ge=10, le=100000)
|
|
41
|
+
max_leverage: Optional[int] = Field(5, ge=1, le=50)
|
|
42
|
+
enable_autonomous_trading: Optional[bool] = Field(False)
|
|
43
|
+
|
|
44
|
+
@field_validator("wallet_address", "agent_wallet_address", mode="before")
|
|
45
|
+
@classmethod
|
|
46
|
+
def validate_address(cls, v):
|
|
47
|
+
if v is None:
|
|
48
|
+
return v
|
|
49
|
+
if not WALLET_ADDRESS_PATTERN.match(v):
|
|
50
|
+
raise ValueError("Invalid wallet address format (expected 0x followed by 40 hex chars)")
|
|
51
|
+
return v.lower()
|
|
52
|
+
|
|
53
|
+
@field_validator("private_key", "agent_wallet_private_key", mode="before")
|
|
54
|
+
@classmethod
|
|
55
|
+
def validate_private_key(cls, v):
|
|
56
|
+
if v is None:
|
|
57
|
+
return v
|
|
58
|
+
# Remove 0x prefix if present for validation
|
|
59
|
+
key = v[2:] if v.startswith("0x") else v
|
|
60
|
+
if len(key) != 64 or not all(c in "0123456789abcdefABCDEF" for c in key):
|
|
61
|
+
raise ValueError("Invalid private key format (expected 64 hex chars)")
|
|
62
|
+
return v
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class UpdateTradingLimitsRequest(BaseModel):
|
|
66
|
+
"""Request to update trading limits"""
|
|
67
|
+
|
|
68
|
+
max_order_size_usd: Optional[float] = Field(None, ge=10, le=100000)
|
|
69
|
+
max_total_exposure_usd: Optional[float] = Field(None, ge=100, le=1000000)
|
|
70
|
+
max_position_per_market_usd: Optional[float] = Field(None, ge=100, le=500000)
|
|
71
|
+
max_leverage: Optional[int] = Field(None, ge=1, le=50)
|
|
72
|
+
max_daily_loss_usd: Optional[float] = Field(None, ge=10, le=50000)
|
|
73
|
+
require_confirmation_above_usd: Optional[float] = Field(None, ge=0)
|
|
74
|
+
enable_autonomous_trading: Optional[bool] = Field(None)
|
|
75
|
+
allowed_coins: Optional[List[str]] = Field(None)
|
|
76
|
+
blocked_coins: Optional[List[str]] = Field(None)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class ExecuteToolRequest(BaseModel):
|
|
80
|
+
"""Request to execute a tool action"""
|
|
81
|
+
|
|
82
|
+
tool_name: str = Field(..., description="Name of the tool to execute")
|
|
83
|
+
arguments: Optional[Dict[str, Any]] = Field(default_factory=dict)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class SetDemoModeRequest(BaseModel):
|
|
87
|
+
"""Request to set demo mode"""
|
|
88
|
+
demo_mode: bool = Field(..., description="True for read-only, False for trading")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class SetEnabledRequest(BaseModel):
|
|
92
|
+
"""Request to enable/disable the tool"""
|
|
93
|
+
enabled: bool = Field(..., description="True to enable, False to disable")
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# =============================================================================
|
|
97
|
+
# Response Models
|
|
98
|
+
# =============================================================================
|
|
99
|
+
|
|
100
|
+
class HyperliquidStatusResponse(BaseModel):
|
|
101
|
+
"""Response for configuration status"""
|
|
102
|
+
|
|
103
|
+
configured: bool
|
|
104
|
+
wallet_address: Optional[str] = None
|
|
105
|
+
agent_wallet_address: Optional[str] = None
|
|
106
|
+
testnet: bool = True
|
|
107
|
+
demo_mode: bool = True
|
|
108
|
+
enabled: bool = False
|
|
109
|
+
trading_limits: Optional[Dict[str, Any]] = None
|
|
110
|
+
connection_count: Optional[int] = None
|
|
111
|
+
last_connected_at: Optional[str] = None
|
|
112
|
+
last_error: Optional[str] = None
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class ExecuteToolResponse(BaseModel):
|
|
116
|
+
"""Response for tool execution"""
|
|
117
|
+
|
|
118
|
+
success: bool
|
|
119
|
+
data: Optional[Any] = None
|
|
120
|
+
error: Optional[str] = None
|
|
121
|
+
tool_name: Optional[str] = None
|
|
122
|
+
execution_time_ms: Optional[float] = None
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class AvailableToolsResponse(BaseModel):
|
|
126
|
+
"""Response listing available tools"""
|
|
127
|
+
|
|
128
|
+
tools: List[Dict[str, Any]]
|
|
129
|
+
count: int
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class AuditLogEntry(BaseModel):
|
|
133
|
+
"""Single audit log entry"""
|
|
134
|
+
|
|
135
|
+
id: int
|
|
136
|
+
action: str
|
|
137
|
+
tool_name: Optional[str] = None
|
|
138
|
+
market_id: Optional[str] = None
|
|
139
|
+
details: Dict[str, Any] = {}
|
|
140
|
+
ip_address: Optional[str] = None
|
|
141
|
+
timestamp: str
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class AuditLogResponse(BaseModel):
|
|
145
|
+
"""Response for audit log query"""
|
|
146
|
+
|
|
147
|
+
entries: List[Dict[str, Any]]
|
|
148
|
+
count: int
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class TradingStatsResponse(BaseModel):
|
|
152
|
+
"""Response for trading statistics"""
|
|
153
|
+
|
|
154
|
+
orders_placed: int = 0
|
|
155
|
+
orders_cancelled: int = 0
|
|
156
|
+
bulk_cancels: int = 0
|
|
157
|
+
leverage_updates: int = 0
|
|
158
|
+
total_actions: int = 0
|
|
159
|
+
first_action: Optional[str] = None
|
|
160
|
+
last_action: Optional[str] = None
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class ErrorResponse(BaseModel):
|
|
164
|
+
"""Error response"""
|
|
165
|
+
|
|
166
|
+
error: str
|
|
167
|
+
detail: Optional[str] = None
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class SuccessResponse(BaseModel):
|
|
171
|
+
"""Generic success response"""
|
|
172
|
+
|
|
173
|
+
success: bool = True
|
|
174
|
+
message: Optional[str] = None
|