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/polymarket_models.py
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pydantic models for Polymarket API endpoints.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any, Dict, List, Optional
|
|
6
|
+
from pydantic import BaseModel, Field, field_validator
|
|
7
|
+
import re
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TradingLimitsRequest(BaseModel):
|
|
11
|
+
"""Trading limits configuration."""
|
|
12
|
+
max_order_size_usd: int = Field(default=1000, ge=1, le=100000)
|
|
13
|
+
max_total_exposure_usd: int = Field(default=5000, ge=1, le=1000000)
|
|
14
|
+
max_position_per_market_usd: int = Field(default=2000, ge=1, le=100000)
|
|
15
|
+
min_liquidity_required: int = Field(default=10000, ge=0)
|
|
16
|
+
max_spread_tolerance: float = Field(default=0.05, ge=0, le=1)
|
|
17
|
+
require_confirmation_above_usd: int = Field(default=500, ge=0)
|
|
18
|
+
enable_autonomous_trading: bool = Field(default=False)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ConfigurePolymarketRequest(BaseModel):
|
|
22
|
+
"""Request to configure Polymarket credentials with proxy wallet support."""
|
|
23
|
+
wallet_address: Optional[str] = Field(
|
|
24
|
+
None,
|
|
25
|
+
description="EOA wallet address (0x...) - derived from private key",
|
|
26
|
+
pattern=r"^0x[a-fA-F0-9]{40}$"
|
|
27
|
+
)
|
|
28
|
+
proxy_wallet_address: Optional[str] = Field(
|
|
29
|
+
None,
|
|
30
|
+
description="Proxy wallet address from Polymarket profile (for website users)",
|
|
31
|
+
pattern=r"^0x[a-fA-F0-9]{40}$"
|
|
32
|
+
)
|
|
33
|
+
private_key: Optional[str] = Field(
|
|
34
|
+
None,
|
|
35
|
+
description="Polygon private key (with or without 0x prefix)",
|
|
36
|
+
min_length=64,
|
|
37
|
+
max_length=66
|
|
38
|
+
)
|
|
39
|
+
signature_type: int = Field(
|
|
40
|
+
default=2,
|
|
41
|
+
ge=0,
|
|
42
|
+
le=2,
|
|
43
|
+
description="Signature type: 0=EOA (hardware wallet), 1=Magic (email wallet), 2=Proxy (Polymarket website users, default)"
|
|
44
|
+
)
|
|
45
|
+
demo_mode: bool = Field(
|
|
46
|
+
default=True,
|
|
47
|
+
description="Use demo mode (read-only, no wallet required)"
|
|
48
|
+
)
|
|
49
|
+
trading_limits: Optional[TradingLimitsRequest] = Field(
|
|
50
|
+
default=None,
|
|
51
|
+
description="Trading safety limits"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
@field_validator("wallet_address")
|
|
55
|
+
@classmethod
|
|
56
|
+
def validate_wallet_address(cls, v: Optional[str]) -> Optional[str]:
|
|
57
|
+
if v and not re.match(r"^0x[a-fA-F0-9]{40}$", v):
|
|
58
|
+
raise ValueError("Invalid wallet address format. Must be 0x followed by 40 hex characters.")
|
|
59
|
+
return v
|
|
60
|
+
|
|
61
|
+
@field_validator("proxy_wallet_address")
|
|
62
|
+
@classmethod
|
|
63
|
+
def validate_proxy_wallet_address(cls, v: Optional[str]) -> Optional[str]:
|
|
64
|
+
if v and not re.match(r"^0x[a-fA-F0-9]{40}$", v):
|
|
65
|
+
raise ValueError("Invalid proxy wallet address format. Must be 0x followed by 40 hex characters.")
|
|
66
|
+
return v
|
|
67
|
+
|
|
68
|
+
@field_validator("private_key")
|
|
69
|
+
@classmethod
|
|
70
|
+
def validate_private_key(cls, v: Optional[str]) -> Optional[str]:
|
|
71
|
+
if v:
|
|
72
|
+
# Remove 0x prefix for validation
|
|
73
|
+
key = v[2:] if v.startswith("0x") else v
|
|
74
|
+
if len(key) != 64 or not re.match(r"^[a-fA-F0-9]+$", key):
|
|
75
|
+
raise ValueError("Invalid private key format. Must be 64 hex characters.")
|
|
76
|
+
return v
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class UpdateTradingLimitsRequest(BaseModel):
|
|
80
|
+
"""Request to update trading limits only."""
|
|
81
|
+
trading_limits: TradingLimitsRequest
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class PolymarketStatusResponse(BaseModel):
|
|
85
|
+
"""Response with Polymarket configuration status."""
|
|
86
|
+
configured: bool
|
|
87
|
+
enabled: bool
|
|
88
|
+
demo_mode: bool
|
|
89
|
+
wallet_address: Optional[str] = None
|
|
90
|
+
proxy_wallet_address: Optional[str] = None
|
|
91
|
+
has_private_key: bool = False
|
|
92
|
+
has_api_credentials: bool = False
|
|
93
|
+
signature_type: int = 2 # 0=EOA, 1=Magic, 2=Proxy
|
|
94
|
+
chain_id: int = 137
|
|
95
|
+
trading_limits: Dict[str, Any]
|
|
96
|
+
connection_count: int = 0
|
|
97
|
+
last_connected_at: Optional[str] = None
|
|
98
|
+
last_error: Optional[str] = None
|
|
99
|
+
allowances_verified: bool = False
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class ExecuteToolRequest(BaseModel):
|
|
103
|
+
"""Request to execute a Polymarket tool."""
|
|
104
|
+
tool_name: str = Field(..., description="Name of the tool to execute")
|
|
105
|
+
arguments: Dict[str, Any] = Field(
|
|
106
|
+
default_factory=dict,
|
|
107
|
+
description="Tool arguments"
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class ExecuteToolResponse(BaseModel):
|
|
112
|
+
"""Response from tool execution."""
|
|
113
|
+
success: bool
|
|
114
|
+
data: Optional[Any] = None
|
|
115
|
+
error: Optional[str] = None
|
|
116
|
+
tool_name: str
|
|
117
|
+
execution_time_ms: float
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class AvailableToolsResponse(BaseModel):
|
|
121
|
+
"""Response with available Polymarket tools."""
|
|
122
|
+
tools: List[Dict[str, Any]]
|
|
123
|
+
demo_mode: bool
|
|
124
|
+
enabled: bool
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class AuditLogEntryResponse(BaseModel):
|
|
128
|
+
"""Single audit log entry."""
|
|
129
|
+
id: int
|
|
130
|
+
action: str
|
|
131
|
+
tool_name: Optional[str]
|
|
132
|
+
market_id: Optional[str]
|
|
133
|
+
details: Optional[Dict[str, Any]]
|
|
134
|
+
ip_address: Optional[str]
|
|
135
|
+
timestamp: str
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class AuditLogResponse(BaseModel):
|
|
139
|
+
"""Response with audit log entries."""
|
|
140
|
+
entries: List[AuditLogEntryResponse]
|
|
141
|
+
count: int
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class TradingStatsResponse(BaseModel):
|
|
145
|
+
"""Response with trading statistics."""
|
|
146
|
+
total_calls: int
|
|
147
|
+
orders_placed: int
|
|
148
|
+
orders_cancelled: int
|
|
149
|
+
first_activity: Optional[str]
|
|
150
|
+
last_activity: Optional[str]
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class ErrorResponse(BaseModel):
|
|
154
|
+
"""Error response."""
|
|
155
|
+
detail: str
|
api/polymarket_routes.py
ADDED
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
"""
|
|
2
|
+
API routes for Polymarket integration.
|
|
3
|
+
|
|
4
|
+
Provides endpoints for configuring wallet credentials, executing tools,
|
|
5
|
+
and managing Polymarket access.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from typing import Optional
|
|
10
|
+
from fastapi import APIRouter, HTTPException, Request, Depends
|
|
11
|
+
|
|
12
|
+
from api.polymarket_models import (
|
|
13
|
+
ConfigurePolymarketRequest,
|
|
14
|
+
UpdateTradingLimitsRequest,
|
|
15
|
+
PolymarketStatusResponse,
|
|
16
|
+
ExecuteToolRequest,
|
|
17
|
+
ExecuteToolResponse,
|
|
18
|
+
AvailableToolsResponse,
|
|
19
|
+
AuditLogResponse,
|
|
20
|
+
AuditLogEntryResponse,
|
|
21
|
+
TradingStatsResponse,
|
|
22
|
+
ErrorResponse,
|
|
23
|
+
)
|
|
24
|
+
from tools.polymarket.models import TradingLimits
|
|
25
|
+
from api.dependencies import get_user_id, get_client_ip
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
router = APIRouter(tags=["polymarket"])
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
async def get_polymarket_tool():
|
|
33
|
+
"""Get PolymarketTool from container."""
|
|
34
|
+
from core.container import DependencyContainer
|
|
35
|
+
|
|
36
|
+
container = DependencyContainer.get_instance()
|
|
37
|
+
if not container:
|
|
38
|
+
raise HTTPException(status_code=503, detail="Service unavailable")
|
|
39
|
+
|
|
40
|
+
tool = container.get_service("polymarket")
|
|
41
|
+
if not tool:
|
|
42
|
+
raise HTTPException(
|
|
43
|
+
status_code=503,
|
|
44
|
+
detail="Polymarket service not available"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
return tool
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
async def get_polymarket_db():
|
|
51
|
+
"""Get PolymarketDBHandler from container."""
|
|
52
|
+
from core.container import DependencyContainer
|
|
53
|
+
|
|
54
|
+
container = DependencyContainer.get_instance()
|
|
55
|
+
if not container:
|
|
56
|
+
raise HTTPException(status_code=503, detail="Service unavailable")
|
|
57
|
+
|
|
58
|
+
db = container.get_service("polymarket_db")
|
|
59
|
+
if not db:
|
|
60
|
+
raise HTTPException(
|
|
61
|
+
status_code=503,
|
|
62
|
+
detail="Polymarket database not available"
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
return db
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# ========================================
|
|
69
|
+
# CONFIGURATION ENDPOINTS
|
|
70
|
+
# ========================================
|
|
71
|
+
|
|
72
|
+
@router.post(
|
|
73
|
+
"/configure",
|
|
74
|
+
response_model=PolymarketStatusResponse,
|
|
75
|
+
responses={400: {"model": ErrorResponse}}
|
|
76
|
+
)
|
|
77
|
+
async def configure_polymarket(
|
|
78
|
+
request: Request,
|
|
79
|
+
data: ConfigurePolymarketRequest,
|
|
80
|
+
user_id: str = Depends(get_user_id)
|
|
81
|
+
):
|
|
82
|
+
"""
|
|
83
|
+
Configure Polymarket credentials.
|
|
84
|
+
|
|
85
|
+
Set up wallet address and private key for trading, or enable demo mode
|
|
86
|
+
for read-only access to market data.
|
|
87
|
+
|
|
88
|
+
**Demo Mode**: Set `demo_mode: true` to use Polymarket without a wallet.
|
|
89
|
+
You can search markets, view prices, and analyze data, but cannot trade.
|
|
90
|
+
|
|
91
|
+
**Trading Mode**: Set `demo_mode: false` and provide:
|
|
92
|
+
- `wallet_address`: Your Polygon wallet address (0x...)
|
|
93
|
+
- `private_key`: Your wallet's private key (64 hex characters)
|
|
94
|
+
|
|
95
|
+
**Security**: Private keys are encrypted at rest using AES-128-CBC.
|
|
96
|
+
"""
|
|
97
|
+
db = await get_polymarket_db()
|
|
98
|
+
|
|
99
|
+
# Validate: if not demo mode, need wallet credentials
|
|
100
|
+
# Check if this is an update (existing credentials) or new setup
|
|
101
|
+
existing_credentials = await db.get_credentials(user_id)
|
|
102
|
+
|
|
103
|
+
if not data.demo_mode:
|
|
104
|
+
# For new setup, require wallet address and private key
|
|
105
|
+
# For updates, allow partial updates (use existing values)
|
|
106
|
+
if not existing_credentials:
|
|
107
|
+
if not data.wallet_address:
|
|
108
|
+
raise HTTPException(
|
|
109
|
+
status_code=400,
|
|
110
|
+
detail="Wallet address required when not in demo mode"
|
|
111
|
+
)
|
|
112
|
+
if not data.private_key:
|
|
113
|
+
raise HTTPException(
|
|
114
|
+
status_code=400,
|
|
115
|
+
detail="Private key required when not in demo mode"
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# Build trading limits
|
|
119
|
+
trading_limits = None
|
|
120
|
+
if data.trading_limits:
|
|
121
|
+
trading_limits = TradingLimits(
|
|
122
|
+
max_order_size_usd=data.trading_limits.max_order_size_usd,
|
|
123
|
+
max_total_exposure_usd=data.trading_limits.max_total_exposure_usd,
|
|
124
|
+
max_position_per_market_usd=data.trading_limits.max_position_per_market_usd,
|
|
125
|
+
min_liquidity_required=data.trading_limits.min_liquidity_required,
|
|
126
|
+
max_spread_tolerance=data.trading_limits.max_spread_tolerance,
|
|
127
|
+
require_confirmation_above_usd=data.trading_limits.require_confirmation_above_usd,
|
|
128
|
+
enable_autonomous_trading=data.trading_limits.enable_autonomous_trading,
|
|
129
|
+
)
|
|
130
|
+
elif existing_credentials:
|
|
131
|
+
# Preserve existing trading limits if not provided
|
|
132
|
+
trading_limits = existing_credentials.trading_limits
|
|
133
|
+
|
|
134
|
+
# Save credentials with proxy wallet support
|
|
135
|
+
await db.save_credentials(
|
|
136
|
+
user_id=user_id,
|
|
137
|
+
wallet_address=data.wallet_address,
|
|
138
|
+
proxy_wallet_address=data.proxy_wallet_address,
|
|
139
|
+
private_key=data.private_key,
|
|
140
|
+
signature_type=data.signature_type,
|
|
141
|
+
demo_mode=data.demo_mode,
|
|
142
|
+
enabled=True,
|
|
143
|
+
trading_limits=trading_limits
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
return await get_status(request, user_id)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@router.get("/status", response_model=PolymarketStatusResponse)
|
|
150
|
+
async def get_status(
|
|
151
|
+
request: Request,
|
|
152
|
+
user_id: str = Depends(get_user_id)
|
|
153
|
+
):
|
|
154
|
+
"""
|
|
155
|
+
Get Polymarket configuration status.
|
|
156
|
+
|
|
157
|
+
Returns current configuration including wallet address (masked),
|
|
158
|
+
trading limits, and connection statistics.
|
|
159
|
+
"""
|
|
160
|
+
db = await get_polymarket_db()
|
|
161
|
+
|
|
162
|
+
credentials = await db.get_credentials(user_id)
|
|
163
|
+
|
|
164
|
+
if not credentials:
|
|
165
|
+
return PolymarketStatusResponse(
|
|
166
|
+
configured=False,
|
|
167
|
+
enabled=False,
|
|
168
|
+
demo_mode=True,
|
|
169
|
+
has_api_credentials=False,
|
|
170
|
+
signature_type=2,
|
|
171
|
+
chain_id=137,
|
|
172
|
+
trading_limits=TradingLimits().to_dict(),
|
|
173
|
+
allowances_verified=False
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# Mask wallet address for display
|
|
177
|
+
wallet_display = None
|
|
178
|
+
if credentials.wallet_address:
|
|
179
|
+
addr = credentials.wallet_address
|
|
180
|
+
wallet_display = f"{addr[:6]}...{addr[-4:]}"
|
|
181
|
+
|
|
182
|
+
# Mask proxy wallet address for display
|
|
183
|
+
proxy_wallet_display = None
|
|
184
|
+
if credentials.proxy_wallet_address:
|
|
185
|
+
addr = credentials.proxy_wallet_address
|
|
186
|
+
proxy_wallet_display = f"{addr[:6]}...{addr[-4:]}"
|
|
187
|
+
|
|
188
|
+
# Get connection stats from DB
|
|
189
|
+
query = """
|
|
190
|
+
SELECT connection_count, last_connected_at, last_error
|
|
191
|
+
FROM polymarket_credentials
|
|
192
|
+
WHERE user_id = ?
|
|
193
|
+
"""
|
|
194
|
+
stats = await db.db.fetch_one(query, (user_id,))
|
|
195
|
+
|
|
196
|
+
return PolymarketStatusResponse(
|
|
197
|
+
configured=True,
|
|
198
|
+
enabled=credentials.enabled,
|
|
199
|
+
demo_mode=credentials.demo_mode,
|
|
200
|
+
wallet_address=wallet_display,
|
|
201
|
+
proxy_wallet_address=proxy_wallet_display,
|
|
202
|
+
has_private_key=bool(credentials.private_key),
|
|
203
|
+
has_api_credentials=credentials.has_api_credentials(),
|
|
204
|
+
signature_type=credentials.signature_type,
|
|
205
|
+
chain_id=credentials.chain_id,
|
|
206
|
+
trading_limits=credentials.trading_limits.to_dict(),
|
|
207
|
+
connection_count=stats["connection_count"] if stats else 0,
|
|
208
|
+
last_connected_at=stats["last_connected_at"] if stats else None,
|
|
209
|
+
last_error=stats["last_error"] if stats else None,
|
|
210
|
+
allowances_verified=credentials.allowances_verified
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
@router.patch(
|
|
215
|
+
"/trading-limits",
|
|
216
|
+
response_model=PolymarketStatusResponse,
|
|
217
|
+
responses={404: {"model": ErrorResponse}}
|
|
218
|
+
)
|
|
219
|
+
async def update_trading_limits(
|
|
220
|
+
request: Request,
|
|
221
|
+
data: UpdateTradingLimitsRequest,
|
|
222
|
+
user_id: str = Depends(get_user_id)
|
|
223
|
+
):
|
|
224
|
+
"""
|
|
225
|
+
Update trading limits without changing credentials.
|
|
226
|
+
|
|
227
|
+
Allows adjusting safety limits like max order size, exposure limits,
|
|
228
|
+
and autonomous trading settings.
|
|
229
|
+
"""
|
|
230
|
+
db = await get_polymarket_db()
|
|
231
|
+
|
|
232
|
+
credentials = await db.get_credentials(user_id)
|
|
233
|
+
if not credentials:
|
|
234
|
+
raise HTTPException(
|
|
235
|
+
status_code=404,
|
|
236
|
+
detail="Polymarket not configured. Use POST /configure first."
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
trading_limits = TradingLimits(
|
|
240
|
+
max_order_size_usd=data.trading_limits.max_order_size_usd,
|
|
241
|
+
max_total_exposure_usd=data.trading_limits.max_total_exposure_usd,
|
|
242
|
+
max_position_per_market_usd=data.trading_limits.max_position_per_market_usd,
|
|
243
|
+
min_liquidity_required=data.trading_limits.min_liquidity_required,
|
|
244
|
+
max_spread_tolerance=data.trading_limits.max_spread_tolerance,
|
|
245
|
+
require_confirmation_above_usd=data.trading_limits.require_confirmation_above_usd,
|
|
246
|
+
enable_autonomous_trading=data.trading_limits.enable_autonomous_trading,
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
await db.save_credentials(
|
|
250
|
+
user_id=user_id,
|
|
251
|
+
wallet_address=credentials.wallet_address,
|
|
252
|
+
proxy_wallet_address=credentials.proxy_wallet_address,
|
|
253
|
+
signature_type=credentials.signature_type,
|
|
254
|
+
demo_mode=credentials.demo_mode,
|
|
255
|
+
enabled=credentials.enabled,
|
|
256
|
+
trading_limits=trading_limits
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
return await get_status(request, user_id)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
@router.post("/disable", response_model=PolymarketStatusResponse)
|
|
263
|
+
async def disable_polymarket(
|
|
264
|
+
request: Request,
|
|
265
|
+
user_id: str = Depends(get_user_id)
|
|
266
|
+
):
|
|
267
|
+
"""
|
|
268
|
+
Disable Polymarket access.
|
|
269
|
+
|
|
270
|
+
Disables Polymarket without deleting credentials.
|
|
271
|
+
Can be re-enabled later.
|
|
272
|
+
"""
|
|
273
|
+
db = await get_polymarket_db()
|
|
274
|
+
|
|
275
|
+
credentials = await db.get_credentials(user_id)
|
|
276
|
+
if credentials:
|
|
277
|
+
await db.save_credentials(
|
|
278
|
+
user_id=user_id,
|
|
279
|
+
wallet_address=credentials.wallet_address,
|
|
280
|
+
proxy_wallet_address=credentials.proxy_wallet_address,
|
|
281
|
+
signature_type=credentials.signature_type,
|
|
282
|
+
demo_mode=credentials.demo_mode,
|
|
283
|
+
enabled=False,
|
|
284
|
+
trading_limits=credentials.trading_limits
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
return await get_status(request, user_id)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
@router.post("/enable", response_model=PolymarketStatusResponse)
|
|
291
|
+
async def enable_polymarket(
|
|
292
|
+
request: Request,
|
|
293
|
+
user_id: str = Depends(get_user_id)
|
|
294
|
+
):
|
|
295
|
+
"""
|
|
296
|
+
Enable Polymarket access.
|
|
297
|
+
|
|
298
|
+
Re-enables Polymarket if it was disabled.
|
|
299
|
+
"""
|
|
300
|
+
db = await get_polymarket_db()
|
|
301
|
+
|
|
302
|
+
credentials = await db.get_credentials(user_id)
|
|
303
|
+
if not credentials:
|
|
304
|
+
raise HTTPException(
|
|
305
|
+
status_code=404,
|
|
306
|
+
detail="Polymarket not configured. Use POST /configure first."
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
await db.save_credentials(
|
|
310
|
+
user_id=user_id,
|
|
311
|
+
wallet_address=credentials.wallet_address,
|
|
312
|
+
proxy_wallet_address=credentials.proxy_wallet_address,
|
|
313
|
+
signature_type=credentials.signature_type,
|
|
314
|
+
demo_mode=credentials.demo_mode,
|
|
315
|
+
enabled=True,
|
|
316
|
+
trading_limits=credentials.trading_limits
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
return await get_status(request, user_id)
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
@router.delete("/credentials")
|
|
323
|
+
async def delete_credentials(
|
|
324
|
+
request: Request,
|
|
325
|
+
user_id: str = Depends(get_user_id)
|
|
326
|
+
):
|
|
327
|
+
"""
|
|
328
|
+
Delete Polymarket credentials.
|
|
329
|
+
|
|
330
|
+
Permanently removes wallet credentials and configuration.
|
|
331
|
+
This action cannot be undone.
|
|
332
|
+
"""
|
|
333
|
+
db = await get_polymarket_db()
|
|
334
|
+
await db.delete_credentials(user_id)
|
|
335
|
+
|
|
336
|
+
return {"status": "deleted", "message": "Polymarket credentials removed"}
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
# ========================================
|
|
340
|
+
# TOOL EXECUTION ENDPOINTS
|
|
341
|
+
# ========================================
|
|
342
|
+
|
|
343
|
+
@router.get("/tools", response_model=AvailableToolsResponse)
|
|
344
|
+
async def get_available_tools(
|
|
345
|
+
request: Request,
|
|
346
|
+
user_id: str = Depends(get_user_id)
|
|
347
|
+
):
|
|
348
|
+
"""
|
|
349
|
+
Get available Polymarket tools.
|
|
350
|
+
|
|
351
|
+
Returns list of all Polymarket tools with their schemas.
|
|
352
|
+
"""
|
|
353
|
+
db = await get_polymarket_db()
|
|
354
|
+
tool = await get_polymarket_tool()
|
|
355
|
+
|
|
356
|
+
credentials = await db.get_credentials(user_id)
|
|
357
|
+
if not credentials or not credentials.enabled:
|
|
358
|
+
return AvailableToolsResponse(
|
|
359
|
+
tools=[],
|
|
360
|
+
demo_mode=True,
|
|
361
|
+
enabled=False
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
# Get tools from PolymarketTool
|
|
365
|
+
tools = tool.get_available_tools()
|
|
366
|
+
|
|
367
|
+
return AvailableToolsResponse(
|
|
368
|
+
tools=tools,
|
|
369
|
+
demo_mode=credentials.demo_mode,
|
|
370
|
+
enabled=credentials.enabled
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
@router.post("/execute", response_model=ExecuteToolResponse)
|
|
375
|
+
async def execute_tool(
|
|
376
|
+
request: Request,
|
|
377
|
+
data: ExecuteToolRequest,
|
|
378
|
+
user_id: str = Depends(get_user_id)
|
|
379
|
+
):
|
|
380
|
+
"""
|
|
381
|
+
Execute a Polymarket tool.
|
|
382
|
+
|
|
383
|
+
Executes the specified tool with provided arguments.
|
|
384
|
+
Trading tools require proper wallet configuration.
|
|
385
|
+
"""
|
|
386
|
+
import time
|
|
387
|
+
|
|
388
|
+
polymarket_tool = await get_polymarket_tool()
|
|
389
|
+
db = await get_polymarket_db()
|
|
390
|
+
|
|
391
|
+
# Set user context for the tool
|
|
392
|
+
polymarket_tool.set_user_context(user_id)
|
|
393
|
+
|
|
394
|
+
start_time = time.time()
|
|
395
|
+
|
|
396
|
+
try:
|
|
397
|
+
# Execute the action on the tool
|
|
398
|
+
result = await polymarket_tool.execute_action(data.tool_name, data.arguments)
|
|
399
|
+
execution_time = (time.time() - start_time) * 1000
|
|
400
|
+
|
|
401
|
+
# Log to audit
|
|
402
|
+
await db.audit_log(
|
|
403
|
+
user_id=user_id,
|
|
404
|
+
action="tool_call",
|
|
405
|
+
tool_name=data.tool_name,
|
|
406
|
+
details={"arguments": data.arguments, "success": True},
|
|
407
|
+
ip_address=get_client_ip(request)
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
return ExecuteToolResponse(
|
|
411
|
+
success=True,
|
|
412
|
+
data=result,
|
|
413
|
+
error=None,
|
|
414
|
+
tool_name=data.tool_name,
|
|
415
|
+
execution_time_ms=execution_time
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
except Exception as e:
|
|
419
|
+
execution_time = (time.time() - start_time) * 1000
|
|
420
|
+
|
|
421
|
+
# Log error to audit
|
|
422
|
+
await db.audit_log(
|
|
423
|
+
user_id=user_id,
|
|
424
|
+
action="tool_call_error",
|
|
425
|
+
tool_name=data.tool_name,
|
|
426
|
+
details={"arguments": data.arguments, "error": str(e)},
|
|
427
|
+
ip_address=get_client_ip(request)
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
return ExecuteToolResponse(
|
|
431
|
+
success=False,
|
|
432
|
+
data=None,
|
|
433
|
+
error=str(e),
|
|
434
|
+
tool_name=data.tool_name,
|
|
435
|
+
execution_time_ms=execution_time
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
# ========================================
|
|
440
|
+
# AUDIT & STATS ENDPOINTS
|
|
441
|
+
# ========================================
|
|
442
|
+
|
|
443
|
+
@router.get("/audit", response_model=AuditLogResponse)
|
|
444
|
+
async def get_audit_log(
|
|
445
|
+
request: Request,
|
|
446
|
+
limit: int = 50,
|
|
447
|
+
action: Optional[str] = None,
|
|
448
|
+
user_id: str = Depends(get_user_id)
|
|
449
|
+
):
|
|
450
|
+
"""
|
|
451
|
+
Get Polymarket audit log.
|
|
452
|
+
|
|
453
|
+
Returns history of Polymarket operations including tool calls,
|
|
454
|
+
configuration changes, and errors.
|
|
455
|
+
"""
|
|
456
|
+
db = await get_polymarket_db()
|
|
457
|
+
|
|
458
|
+
entries = await db.get_audit_log(
|
|
459
|
+
user_id,
|
|
460
|
+
limit=min(limit, 100),
|
|
461
|
+
action=action
|
|
462
|
+
)
|
|
463
|
+
|
|
464
|
+
return AuditLogResponse(
|
|
465
|
+
entries=[
|
|
466
|
+
AuditLogEntryResponse(
|
|
467
|
+
id=e["id"],
|
|
468
|
+
action=e["action"],
|
|
469
|
+
tool_name=e["tool_name"],
|
|
470
|
+
market_id=e["market_id"],
|
|
471
|
+
details=e["details"],
|
|
472
|
+
ip_address=e["ip_address"],
|
|
473
|
+
timestamp=e["timestamp"]
|
|
474
|
+
)
|
|
475
|
+
for e in entries
|
|
476
|
+
],
|
|
477
|
+
count=len(entries)
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
@router.get("/stats", response_model=TradingStatsResponse)
|
|
482
|
+
async def get_trading_stats(
|
|
483
|
+
request: Request,
|
|
484
|
+
user_id: str = Depends(get_user_id)
|
|
485
|
+
):
|
|
486
|
+
"""
|
|
487
|
+
Get trading statistics.
|
|
488
|
+
|
|
489
|
+
Returns aggregate statistics about Polymarket usage.
|
|
490
|
+
"""
|
|
491
|
+
db = await get_polymarket_db()
|
|
492
|
+
|
|
493
|
+
stats = await db.get_trading_stats(user_id)
|
|
494
|
+
|
|
495
|
+
return TradingStatsResponse(
|
|
496
|
+
total_calls=stats["total_calls"],
|
|
497
|
+
orders_placed=stats["orders_placed"],
|
|
498
|
+
orders_cancelled=stats["orders_cancelled"],
|
|
499
|
+
first_activity=stats["first_activity"],
|
|
500
|
+
last_activity=stats["last_activity"]
|
|
501
|
+
)
|