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
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Runtime safety checks and validation for Task.
|
|
3
|
+
|
|
4
|
+
This module provides critical runtime safety checks to prevent the issues
|
|
5
|
+
identified in AUTOV2_RUNTIME_FIXES.md
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import logging
|
|
10
|
+
from typing import Optional, Dict, Any, List, Callable
|
|
11
|
+
from functools import wraps
|
|
12
|
+
import time
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class RuntimeSafety:
|
|
18
|
+
"""Runtime safety checks and guards for Task."""
|
|
19
|
+
|
|
20
|
+
@staticmethod
|
|
21
|
+
def add_timeout_guard(timeout_seconds: float = 60.0):
|
|
22
|
+
"""Add timeout protection to async functions.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
timeout_seconds: Timeout in seconds (default 60)
|
|
26
|
+
|
|
27
|
+
Usage:
|
|
28
|
+
@add_timeout_guard(30)
|
|
29
|
+
async def my_async_function():
|
|
30
|
+
# Will timeout after 30 seconds
|
|
31
|
+
"""
|
|
32
|
+
def decorator(func: Callable) -> Callable:
|
|
33
|
+
@wraps(func)
|
|
34
|
+
async def wrapper(*args, **kwargs):
|
|
35
|
+
try:
|
|
36
|
+
return await asyncio.wait_for(
|
|
37
|
+
func(*args, **kwargs),
|
|
38
|
+
timeout=timeout_seconds
|
|
39
|
+
)
|
|
40
|
+
except asyncio.TimeoutError:
|
|
41
|
+
logger.warning(f"{func.__name__} timed out after {timeout_seconds}s")
|
|
42
|
+
# Return sensible default based on function name
|
|
43
|
+
if "approval" in func.__name__.lower():
|
|
44
|
+
return {"approved": True, "reason": "timeout_auto_approved"}
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
return wrapper
|
|
48
|
+
return decorator
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def validate_tool_call_structure(tool_call: Dict[str, Any]) -> bool:
|
|
52
|
+
"""Validate tool call has required structure.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
tool_call: Tool call dict to validate
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
True if valid, False otherwise
|
|
59
|
+
"""
|
|
60
|
+
required = {"name", "id"}
|
|
61
|
+
if not all(field in tool_call for field in required):
|
|
62
|
+
return False
|
|
63
|
+
|
|
64
|
+
# Validate types
|
|
65
|
+
if not isinstance(tool_call.get("name"), str):
|
|
66
|
+
return False
|
|
67
|
+
if not isinstance(tool_call.get("id"), str):
|
|
68
|
+
return False
|
|
69
|
+
|
|
70
|
+
# Validate args if present
|
|
71
|
+
if "args" in tool_call and not isinstance(tool_call["args"], dict):
|
|
72
|
+
return False
|
|
73
|
+
|
|
74
|
+
return True
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def protect_deque_operations(deque_obj, operation: str, *args, **kwargs):
|
|
78
|
+
"""Safely perform operations on deque objects.
|
|
79
|
+
|
|
80
|
+
Deques don't support index-based removal, so we convert to list,
|
|
81
|
+
perform operation, and convert back.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
deque_obj: The deque object
|
|
85
|
+
operation: Operation to perform ('remove', 'pop', etc.)
|
|
86
|
+
*args, **kwargs: Arguments for the operation
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Result of the operation
|
|
90
|
+
"""
|
|
91
|
+
from collections import deque
|
|
92
|
+
|
|
93
|
+
if operation == 'remove_by_index':
|
|
94
|
+
# Convert to list, remove by index, convert back
|
|
95
|
+
idx = args[0] if args else -1
|
|
96
|
+
items_list = list(deque_obj)
|
|
97
|
+
if 0 <= idx < len(items_list):
|
|
98
|
+
removed = items_list.pop(idx)
|
|
99
|
+
# Preserve maxlen if it exists
|
|
100
|
+
maxlen = getattr(deque_obj, 'maxlen', None)
|
|
101
|
+
new_deque = deque(items_list, maxlen=maxlen)
|
|
102
|
+
return new_deque, removed
|
|
103
|
+
return deque_obj, None
|
|
104
|
+
|
|
105
|
+
# For other operations, use standard methods
|
|
106
|
+
return getattr(deque_obj, operation)(*args, **kwargs)
|
|
107
|
+
|
|
108
|
+
@staticmethod
|
|
109
|
+
def validate_session_id(session_id: str) -> bool:
|
|
110
|
+
"""Validate session ID format.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
session_id: Session ID to validate
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
True if valid, False otherwise
|
|
117
|
+
"""
|
|
118
|
+
if not session_id or not isinstance(session_id, str):
|
|
119
|
+
return False
|
|
120
|
+
|
|
121
|
+
# Session ID should not be empty after stripping
|
|
122
|
+
if not session_id.strip():
|
|
123
|
+
return False
|
|
124
|
+
|
|
125
|
+
# Should not contain dangerous characters
|
|
126
|
+
dangerous_chars = ['/', '\\', '..', '\x00', '\n', '\r']
|
|
127
|
+
if any(char in session_id for char in dangerous_chars):
|
|
128
|
+
return False
|
|
129
|
+
|
|
130
|
+
return True
|
|
131
|
+
|
|
132
|
+
@staticmethod
|
|
133
|
+
def safe_json_parse(json_str: str, max_retries: int = 3) -> Optional[Dict]:
|
|
134
|
+
"""Safely parse JSON with retry logic.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
json_str: JSON string to parse
|
|
138
|
+
max_retries: Maximum parse attempts
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
Parsed dict or None if failed
|
|
142
|
+
"""
|
|
143
|
+
import json
|
|
144
|
+
import re
|
|
145
|
+
|
|
146
|
+
for attempt in range(max_retries):
|
|
147
|
+
try:
|
|
148
|
+
# Clean common issues
|
|
149
|
+
cleaned = json_str.strip()
|
|
150
|
+
|
|
151
|
+
# Remove code fences
|
|
152
|
+
if cleaned.startswith('```'):
|
|
153
|
+
cleaned = re.sub(r'^```[a-z]*\n', '', cleaned)
|
|
154
|
+
cleaned = re.sub(r'\n```$', '', cleaned)
|
|
155
|
+
|
|
156
|
+
# Remove think tags
|
|
157
|
+
cleaned = re.sub(r'<think>.*?</think>', '', cleaned, flags=re.DOTALL)
|
|
158
|
+
|
|
159
|
+
# Try to parse
|
|
160
|
+
return json.loads(cleaned)
|
|
161
|
+
|
|
162
|
+
except json.JSONDecodeError as e:
|
|
163
|
+
if attempt == max_retries - 1:
|
|
164
|
+
logger.error(f"JSON parse failed after {max_retries} attempts: {e}")
|
|
165
|
+
return None
|
|
166
|
+
|
|
167
|
+
# Try to fix common issues
|
|
168
|
+
if "Expecting property name" in str(e):
|
|
169
|
+
# Fix trailing commas
|
|
170
|
+
cleaned = re.sub(r',\s*}', '}', cleaned)
|
|
171
|
+
cleaned = re.sub(r',\s*]', ']', cleaned)
|
|
172
|
+
|
|
173
|
+
time.sleep(0.1 * (attempt + 1)) # Exponential backoff
|
|
174
|
+
|
|
175
|
+
return None
|
|
176
|
+
|
|
177
|
+
@staticmethod
|
|
178
|
+
def memory_guard(max_size_mb: float = 100):
|
|
179
|
+
"""Decorator to guard against memory explosion.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
max_size_mb: Maximum allowed memory growth in MB
|
|
183
|
+
|
|
184
|
+
Usage:
|
|
185
|
+
@memory_guard(50)
|
|
186
|
+
def process_screenshots():
|
|
187
|
+
# Will log warning if memory grows by >50MB
|
|
188
|
+
"""
|
|
189
|
+
def decorator(func: Callable) -> Callable:
|
|
190
|
+
@wraps(func)
|
|
191
|
+
def wrapper(*args, **kwargs):
|
|
192
|
+
import psutil
|
|
193
|
+
import os
|
|
194
|
+
|
|
195
|
+
process = psutil.Process(os.getpid())
|
|
196
|
+
mem_before = process.memory_info().rss / 1024 / 1024 # MB
|
|
197
|
+
|
|
198
|
+
try:
|
|
199
|
+
result = func(*args, **kwargs)
|
|
200
|
+
finally:
|
|
201
|
+
mem_after = process.memory_info().rss / 1024 / 1024 # MB
|
|
202
|
+
mem_growth = mem_after - mem_before
|
|
203
|
+
|
|
204
|
+
if mem_growth > max_size_mb:
|
|
205
|
+
logger.warning(
|
|
206
|
+
f"{func.__name__} memory growth: {mem_growth:.1f}MB "
|
|
207
|
+
f"(exceeds {max_size_mb}MB limit)"
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
return result
|
|
211
|
+
|
|
212
|
+
# Handle async functions
|
|
213
|
+
if asyncio.iscoroutinefunction(func):
|
|
214
|
+
@wraps(func)
|
|
215
|
+
async def async_wrapper(*args, **kwargs):
|
|
216
|
+
import psutil
|
|
217
|
+
import os
|
|
218
|
+
|
|
219
|
+
process = psutil.Process(os.getpid())
|
|
220
|
+
mem_before = process.memory_info().rss / 1024 / 1024
|
|
221
|
+
|
|
222
|
+
try:
|
|
223
|
+
result = await func(*args, **kwargs)
|
|
224
|
+
finally:
|
|
225
|
+
mem_after = process.memory_info().rss / 1024 / 1024
|
|
226
|
+
mem_growth = mem_after - mem_before
|
|
227
|
+
|
|
228
|
+
if mem_growth > max_size_mb:
|
|
229
|
+
logger.warning(
|
|
230
|
+
f"{func.__name__} memory growth: {mem_growth:.1f}MB "
|
|
231
|
+
f"(exceeds {max_size_mb}MB limit)"
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
return result
|
|
235
|
+
|
|
236
|
+
return async_wrapper
|
|
237
|
+
|
|
238
|
+
return wrapper
|
|
239
|
+
return decorator
|
|
240
|
+
|
|
241
|
+
@staticmethod
|
|
242
|
+
def validate_token_limits(
|
|
243
|
+
current_tokens: int,
|
|
244
|
+
max_tokens: int,
|
|
245
|
+
safety_buffer: int = 1000
|
|
246
|
+
) -> bool:
|
|
247
|
+
"""Validate token counts are within safe limits.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
current_tokens: Current token count
|
|
251
|
+
max_tokens: Maximum allowed tokens
|
|
252
|
+
safety_buffer: Safety buffer to maintain
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
True if within safe limits, False otherwise
|
|
256
|
+
"""
|
|
257
|
+
if current_tokens <= 0:
|
|
258
|
+
logger.warning("Invalid token count: <= 0")
|
|
259
|
+
return False
|
|
260
|
+
|
|
261
|
+
if current_tokens + safety_buffer >= max_tokens:
|
|
262
|
+
logger.warning(
|
|
263
|
+
f"Token limit approaching: {current_tokens} + {safety_buffer} >= {max_tokens}"
|
|
264
|
+
)
|
|
265
|
+
return False
|
|
266
|
+
|
|
267
|
+
return True
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
# Export convenience decorators
|
|
271
|
+
timeout_guard = RuntimeSafety.add_timeout_guard
|
|
272
|
+
memory_guard = RuntimeSafety.memory_guard
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def apply_runtime_fixes():
|
|
276
|
+
"""Apply all critical runtime fixes identified in AUTOV2_RUNTIME_FIXES.md"""
|
|
277
|
+
|
|
278
|
+
logger.info("Applying Task runtime safety fixes...")
|
|
279
|
+
|
|
280
|
+
# 1. Patch approval methods to add timeouts
|
|
281
|
+
# NOTE: Approval system removed - request_approval now auto-approves
|
|
282
|
+
try:
|
|
283
|
+
from agents.task.agent import approval
|
|
284
|
+
if hasattr(approval, 'request_approval'):
|
|
285
|
+
# No longer needed - approval workflow simplified
|
|
286
|
+
logger.debug("Approval system simplified - timeout patching skipped")
|
|
287
|
+
except Exception as e:
|
|
288
|
+
logger.debug(f"Could not patch approval: {e}")
|
|
289
|
+
|
|
290
|
+
# 2. Add memory monitoring for screenshot operations
|
|
291
|
+
try:
|
|
292
|
+
from agents.task.agent import screenshots
|
|
293
|
+
if hasattr(screenshots, 'create_gif'):
|
|
294
|
+
original = screenshots.create_gif
|
|
295
|
+
screenshots.create_gif = memory_guard(100)(original)
|
|
296
|
+
logger.info("✓ Added memory guard to screenshot operations")
|
|
297
|
+
except Exception as e:
|
|
298
|
+
logger.debug(f"Could not patch screenshots: {e}")
|
|
299
|
+
|
|
300
|
+
logger.info("Runtime safety fixes applied")
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
# Auto-apply fixes when module is imported
|
|
304
|
+
if __name__ != "__main__":
|
|
305
|
+
try:
|
|
306
|
+
apply_runtime_fixes()
|
|
307
|
+
except Exception as e:
|
|
308
|
+
logger.warning(f"Could not apply all runtime fixes: {e}")
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, Optional
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from tools.browser.browser import Browser
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BrowserPoolMixin:
|
|
10
|
+
"""Browser-pool access, tools dict compatibility, and context release for SessionOrchestrator."""
|
|
11
|
+
|
|
12
|
+
@property
|
|
13
|
+
def tools(self) -> Dict[str, Any]:
|
|
14
|
+
"""Backward compatibility: Return tools as a dict."""
|
|
15
|
+
if not self.controller:
|
|
16
|
+
return {}
|
|
17
|
+
result = {}
|
|
18
|
+
for tool_name in self.controller.list_tools():
|
|
19
|
+
tool = self.controller.get_tool(tool_name)
|
|
20
|
+
if tool:
|
|
21
|
+
result[tool_name] = tool
|
|
22
|
+
return result
|
|
23
|
+
|
|
24
|
+
@tools.setter
|
|
25
|
+
def tools(self, value: Dict[str, Any]) -> None:
|
|
26
|
+
"""Backward compatibility: Set tools from a dict."""
|
|
27
|
+
if not self.controller:
|
|
28
|
+
self.logger.warning("Controller not initialized - cannot set tools")
|
|
29
|
+
return
|
|
30
|
+
# Clear existing tools
|
|
31
|
+
for tool_name in self.controller.list_tools():
|
|
32
|
+
self.controller.remove_tool(tool_name)
|
|
33
|
+
# Add all new tools
|
|
34
|
+
for name, tool in value.items():
|
|
35
|
+
self.controller.add_tool(name, tool)
|
|
36
|
+
self.logger.debug(f"Added tool '{name}' to controller")
|
|
37
|
+
|
|
38
|
+
async def get_browser_context(self, agent_id: str, reuse: bool = True, timeout: float = 30.0) -> Optional[Any]:
|
|
39
|
+
"""Get browser context for agent from BrowserManager.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
agent_id: Agent ID (format: agentname_sessionid)
|
|
43
|
+
reuse: Whether to reuse pooled contexts
|
|
44
|
+
timeout: Unused (kept for compatibility)
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
Browser context or None
|
|
48
|
+
"""
|
|
49
|
+
# No BrowserManager is an EXPECTED steady state now — the default CLI (and
|
|
50
|
+
# any non-browser session) provisions none, and the step loop asks for a
|
|
51
|
+
# context every step regardless of loaded tools. Log at debug, not error
|
|
52
|
+
# (OR-3): an error here is misleading noise on every step of a normal run.
|
|
53
|
+
if not self.browser_manager:
|
|
54
|
+
self.logger.debug(f"No BrowserManager - no browser context for {agent_id}")
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
# Agent ID already contains session (format set in Agent.__init__)
|
|
58
|
+
# No need to manipulate - use as-is
|
|
59
|
+
context = await self.browser_manager.get_context(agent_id, reuse=reuse)
|
|
60
|
+
|
|
61
|
+
# Track context for cleanup (prevents leaks if agent removed before cleanup)
|
|
62
|
+
if context and hasattr(self, '_browser_contexts'):
|
|
63
|
+
self._browser_contexts.add(agent_id)
|
|
64
|
+
self.logger.debug(f"Tracking browser context for cleanup: {agent_id}")
|
|
65
|
+
|
|
66
|
+
# Track context acquisition with telemetry
|
|
67
|
+
if context and hasattr(self, 'telemetry_manager') and self.telemetry_manager:
|
|
68
|
+
try:
|
|
69
|
+
self.telemetry_manager.capture_event(
|
|
70
|
+
event_type="browser_context_acquired",
|
|
71
|
+
data={
|
|
72
|
+
"agent_id": agent_id,
|
|
73
|
+
"session_id": self.session_id,
|
|
74
|
+
"context_id": id(context),
|
|
75
|
+
"reused": reuse
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
except Exception as e:
|
|
79
|
+
self.logger.debug(f"Failed to emit browser context telemetry: {e}")
|
|
80
|
+
|
|
81
|
+
return context
|
|
82
|
+
|
|
83
|
+
async def _ensure_browser_available(self) -> Optional['Browser']:
|
|
84
|
+
"""Get browser from BrowserManager (single source of truth).
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
Browser instance from BrowserManager, or None if unavailable
|
|
88
|
+
"""
|
|
89
|
+
if not self.browser_manager:
|
|
90
|
+
self.logger.error("BrowserManager required but not available")
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
# Initialize BrowserManager if needed
|
|
94
|
+
if not self.browser_manager.is_initialized:
|
|
95
|
+
try:
|
|
96
|
+
await self.browser_manager.initialize()
|
|
97
|
+
except Exception as e:
|
|
98
|
+
self.logger.error(f"Failed to initialize BrowserManager: {e}")
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
# Get browser from BrowserManager (ONLY source)
|
|
102
|
+
try:
|
|
103
|
+
browser = await self.browser_manager.get_browser()
|
|
104
|
+
if browser:
|
|
105
|
+
self.logger.debug("Got browser from BrowserManager")
|
|
106
|
+
return browser
|
|
107
|
+
else:
|
|
108
|
+
self.logger.error("BrowserManager has no browser available")
|
|
109
|
+
return None
|
|
110
|
+
except Exception as e:
|
|
111
|
+
self.logger.error(f"Failed to get browser from BrowserManager: {e}")
|
|
112
|
+
return None
|
|
113
|
+
|
|
114
|
+
async def release_browser_context(self, context_id: str, close: bool = True):
|
|
115
|
+
"""Release a browser context back to the pool or close it.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
context_id: ID of the context to release
|
|
119
|
+
close: If True, close the context instead of returning to pool
|
|
120
|
+
|
|
121
|
+
This delegates to BrowserManager if available, otherwise is a no-op.
|
|
122
|
+
"""
|
|
123
|
+
if self.browser_manager:
|
|
124
|
+
try:
|
|
125
|
+
await self.browser_manager.release_context(context_id, close=close)
|
|
126
|
+
self.logger.debug(f"Released browser context {context_id} (close={close})")
|
|
127
|
+
except Exception as e:
|
|
128
|
+
self.logger.warning(f"Failed to release browser context {context_id}: {e}")
|
|
129
|
+
else:
|
|
130
|
+
self.logger.debug(f"No browser_manager available to release context {context_id}")
|