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,642 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Telemetry Feed Formatters
|
|
3
|
+
|
|
4
|
+
Extracts feed formatting logic from ProductTelemetry into specialized formatter classes.
|
|
5
|
+
Each formatter handles one event type, converting telemetry events into feed-friendly formats.
|
|
6
|
+
|
|
7
|
+
Architecture:
|
|
8
|
+
- BaseFeedFormatter: Abstract base for all formatters
|
|
9
|
+
- Concrete formatters: One per event type (AgentStepFormatter, LLMRequestFormatter, etc.)
|
|
10
|
+
- FeedFormatterRegistry: Maps event names to formatters
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import logging
|
|
14
|
+
import time
|
|
15
|
+
from datetime import datetime
|
|
16
|
+
from typing import Dict, Any, Optional, List
|
|
17
|
+
from abc import ABC, abstractmethod
|
|
18
|
+
|
|
19
|
+
from agents.task.telemetry.views import BaseTelemetryEvent
|
|
20
|
+
|
|
21
|
+
# Import logger
|
|
22
|
+
from agents.task.logging_config import get_task_logger
|
|
23
|
+
logger = get_task_logger('telemetry.formatters')
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class BaseFeedFormatter(ABC):
|
|
27
|
+
"""Base class for feed formatters.
|
|
28
|
+
|
|
29
|
+
Each formatter converts a telemetry event into a feed-friendly format
|
|
30
|
+
for consumption by web UI, dashboards, etc.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
@abstractmethod
|
|
34
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
35
|
+
"""Format event into feed structure.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
event: The telemetry event to format
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
Dictionary with feed-friendly structure
|
|
42
|
+
"""
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
# Known tool/service names that namespace their actions
|
|
46
|
+
KNOWN_TOOLS = {
|
|
47
|
+
'polymarket', 'mcp', 'twitter', 'email', 'perplexity',
|
|
48
|
+
'filesystem', 'browser', 'collabland', 'alchemy', 'task'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def _detect_service_for_action(action_name: str) -> str:
|
|
53
|
+
"""Detect which service an action belongs to based on its name.
|
|
54
|
+
|
|
55
|
+
Uses a multi-tier detection strategy:
|
|
56
|
+
1. Check for known tool prefix (e.g., 'polymarket_get_markets' → 'polymarket')
|
|
57
|
+
2. Fall back to keyword-based detection for legacy actions
|
|
58
|
+
3. Return 'default' if no match found
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
action_name: The name of the action
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
The service name or 'default' if not detected
|
|
65
|
+
"""
|
|
66
|
+
action_name_lower = action_name.lower()
|
|
67
|
+
|
|
68
|
+
# Strategy 1: Check for known tool prefix pattern (tool_action)
|
|
69
|
+
for tool in BaseFeedFormatter.KNOWN_TOOLS:
|
|
70
|
+
if action_name_lower.startswith(f"{tool}_"):
|
|
71
|
+
return tool
|
|
72
|
+
|
|
73
|
+
# Strategy 2: Keyword-based detection for actions without prefix
|
|
74
|
+
if 'perplexity' in action_name_lower or 'search_web' in action_name_lower:
|
|
75
|
+
return 'perplexity'
|
|
76
|
+
elif any(kw in action_name_lower for kw in ['document', 'doc_', 'extract_text', 'process_',
|
|
77
|
+
'file', 'write_file', 'read_file', 'append_file',
|
|
78
|
+
'delete_file', 'create_directory', 'list_directory']):
|
|
79
|
+
return 'filesystem'
|
|
80
|
+
elif any(kw in action_name_lower for kw in ['click', 'scroll', 'input', 'navigate', 'go_to',
|
|
81
|
+
'browse_to', 'back', 'forward', 'reload', 'screenshot']):
|
|
82
|
+
return 'browser'
|
|
83
|
+
|
|
84
|
+
# Strategy 3: Try to extract prefix from first underscore
|
|
85
|
+
# e.g., 'custom_tool_action' would detect 'custom_tool' if underscore found
|
|
86
|
+
if '_' in action_name_lower:
|
|
87
|
+
potential_tool = action_name_lower.split('_')[0]
|
|
88
|
+
# Only use if it looks like a tool name (3+ chars, not a common verb)
|
|
89
|
+
if len(potential_tool) >= 3 and potential_tool not in {'get', 'set', 'add', 'del', 'run'}:
|
|
90
|
+
return potential_tool
|
|
91
|
+
|
|
92
|
+
return 'default'
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class AgentStepFormatter(BaseFeedFormatter):
|
|
96
|
+
"""Formatter for agent step events."""
|
|
97
|
+
|
|
98
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
99
|
+
"""Format agent step event for feed."""
|
|
100
|
+
# Process actions for feed
|
|
101
|
+
processed_actions = []
|
|
102
|
+
try:
|
|
103
|
+
raw_actions = event.properties.get('actions', [])
|
|
104
|
+
if raw_actions:
|
|
105
|
+
for action in raw_actions:
|
|
106
|
+
try:
|
|
107
|
+
if isinstance(action, dict) and len(action) > 0:
|
|
108
|
+
action_keys = list(action.keys())
|
|
109
|
+
if not action_keys:
|
|
110
|
+
continue
|
|
111
|
+
|
|
112
|
+
action_name = action_keys[0]
|
|
113
|
+
service = self._detect_service_for_action(action_name)
|
|
114
|
+
|
|
115
|
+
# Strip service prefix from display name if present
|
|
116
|
+
# e.g., 'polymarket_get_markets' → 'get_markets' when service='polymarket'
|
|
117
|
+
display_name = action_name
|
|
118
|
+
if service != 'default':
|
|
119
|
+
prefix = f"{service}_"
|
|
120
|
+
if action_name.lower().startswith(prefix):
|
|
121
|
+
display_name = action_name[len(prefix):]
|
|
122
|
+
|
|
123
|
+
# Extract parameters safely
|
|
124
|
+
parameters = {}
|
|
125
|
+
if action_name in action and action[action_name] is not None:
|
|
126
|
+
parameters = action[action_name]
|
|
127
|
+
|
|
128
|
+
processed_action = {
|
|
129
|
+
'action_type': action_name, # Keep full name for execution
|
|
130
|
+
'name': display_name, # Clean name for display
|
|
131
|
+
'service': service,
|
|
132
|
+
'params': parameters
|
|
133
|
+
}
|
|
134
|
+
processed_actions.append(processed_action)
|
|
135
|
+
except Exception as e:
|
|
136
|
+
logger.debug(f"Error processing action: {e}")
|
|
137
|
+
continue
|
|
138
|
+
except Exception as e:
|
|
139
|
+
logger.debug(f"Error processing actions: {e}")
|
|
140
|
+
|
|
141
|
+
# Get context data if available
|
|
142
|
+
context_data = event.properties.get('context_data', {})
|
|
143
|
+
|
|
144
|
+
# Extract reasoning from multiple sources
|
|
145
|
+
reasoning = ""
|
|
146
|
+
if event.properties.get('reasoning'):
|
|
147
|
+
reasoning = event.properties.get('reasoning')
|
|
148
|
+
elif context_data and isinstance(context_data, dict):
|
|
149
|
+
# Check outputs for reasoning
|
|
150
|
+
if 'outputs' in context_data and isinstance(context_data['outputs'], dict):
|
|
151
|
+
reasoning = context_data['outputs'].get('reasoning', '')
|
|
152
|
+
|
|
153
|
+
# Check if there's any browser URL information
|
|
154
|
+
browser_url = None
|
|
155
|
+
if context_data and isinstance(context_data, dict):
|
|
156
|
+
# Check inputs and outputs for URL info
|
|
157
|
+
for section in ['inputs', 'outputs']:
|
|
158
|
+
if section in context_data and isinstance(context_data[section], dict):
|
|
159
|
+
section_data = context_data[section]
|
|
160
|
+
for key in ['url', 'page_url', 'current_url']:
|
|
161
|
+
if key in section_data and section_data[key]:
|
|
162
|
+
browser_url = section_data[key]
|
|
163
|
+
break
|
|
164
|
+
if browser_url:
|
|
165
|
+
break
|
|
166
|
+
|
|
167
|
+
# Check actions for URL information if we still don't have it
|
|
168
|
+
if not browser_url and processed_actions:
|
|
169
|
+
for action in processed_actions:
|
|
170
|
+
if action['service'] == 'browser' and action['name'] in ['navigate_to', 'open_tab']:
|
|
171
|
+
if 'params' in action and 'url' in action['params']:
|
|
172
|
+
browser_url = action['params']['url']
|
|
173
|
+
break
|
|
174
|
+
|
|
175
|
+
# Create step update data
|
|
176
|
+
update_data = {
|
|
177
|
+
'type': 'step',
|
|
178
|
+
'step': event.properties.get('step', 0),
|
|
179
|
+
'timestamp': time.time(),
|
|
180
|
+
'datetime': datetime.now().isoformat(),
|
|
181
|
+
'data': {
|
|
182
|
+
'actions': processed_actions,
|
|
183
|
+
'errors': event.properties.get('step_error', []),
|
|
184
|
+
'consecutive_failures': event.properties.get('consecutive_failures', 0),
|
|
185
|
+
'agent_name': event.properties.get('agent_name', 'Unknown'),
|
|
186
|
+
'agent_type': event.properties.get('agent_type', 'Unknown'),
|
|
187
|
+
'task_progress': event.properties.get('task_progress', ''),
|
|
188
|
+
'current_task': event.properties.get('current_task', ''),
|
|
189
|
+
'reasoning': reasoning,
|
|
190
|
+
'context': context_data,
|
|
191
|
+
# New iteration fields for enhanced UI rendering
|
|
192
|
+
'iteration': event.properties.get('iteration') or event.properties.get('step', 0),
|
|
193
|
+
'iteration_type': event.properties.get('iteration_type', 'mixed'),
|
|
194
|
+
'iteration_status': event.properties.get('iteration_status', 'active'),
|
|
195
|
+
'files_created': event.properties.get('files_created', []),
|
|
196
|
+
'files_modified': event.properties.get('files_modified', []),
|
|
197
|
+
'files_read': event.properties.get('files_read', []),
|
|
198
|
+
'files_deleted': event.properties.get('files_deleted', []),
|
|
199
|
+
'error_message': event.properties.get('error_message'),
|
|
200
|
+
'loop_warning': event.properties.get('loop_warning'),
|
|
201
|
+
'is_done': event.properties.get('is_done', False),
|
|
202
|
+
'reasoning_synthesized': event.properties.get('reasoning_synthesized', False)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
# Ensure agent name is extracted from agent_id if not explicitly provided
|
|
207
|
+
if update_data['data']['agent_name'] == 'Unknown' and event.properties.get('agent_id'):
|
|
208
|
+
agent_id = event.properties.get('agent_id')
|
|
209
|
+
if '_' in agent_id:
|
|
210
|
+
prefix = agent_id.split('_')[0]
|
|
211
|
+
update_data['data']['agent_name'] = prefix.capitalize()
|
|
212
|
+
|
|
213
|
+
# Add agent name at root level for backwards compatibility
|
|
214
|
+
update_data['agent_name'] = update_data['data']['agent_name']
|
|
215
|
+
|
|
216
|
+
# Add browser URL information if available
|
|
217
|
+
if browser_url:
|
|
218
|
+
update_data['data']['page_url'] = browser_url
|
|
219
|
+
update_data['data']['current_url'] = browser_url
|
|
220
|
+
|
|
221
|
+
return update_data
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class LLMRequestFormatter(BaseFeedFormatter):
|
|
225
|
+
"""Formatter for LLM request events."""
|
|
226
|
+
|
|
227
|
+
@staticmethod
|
|
228
|
+
def _detect_provider(model_name: str) -> str:
|
|
229
|
+
"""Detect the provider based on model name."""
|
|
230
|
+
from agents.task.utils import detect_llm_provider
|
|
231
|
+
provider = detect_llm_provider(None, model_name)
|
|
232
|
+
return 'unknown' if provider == 'generic' else provider
|
|
233
|
+
|
|
234
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
235
|
+
"""Format LLM request event for feed."""
|
|
236
|
+
return {
|
|
237
|
+
'type': 'llm_request',
|
|
238
|
+
'timestamp': time.time(),
|
|
239
|
+
'datetime': datetime.now().isoformat(),
|
|
240
|
+
'data': {
|
|
241
|
+
'component': event.properties.get('component', 'Unknown'),
|
|
242
|
+
'purpose': event.properties.get('purpose', 'Unknown'),
|
|
243
|
+
'model_name': event.properties.get('model_name', 'Unknown'),
|
|
244
|
+
'provider': self._detect_provider(event.properties.get('model_name', '')),
|
|
245
|
+
'duration_seconds': event.properties.get('duration_seconds', 0),
|
|
246
|
+
'success': event.properties.get('success', False),
|
|
247
|
+
'token_count': event.properties.get('token_count', None),
|
|
248
|
+
'prompt_tokens': event.properties.get('prompt_tokens', None),
|
|
249
|
+
'completion_tokens': event.properties.get('completion_tokens', None),
|
|
250
|
+
'cost_estimate': event.properties.get('cost_estimate', None),
|
|
251
|
+
'agent_id': event.properties.get('agent_id', None),
|
|
252
|
+
'request_id': event.properties.get('request_id', None)
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
class SessionStartFormatter(BaseFeedFormatter):
|
|
258
|
+
"""Formatter for session start events."""
|
|
259
|
+
|
|
260
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
261
|
+
"""Format session start event for feed."""
|
|
262
|
+
task = event.properties.get('task', '')
|
|
263
|
+
|
|
264
|
+
# If task is empty, try to get it from event directly
|
|
265
|
+
if not task and hasattr(event, 'task'):
|
|
266
|
+
task = event.task
|
|
267
|
+
|
|
268
|
+
session_data = {
|
|
269
|
+
'session_id': event.properties.get('session_id', 'unknown'),
|
|
270
|
+
'task': task,
|
|
271
|
+
'model_name': event.properties.get('model_name', 'Unknown'),
|
|
272
|
+
'agent_id': event.properties.get('agent_id', ''),
|
|
273
|
+
'agent_type': event.properties.get('agent_type', ''),
|
|
274
|
+
'use_vision': event.properties.get('use_vision', False),
|
|
275
|
+
'internal_planning': event.properties.get('internal_planning', True)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return {
|
|
279
|
+
'type': 'session_start',
|
|
280
|
+
'timestamp': time.time(),
|
|
281
|
+
'datetime': datetime.now().isoformat(),
|
|
282
|
+
'data': session_data
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class MultiAgentRelationshipFormatter(BaseFeedFormatter):
|
|
287
|
+
"""Formatter for multi-agent relationship events."""
|
|
288
|
+
|
|
289
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
290
|
+
"""Format multi-agent relationship event for feed."""
|
|
291
|
+
relationship_data = event.properties
|
|
292
|
+
|
|
293
|
+
# Build enhanced agent data
|
|
294
|
+
agent_details = []
|
|
295
|
+
agent_types = relationship_data.get('agent_types', {})
|
|
296
|
+
agent_sequence = relationship_data.get('execution_sequence',
|
|
297
|
+
relationship_data.get('agent_sequence', []))
|
|
298
|
+
|
|
299
|
+
for agent_id in relationship_data.get('agent_ids', []):
|
|
300
|
+
agent_type = agent_types.get(agent_id, "Unknown")
|
|
301
|
+
|
|
302
|
+
agent_name = "Unknown"
|
|
303
|
+
if '_' in agent_id:
|
|
304
|
+
prefix = agent_id.split('_')[0]
|
|
305
|
+
agent_name = prefix.capitalize()
|
|
306
|
+
|
|
307
|
+
sequence_position = -1
|
|
308
|
+
if agent_id in agent_sequence:
|
|
309
|
+
sequence_position = agent_sequence.index(agent_id)
|
|
310
|
+
|
|
311
|
+
agent_details.append({
|
|
312
|
+
'id': agent_id,
|
|
313
|
+
'agent_id': agent_id,
|
|
314
|
+
'name': agent_name,
|
|
315
|
+
'agent_name': agent_name,
|
|
316
|
+
'type': agent_type,
|
|
317
|
+
'agent_type': agent_type,
|
|
318
|
+
'model': relationship_data.get('agent_models', {}).get(agent_id, 'Unknown'),
|
|
319
|
+
'sequence_position': sequence_position
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
# Sort by sequence position
|
|
323
|
+
agent_details.sort(key=lambda x: x['sequence_position'] if x['sequence_position'] >= 0 else 999)
|
|
324
|
+
|
|
325
|
+
return {
|
|
326
|
+
'type': 'multi_agent_relationship',
|
|
327
|
+
'timestamp': time.time(),
|
|
328
|
+
'datetime': datetime.now().isoformat(),
|
|
329
|
+
'data': {
|
|
330
|
+
'agent_ids': relationship_data.get('agent_ids', []),
|
|
331
|
+
'agent_types': relationship_data.get('agent_types', {}),
|
|
332
|
+
'agent_sequence': relationship_data.get('agent_sequence', []),
|
|
333
|
+
'agent_models': relationship_data.get('agent_models', {}),
|
|
334
|
+
'orchestrator_type': relationship_data.get('orchestrator_type', 'default'),
|
|
335
|
+
'agent_details': agent_details
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
class ControllerRegisteredFunctionsFormatter(BaseFeedFormatter):
|
|
341
|
+
"""Formatter for controller registered functions events.
|
|
342
|
+
|
|
343
|
+
Transforms internal controller_registered_functions events into
|
|
344
|
+
user-friendly available_actions format for the webview services panel.
|
|
345
|
+
"""
|
|
346
|
+
|
|
347
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
348
|
+
"""Format controller registered functions as available actions."""
|
|
349
|
+
properties = event.properties
|
|
350
|
+
registered_functions = properties.get('registered_functions', [])
|
|
351
|
+
|
|
352
|
+
# Group functions by service
|
|
353
|
+
by_service = {}
|
|
354
|
+
for func in registered_functions:
|
|
355
|
+
if isinstance(func, dict):
|
|
356
|
+
service = func.get('service', 'default')
|
|
357
|
+
action_name = func.get('name', 'unknown')
|
|
358
|
+
else:
|
|
359
|
+
# Handle RegisteredFunction dataclass
|
|
360
|
+
service = getattr(func, 'service', 'default')
|
|
361
|
+
action_name = getattr(func, 'name', 'unknown')
|
|
362
|
+
|
|
363
|
+
if service not in by_service:
|
|
364
|
+
by_service[service] = []
|
|
365
|
+
by_service[service].append(action_name)
|
|
366
|
+
|
|
367
|
+
return {
|
|
368
|
+
'type': 'available_actions',
|
|
369
|
+
'timestamp': time.time(),
|
|
370
|
+
'datetime': datetime.now().isoformat(),
|
|
371
|
+
'data': {
|
|
372
|
+
'by_service': by_service,
|
|
373
|
+
'total_actions': len(registered_functions)
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
class ToolExecutionFormatter(BaseFeedFormatter):
|
|
379
|
+
"""Formatter for tool execution events."""
|
|
380
|
+
|
|
381
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
382
|
+
"""Format tool execution event for feed."""
|
|
383
|
+
return {
|
|
384
|
+
'type': 'tool_execution',
|
|
385
|
+
'timestamp': time.time(),
|
|
386
|
+
'datetime': datetime.now().isoformat(),
|
|
387
|
+
'step': event.properties.get('step', 0),
|
|
388
|
+
'data': {
|
|
389
|
+
'tool_name': event.properties.get('tool_name', 'Unknown'),
|
|
390
|
+
'action_name': event.properties.get('action_name', 'Unknown'),
|
|
391
|
+
'success': event.properties.get('success', False),
|
|
392
|
+
'duration_seconds': event.properties.get('duration_seconds', 0),
|
|
393
|
+
'error': event.properties.get('error'),
|
|
394
|
+
'result_size': event.properties.get('result_size'),
|
|
395
|
+
'result_truncated': event.properties.get('result_truncated', False),
|
|
396
|
+
'result_preview': event.properties.get('result_preview'),
|
|
397
|
+
'parameters': event.properties.get('parameters', {})
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
class ErrorFormatter(BaseFeedFormatter):
|
|
403
|
+
"""Formatter for error events."""
|
|
404
|
+
|
|
405
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
406
|
+
"""Format error event for feed."""
|
|
407
|
+
return {
|
|
408
|
+
'type': 'error',
|
|
409
|
+
'timestamp': time.time(),
|
|
410
|
+
'datetime': datetime.now().isoformat(),
|
|
411
|
+
'step': event.properties.get('step', 0),
|
|
412
|
+
'data': {
|
|
413
|
+
'error_type': event.properties.get('error_type', 'Unknown'),
|
|
414
|
+
'error_message': event.properties.get('error_message', ''),
|
|
415
|
+
'error_stack': event.properties.get('error_stack'),
|
|
416
|
+
'recoverable': event.properties.get('recoverable', True),
|
|
417
|
+
'context': event.properties.get('context', {})
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
class SessionCompletionFormatter(BaseFeedFormatter):
|
|
423
|
+
"""Formatter for session completion events."""
|
|
424
|
+
|
|
425
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
426
|
+
"""Format session completion event for feed."""
|
|
427
|
+
return {
|
|
428
|
+
'type': 'session_completion',
|
|
429
|
+
'timestamp': time.time(),
|
|
430
|
+
'datetime': datetime.now().isoformat(),
|
|
431
|
+
'data': {
|
|
432
|
+
'success': event.properties.get('success', False),
|
|
433
|
+
'total_steps': event.properties.get('total_steps', 0),
|
|
434
|
+
'duration_seconds': event.properties.get('duration_seconds', 0),
|
|
435
|
+
'error_message': event.properties.get('error_message'),
|
|
436
|
+
'metrics': event.properties.get('metrics', {})
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
class GenericEventFormatter(BaseFeedFormatter):
|
|
442
|
+
"""Formatter for unrecognized/generic events.
|
|
443
|
+
|
|
444
|
+
Provides a simple envelope with raw properties so UI can display unknown events.
|
|
445
|
+
"""
|
|
446
|
+
|
|
447
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
448
|
+
"""Format generic event for feed."""
|
|
449
|
+
return {
|
|
450
|
+
'type': event.name,
|
|
451
|
+
'timestamp': time.time(),
|
|
452
|
+
'datetime': datetime.now().isoformat(),
|
|
453
|
+
'data': dict(event.properties) if hasattr(event, 'properties') else {}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
class UserMessageFormatter(BaseFeedFormatter):
|
|
458
|
+
"""Formatter for user message feed events.
|
|
459
|
+
|
|
460
|
+
Formats user messages for display in the chat UI.
|
|
461
|
+
CRITICAL: Output type MUST be 'user_message' to match chat.js handleUserMessage().
|
|
462
|
+
"""
|
|
463
|
+
|
|
464
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
465
|
+
"""Format user message event for chat display."""
|
|
466
|
+
return {
|
|
467
|
+
'type': 'user_message',
|
|
468
|
+
'timestamp': time.time(),
|
|
469
|
+
'datetime': datetime.now().isoformat(),
|
|
470
|
+
'data': {
|
|
471
|
+
'text': event.properties.get('text', ''),
|
|
472
|
+
'message': event.properties.get('text', ''), # Alias for compatibility
|
|
473
|
+
'kind': event.properties.get('kind', 'comment'),
|
|
474
|
+
'state': event.properties.get('state', 'queued'),
|
|
475
|
+
'metadata': event.properties.get('metadata', {})
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
class QueueStatusFormatter(BaseFeedFormatter):
|
|
481
|
+
"""Formatter for queue status events.
|
|
482
|
+
|
|
483
|
+
Formats queue status updates for the chat UI queue indicator.
|
|
484
|
+
"""
|
|
485
|
+
|
|
486
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
487
|
+
"""Format queue status event for UI updates."""
|
|
488
|
+
return {
|
|
489
|
+
'type': 'queue_status',
|
|
490
|
+
'timestamp': time.time(),
|
|
491
|
+
'datetime': datetime.now().isoformat(),
|
|
492
|
+
'data': {
|
|
493
|
+
'queued_count': event.properties.get('queued_count', 0),
|
|
494
|
+
'processing': event.properties.get('processing', False),
|
|
495
|
+
'oldest_message_age_seconds': event.properties.get('oldest_message_age_seconds')
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
class SessionPausedFormatter(BaseFeedFormatter):
|
|
501
|
+
"""Formatter for session paused events."""
|
|
502
|
+
|
|
503
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
504
|
+
"""Format session paused event for feed."""
|
|
505
|
+
return {
|
|
506
|
+
'type': 'session_paused',
|
|
507
|
+
'timestamp': time.time(),
|
|
508
|
+
'datetime': datetime.now().isoformat(),
|
|
509
|
+
'data': {
|
|
510
|
+
'session_id': event.properties.get('session_id', ''),
|
|
511
|
+
'reason': event.properties.get('reason', 'user_interrupt'),
|
|
512
|
+
'paused_by': event.properties.get('paused_by', 'user'),
|
|
513
|
+
'status': 'paused'
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
class SessionResumedFormatter(BaseFeedFormatter):
|
|
519
|
+
"""Formatter for session resumed events."""
|
|
520
|
+
|
|
521
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
522
|
+
"""Format session resumed event for feed."""
|
|
523
|
+
return {
|
|
524
|
+
'type': 'session_resumed',
|
|
525
|
+
'timestamp': time.time(),
|
|
526
|
+
'datetime': datetime.now().isoformat(),
|
|
527
|
+
'data': {
|
|
528
|
+
'session_id': event.properties.get('session_id', ''),
|
|
529
|
+
'resumed_by': event.properties.get('resumed_by', 'user'),
|
|
530
|
+
'status': 'running'
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
class SessionStatusFormatter(BaseFeedFormatter):
|
|
536
|
+
"""Formatter for generic session status events."""
|
|
537
|
+
|
|
538
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
539
|
+
"""Format session status event for feed."""
|
|
540
|
+
return {
|
|
541
|
+
'type': 'status',
|
|
542
|
+
'timestamp': time.time(),
|
|
543
|
+
'datetime': datetime.now().isoformat(),
|
|
544
|
+
'data': {
|
|
545
|
+
'session_id': event.properties.get('session_id', ''),
|
|
546
|
+
'status': event.properties.get('status', 'unknown'),
|
|
547
|
+
'previous_status': event.properties.get('previous_status'),
|
|
548
|
+
'reason': event.properties.get('reason')
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
class IterationCompleteFormatter(BaseFeedFormatter):
|
|
554
|
+
"""Formatter for iteration complete events.
|
|
555
|
+
|
|
556
|
+
Provides a clean boundary marker for the UI to render iteration summaries
|
|
557
|
+
with file chips and status indicators.
|
|
558
|
+
"""
|
|
559
|
+
|
|
560
|
+
def format(self, event: BaseTelemetryEvent) -> Dict[str, Any]:
|
|
561
|
+
"""Format iteration complete event for feed."""
|
|
562
|
+
props = event.properties
|
|
563
|
+
|
|
564
|
+
return {
|
|
565
|
+
'type': 'iteration_complete',
|
|
566
|
+
'timestamp': time.time(),
|
|
567
|
+
'datetime': datetime.now().isoformat(),
|
|
568
|
+
'data': {
|
|
569
|
+
'iteration': props.get('iteration', 0),
|
|
570
|
+
'step': props.get('step', 0),
|
|
571
|
+
'iteration_type': props.get('iteration_type', 'mixed'),
|
|
572
|
+
'iteration_status': props.get('iteration_status', 'completed'),
|
|
573
|
+
'reasoning_summary': props.get('reasoning_summary', ''),
|
|
574
|
+
'actions': props.get('actions_executed', []),
|
|
575
|
+
'action_results': props.get('action_results', []),
|
|
576
|
+
'files_created': props.get('files_created', []),
|
|
577
|
+
'files_modified': props.get('files_modified', []),
|
|
578
|
+
'files_read': props.get('files_read', []),
|
|
579
|
+
'files_deleted': props.get('files_deleted', []),
|
|
580
|
+
'success': props.get('success', True),
|
|
581
|
+
'error': props.get('error'),
|
|
582
|
+
'is_done': props.get('is_done', False),
|
|
583
|
+
'duration_seconds': props.get('duration_seconds', 0.0)
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
class FeedFormatterRegistry:
|
|
589
|
+
"""Registry mapping event names to formatters."""
|
|
590
|
+
|
|
591
|
+
def __init__(self):
|
|
592
|
+
self._formatters: Dict[str, BaseFeedFormatter] = {
|
|
593
|
+
'agent_step': AgentStepFormatter(),
|
|
594
|
+
'llm_request': LLMRequestFormatter(),
|
|
595
|
+
'session_start': SessionStartFormatter(),
|
|
596
|
+
'session_completion': SessionCompletionFormatter(),
|
|
597
|
+
'multi_agent_relationship': MultiAgentRelationshipFormatter(),
|
|
598
|
+
'multi_agent_relationship_detailed': MultiAgentRelationshipFormatter(),
|
|
599
|
+
'session_relationship': MultiAgentRelationshipFormatter(),
|
|
600
|
+
'controller_registered_functions': ControllerRegisteredFunctionsFormatter(),
|
|
601
|
+
'tool_execution': ToolExecutionFormatter(),
|
|
602
|
+
'error': ErrorFormatter(),
|
|
603
|
+
# User message and queue status formatters for chat UI
|
|
604
|
+
'user_message': UserMessageFormatter(),
|
|
605
|
+
'queue_status': QueueStatusFormatter(),
|
|
606
|
+
# Session state change formatters
|
|
607
|
+
'session_paused': SessionPausedFormatter(),
|
|
608
|
+
'session_resumed': SessionResumedFormatter(),
|
|
609
|
+
'status': SessionStatusFormatter(),
|
|
610
|
+
# Iteration complete formatter for enhanced UI
|
|
611
|
+
'iteration_complete': IterationCompleteFormatter(),
|
|
612
|
+
}
|
|
613
|
+
self._generic_formatter = GenericEventFormatter()
|
|
614
|
+
|
|
615
|
+
def get_formatter(self, event_name: str) -> BaseFeedFormatter:
|
|
616
|
+
"""Get formatter for event name.
|
|
617
|
+
|
|
618
|
+
Args:
|
|
619
|
+
event_name: The name of the event type
|
|
620
|
+
|
|
621
|
+
Returns:
|
|
622
|
+
Formatter for the event, or generic formatter if not registered
|
|
623
|
+
"""
|
|
624
|
+
return self._formatters.get(event_name, self._generic_formatter)
|
|
625
|
+
|
|
626
|
+
def register_formatter(self, event_name: str, formatter: BaseFeedFormatter) -> None:
|
|
627
|
+
"""Register a custom formatter.
|
|
628
|
+
|
|
629
|
+
Args:
|
|
630
|
+
event_name: The event name to register formatter for
|
|
631
|
+
formatter: The formatter instance
|
|
632
|
+
"""
|
|
633
|
+
self._formatters[event_name] = formatter
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
# Global registry instance
|
|
637
|
+
_registry = FeedFormatterRegistry()
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
def get_formatter_registry() -> FeedFormatterRegistry:
|
|
641
|
+
"""Get the global formatter registry."""
|
|
642
|
+
return _registry
|