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
cli/ui/events.py
ADDED
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
"""Typed feed-event model for the POLYROB CLI renderer (Phase 1).
|
|
2
|
+
|
|
3
|
+
Normalises the 14 real feed dicts emitted by
|
|
4
|
+
``agents/task/telemetry/formatters.py`` into a small set of typed
|
|
5
|
+
``RenderEvent`` dataclasses. The field names are taken DIRECTLY from the
|
|
6
|
+
formatter source — this file is the authoritative mapping so that wrong-key
|
|
7
|
+
bugs like the ``cost``/``cost_estimate`` or ``total_tokens``/``token_count``
|
|
8
|
+
mis-reads in the old ``_feed.py`` cannot silently recur.
|
|
9
|
+
|
|
10
|
+
Key mapping (formatters.py → RenderEvent field):
|
|
11
|
+
llm_request
|
|
12
|
+
data.model_name → LLMCall.model_name
|
|
13
|
+
data.provider → LLMCall.provider
|
|
14
|
+
data.prompt_tokens → LLMCall.prompt_tokens
|
|
15
|
+
data.completion_tokens→ LLMCall.completion_tokens
|
|
16
|
+
data.token_count → LLMCall.token_count
|
|
17
|
+
data.cost_estimate → LLMCall.cost_estimate (NOT "cost")
|
|
18
|
+
data.duration_seconds → LLMCall.duration_seconds
|
|
19
|
+
data.success → LLMCall.success
|
|
20
|
+
|
|
21
|
+
step
|
|
22
|
+
data.reasoning → Step.reasoning
|
|
23
|
+
data.context.outputs.memory → Step.memory
|
|
24
|
+
data.actions → Step.actions
|
|
25
|
+
|
|
26
|
+
session_start
|
|
27
|
+
data.task → SessionStart.task
|
|
28
|
+
data.model_name → SessionStart.model_name
|
|
29
|
+
data.agent_id → SessionStart.agent_id
|
|
30
|
+
data.use_vision → SessionStart.use_vision
|
|
31
|
+
|
|
32
|
+
tool_execution
|
|
33
|
+
data.tool_name → ToolExec.tool_name
|
|
34
|
+
data.action_name → ToolExec.action_name
|
|
35
|
+
data.success → ToolExec.success
|
|
36
|
+
data.duration_seconds → ToolExec.duration_seconds
|
|
37
|
+
data.error → ToolExec.error
|
|
38
|
+
|
|
39
|
+
iteration_complete
|
|
40
|
+
data.iteration → IterationDone.iteration
|
|
41
|
+
data.iteration_status → IterationDone.iteration_status
|
|
42
|
+
data.is_done → IterationDone.is_done
|
|
43
|
+
|
|
44
|
+
error
|
|
45
|
+
data.error_message → ErrorEvent.error_message
|
|
46
|
+
data.error_type → ErrorEvent.error_type
|
|
47
|
+
|
|
48
|
+
session_completion
|
|
49
|
+
data.success → SessionDone.success
|
|
50
|
+
data.total_steps → SessionDone.total_steps
|
|
51
|
+
data.metrics.final_result → SessionDone.final_result
|
|
52
|
+
data.error_message → SessionDone.error_message
|
|
53
|
+
|
|
54
|
+
agent_registration (live-emitted; §0 amendment 2)
|
|
55
|
+
data.agent_id / agent_name / agent_type / model_name / task → AgentRegistration
|
|
56
|
+
|
|
57
|
+
agent_end (live-emitted; §0 amendment 2)
|
|
58
|
+
data.agent_id / steps / max_steps_reached / success / errors → AgentEnd
|
|
59
|
+
|
|
60
|
+
All other types (status / user_message / queue_status /
|
|
61
|
+
multi_agent_relationship / multi_agent_relationship_detailed /
|
|
62
|
+
session_relationship / available_actions / session_paused /
|
|
63
|
+
session_resumed) become ``Info``. Unknown types also become ``Info``
|
|
64
|
+
(never crash).
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
from __future__ import annotations
|
|
68
|
+
|
|
69
|
+
import logging
|
|
70
|
+
from dataclasses import dataclass, field
|
|
71
|
+
from typing import Any, Dict, List, Optional
|
|
72
|
+
|
|
73
|
+
logger = logging.getLogger(__name__)
|
|
74
|
+
|
|
75
|
+
# ---------------------------------------------------------------------------
|
|
76
|
+
# Dataclasses
|
|
77
|
+
# ---------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@dataclass
|
|
81
|
+
class SessionStart:
|
|
82
|
+
"""Emitted when the agent session begins."""
|
|
83
|
+
|
|
84
|
+
type: str = "session_start"
|
|
85
|
+
task: str = ""
|
|
86
|
+
model_name: str = ""
|
|
87
|
+
agent_id: str = ""
|
|
88
|
+
use_vision: bool = False
|
|
89
|
+
raw: Dict[str, Any] = field(default_factory=dict)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@dataclass
|
|
93
|
+
class Step:
|
|
94
|
+
"""One agent step: reasoning + memory + actions."""
|
|
95
|
+
|
|
96
|
+
type: str = "step"
|
|
97
|
+
step: int = 0
|
|
98
|
+
reasoning: str = ""
|
|
99
|
+
memory: str = ""
|
|
100
|
+
actions: List[Dict[str, Any]] = field(default_factory=list)
|
|
101
|
+
raw: Dict[str, Any] = field(default_factory=dict)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@dataclass
|
|
105
|
+
class LLMCall:
|
|
106
|
+
"""Result of an LLM API call (real field names from LLMRequestFormatter)."""
|
|
107
|
+
|
|
108
|
+
type: str = "llm_request"
|
|
109
|
+
model_name: str = ""
|
|
110
|
+
provider: str = ""
|
|
111
|
+
prompt_tokens: Optional[int] = None
|
|
112
|
+
completion_tokens: Optional[int] = None
|
|
113
|
+
token_count: Optional[int] = None
|
|
114
|
+
cost_estimate: Optional[float] = None
|
|
115
|
+
duration_seconds: float = 0.0
|
|
116
|
+
success: bool = True
|
|
117
|
+
raw: Dict[str, Any] = field(default_factory=dict)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@dataclass
|
|
121
|
+
class ToolExec:
|
|
122
|
+
"""Result of a single tool execution (real field names from ToolExecutionFormatter).
|
|
123
|
+
|
|
124
|
+
``parameters``/``result_preview``/``result_truncated`` are carried so the CLI
|
|
125
|
+
can render a tool transcript (call args + result preview) BY DEFAULT, not just
|
|
126
|
+
under ``/verbose``. The feed dict has always carried them; they were previously
|
|
127
|
+
dropped on the floor here.
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
type: str = "tool_execution"
|
|
131
|
+
step: int = 0
|
|
132
|
+
tool_name: str = ""
|
|
133
|
+
action_name: str = ""
|
|
134
|
+
success: bool = True
|
|
135
|
+
duration_seconds: float = 0.0
|
|
136
|
+
error: Optional[str] = None
|
|
137
|
+
parameters: Dict[str, Any] = field(default_factory=dict)
|
|
138
|
+
result_preview: Optional[str] = None
|
|
139
|
+
result_truncated: bool = False
|
|
140
|
+
raw: Dict[str, Any] = field(default_factory=dict)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@dataclass
|
|
144
|
+
class IterationDone:
|
|
145
|
+
"""Iteration boundary marker (IterationCompleteFormatter)."""
|
|
146
|
+
|
|
147
|
+
type: str = "iteration_complete"
|
|
148
|
+
iteration: int = 0
|
|
149
|
+
step: int = 0
|
|
150
|
+
iteration_status: str = ""
|
|
151
|
+
is_done: bool = False
|
|
152
|
+
raw: Dict[str, Any] = field(default_factory=dict)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
@dataclass
|
|
156
|
+
class ErrorEvent:
|
|
157
|
+
"""An agent error (ErrorFormatter)."""
|
|
158
|
+
|
|
159
|
+
type: str = "error"
|
|
160
|
+
step: int = 0
|
|
161
|
+
error_message: str = ""
|
|
162
|
+
error_type: str = ""
|
|
163
|
+
raw: Dict[str, Any] = field(default_factory=dict)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@dataclass
|
|
167
|
+
class SessionDone:
|
|
168
|
+
"""Session completion (SessionCompletionFormatter)."""
|
|
169
|
+
|
|
170
|
+
type: str = "session_completion"
|
|
171
|
+
success: bool = True
|
|
172
|
+
total_steps: int = 0
|
|
173
|
+
final_result: str = ""
|
|
174
|
+
error_message: str = ""
|
|
175
|
+
duration_seconds: float = 0.0
|
|
176
|
+
raw: Dict[str, Any] = field(default_factory=dict)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@dataclass
|
|
180
|
+
class AgentRegistration:
|
|
181
|
+
"""An agent (main or sub-agent) was registered (AgentRegistrationFormatter).
|
|
182
|
+
|
|
183
|
+
Real shape (captured live):
|
|
184
|
+
data.agent_id, data.agent_name, data.agent_type, data.model_name,
|
|
185
|
+
data.task, data.session_id
|
|
186
|
+
Used for sub-agent grouping: the first registration is the main agent;
|
|
187
|
+
subsequent registrations with different agent_ids are sub-agents.
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
type: str = "agent_registration"
|
|
191
|
+
agent_id: str = ""
|
|
192
|
+
agent_name: str = ""
|
|
193
|
+
agent_type: str = ""
|
|
194
|
+
model_name: str = ""
|
|
195
|
+
task: str = ""
|
|
196
|
+
raw: Dict[str, Any] = field(default_factory=dict)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
@dataclass
|
|
200
|
+
class AgentEnd:
|
|
201
|
+
"""An agent finished its run (AgentEndFormatter).
|
|
202
|
+
|
|
203
|
+
Real shape (captured live):
|
|
204
|
+
data.agent_id, data.steps, data.max_steps_reached, data.success,
|
|
205
|
+
data.errors[]
|
|
206
|
+
"""
|
|
207
|
+
|
|
208
|
+
type: str = "agent_end"
|
|
209
|
+
agent_id: str = ""
|
|
210
|
+
steps: int = 0
|
|
211
|
+
max_steps_reached: bool = False
|
|
212
|
+
success: bool = True
|
|
213
|
+
errors: List[Any] = field(default_factory=list)
|
|
214
|
+
raw: Dict[str, Any] = field(default_factory=dict)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
@dataclass
|
|
218
|
+
class Info:
|
|
219
|
+
"""Passthrough wrapper for informational / status events.
|
|
220
|
+
|
|
221
|
+
Covers: status, user_message, queue_status, multi_agent_relationship,
|
|
222
|
+
multi_agent_relationship_detailed, session_relationship,
|
|
223
|
+
available_actions, session_paused, session_resumed, and any unknown types.
|
|
224
|
+
"""
|
|
225
|
+
|
|
226
|
+
type: str = "info"
|
|
227
|
+
content: str = ""
|
|
228
|
+
raw: Dict[str, Any] = field(default_factory=dict)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
from cli.ui.event_registry import RegisteredEvent # noqa: E402 (no top-level cli deps)
|
|
232
|
+
import cli.ui.event_specs # noqa: E402,F401 — registers built-in extension events (T4-02)
|
|
233
|
+
|
|
234
|
+
# Union alias for type annotations
|
|
235
|
+
RenderEvent = (
|
|
236
|
+
SessionStart
|
|
237
|
+
| Step
|
|
238
|
+
| LLMCall
|
|
239
|
+
| ToolExec
|
|
240
|
+
| IterationDone
|
|
241
|
+
| ErrorEvent
|
|
242
|
+
| SessionDone
|
|
243
|
+
| AgentRegistration
|
|
244
|
+
| AgentEnd
|
|
245
|
+
| RegisteredEvent
|
|
246
|
+
| Info
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
# ---------------------------------------------------------------------------
|
|
250
|
+
# Normalisation
|
|
251
|
+
# ---------------------------------------------------------------------------
|
|
252
|
+
|
|
253
|
+
#: Feed types that map to ``Info`` (pass-through, no rich extraction needed).
|
|
254
|
+
_INFO_TYPES = frozenset(
|
|
255
|
+
{
|
|
256
|
+
"status",
|
|
257
|
+
"user_message",
|
|
258
|
+
"queue_status",
|
|
259
|
+
"multi_agent_relationship",
|
|
260
|
+
"multi_agent_relationship_detailed",
|
|
261
|
+
"session_relationship",
|
|
262
|
+
"available_actions",
|
|
263
|
+
"session_paused",
|
|
264
|
+
"session_resumed",
|
|
265
|
+
}
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def normalize(feed_dict: Dict[str, Any]) -> RenderEvent:
|
|
270
|
+
"""Normalise a raw feed dict into a typed ``RenderEvent``.
|
|
271
|
+
|
|
272
|
+
Never raises; unknown types become ``Info``.
|
|
273
|
+
|
|
274
|
+
Args:
|
|
275
|
+
feed_dict: A sanitized update dict as emitted by
|
|
276
|
+
``ProductTelemetry._on_feed_entry``.
|
|
277
|
+
|
|
278
|
+
Returns:
|
|
279
|
+
A typed ``RenderEvent`` dataclass.
|
|
280
|
+
"""
|
|
281
|
+
try:
|
|
282
|
+
return _normalize_inner(feed_dict)
|
|
283
|
+
except Exception as exc: # pragma: no cover
|
|
284
|
+
logger.debug("events.normalize error for %r: %s", feed_dict.get("type"), exc)
|
|
285
|
+
return Info(
|
|
286
|
+
type=feed_dict.get("type", "unknown"),
|
|
287
|
+
raw=feed_dict,
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def _normalize_inner(feed_dict: Dict[str, Any]) -> RenderEvent:
|
|
292
|
+
event_type = feed_dict.get("type", "unknown")
|
|
293
|
+
data = feed_dict.get("data", {}) or {}
|
|
294
|
+
|
|
295
|
+
# Extension seam (D2): a registered spec wins over the built-in fallback, so a
|
|
296
|
+
# new core event type surfaces without editing this function.
|
|
297
|
+
from cli.ui.event_registry import get_spec
|
|
298
|
+
spec = get_spec(event_type)
|
|
299
|
+
if spec is not None:
|
|
300
|
+
return spec.parse(feed_dict)
|
|
301
|
+
|
|
302
|
+
if event_type == "session_start":
|
|
303
|
+
return SessionStart(
|
|
304
|
+
task=data.get("task", ""),
|
|
305
|
+
model_name=data.get("model_name", ""),
|
|
306
|
+
agent_id=data.get("agent_id", ""),
|
|
307
|
+
use_vision=bool(data.get("use_vision", False)),
|
|
308
|
+
raw=feed_dict,
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
if event_type == "step":
|
|
312
|
+
# memory lives inside data.context.outputs.memory
|
|
313
|
+
ctx = data.get("context", {}) or {}
|
|
314
|
+
outputs = ctx.get("outputs", {}) or {}
|
|
315
|
+
memory = outputs.get("memory", "")
|
|
316
|
+
return Step(
|
|
317
|
+
step=int(feed_dict.get("step", data.get("step", data.get("iteration", 0)))),
|
|
318
|
+
reasoning=data.get("reasoning", ""),
|
|
319
|
+
memory=memory,
|
|
320
|
+
actions=list(data.get("actions", [])),
|
|
321
|
+
raw=feed_dict,
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
if event_type == "llm_request":
|
|
325
|
+
cost_raw = data.get("cost_estimate")
|
|
326
|
+
cost = float(cost_raw) if cost_raw is not None else None
|
|
327
|
+
return LLMCall(
|
|
328
|
+
model_name=data.get("model_name", ""),
|
|
329
|
+
provider=data.get("provider", ""),
|
|
330
|
+
prompt_tokens=_int_or_none(data.get("prompt_tokens")),
|
|
331
|
+
completion_tokens=_int_or_none(data.get("completion_tokens")),
|
|
332
|
+
token_count=_int_or_none(data.get("token_count")),
|
|
333
|
+
cost_estimate=cost,
|
|
334
|
+
duration_seconds=float(data.get("duration_seconds") or 0.0),
|
|
335
|
+
success=bool(data.get("success", True)),
|
|
336
|
+
raw=feed_dict,
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
if event_type == "tool_execution":
|
|
340
|
+
raw_params = data.get("parameters")
|
|
341
|
+
params = raw_params if isinstance(raw_params, dict) else {}
|
|
342
|
+
preview = data.get("result_preview")
|
|
343
|
+
return ToolExec(
|
|
344
|
+
step=int(feed_dict.get("step", 0)),
|
|
345
|
+
tool_name=data.get("tool_name", ""),
|
|
346
|
+
action_name=data.get("action_name", ""),
|
|
347
|
+
success=bool(data.get("success", True)),
|
|
348
|
+
duration_seconds=float(data.get("duration_seconds") or 0.0),
|
|
349
|
+
error=data.get("error"),
|
|
350
|
+
parameters=params,
|
|
351
|
+
result_preview=str(preview) if preview is not None else None,
|
|
352
|
+
result_truncated=bool(data.get("result_truncated", False)),
|
|
353
|
+
raw=feed_dict,
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
if event_type == "iteration_complete":
|
|
357
|
+
return IterationDone(
|
|
358
|
+
iteration=int(data.get("iteration", 0)),
|
|
359
|
+
step=int(data.get("step", 0)),
|
|
360
|
+
iteration_status=data.get("iteration_status", ""),
|
|
361
|
+
is_done=bool(data.get("is_done", False)),
|
|
362
|
+
raw=feed_dict,
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
if event_type == "error":
|
|
366
|
+
return ErrorEvent(
|
|
367
|
+
step=int(feed_dict.get("step", 0)),
|
|
368
|
+
error_message=data.get("error_message", ""),
|
|
369
|
+
error_type=data.get("error_type", ""),
|
|
370
|
+
raw=feed_dict,
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
if event_type == "session_completion":
|
|
374
|
+
metrics = data.get("metrics", {}) or {}
|
|
375
|
+
return SessionDone(
|
|
376
|
+
success=bool(data.get("success", True)),
|
|
377
|
+
total_steps=int(data.get("total_steps", 0)),
|
|
378
|
+
final_result=str(metrics.get("final_result", "") or ""),
|
|
379
|
+
error_message=str(data.get("error_message", "") or ""),
|
|
380
|
+
duration_seconds=float(data.get("duration_seconds") or 0.0),
|
|
381
|
+
raw=feed_dict,
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
if event_type == "agent_registration":
|
|
385
|
+
return AgentRegistration(
|
|
386
|
+
agent_id=data.get("agent_id", ""),
|
|
387
|
+
agent_name=data.get("agent_name", ""),
|
|
388
|
+
agent_type=data.get("agent_type", ""),
|
|
389
|
+
model_name=data.get("model_name", ""),
|
|
390
|
+
task=data.get("task", ""),
|
|
391
|
+
raw=feed_dict,
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
if event_type == "agent_end":
|
|
395
|
+
return AgentEnd(
|
|
396
|
+
agent_id=data.get("agent_id", ""),
|
|
397
|
+
steps=int(data.get("steps", 0)),
|
|
398
|
+
max_steps_reached=bool(data.get("max_steps_reached", False)),
|
|
399
|
+
success=bool(data.get("success", True)),
|
|
400
|
+
errors=list(data.get("errors", []) or []),
|
|
401
|
+
raw=feed_dict,
|
|
402
|
+
)
|
|
403
|
+
|
|
404
|
+
if event_type in _INFO_TYPES:
|
|
405
|
+
content = data.get("content", data.get("message", data.get("text", "")))
|
|
406
|
+
return Info(
|
|
407
|
+
type=event_type,
|
|
408
|
+
content=str(content) if content else "",
|
|
409
|
+
raw=feed_dict,
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
# Unknown type — log at debug, never crash.
|
|
413
|
+
logger.debug("events.normalize: unknown feed type %r — mapping to Info", event_type)
|
|
414
|
+
content = data.get("content", data.get("message", ""))
|
|
415
|
+
return Info(
|
|
416
|
+
type=event_type,
|
|
417
|
+
content=str(content) if content else "",
|
|
418
|
+
raw=feed_dict,
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
# ---------------------------------------------------------------------------
|
|
423
|
+
# Helpers
|
|
424
|
+
# ---------------------------------------------------------------------------
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def _int_or_none(value: Any) -> Optional[int]:
|
|
428
|
+
if value is None:
|
|
429
|
+
return None
|
|
430
|
+
try:
|
|
431
|
+
return int(value)
|
|
432
|
+
except (TypeError, ValueError):
|
|
433
|
+
return None
|
cli/ui/identity.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""The agent's display name for the chat UI — the resolved INSTANCE id.
|
|
2
|
+
|
|
3
|
+
Chat bubbles (``● rob`` / ``rob:``), the activity line (``rob · working…``), the
|
|
4
|
+
separator rule, and the streaming box all show the agent's OWN name. That name is
|
|
5
|
+
the INSTANCE id (default ``rob``, or ``POLYROB_INSTANCE_ID``), NOT the framework
|
|
6
|
+
name (``polyrob``): an operator who renames the instance should see the new name in
|
|
7
|
+
every bubble, matching the `polyrob run` banner — not a hardcoded ``rob``.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def agent_display_name() -> str:
|
|
13
|
+
"""Return the agent's display name (resolved instance id; default ``rob``)."""
|
|
14
|
+
from core.instance import resolve_instance_id
|
|
15
|
+
return resolve_instance_id()
|
cli/ui/lifecycle.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"""lifecycle.py — the CLI's single source of truth for "is a turn active, and
|
|
2
|
+
for how long".
|
|
3
|
+
|
|
4
|
+
Before this object the CLI had four uncoordinated notions of session time/status
|
|
5
|
+
(session-age clock shown as "elapsed", an ad-hoc ``status`` string driven by feed
|
|
6
|
+
events, a correct-but-unused per-turn clock, and the agent-side ``SessionStatus``).
|
|
7
|
+
``TurnLifecycle`` collapses them into one model the renderer/status-bar derive from.
|
|
8
|
+
|
|
9
|
+
Design (docs/plans/2026-06-26-session-runtime-lifecycle-PLAN.md §1, Fusion-validated):
|
|
10
|
+
|
|
11
|
+
**Two orthogonal lanes** — a background autonomy turn (cron/goal/self-wake) can run
|
|
12
|
+
*while* the user's foreground turn runs, so one scalar phase can't hold both:
|
|
13
|
+
|
|
14
|
+
- **foreground** — user turns. Owns the work clock (``active_elapsed``) and the
|
|
15
|
+
primary status word. Driven ONLY by the turn runner via ``begin_turn``/``end_turn``.
|
|
16
|
+
- **autonomy** — background turns. A simple in-flight counter that drives a muted
|
|
17
|
+
``⟲ autonomy`` indicator. NEVER touches the work clock or the status word.
|
|
18
|
+
|
|
19
|
+
**Invariant:** feed events (``Step``/``LLMCall``/``ToolExec``/…) NEVER mutate this
|
|
20
|
+
object — only the turn seams do. That is what makes "running while idle" impossible
|
|
21
|
+
by construction (a stray/background feed event can't flip the foreground lane) and
|
|
22
|
+
makes a post-cancel straggler event harmless.
|
|
23
|
+
|
|
24
|
+
**Turn token** — ``begin_turn`` returns a monotonically-increasing token; ``end_turn``
|
|
25
|
+
is a no-op unless handed the *current* token. This defeats the Ctrl-C→immediate-resubmit
|
|
26
|
+
race where a cancelled task's late ``end_turn`` would otherwise settle the *new* turn.
|
|
27
|
+
|
|
28
|
+
The clock is injected so timing is deterministic in tests.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
import time
|
|
34
|
+
from enum import Enum
|
|
35
|
+
from typing import Callable
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Phase(Enum):
|
|
39
|
+
"""Foreground-lane phase."""
|
|
40
|
+
|
|
41
|
+
IDLE = "idle" # no user turn in flight (waiting for the user / follow-up)
|
|
42
|
+
ACTIVE = "active" # a user turn is running (between begin_turn and end_turn)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class TurnOutcome(Enum):
|
|
46
|
+
"""How a foreground turn ended (sticky on the bar until the next turn)."""
|
|
47
|
+
|
|
48
|
+
NONE = "none" # no turn yet, or last turn succeeded
|
|
49
|
+
OK = "ok" # passed to end_turn for a clean finish (→ NONE on idle)
|
|
50
|
+
ERROR = "error" # the turn raised
|
|
51
|
+
CANCELLED = "cancelled" # the turn was interrupted (Ctrl-C)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
#: Derived status words. ``working`` while ACTIVE; on IDLE the last outcome decides.
|
|
55
|
+
_OUTCOME_WORD = {
|
|
56
|
+
TurnOutcome.NONE: "ready",
|
|
57
|
+
TurnOutcome.OK: "ready",
|
|
58
|
+
TurnOutcome.ERROR: "error",
|
|
59
|
+
TurnOutcome.CANCELLED: "stopped",
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class TurnLifecycle:
|
|
64
|
+
"""Single source of truth for the CLI's active-turn + work-clock + status word.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
clock: Monotonic clock (injectable for tests). Defaults to ``time.monotonic``.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
def __init__(self, *, clock: Callable[[], float] = time.monotonic) -> None:
|
|
71
|
+
self._clock = clock
|
|
72
|
+
# Foreground lane.
|
|
73
|
+
self.phase: Phase = Phase.IDLE
|
|
74
|
+
self.active_started_at: float | None = None
|
|
75
|
+
self.last_outcome: TurnOutcome = TurnOutcome.NONE
|
|
76
|
+
self._token: int = 0
|
|
77
|
+
# Autonomy lane (orthogonal): count of in-flight background turns.
|
|
78
|
+
self._autonomy_active: int = 0
|
|
79
|
+
|
|
80
|
+
# ------------------------------------------------------------------
|
|
81
|
+
# Foreground lane — user turns (called from the turn runner ONLY)
|
|
82
|
+
# ------------------------------------------------------------------
|
|
83
|
+
|
|
84
|
+
def begin_turn(self) -> int:
|
|
85
|
+
"""Start a user turn → ACTIVE; the work clock starts at 0 and runs.
|
|
86
|
+
|
|
87
|
+
Idempotent: calling it again while already ACTIVE is a no-op that returns
|
|
88
|
+
the SAME token and does NOT reset the clock (defends against a duplicate
|
|
89
|
+
submit/race). Clears any sticky error/cancel outcome.
|
|
90
|
+
|
|
91
|
+
Returns the turn token to hand back to ``end_turn``.
|
|
92
|
+
"""
|
|
93
|
+
if self.phase is Phase.ACTIVE:
|
|
94
|
+
return self._token # already running — don't restart the clock
|
|
95
|
+
self._token += 1
|
|
96
|
+
self.phase = Phase.ACTIVE
|
|
97
|
+
self.active_started_at = self._clock()
|
|
98
|
+
self.last_outcome = TurnOutcome.NONE
|
|
99
|
+
return self._token
|
|
100
|
+
|
|
101
|
+
def end_turn(self, token: int, outcome: TurnOutcome = TurnOutcome.OK) -> None:
|
|
102
|
+
"""End the user turn → IDLE; the work clock freezes (reads 0 on idle).
|
|
103
|
+
|
|
104
|
+
No-op unless *token* is the current turn's token AND a turn is active —
|
|
105
|
+
so a stale (cancelled-then-resubmitted) task's late settle can't touch the
|
|
106
|
+
new turn, and a double end_turn is harmless. ``OK`` settles to ``ready``;
|
|
107
|
+
``ERROR``/``CANCELLED`` are sticky until the next ``begin_turn``.
|
|
108
|
+
"""
|
|
109
|
+
if self.phase is not Phase.ACTIVE or token != self._token:
|
|
110
|
+
return
|
|
111
|
+
self.phase = Phase.IDLE
|
|
112
|
+
self.active_started_at = None
|
|
113
|
+
self.last_outcome = TurnOutcome.NONE if outcome is TurnOutcome.OK else outcome
|
|
114
|
+
|
|
115
|
+
# ------------------------------------------------------------------
|
|
116
|
+
# Autonomy lane — background turns (orthogonal to the foreground lane)
|
|
117
|
+
# ------------------------------------------------------------------
|
|
118
|
+
|
|
119
|
+
def begin_background(self) -> None:
|
|
120
|
+
"""A background (cron/goal/self-wake) turn started. Lights the muted
|
|
121
|
+
autonomy indicator without touching the work clock or status word."""
|
|
122
|
+
self._autonomy_active += 1
|
|
123
|
+
|
|
124
|
+
def end_background(self) -> None:
|
|
125
|
+
"""A background turn finished. Floored at 0 (underflow-safe)."""
|
|
126
|
+
self._autonomy_active = max(0, self._autonomy_active - 1)
|
|
127
|
+
|
|
128
|
+
def autonomy_busy(self) -> bool:
|
|
129
|
+
"""True when one or more background turns are in flight."""
|
|
130
|
+
return self._autonomy_active > 0
|
|
131
|
+
|
|
132
|
+
# ------------------------------------------------------------------
|
|
133
|
+
# Derived reads (the renderer / status bar consume these)
|
|
134
|
+
# ------------------------------------------------------------------
|
|
135
|
+
|
|
136
|
+
def is_active(self) -> bool:
|
|
137
|
+
"""True when a user turn is running (drives the spinner + cooking line)."""
|
|
138
|
+
return self.phase is Phase.ACTIVE
|
|
139
|
+
|
|
140
|
+
def active_elapsed(self) -> float:
|
|
141
|
+
"""Work-clock seconds: ``now - active_started_at`` while ACTIVE, else 0.0.
|
|
142
|
+
|
|
143
|
+
Frozen (0.0) on idle — this is the fix for the bar showing session age
|
|
144
|
+
("1h26m") while the user sits at the prompt.
|
|
145
|
+
"""
|
|
146
|
+
if self.phase is Phase.ACTIVE and self.active_started_at is not None:
|
|
147
|
+
return max(0.0, self._clock() - self.active_started_at)
|
|
148
|
+
return 0.0
|
|
149
|
+
|
|
150
|
+
def status_word(self) -> str:
|
|
151
|
+
"""The single derived status word: working / ready / error / stopped.
|
|
152
|
+
|
|
153
|
+
``running``-while-idle is impossible by construction: the word is
|
|
154
|
+
``working`` iff the foreground phase is ACTIVE, and the phase only goes
|
|
155
|
+
ACTIVE via ``begin_turn``.
|
|
156
|
+
"""
|
|
157
|
+
if self.phase is Phase.ACTIVE:
|
|
158
|
+
return "working"
|
|
159
|
+
return _OUTCOME_WORD.get(self.last_outcome, "ready")
|
cli/ui/live_hooks.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""live_hooks.py — bridge the orchestrator's lifecycle hooks into SessionState.
|
|
2
|
+
|
|
3
|
+
The orchestrator fires sub-agent start/end hooks (``_run_subagent_start_hooks`` /
|
|
4
|
+
``_run_subagent_end_hooks`` in ``agents/task/session/hooks.py``, fired from
|
|
5
|
+
``sub_agent_manager.py``) but nothing in the CLI subscribed — so a ``delegate_task``
|
|
6
|
+
spawn was invisible. ``make_subagent_hooks`` builds the two fail-open callbacks the
|
|
7
|
+
REPL registers on the orchestrator; they bump the live sub-agent counter on
|
|
8
|
+
``SessionState`` (which the status line reads).
|
|
9
|
+
|
|
10
|
+
Hooks are called by the orchestrator with keyword args (``goal``, ``agent_id``,
|
|
11
|
+
``parent_session_id`` and, on end, ``ok``). The callbacks accept arbitrary kwargs
|
|
12
|
+
and never raise — a UI-counter hook must never break the agent loop.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from typing import Any, Callable, Tuple
|
|
18
|
+
|
|
19
|
+
from cli.ui.state import SessionState
|
|
20
|
+
|
|
21
|
+
Hook = Callable[..., None]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def make_subagent_hooks(state: SessionState) -> Tuple[Hook, Hook]:
|
|
25
|
+
"""Return ``(start_hook, end_hook)`` that keep ``state.subagents_active`` live.
|
|
26
|
+
|
|
27
|
+
Both are fail-open (swallow any error) and accept arbitrary kwargs so a
|
|
28
|
+
change to the orchestrator's hook signature can't crash the REPL.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def _start(**_event: Any) -> None:
|
|
32
|
+
try:
|
|
33
|
+
state.note_subagent_start()
|
|
34
|
+
except Exception: # pragma: no cover - a UI counter must never break the loop
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
def _end(**_event: Any) -> None:
|
|
38
|
+
try:
|
|
39
|
+
state.note_subagent_end()
|
|
40
|
+
except Exception: # pragma: no cover
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
return _start, _end
|