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,882 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from dataclasses import asdict, dataclass, is_dataclass
|
|
3
|
+
from typing import Any, Dict, List, Optional, Union
|
|
4
|
+
import time
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from agents.task.path import pm
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class BaseTelemetryEvent(ABC):
|
|
11
|
+
@property
|
|
12
|
+
@abstractmethod
|
|
13
|
+
def name(self) -> str:
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def properties(self) -> Dict[str, Any]:
|
|
18
|
+
try:
|
|
19
|
+
# Import and check if the object is a dataclass before using asdict
|
|
20
|
+
if is_dataclass(self):
|
|
21
|
+
return {k: v for k, v in asdict(self).items() if k != 'name'}
|
|
22
|
+
# Fallback for non-dataclass instances
|
|
23
|
+
return {k: v for k, v in self.__dict__.items() if k != 'name' and not k.startswith('_')}
|
|
24
|
+
except (TypeError, ValueError, ImportError):
|
|
25
|
+
# Fallback for any errors or if is_dataclass is not available
|
|
26
|
+
return {k: v for k, v in self.__dict__.items() if k != 'name' and not k.startswith('_')}
|
|
27
|
+
|
|
28
|
+
def get_session_id(self) -> Optional[str]:
|
|
29
|
+
"""Get the session ID associated with this event.
|
|
30
|
+
|
|
31
|
+
Default implementation checks common attributes that might contain the session ID.
|
|
32
|
+
Override this method in subclasses to provide more specific session ID extraction.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
The session ID or None if not found
|
|
36
|
+
"""
|
|
37
|
+
# Check for explicit session_id attribute
|
|
38
|
+
if hasattr(self, 'session_id') and getattr(self, 'session_id'):
|
|
39
|
+
# Session ID already cleaned by session creator
|
|
40
|
+
return getattr(self, 'session_id')
|
|
41
|
+
|
|
42
|
+
# Check for parent_session_id attribute (used in relationship events)
|
|
43
|
+
if hasattr(self, 'parent_session_id') and getattr(self, 'parent_session_id'):
|
|
44
|
+
# Session ID already cleaned by session creator
|
|
45
|
+
return getattr(self, 'parent_session_id')
|
|
46
|
+
|
|
47
|
+
# Try to extract from agent_id if available
|
|
48
|
+
if hasattr(self, 'agent_id') and getattr(self, 'agent_id'):
|
|
49
|
+
from agents.task.utils import extract_session_from_agent_id
|
|
50
|
+
agent_id = getattr(self, 'agent_id')
|
|
51
|
+
return extract_session_from_agent_id(agent_id)
|
|
52
|
+
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass
|
|
57
|
+
class RegisteredFunction:
|
|
58
|
+
name: str
|
|
59
|
+
params: dict[str, Any]
|
|
60
|
+
service: str = "default" # Track which service the function belongs to
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass
|
|
64
|
+
class ControllerRegisteredFunctionsTelemetryEvent(BaseTelemetryEvent):
|
|
65
|
+
registered_functions: list[RegisteredFunction]
|
|
66
|
+
name: str = 'controller_registered_functions'
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@dataclass
|
|
70
|
+
class AgentStepTelemetryEvent(BaseTelemetryEvent):
|
|
71
|
+
agent_id: str
|
|
72
|
+
step: int
|
|
73
|
+
step_error: list[str]
|
|
74
|
+
consecutive_failures: int
|
|
75
|
+
actions: list[dict]
|
|
76
|
+
service_actions: Optional[list[str]] = None # Track actions by service type
|
|
77
|
+
action_details: Optional[Dict[str, Any]] = None # Additional action details
|
|
78
|
+
agent_name: Optional[str] = None # Add agent name
|
|
79
|
+
agent_type: Optional[str] = None # Add agent type
|
|
80
|
+
task_progress: Optional[str] = None # Add task progress
|
|
81
|
+
current_task: Optional[str] = None # Add current task
|
|
82
|
+
reasoning: Optional[str] = None # Add reasoning field
|
|
83
|
+
context_data: Optional[Dict[str, Any]] = None # Additional context data
|
|
84
|
+
|
|
85
|
+
# Iteration metadata for enhanced UI rendering
|
|
86
|
+
iteration: Optional[int] = None # Logical iteration number (1-indexed)
|
|
87
|
+
iteration_type: str = "mixed" # thinking, browser, filesystem, mcp, mixed, done
|
|
88
|
+
iteration_status: str = "active" # active, completed, partial, failed, thinking, cancelled, timeout, done
|
|
89
|
+
|
|
90
|
+
# File tracking per iteration
|
|
91
|
+
files_created: Optional[List[str]] = None
|
|
92
|
+
files_modified: Optional[List[str]] = None
|
|
93
|
+
files_read: Optional[List[str]] = None
|
|
94
|
+
files_deleted: Optional[List[str]] = None
|
|
95
|
+
|
|
96
|
+
# Error/warning info
|
|
97
|
+
error_message: Optional[str] = None
|
|
98
|
+
loop_warning: Optional[str] = None
|
|
99
|
+
is_done: bool = False
|
|
100
|
+
|
|
101
|
+
# Synthesis indicator
|
|
102
|
+
reasoning_synthesized: bool = False
|
|
103
|
+
|
|
104
|
+
name: str = 'agent_step'
|
|
105
|
+
|
|
106
|
+
def __post_init__(self):
|
|
107
|
+
"""Initialize optional fields and extract agent name from agent_id.
|
|
108
|
+
|
|
109
|
+
Note: Service detection and action categorization moved to formatters.py
|
|
110
|
+
where it belongs (presentation layer, not data layer).
|
|
111
|
+
"""
|
|
112
|
+
if self.service_actions is None:
|
|
113
|
+
self.service_actions = []
|
|
114
|
+
|
|
115
|
+
if self.action_details is None:
|
|
116
|
+
self.action_details = {}
|
|
117
|
+
|
|
118
|
+
# Extract agent name from agent_id if not explicitly provided
|
|
119
|
+
if (not self.agent_name or self.agent_name == 'Unknown') and self.agent_id and '_' in self.agent_id:
|
|
120
|
+
prefix = self.agent_id.split('_')[0]
|
|
121
|
+
# Capitalize first letter for display
|
|
122
|
+
self.agent_name = prefix.capitalize()
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@dataclass
|
|
126
|
+
class AgentRunTelemetryEvent(BaseTelemetryEvent):
|
|
127
|
+
agent_id: str
|
|
128
|
+
use_vision: bool
|
|
129
|
+
task: str
|
|
130
|
+
model_name: str
|
|
131
|
+
chat_model_library: str
|
|
132
|
+
version: str
|
|
133
|
+
source: str
|
|
134
|
+
name: str = 'agent_run'
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@dataclass
|
|
138
|
+
class AgentEndTelemetryEvent(BaseTelemetryEvent):
|
|
139
|
+
agent_id: str
|
|
140
|
+
steps: int
|
|
141
|
+
max_steps_reached: bool
|
|
142
|
+
success: bool
|
|
143
|
+
errors: list[str]
|
|
144
|
+
name: str = 'agent_end'
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@dataclass
|
|
148
|
+
class LLMRequestTelemetryEvent(BaseTelemetryEvent):
|
|
149
|
+
"""
|
|
150
|
+
Telemetry event for LLM requests and usage.
|
|
151
|
+
|
|
152
|
+
This is the canonical event class for tracking LLM requests and usage.
|
|
153
|
+
It replaces both the old LLMRequestTelemetryEvent and LLMUsageTelemetryEvent
|
|
154
|
+
classes to eliminate redundancy. Downstream collectors should be configured
|
|
155
|
+
to handle events with the 'llm_request' name.
|
|
156
|
+
"""
|
|
157
|
+
component: str
|
|
158
|
+
purpose: str
|
|
159
|
+
model_name: str
|
|
160
|
+
duration_seconds: float
|
|
161
|
+
success: bool
|
|
162
|
+
token_count: Optional[int] = None
|
|
163
|
+
session_id: Optional[str] = None
|
|
164
|
+
error: Optional[str] = None # Add error field for error reporting
|
|
165
|
+
prompt_tokens: Optional[int] = None # For detailed token usage
|
|
166
|
+
completion_tokens: Optional[int] = None # For detailed token usage
|
|
167
|
+
provider: Optional[str] = None # Provider name (openai, anthropic, etc.)
|
|
168
|
+
parameters: Optional[Dict[str, Any]] = None # Additional parameters
|
|
169
|
+
cost_estimate: Optional[float] = None # Estimated cost of the request
|
|
170
|
+
agent_id: Optional[str] = None # Optional agent ID
|
|
171
|
+
# Unique identifier for this LLM request so that downstream analytics can
|
|
172
|
+
# safely deuplicate entries that originate from multiple telemetry
|
|
173
|
+
# sources (e.g. llm_usage JSON + feed event). When not provided by the
|
|
174
|
+
# caller a UUID will be generated automatically inside
|
|
175
|
+
# ProductTelemetry.capture_llm_usage().
|
|
176
|
+
request_id: Optional[str] = None
|
|
177
|
+
name: str = 'llm_request'
|
|
178
|
+
|
|
179
|
+
def __post_init__(self):
|
|
180
|
+
"""Initialize provider after dataclass initialization.
|
|
181
|
+
|
|
182
|
+
This resolves the dataclass-vs-property collision by ensuring
|
|
183
|
+
the provider field is set based on the model_name.
|
|
184
|
+
"""
|
|
185
|
+
# FIXED: Initialize provider field if not set
|
|
186
|
+
if self.provider is None and self.model_name:
|
|
187
|
+
# Use centralized provider detection directly
|
|
188
|
+
from agents.task.utils import detect_llm_provider
|
|
189
|
+
provider = detect_llm_provider(None, self.model_name)
|
|
190
|
+
# Map 'generic' to 'unknown' for consistency with existing code
|
|
191
|
+
self.provider = 'unknown' if provider == 'generic' else provider
|
|
192
|
+
|
|
193
|
+
# Initialize parameters if needed
|
|
194
|
+
if self.parameters is None:
|
|
195
|
+
self.parameters = {}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@dataclass
|
|
199
|
+
class InterfaceTelemetryEvent(BaseTelemetryEvent):
|
|
200
|
+
"""Telemetry event for UI/interface related events"""
|
|
201
|
+
event_type: str # e.g., 'view_loaded', 'session_created', 'screenshot_saved'
|
|
202
|
+
session_id: str
|
|
203
|
+
data: Optional[dict] = None
|
|
204
|
+
name: str = 'interface_event'
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
# DEPRECATED: PlannerOutputTelemetryEvent - planning is now integrated into agent
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@dataclass
|
|
212
|
+
class SessionRelationshipTelemetryEvent(BaseTelemetryEvent):
|
|
213
|
+
"""Telemetry event for tracking parent-child agent relationships in multi-agent sessions"""
|
|
214
|
+
parent_session_id: str
|
|
215
|
+
agent_ids: List[str]
|
|
216
|
+
agent_types: Dict[str, str] # Maps agent_id -> agent_type
|
|
217
|
+
agent_sequence: List[str] # Order of execution
|
|
218
|
+
orchestrator_type: str = "default"
|
|
219
|
+
name: str = 'multi_agent_relationship' # Changed from 'session_relationship' to match expected name
|
|
220
|
+
|
|
221
|
+
def get_session_id(self) -> str:
|
|
222
|
+
"""Get the session ID for this event"""
|
|
223
|
+
return self.parent_session_id
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
class MultiAgentRelationshipEvent(BaseTelemetryEvent):
|
|
227
|
+
"""Detailed telemetry event for multi-agent relationships."""
|
|
228
|
+
|
|
229
|
+
def __init__(self, agent_ids: List[str], agent_types: Dict[str, str], execution_sequence: List[str],
|
|
230
|
+
agent_details: List[Dict] = None, start_times: Dict[str, float] = None,
|
|
231
|
+
end_times: Dict[str, float] = None, durations: Dict[str, float] = None,
|
|
232
|
+
agent_models: Dict[str, str] = None, session_id: Optional[str] = None):
|
|
233
|
+
self.agent_ids = agent_ids
|
|
234
|
+
self.agent_types = agent_types
|
|
235
|
+
self.execution_sequence = execution_sequence
|
|
236
|
+
self.agent_details = agent_details or []
|
|
237
|
+
self.start_times = start_times or {}
|
|
238
|
+
self.end_times = end_times or {}
|
|
239
|
+
self.durations = durations or {}
|
|
240
|
+
self.agent_models = agent_models or {}
|
|
241
|
+
self.session_id = session_id # Explicit session context when available
|
|
242
|
+
|
|
243
|
+
# Ensure model information is added to agent_details if provided separately
|
|
244
|
+
if self.agent_models and self.agent_details:
|
|
245
|
+
for agent_detail in self.agent_details:
|
|
246
|
+
agent_id = agent_detail.get('id') or agent_detail.get('agent_id')
|
|
247
|
+
if agent_id and agent_id in self.agent_models:
|
|
248
|
+
if not agent_detail.get('model'):
|
|
249
|
+
agent_detail['model'] = self.agent_models[agent_id]
|
|
250
|
+
|
|
251
|
+
@property
|
|
252
|
+
def name(self) -> str:
|
|
253
|
+
"""Get the name of this event. Implements the abstract property from BaseTelemetryEvent."""
|
|
254
|
+
return 'multi_agent_relationship_detailed'
|
|
255
|
+
|
|
256
|
+
@property
|
|
257
|
+
def properties(self) -> Dict[str, Any]:
|
|
258
|
+
"""Get the properties for the event.
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
Dict with event properties
|
|
262
|
+
"""
|
|
263
|
+
props = {
|
|
264
|
+
'agent_ids': self.agent_ids,
|
|
265
|
+
'agent_types': self.agent_types,
|
|
266
|
+
'execution_sequence': self.execution_sequence,
|
|
267
|
+
'agent_details': self.agent_details,
|
|
268
|
+
'agent_models': self.agent_models, # Explicitly include agent_models
|
|
269
|
+
'orchestrator_type': 'default'
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
# Add timing data if available
|
|
273
|
+
if self.start_times:
|
|
274
|
+
props['start_times'] = self.start_times
|
|
275
|
+
if self.end_times:
|
|
276
|
+
props['end_times'] = self.end_times
|
|
277
|
+
if self.durations:
|
|
278
|
+
props['durations'] = self.durations
|
|
279
|
+
|
|
280
|
+
return props
|
|
281
|
+
|
|
282
|
+
def get_session_id(self) -> Optional[str]:
|
|
283
|
+
"""Return the session identifier for the event so it can be routed to the correct feed."""
|
|
284
|
+
if self.session_id:
|
|
285
|
+
return self.session_id
|
|
286
|
+
# Fallback: derive from first agent id
|
|
287
|
+
if self.agent_ids:
|
|
288
|
+
first = self.agent_ids[0]
|
|
289
|
+
if '_' in first:
|
|
290
|
+
return first.split('_', 1)[1]
|
|
291
|
+
return None
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
class SessionStartTelemetryEvent(BaseTelemetryEvent):
|
|
295
|
+
"""Event for session start."""
|
|
296
|
+
|
|
297
|
+
def __init__(self, session_id: str, task: str, model_name: str, *args, **kwargs):
|
|
298
|
+
"""Initialize a session start event with task information.
|
|
299
|
+
|
|
300
|
+
Args:
|
|
301
|
+
session_id: The session ID
|
|
302
|
+
task: The description of the task being executed
|
|
303
|
+
model_name: The name of the model being used
|
|
304
|
+
"""
|
|
305
|
+
# Remove super() call since BaseTelemetryEvent has no __init__
|
|
306
|
+
self.session_id = session_id
|
|
307
|
+
self.task = task
|
|
308
|
+
self.model_name = model_name
|
|
309
|
+
self._name = 'session_start'
|
|
310
|
+
|
|
311
|
+
# Store additional attributes
|
|
312
|
+
for key, value in kwargs.items():
|
|
313
|
+
setattr(self, key, value)
|
|
314
|
+
|
|
315
|
+
@property
|
|
316
|
+
def name(self) -> str:
|
|
317
|
+
"""Get the name of this event. Implements the abstract property from BaseTelemetryEvent."""
|
|
318
|
+
return self._name
|
|
319
|
+
|
|
320
|
+
@property
|
|
321
|
+
def properties(self) -> Dict[str, Any]:
|
|
322
|
+
"""Get the properties of this event."""
|
|
323
|
+
# Build a comprehension of public attributes
|
|
324
|
+
props = {
|
|
325
|
+
'session_id': self.session_id,
|
|
326
|
+
'task': self.task,
|
|
327
|
+
'model_name': self.model_name
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
# Include other instance attributes that don't start with underscore
|
|
331
|
+
for key, value in self.__dict__.items():
|
|
332
|
+
if not key.startswith('_') and key not in props:
|
|
333
|
+
props[key] = value
|
|
334
|
+
|
|
335
|
+
return props
|
|
336
|
+
|
|
337
|
+
def get_session_id(self) -> str:
|
|
338
|
+
"""Get the session ID associated with this event."""
|
|
339
|
+
return self.session_id
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
@dataclass
|
|
343
|
+
class SessionCompletionTelemetryEvent(BaseTelemetryEvent):
|
|
344
|
+
"""Event for session completion."""
|
|
345
|
+
session_id: str
|
|
346
|
+
success: bool
|
|
347
|
+
total_steps: int
|
|
348
|
+
duration_seconds: float
|
|
349
|
+
error_message: Optional[str] = None
|
|
350
|
+
metrics: Optional[Dict[str, Any]] = None
|
|
351
|
+
name: str = 'session_completion'
|
|
352
|
+
|
|
353
|
+
def get_session_id(self) -> str:
|
|
354
|
+
"""Get the session ID for this event"""
|
|
355
|
+
return self.session_id
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
@dataclass
|
|
359
|
+
class ScreenshotSavedTelemetryEvent(BaseTelemetryEvent):
|
|
360
|
+
"""Event for when a screenshot is saved to disk."""
|
|
361
|
+
agent_id: str
|
|
362
|
+
step: int
|
|
363
|
+
screenshot_path: str
|
|
364
|
+
name: str = 'screenshot_saved'
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
@dataclass
|
|
368
|
+
class AgentRegistrationEvent(BaseTelemetryEvent):
|
|
369
|
+
"""Event for agent registration."""
|
|
370
|
+
agent_id: str
|
|
371
|
+
agent_name: str
|
|
372
|
+
agent_type: str
|
|
373
|
+
model_name: str
|
|
374
|
+
task: str
|
|
375
|
+
session_id: Optional[str] = None
|
|
376
|
+
name: str = 'agent_registration'
|
|
377
|
+
|
|
378
|
+
def __post_init__(self):
|
|
379
|
+
"""Ensure model_name is properly set."""
|
|
380
|
+
# Set a default model_name if it's empty
|
|
381
|
+
if not self.model_name or self.model_name == "None":
|
|
382
|
+
self.model_name = "Unknown"
|
|
383
|
+
|
|
384
|
+
def get_session_id(self) -> Optional[str]:
|
|
385
|
+
"""Get the session ID for this event"""
|
|
386
|
+
if self.session_id:
|
|
387
|
+
return self.session_id
|
|
388
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
389
|
+
return self.agent_id.split('_', 1)[1]
|
|
390
|
+
return None
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
@dataclass
|
|
394
|
+
class HumanApprovalRequestedEvent(BaseTelemetryEvent):
|
|
395
|
+
"""Event for when human approval is requested for an action."""
|
|
396
|
+
agent_id: str
|
|
397
|
+
step: int
|
|
398
|
+
reason: str
|
|
399
|
+
required: bool = True
|
|
400
|
+
payload: Optional[Dict[str, Any]] = None
|
|
401
|
+
action_preview: Optional[List[str]] = None # List of action names/types
|
|
402
|
+
checkpoint_type: Optional[str] = None # 'pre_action', 'destructive', 'final'
|
|
403
|
+
timeout_seconds: Optional[int] = None
|
|
404
|
+
name: str = 'human_approval_requested'
|
|
405
|
+
|
|
406
|
+
def get_session_id(self) -> Optional[str]:
|
|
407
|
+
"""Get the session ID for this event"""
|
|
408
|
+
if hasattr(self, 'session_id') and getattr(self, 'session_id'):
|
|
409
|
+
return getattr(self, 'session_id')
|
|
410
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
411
|
+
return self.agent_id.split('_', 1)[1]
|
|
412
|
+
return None
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
@dataclass
|
|
416
|
+
class HumanApprovalDecisionEvent(BaseTelemetryEvent):
|
|
417
|
+
"""Event for when a human provides an approval decision."""
|
|
418
|
+
agent_id: str
|
|
419
|
+
step: int
|
|
420
|
+
approved: bool
|
|
421
|
+
note: Optional[str] = None
|
|
422
|
+
decision_time_seconds: Optional[float] = None # Time taken to make decision
|
|
423
|
+
override_type: Optional[str] = None # 'approve', 'reject', 'skip', 'edit'
|
|
424
|
+
edited_params: Optional[Dict[str, Any]] = None # If action params were edited
|
|
425
|
+
name: str = 'human_approval_decision'
|
|
426
|
+
|
|
427
|
+
def get_session_id(self) -> Optional[str]:
|
|
428
|
+
"""Get the session ID for this event"""
|
|
429
|
+
if hasattr(self, 'session_id') and getattr(self, 'session_id'):
|
|
430
|
+
return getattr(self, 'session_id')
|
|
431
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
432
|
+
return self.agent_id.split('_', 1)[1]
|
|
433
|
+
return None
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
@dataclass
|
|
437
|
+
class UserGuidanceEvent(BaseTelemetryEvent):
|
|
438
|
+
"""Event for when user provides guidance/message to agent."""
|
|
439
|
+
agent_id: str
|
|
440
|
+
kind: str # 'message', 'todo_update', 'approval', 'correction'
|
|
441
|
+
text: str
|
|
442
|
+
injected_at: Optional[str] = None # Where in agent flow it was injected
|
|
443
|
+
processed: bool = False
|
|
444
|
+
name: str = 'user_guidance'
|
|
445
|
+
|
|
446
|
+
def get_session_id(self) -> Optional[str]:
|
|
447
|
+
"""Get the session ID for this event"""
|
|
448
|
+
if hasattr(self, 'session_id') and getattr(self, 'session_id'):
|
|
449
|
+
return getattr(self, 'session_id')
|
|
450
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
451
|
+
return self.agent_id.split('_', 1)[1]
|
|
452
|
+
return None
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
@dataclass
|
|
456
|
+
class TodoStatusEvent(BaseTelemetryEvent):
|
|
457
|
+
"""Event for TODO list status updates."""
|
|
458
|
+
agent_id: str
|
|
459
|
+
todos_total: int
|
|
460
|
+
todos_completed: int
|
|
461
|
+
todos_pending: int
|
|
462
|
+
todo_items: Optional[List[Dict[str, Any]]] = None
|
|
463
|
+
enforcement_triggered: bool = False # If Done was blocked due to incomplete TODOs
|
|
464
|
+
name: str = 'todo_status'
|
|
465
|
+
|
|
466
|
+
def get_session_id(self) -> Optional[str]:
|
|
467
|
+
"""Get the session ID for this event"""
|
|
468
|
+
if hasattr(self, 'session_id') and getattr(self, 'session_id'):
|
|
469
|
+
return getattr(self, 'session_id')
|
|
470
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
471
|
+
return self.agent_id.split('_', 1)[1]
|
|
472
|
+
return None
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
@dataclass
|
|
476
|
+
class AssistantMessageEvent(BaseTelemetryEvent):
|
|
477
|
+
"""Event for chat-like assistant messages in HITL flow."""
|
|
478
|
+
agent_id: str
|
|
479
|
+
step: int
|
|
480
|
+
message: str
|
|
481
|
+
page_summary: Optional[str] = None
|
|
482
|
+
next_goal: Optional[str] = None
|
|
483
|
+
key_actions: Optional[List[str]] = None
|
|
484
|
+
url: Optional[str] = None
|
|
485
|
+
title: Optional[str] = None
|
|
486
|
+
name: str = 'assistant_message'
|
|
487
|
+
|
|
488
|
+
def get_session_id(self) -> Optional[str]:
|
|
489
|
+
"""Get the session ID for this event"""
|
|
490
|
+
if hasattr(self, 'session_id') and getattr(self, 'session_id'):
|
|
491
|
+
return getattr(self, 'session_id')
|
|
492
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
493
|
+
return self.agent_id.split('_', 1)[1]
|
|
494
|
+
return None
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
@dataclass
|
|
498
|
+
class UserMessageDuringExecutionEvent(BaseTelemetryEvent):
|
|
499
|
+
"""Event for user messages sent during agent execution (continuous chat).
|
|
500
|
+
|
|
501
|
+
This is for analytics/telemetry purposes. For UI display, use UserMessageFeedEvent.
|
|
502
|
+
"""
|
|
503
|
+
agent_id: str
|
|
504
|
+
step: int
|
|
505
|
+
message_text: str # Truncated for privacy
|
|
506
|
+
message_kind: str
|
|
507
|
+
queue_depth: int
|
|
508
|
+
execution_phase: str # "running", "browser_action", "llm_call"
|
|
509
|
+
name: str = 'user_message_during_execution'
|
|
510
|
+
|
|
511
|
+
def get_session_id(self) -> Optional[str]:
|
|
512
|
+
"""Get the session ID for this event"""
|
|
513
|
+
if hasattr(self, 'session_id') and getattr(self, 'session_id'):
|
|
514
|
+
return getattr(self, 'session_id')
|
|
515
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
516
|
+
return self.agent_id.split('_', 1)[1]
|
|
517
|
+
return None
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
@dataclass
|
|
521
|
+
class UserMessageFeedEvent(BaseTelemetryEvent):
|
|
522
|
+
"""Event for user messages - rendered in chat UI.
|
|
523
|
+
|
|
524
|
+
This event is specifically for the feed/chat rendering.
|
|
525
|
+
Separate from UserMessageDuringExecutionEvent which is for analytics.
|
|
526
|
+
|
|
527
|
+
CRITICAL: The 'name' field MUST be 'user_message' to match chat.js expectations.
|
|
528
|
+
"""
|
|
529
|
+
agent_id: str
|
|
530
|
+
text: str
|
|
531
|
+
kind: str = "comment" # comment, guidance, correction
|
|
532
|
+
step: int = 0
|
|
533
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
534
|
+
state: str = "queued" # queued, injected, processed
|
|
535
|
+
name: str = 'user_message' # CRITICAL: Must match chat.js handleUserMessage()
|
|
536
|
+
|
|
537
|
+
def get_session_id(self) -> Optional[str]:
|
|
538
|
+
"""Get the session ID for this event"""
|
|
539
|
+
if hasattr(self, 'session_id') and getattr(self, 'session_id'):
|
|
540
|
+
return getattr(self, 'session_id')
|
|
541
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
542
|
+
return self.agent_id.split('_', 1)[1]
|
|
543
|
+
return None
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
@dataclass
|
|
547
|
+
class QueueStatusEvent(BaseTelemetryEvent):
|
|
548
|
+
"""Event for message queue status updates.
|
|
549
|
+
|
|
550
|
+
Emitted when the message queue changes to update UI indicators.
|
|
551
|
+
"""
|
|
552
|
+
agent_id: str
|
|
553
|
+
queued_count: int
|
|
554
|
+
processing: bool = False
|
|
555
|
+
oldest_message_age_seconds: Optional[float] = None
|
|
556
|
+
name: str = 'queue_status'
|
|
557
|
+
|
|
558
|
+
def get_session_id(self) -> Optional[str]:
|
|
559
|
+
"""Get the session ID for this event"""
|
|
560
|
+
if hasattr(self, 'session_id') and getattr(self, 'session_id'):
|
|
561
|
+
return getattr(self, 'session_id')
|
|
562
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
563
|
+
return self.agent_id.split('_', 1)[1]
|
|
564
|
+
return None
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
@dataclass
|
|
568
|
+
class StreamingOutputEvent(BaseTelemetryEvent):
|
|
569
|
+
"""Event for streaming LLM output in continuous chat."""
|
|
570
|
+
agent_id: str
|
|
571
|
+
step: int
|
|
572
|
+
total_chunks: int
|
|
573
|
+
total_chars: int
|
|
574
|
+
provider: str
|
|
575
|
+
duration_seconds: float
|
|
576
|
+
callbacks_count: int
|
|
577
|
+
callback_failures: int
|
|
578
|
+
name: str = 'streaming_output'
|
|
579
|
+
|
|
580
|
+
def get_session_id(self) -> Optional[str]:
|
|
581
|
+
"""Get the session ID for this event"""
|
|
582
|
+
if hasattr(self, 'session_id') and getattr(self, 'session_id'):
|
|
583
|
+
return getattr(self, 'session_id')
|
|
584
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
585
|
+
return self.agent_id.split('_', 1)[1]
|
|
586
|
+
return None
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
@dataclass
|
|
590
|
+
class AgentQuestionEvent(BaseTelemetryEvent):
|
|
591
|
+
"""Event for agent-initiated questions to user."""
|
|
592
|
+
agent_id: str
|
|
593
|
+
step: int
|
|
594
|
+
question_prompt: str # Truncated
|
|
595
|
+
response_time_seconds: float
|
|
596
|
+
timed_out: bool
|
|
597
|
+
user_response: Optional[str] # Truncated
|
|
598
|
+
name: str = 'agent_question'
|
|
599
|
+
|
|
600
|
+
def get_session_id(self) -> Optional[str]:
|
|
601
|
+
"""Get the session ID for this event"""
|
|
602
|
+
if hasattr(self, 'session_id') and getattr(self, 'session_id'):
|
|
603
|
+
return getattr(self, 'session_id')
|
|
604
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
605
|
+
return self.agent_id.split('_', 1)[1]
|
|
606
|
+
return None
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
@dataclass
|
|
610
|
+
class PostCompletionContinuationEvent(BaseTelemetryEvent):
|
|
611
|
+
"""Event for user continuing task after agent completion."""
|
|
612
|
+
agent_id: str
|
|
613
|
+
final_step: int
|
|
614
|
+
continuation_message: str # Truncated
|
|
615
|
+
delay_seconds: float # Time between done and message
|
|
616
|
+
new_task_count: int # Steps after continuation
|
|
617
|
+
name: str = 'post_completion_continuation'
|
|
618
|
+
|
|
619
|
+
def get_session_id(self) -> Optional[str]:
|
|
620
|
+
"""Get the session ID for this event"""
|
|
621
|
+
if hasattr(self, 'session_id') and getattr(self, 'session_id'):
|
|
622
|
+
return getattr(self, 'session_id')
|
|
623
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
624
|
+
return self.agent_id.split('_', 1)[1]
|
|
625
|
+
return None
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
@dataclass
|
|
629
|
+
class ToolExecutionTelemetryEvent(BaseTelemetryEvent):
|
|
630
|
+
"""Event for individual tool executions to track performance and results.
|
|
631
|
+
|
|
632
|
+
This event captures granular details about each tool execution including:
|
|
633
|
+
- Which tool/action was executed
|
|
634
|
+
- Parameters passed
|
|
635
|
+
- Execution timing
|
|
636
|
+
- Success/failure status
|
|
637
|
+
- Result size and truncation
|
|
638
|
+
"""
|
|
639
|
+
agent_id: str
|
|
640
|
+
step: int
|
|
641
|
+
tool_name: str # e.g., 'filesystem', 'browser', 'task'
|
|
642
|
+
action_name: str # e.g., 'read_file', 'click', 'task_todo_list'
|
|
643
|
+
parameters: Dict[str, Any] # Action parameters (sanitized)
|
|
644
|
+
duration_seconds: float # Execution time
|
|
645
|
+
success: bool # Whether execution succeeded
|
|
646
|
+
error: Optional[str] = None # Error message if failed
|
|
647
|
+
result_size: Optional[int] = None # Size of result in characters
|
|
648
|
+
result_truncated: bool = False # Whether result was truncated
|
|
649
|
+
result_preview: Optional[str] = None # First 200 chars of result
|
|
650
|
+
session_id: Optional[str] = None # Explicit session ID
|
|
651
|
+
name: str = 'tool_execution'
|
|
652
|
+
|
|
653
|
+
def get_session_id(self) -> Optional[str]:
|
|
654
|
+
"""Get the session ID for this event"""
|
|
655
|
+
if self.session_id:
|
|
656
|
+
return self.session_id
|
|
657
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
658
|
+
return self.agent_id.split('_', 1)[1]
|
|
659
|
+
return None
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
@dataclass
|
|
663
|
+
class ErrorTelemetryEvent(BaseTelemetryEvent):
|
|
664
|
+
"""Event for tracking errors with context.
|
|
665
|
+
|
|
666
|
+
Provides dedicated error tracking separate from step events to enable:
|
|
667
|
+
- Error analytics and dashboards
|
|
668
|
+
- Error rate monitoring
|
|
669
|
+
- Root cause analysis
|
|
670
|
+
- Recovery tracking
|
|
671
|
+
"""
|
|
672
|
+
agent_id: str
|
|
673
|
+
step: int
|
|
674
|
+
error_type: str # 'tool_error', 'llm_error', 'validation_error', 'timeout', etc.
|
|
675
|
+
error_message: str # Error message
|
|
676
|
+
error_stack: Optional[str] = None # Stack trace (sanitized)
|
|
677
|
+
recoverable: bool = True # Whether error is recoverable
|
|
678
|
+
context: Optional[Dict[str, Any]] = None # Additional context
|
|
679
|
+
session_id: Optional[str] = None # Explicit session ID
|
|
680
|
+
name: str = 'error'
|
|
681
|
+
|
|
682
|
+
def get_session_id(self) -> Optional[str]:
|
|
683
|
+
"""Get the session ID for this event"""
|
|
684
|
+
if self.session_id:
|
|
685
|
+
return self.session_id
|
|
686
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
687
|
+
return self.agent_id.split('_', 1)[1]
|
|
688
|
+
return None
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
@dataclass
|
|
692
|
+
class VisionContentInjectedEvent(BaseTelemetryEvent):
|
|
693
|
+
"""Track when vision content is injected into agent context."""
|
|
694
|
+
agent_id: str
|
|
695
|
+
step: int
|
|
696
|
+
image_count: int
|
|
697
|
+
image_sources: List[str] # ['msg_0', 'msg_1', ...]
|
|
698
|
+
model_name: str
|
|
699
|
+
vision_supported: bool
|
|
700
|
+
injection_position: int
|
|
701
|
+
survived_recalibration: bool
|
|
702
|
+
|
|
703
|
+
name: str = "vision_content_injected"
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
@dataclass
|
|
707
|
+
class VisionResponseAnalyzedEvent(BaseTelemetryEvent):
|
|
708
|
+
"""Track LLM response analysis for vision content."""
|
|
709
|
+
agent_id: str
|
|
710
|
+
step: int
|
|
711
|
+
expected_image_count: int
|
|
712
|
+
mentioned_visual_content: bool
|
|
713
|
+
response_length: int
|
|
714
|
+
model_name: str
|
|
715
|
+
vision_keywords_found: List[str] # Which keywords were detected
|
|
716
|
+
|
|
717
|
+
name: str = "vision_response_analyzed"
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
@dataclass
|
|
721
|
+
class ProviderFailureEvent(BaseTelemetryEvent):
|
|
722
|
+
"""Telemetry event for LLM provider failures.
|
|
723
|
+
|
|
724
|
+
This event is emitted when an LLM provider fails and a fallback is attempted.
|
|
725
|
+
Used for monitoring provider health, tracking failure patterns, and
|
|
726
|
+
understanding fallback behavior.
|
|
727
|
+
|
|
728
|
+
Attributes:
|
|
729
|
+
failed_provider: Provider that failed (e.g., 'openai', 'anthropic')
|
|
730
|
+
failed_model: Model that was being used when failure occurred
|
|
731
|
+
error_type: Type of error (e.g., 'LLMRateLimitError', 'LLMAuthenticationError')
|
|
732
|
+
error_message: Truncated error message
|
|
733
|
+
fallback_provider: Provider selected for fallback (None if no fallback available)
|
|
734
|
+
fallback_model: Model selected for fallback
|
|
735
|
+
fallback_success: Whether the fallback attempt succeeded
|
|
736
|
+
attempt_number: Which attempt this was (1 = first try, 2+ = fallback attempts)
|
|
737
|
+
session_id: Session where failure occurred
|
|
738
|
+
agent_id: Agent that encountered the failure
|
|
739
|
+
step: Step number when failure occurred
|
|
740
|
+
"""
|
|
741
|
+
failed_provider: str
|
|
742
|
+
failed_model: str
|
|
743
|
+
error_type: str
|
|
744
|
+
error_message: str
|
|
745
|
+
fallback_provider: Optional[str] = None
|
|
746
|
+
fallback_model: Optional[str] = None
|
|
747
|
+
fallback_success: Optional[bool] = None
|
|
748
|
+
attempt_number: int = 1
|
|
749
|
+
session_id: Optional[str] = None
|
|
750
|
+
agent_id: Optional[str] = None
|
|
751
|
+
step: Optional[int] = None
|
|
752
|
+
timestamp: Optional[float] = None
|
|
753
|
+
name: str = 'provider_failure'
|
|
754
|
+
|
|
755
|
+
def __post_init__(self):
|
|
756
|
+
"""Initialize timestamp if not provided."""
|
|
757
|
+
if self.timestamp is None:
|
|
758
|
+
self.timestamp = time.time()
|
|
759
|
+
|
|
760
|
+
def get_session_id(self) -> Optional[str]:
|
|
761
|
+
"""Get the session ID for this event"""
|
|
762
|
+
if self.session_id:
|
|
763
|
+
return self.session_id
|
|
764
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
765
|
+
return self.agent_id.split('_', 1)[1]
|
|
766
|
+
return None
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
@dataclass
|
|
770
|
+
class ProviderFallbackSuccessEvent(BaseTelemetryEvent):
|
|
771
|
+
"""Telemetry event for successful provider fallback.
|
|
772
|
+
|
|
773
|
+
Emitted when a fallback provider successfully handles a request
|
|
774
|
+
after the primary provider failed.
|
|
775
|
+
"""
|
|
776
|
+
original_provider: str
|
|
777
|
+
original_model: str
|
|
778
|
+
fallback_provider: str
|
|
779
|
+
fallback_model: str
|
|
780
|
+
original_error_type: str
|
|
781
|
+
total_attempts: int
|
|
782
|
+
total_fallback_time_seconds: float
|
|
783
|
+
session_id: Optional[str] = None
|
|
784
|
+
agent_id: Optional[str] = None
|
|
785
|
+
step: Optional[int] = None
|
|
786
|
+
name: str = 'provider_fallback_success'
|
|
787
|
+
|
|
788
|
+
def get_session_id(self) -> Optional[str]:
|
|
789
|
+
"""Get the session ID for this event"""
|
|
790
|
+
if self.session_id:
|
|
791
|
+
return self.session_id
|
|
792
|
+
elif self.agent_id and '_' in self.agent_id:
|
|
793
|
+
return self.agent_id.split('_', 1)[1]
|
|
794
|
+
return None
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
@dataclass
|
|
798
|
+
class SessionPausedEvent(BaseTelemetryEvent):
|
|
799
|
+
"""Event emitted when a session is paused by user.
|
|
800
|
+
|
|
801
|
+
Used for audit trail and UI synchronization.
|
|
802
|
+
"""
|
|
803
|
+
session_id: str
|
|
804
|
+
reason: str = "user_interrupt" # user_interrupt, timeout, error
|
|
805
|
+
paused_by: str = "user" # user, system, admin
|
|
806
|
+
name: str = 'session_paused'
|
|
807
|
+
|
|
808
|
+
def get_session_id(self) -> Optional[str]:
|
|
809
|
+
return self.session_id
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
@dataclass
|
|
813
|
+
class SessionResumedEvent(BaseTelemetryEvent):
|
|
814
|
+
"""Event emitted when a session is resumed by user.
|
|
815
|
+
|
|
816
|
+
Used for audit trail and UI synchronization.
|
|
817
|
+
"""
|
|
818
|
+
session_id: str
|
|
819
|
+
resumed_by: str = "user" # user, system, admin
|
|
820
|
+
name: str = 'session_resumed'
|
|
821
|
+
|
|
822
|
+
def get_session_id(self) -> Optional[str]:
|
|
823
|
+
return self.session_id
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
@dataclass
|
|
827
|
+
class SessionStatusEvent(BaseTelemetryEvent):
|
|
828
|
+
"""Generic status event for session state changes.
|
|
829
|
+
|
|
830
|
+
Used for UI synchronization via feed events.
|
|
831
|
+
"""
|
|
832
|
+
session_id: str
|
|
833
|
+
status: str # running, paused, completed, error
|
|
834
|
+
previous_status: Optional[str] = None
|
|
835
|
+
reason: Optional[str] = None
|
|
836
|
+
name: str = 'status'
|
|
837
|
+
|
|
838
|
+
def get_session_id(self) -> Optional[str]:
|
|
839
|
+
return self.session_id
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
@dataclass
|
|
843
|
+
class IterationCompleteEvent(BaseTelemetryEvent):
|
|
844
|
+
"""Event emitted when an agent iteration completes.
|
|
845
|
+
|
|
846
|
+
This provides a clean boundary marker for the UI to know
|
|
847
|
+
when one iteration ends and another begins. Contains full
|
|
848
|
+
summary of what happened in the iteration.
|
|
849
|
+
"""
|
|
850
|
+
agent_id: str
|
|
851
|
+
iteration: int
|
|
852
|
+
step: int
|
|
853
|
+
|
|
854
|
+
# Iteration classification
|
|
855
|
+
iteration_type: str # thinking, browser, filesystem, mcp, mixed, done
|
|
856
|
+
iteration_status: str # completed, partial, failed, timeout, done
|
|
857
|
+
|
|
858
|
+
# Summary
|
|
859
|
+
reasoning_summary: str
|
|
860
|
+
actions_executed: List[Dict[str, Any]]
|
|
861
|
+
action_results: List[Dict[str, Any]] # Success/failure per action
|
|
862
|
+
|
|
863
|
+
# Files touched (empty lists if none)
|
|
864
|
+
files_created: List[str]
|
|
865
|
+
files_modified: List[str]
|
|
866
|
+
files_read: List[str]
|
|
867
|
+
files_deleted: List[str]
|
|
868
|
+
|
|
869
|
+
# Status
|
|
870
|
+
success: bool
|
|
871
|
+
error: Optional[str] = None
|
|
872
|
+
is_done: bool = False
|
|
873
|
+
|
|
874
|
+
# Timing
|
|
875
|
+
duration_seconds: float = 0.0
|
|
876
|
+
|
|
877
|
+
name: str = 'iteration_complete'
|
|
878
|
+
|
|
879
|
+
def get_session_id(self) -> Optional[str]:
|
|
880
|
+
if self.agent_id and '_' in self.agent_id:
|
|
881
|
+
return self.agent_id.split('_', 1)[1]
|
|
882
|
+
return None
|