aria-code 0.167.0__py3-none-win_amd64.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.
- aria_bots/__init__.py +7 -0
- aria_bots/channels/README.md +97 -0
- aria_bots/channels/__init__.py +1 -0
- aria_bots/channels/approvals.py +263 -0
- aria_bots/channels/conversation.py +280 -0
- aria_bots/channels/digest.py +186 -0
- aria_bots/channels/registry.py +95 -0
- aria_bots/engine.py +144 -0
- aria_bots/feishu_bot.py +1385 -0
- aria_bots/logistics/__init__.py +1 -0
- aria_bots/logistics/carriers.py +253 -0
- aria_bots/logistics/freight.py +154 -0
- aria_bots/logistics/inventory.py +242 -0
- aria_bots/logistics/mcp_server.py +156 -0
- aria_bots/logistics/records.py +119 -0
- aria_bots/logistics/tenancy.py +152 -0
- aria_bots/market.py +91 -0
- aria_bots/relay_client.py +326 -0
- aria_bots/telegram_bot.py +299 -0
- aria_code/__init__.py +111 -0
- aria_code/_bin/aria-native.exe +0 -0
- aria_code/_bin/aria-runtime.exe +0 -0
- aria_code/_version.py +20 -0
- aria_code/account_memory.py +296 -0
- aria_code/account_session.py +166 -0
- aria_code/adk_apps/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/agent.py +32 -0
- aria_code/adk_apps/aria_research/__init__.py +1 -0
- aria_code/adk_apps/aria_research/agent.py +31 -0
- aria_code/agents/__init__.py +49 -0
- aria_code/agents/base.py +329 -0
- aria_code/agents/code_review.py +200 -0
- aria_code/agents/deep/__init__.py +37 -0
- aria_code/agents/deep/calibration_loop.py +144 -0
- aria_code/agents/deep/critic.py +125 -0
- aria_code/agents/deep/deepen.py +193 -0
- aria_code/agents/deep/models.py +149 -0
- aria_code/agents/deep/pipeline.py +164 -0
- aria_code/agents/deep/quant_fusion.py +192 -0
- aria_code/agents/deep/themes.py +95 -0
- aria_code/agents/deep/tiers.py +106 -0
- aria_code/agents/engineering/__init__.py +14 -0
- aria_code/agents/engineering/coder.py +222 -0
- aria_code/agents/engineering/tester.py +145 -0
- aria_code/agents/financial/__init__.py +21 -0
- aria_code/agents/financial/cashflow_burn.py +119 -0
- aria_code/agents/financial/catalyst.py +279 -0
- aria_code/agents/financial/corporate_finance.py +175 -0
- aria_code/agents/financial/debate.py +224 -0
- aria_code/agents/financial/earnings.py +315 -0
- aria_code/agents/financial/fundamental.py +178 -0
- aria_code/agents/financial/macro.py +111 -0
- aria_code/agents/financial/news.py +231 -0
- aria_code/agents/financial/risk.py +146 -0
- aria_code/agents/financial/sector.py +279 -0
- aria_code/agents/financial/strategist.py +121 -0
- aria_code/agents/financial/stripe_revenue.py +127 -0
- aria_code/agents/financial/synthesis.py +274 -0
- aria_code/agents/financial/technical.py +277 -0
- aria_code/agents/orchestrator.py +44 -0
- aria_code/agents/portfolio_agent.py +392 -0
- aria_code/agents/realty/__init__.py +62 -0
- aria_code/agents/realty/asset_diagnosis.py +152 -0
- aria_code/agents/realty/business_match.py +166 -0
- aria_code/agents/realty/cashflow_verify.py +209 -0
- aria_code/agents/realty/contract_rules.py +210 -0
- aria_code/agents/realty/energy_anomaly.py +189 -0
- aria_code/agents/realty/exit_settlement.py +208 -0
- aria_code/agents/realty/fulfillment_risk.py +206 -0
- aria_code/agents/realty/ops_optimize.py +160 -0
- aria_code/agents/realty/revenue_share.py +215 -0
- aria_code/agents/registry.py +168 -0
- aria_code/agents/signal_scheme.py +111 -0
- aria_code/agents/sports/__init__.py +0 -0
- aria_code/agents/sports/football_agent.py +197 -0
- aria_code/agents/supervisor.py +113 -0
- aria_code/agents/team.py +500 -0
- aria_code/agents/video/__init__.py +16 -0
- aria_code/agents/video/director.py +376 -0
- aria_code/agents/video/qa_agent.py +143 -0
- aria_code/agents/video/script_doctor.py +112 -0
- aria_code/agents/warehouse/__init__.py +25 -0
- aria_code/agents/warehouse/contracts.py +26 -0
- aria_code/agents/warehouse/dashboard.py +155 -0
- aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
- aria_code/agents/warehouse/inbound_exceptions.py +25 -0
- aria_code/agents/warehouse/inventory_health.py +24 -0
- aria_code/agents/warehouse/local_run.py +71 -0
- aria_code/agents/warehouse/local_snapshot.py +132 -0
- aria_code/agents/warehouse/logistics_cost.py +84 -0
- aria_code/agents/warehouse/logistics_sync.py +21 -0
- aria_code/agents/warehouse/navigation.schema.json +110 -0
- aria_code/agents/warehouse/task_agent.py +172 -0
- aria_code/agents/warehouse/workflow.py +31 -0
- aria_code/aliyun_data_client.py +4 -0
- aria_code/apps/README.md +12 -0
- aria_code/apps/__init__.py +2 -0
- aria_code/apps/channels/README.md +9 -0
- aria_code/apps/channels/__init__.py +17 -0
- aria_code/apps/channels/approvals.py +11 -0
- aria_code/apps/channels/conversation.py +11 -0
- aria_code/apps/channels/digest.py +11 -0
- aria_code/apps/channels/intake.py +92 -0
- aria_code/apps/channels/registry.py +11 -0
- aria_code/apps/channels/tradingview.py +94 -0
- aria_code/apps/cli/README.md +13 -0
- aria_code/apps/cli/__init__.py +2 -0
- aria_code/apps/cli/_optional.py +120 -0
- aria_code/apps/cli/app_server.py +656 -0
- aria_code/apps/cli/auto_update.py +125 -0
- aria_code/apps/cli/bootstrap.py +206 -0
- aria_code/apps/cli/broker_render.py +206 -0
- aria_code/apps/cli/chat_turn.py +1327 -0
- aria_code/apps/cli/cloud_models.py +231 -0
- aria_code/apps/cli/codegen_paths.py +29 -0
- aria_code/apps/cli/commands/__init__.py +34 -0
- aria_code/apps/cli/commands/_business_render.py +78 -0
- aria_code/apps/cli/commands/_ui.py +71 -0
- aria_code/apps/cli/commands/analysis_cmds.py +378 -0
- aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
- aria_code/apps/cli/commands/auth_cmds.py +215 -0
- aria_code/apps/cli/commands/backtest_cmds.py +2518 -0
- aria_code/apps/cli/commands/broker_cmds.py +1236 -0
- aria_code/apps/cli/commands/business_workflow_cmds.py +379 -0
- aria_code/apps/cli/commands/canvas_cmds.py +77 -0
- aria_code/apps/cli/commands/catalog.py +189 -0
- aria_code/apps/cli/commands/core_cmds.py +2748 -0
- aria_code/apps/cli/commands/data_cmds.py +521 -0
- aria_code/apps/cli/commands/diagnostic_cmds.py +285 -0
- aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
- aria_code/apps/cli/commands/engineering_cmds.py +399 -0
- aria_code/apps/cli/commands/file_cmds.py +312 -0
- aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
- aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
- aria_code/apps/cli/commands/market.py +544 -0
- aria_code/apps/cli/commands/market_cmds.py +1419 -0
- aria_code/apps/cli/commands/market_context.py +432 -0
- aria_code/apps/cli/commands/market_render.py +7 -0
- aria_code/apps/cli/commands/model_cmds.py +2374 -0
- aria_code/apps/cli/commands/ops_cmds.py +721 -0
- aria_code/apps/cli/commands/orchestrator_cmds.py +181 -0
- aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
- aria_code/apps/cli/commands/portfolio_cmds.py +1316 -0
- aria_code/apps/cli/commands/report.py +476 -0
- aria_code/apps/cli/commands/scaffold_templates.py +617 -0
- aria_code/apps/cli/commands/session_cmds.py +236 -0
- aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
- aria_code/apps/cli/commands/team.py +723 -0
- aria_code/apps/cli/commands/team_render.py +8 -0
- aria_code/apps/cli/commands/ui_cmds.py +401 -0
- aria_code/apps/cli/commands/warehouse_cmds.py +297 -0
- aria_code/apps/cli/commands/workflow_cmds.py +629 -0
- aria_code/apps/cli/commands/workspace_cmds.py +1543 -0
- aria_code/apps/cli/config_paths.py +73 -0
- aria_code/apps/cli/config_store.py +158 -0
- aria_code/apps/cli/constants.py +88 -0
- aria_code/apps/cli/context.py +34 -0
- aria_code/apps/cli/conversation_policy.py +53 -0
- aria_code/apps/cli/deterministic.py +200 -0
- aria_code/apps/cli/direct.py +48 -0
- aria_code/apps/cli/earnings_view.py +172 -0
- aria_code/apps/cli/endpoint_migration.py +64 -0
- aria_code/apps/cli/exec_events.py +255 -0
- aria_code/apps/cli/file_references.py +155 -0
- aria_code/apps/cli/finance_service_catalog.py +111 -0
- aria_code/apps/cli/football_reports.py +231 -0
- aria_code/apps/cli/github_app_auth.py +135 -0
- aria_code/apps/cli/google_login.py +239 -0
- aria_code/apps/cli/handlers/__init__.py +11 -0
- aria_code/apps/cli/handlers/broker_handlers.py +122 -0
- aria_code/apps/cli/handlers/chart_handlers.py +1314 -0
- aria_code/apps/cli/handlers/market_handlers.py +2570 -0
- aria_code/apps/cli/handlers/realty_handlers.py +114 -0
- aria_code/apps/cli/handlers/sports_handlers.py +22 -0
- aria_code/apps/cli/handlers/strategy_advice.py +82 -0
- aria_code/apps/cli/headless.py +352 -0
- aria_code/apps/cli/helpers.py +326 -0
- aria_code/apps/cli/hooks.py +180 -0
- aria_code/apps/cli/i18n.py +310 -0
- aria_code/apps/cli/intent.py +136 -0
- aria_code/apps/cli/intent_router.py +305 -0
- aria_code/apps/cli/intent_shadow.py +72 -0
- aria_code/apps/cli/intent_signals.py +347 -0
- aria_code/apps/cli/lifecycle_hooks.py +48 -0
- aria_code/apps/cli/local_tool_schemas.py +550 -0
- aria_code/apps/cli/main.py +39 -0
- aria_code/apps/cli/market_hours.py +100 -0
- aria_code/apps/cli/market_metadata.py +135 -0
- aria_code/apps/cli/market_universe.py +487 -0
- aria_code/apps/cli/message_processing.py +310 -0
- aria_code/apps/cli/mixin_binding.py +32 -0
- aria_code/apps/cli/model_catalog.py +652 -0
- aria_code/apps/cli/model_probe.py +169 -0
- aria_code/apps/cli/model_retirement.py +65 -0
- aria_code/apps/cli/native_branding.py +12 -0
- aria_code/apps/cli/native_bridge.py +118 -0
- aria_code/apps/cli/native_entry.py +58 -0
- aria_code/apps/cli/pdf_report.py +977 -0
- aria_code/apps/cli/plan_mode.py +139 -0
- aria_code/apps/cli/plotly_html.py +15 -0
- aria_code/apps/cli/prediction_feedback.py +202 -0
- aria_code/apps/cli/preflight.py +502 -0
- aria_code/apps/cli/project_aria.py +60 -0
- aria_code/apps/cli/prompt_assembly.py +78 -0
- aria_code/apps/cli/prompts/__init__.py +0 -0
- aria_code/apps/cli/prompts/coding.py +71 -0
- aria_code/apps/cli/prompts/select.py +193 -0
- aria_code/apps/cli/prompts/system_prompts.py +562 -0
- aria_code/apps/cli/prompts/ui.py +436 -0
- aria_code/apps/cli/provider_endpoints.py +237 -0
- aria_code/apps/cli/provider_keys.py +73 -0
- aria_code/apps/cli/providers/__init__.py +1 -0
- aria_code/apps/cli/providers/base.py +775 -0
- aria_code/apps/cli/providers/chat_routing.py +139 -0
- aria_code/apps/cli/providers/collaboration.py +98 -0
- aria_code/apps/cli/providers/llm/__init__.py +1 -0
- aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
- aria_code/apps/cli/providers/llm/ollama_stream.py +1574 -0
- aria_code/apps/cli/providers/llm/response_cache.py +60 -0
- aria_code/apps/cli/providers/llm/sse_stream.py +298 -0
- aria_code/apps/cli/providers/runtime_bridge.py +586 -0
- aria_code/apps/cli/providers/vertexai_stream.py +592 -0
- aria_code/apps/cli/release_download.py +159 -0
- aria_code/apps/cli/review_runner.py +111 -0
- aria_code/apps/cli/runtime_consumer.py +769 -0
- aria_code/apps/cli/sandbox.py +32 -0
- aria_code/apps/cli/session_export.py +120 -0
- aria_code/apps/cli/session_jsonl.py +208 -0
- aria_code/apps/cli/session_refresh.py +123 -0
- aria_code/apps/cli/session_store.py +125 -0
- aria_code/apps/cli/skills_catalog.py +273 -0
- aria_code/apps/cli/task_isolation.py +211 -0
- aria_code/apps/cli/terminal_chrome.py +412 -0
- aria_code/apps/cli/todo_tracker.py +190 -0
- aria_code/apps/cli/tool_executor.py +932 -0
- aria_code/apps/cli/tool_registry.py +34 -0
- aria_code/apps/cli/tool_scope.py +113 -0
- aria_code/apps/cli/tools/__init__.py +40 -0
- aria_code/apps/cli/tools/context.py +46 -0
- aria_code/apps/cli/tools/file_tools.py +181 -0
- aria_code/apps/cli/tools/market_tools.py +626 -0
- aria_code/apps/cli/tools/notebook_tools.py +111 -0
- aria_code/apps/cli/tools/system_tools.py +656 -0
- aria_code/apps/cli/tools/write_tools.py +961 -0
- aria_code/apps/cli/tradingview_bridge.py +529 -0
- aria_code/apps/cli/transactions.py +269 -0
- aria_code/apps/cli/turn_planning.py +137 -0
- aria_code/apps/cli/update_check.py +257 -0
- aria_code/apps/cli/updater.py +373 -0
- aria_code/apps/cli/utils/__init__.py +0 -0
- aria_code/apps/cli/utils/market_detect.py +1663 -0
- aria_code/apps/cli/web_login.py +136 -0
- aria_code/apps/cli/workflow_runner.py +127 -0
- aria_code/apps/cli/workspace_route.py +121 -0
- aria_code/apps/daemon/README.md +14 -0
- aria_code/apps/vscode/README.md +115 -0
- aria_code/apps/vscode/package.json +70 -0
- aria_code/aria_cli.py +5244 -0
- aria_code/aria_daemon.py +1372 -0
- aria_code/aria_feishu_bot.py +16 -0
- aria_code/aria_mcp_server.py +61 -0
- aria_code/aria_relay_client.py +4 -0
- aria_code/aria_telegram_bot.py +11 -0
- aria_code/ariarc.py +385 -0
- aria_code/artifacts.py +581 -0
- aria_code/backtest_engine.py +4 -0
- aria_code/backtest_report.py +4 -0
- aria_code/brokers/__init__.py +78 -0
- aria_code/brokers/automation.py +193 -0
- aria_code/brokers/base.py +231 -0
- aria_code/brokers/capabilities.py +264 -0
- aria_code/brokers/cn/__init__.py +10 -0
- aria_code/brokers/cn/easytrader_broker.py +193 -0
- aria_code/brokers/cn/futu_broker.py +194 -0
- aria_code/brokers/cn/longbridge_broker.py +190 -0
- aria_code/brokers/cn/tiger_broker.py +196 -0
- aria_code/brokers/cn/xtquant_broker.py +225 -0
- aria_code/brokers/config.py +414 -0
- aria_code/brokers/intl/__init__.py +5 -0
- aria_code/brokers/intl/alpaca_broker.py +183 -0
- aria_code/brokers/intl/ibkr_broker.py +215 -0
- aria_code/brokers/intl/trading212_broker.py +183 -0
- aria_code/brokers/intl/webull_broker.py +156 -0
- aria_code/brokers/paper_broker.py +266 -0
- aria_code/brokers/planning.py +296 -0
- aria_code/brokers/registry.py +213 -0
- aria_code/brokers/trading.py +267 -0
- aria_code/canva_client.py +4 -0
- aria_code/change_store.py +127 -0
- aria_code/clients/__init__.py +0 -0
- aria_code/clients/aliyun_data_client.py +660 -0
- aria_code/clients/aria_relay_client.py +16 -0
- aria_code/clients/canva_client.py +284 -0
- aria_code/clients/figma_client.py +100 -0
- aria_code/clients/football_data_client.py +1671 -0
- aria_code/clients/kling_video_client.py +182 -0
- aria_code/clients/market_data_client.py +1985 -0
- aria_code/clients/openai_image_client.py +242 -0
- aria_code/clients/runway_video_client.py +157 -0
- aria_code/clients/warehouse_erp_client.py +105 -0
- aria_code/cloud_memory.py +190 -0
- aria_code/command_safety.py +19 -0
- aria_code/computer_use_server.py +276 -0
- aria_code/computer_use_tools.py +4 -0
- aria_code/dashboard_generator.py +579 -0
- aria_code/data_analysis_tools.py +4 -0
- aria_code/data_cleaner.py +483 -0
- aria_code/data_service.py +513 -0
- aria_code/datasources/__init__.py +23 -0
- aria_code/datasources/base.py +166 -0
- aria_code/datasources/router.py +253 -0
- aria_code/datasources/sec_statements.py +217 -0
- aria_code/datasources/sources/__init__.py +15 -0
- aria_code/datasources/sources/akshare_source.py +269 -0
- aria_code/datasources/sources/alpha_vantage_source.py +203 -0
- aria_code/datasources/sources/edgar_source.py +219 -0
- aria_code/datasources/sources/finnhub_source.py +198 -0
- aria_code/datasources/sources/fred_source.py +223 -0
- aria_code/datasources/sources/tushare_source.py +143 -0
- aria_code/datasources/sources/web_scraper_source.py +278 -0
- aria_code/datasources/sources/world_bank_source.py +206 -0
- aria_code/datasources/sources/yfinance_source.py +152 -0
- aria_code/doctor.py +860 -0
- aria_code/domain/__init__.py +0 -0
- aria_code/domain/_finance_core/__init__.py +5 -0
- aria_code/domain/_finance_core/backtest_engine.py +325 -0
- aria_code/domain/_finance_core/performance_stats.py +101 -0
- aria_code/domain/backtest_engine.py +75 -0
- aria_code/domain/backtest_report.py +488 -0
- aria_code/domain/finance_formulas.py +389 -0
- aria_code/domain/performance_stats.py +6 -0
- aria_code/domain/portfolio_ledger.py +307 -0
- aria_code/domain/strategy_vault.py +421 -0
- aria_code/evals/__init__.py +37 -0
- aria_code/evals/behavior.py +113 -0
- aria_code/evals/gap.py +93 -0
- aria_code/evals/harness.py +949 -0
- aria_code/evals/review_probe.py +132 -0
- aria_code/evals/runner.py +425 -0
- aria_code/evals/scorecard.py +322 -0
- aria_code/evals/summary.py +125 -0
- aria_code/external_agent_runner.py +115 -0
- aria_code/figma_client.py +4 -0
- aria_code/file_analysis_tools.py +4 -0
- aria_code/finance_formulas.py +4 -0
- aria_code/football_data_client.py +4 -0
- aria_code/image_gen_tools.py +4 -0
- aria_code/intent_classifier.py +459 -0
- aria_code/kling_video_client.py +4 -0
- aria_code/licensing.py +151 -0
- aria_code/local_finance_tools.py +4 -0
- aria_code/local_image_provider.py +4 -0
- aria_code/local_llm_provider.py +4 -0
- aria_code/macro_tools.py +4 -0
- aria_code/markdown_pdf.py +289 -0
- aria_code/market_data_client.py +4 -0
- aria_code/mcp_client.py +744 -0
- aria_code/memory_manager.py +273 -0
- aria_code/model_capability.py +512 -0
- aria_code/notification_tools.py +4 -0
- aria_code/openai_image_client.py +4 -0
- aria_code/packages/__init__.py +26 -0
- aria_code/packages/adk_bridge/__init__.py +11 -0
- aria_code/packages/adk_bridge/code_review_tools.py +49 -0
- aria_code/packages/adk_bridge/market_tools.py +125 -0
- aria_code/packages/aria_agents/__init__.py +5 -0
- aria_code/packages/aria_agents/manifest.py +78 -0
- aria_code/packages/aria_core/__init__.py +34 -0
- aria_code/packages/aria_core/architecture.py +269 -0
- aria_code/packages/aria_core/export.py +147 -0
- aria_code/packages/aria_core/manifest.py +65 -0
- aria_code/packages/aria_core/paths.py +57 -0
- aria_code/packages/aria_core/secure_file.py +68 -0
- aria_code/packages/aria_infra/__init__.py +15 -0
- aria_code/packages/aria_infra/arthera.py +58 -0
- aria_code/packages/aria_infra/doctor.py +246 -0
- aria_code/packages/aria_infra/product.py +40 -0
- aria_code/packages/aria_mcp/__init__.py +25 -0
- aria_code/packages/aria_mcp/bridge.py +232 -0
- aria_code/packages/aria_mcp/circuit.py +82 -0
- aria_code/packages/aria_mcp/config.py +162 -0
- aria_code/packages/aria_mcp/installer.py +95 -0
- aria_code/packages/aria_mcp/server.py +1705 -0
- aria_code/packages/aria_mcp/tools.py +81 -0
- aria_code/packages/aria_sdk/__init__.py +19 -0
- aria_code/packages/aria_sdk/client.py +393 -0
- aria_code/packages/aria_sdk/providers.py +70 -0
- aria_code/packages/aria_sdk/streaming.py +75 -0
- aria_code/packages/aria_sdk/types.py +86 -0
- aria_code/packages/aria_services/__init__.py +92 -0
- aria_code/packages/aria_services/cache.py +60 -0
- aria_code/packages/aria_services/context.py +356 -0
- aria_code/packages/aria_services/context_checkpoints.py +157 -0
- aria_code/packages/aria_services/data.py +11 -0
- aria_code/packages/aria_services/provider_health.py +304 -0
- aria_code/packages/aria_services/references.py +247 -0
- aria_code/packages/aria_services/registry.py +249 -0
- aria_code/packages/aria_services/research_protocol.py +137 -0
- aria_code/packages/aria_services/research_quality.py +186 -0
- aria_code/packages/aria_services/settings.py +160 -0
- aria_code/packages/aria_services/usage.py +151 -0
- aria_code/packages/aria_skills/__init__.py +46 -0
- aria_code/packages/aria_skills/catalog.py +149 -0
- aria_code/packages/aria_skills/loader.py +455 -0
- aria_code/packages/aria_skills/registry.py +84 -0
- aria_code/packages/aria_tools/__init__.py +5 -0
- aria_code/packages/aria_tools/financial/__init__.py +5 -0
- aria_code/packages/aria_tools/financial/_paths.py +92 -0
- aria_code/packages/aria_tools/registry.py +129 -0
- aria_code/packages/quant_engine/__init__.py +33 -0
- aria_code/packages/quant_engine/_namespace.py +24 -0
- aria_code/packages/quant_engine/backtest/__init__.py +10 -0
- aria_code/packages/quant_engine/backtest/core.py +53 -0
- aria_code/packages/quant_engine/backtest/engine.py +102 -0
- aria_code/packages/quant_engine/portfolio/__init__.py +9 -0
- aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
- aria_code/packages/quant_engine/sports/__init__.py +76 -0
- aria_code/packages/quant_engine/sports/calibrator.py +354 -0
- aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
- aria_code/packages/quant_engine/sports/elo.py +300 -0
- aria_code/packages/quant_engine/sports/form.py +188 -0
- aria_code/packages/quant_engine/sports/h2h.py +195 -0
- aria_code/packages/quant_engine/sports/predictor.py +312 -0
- aria_code/packages/quant_engine/sports/tracker.py +665 -0
- aria_code/packages/quant_engine/stochastic/__init__.py +31 -0
- aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
- aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
- aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
- aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
- aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
- aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
- aria_code/packs/__init__.py +85 -0
- aria_code/packs/base.py +168 -0
- aria_code/packs/finance/__init__.py +250 -0
- aria_code/packs/healthcare/__init__.py +40 -0
- aria_code/packs/logistics/__init__.py +171 -0
- aria_code/packs/payments/__init__.py +139 -0
- aria_code/packs/realty/__init__.py +190 -0
- aria_code/packs/registry.py +202 -0
- aria_code/packs/rules.py +90 -0
- aria_code/plan_utils.py +194 -0
- aria_code/plugin_loader.py +328 -0
- aria_code/portfolio_ledger.py +4 -0
- aria_code/preview_server.py +449 -0
- aria_code/privacy/__init__.py +5 -0
- aria_code/privacy/feedback.py +123 -0
- aria_code/project_review.py +278 -0
- aria_code/project_review_api.py +235 -0
- aria_code/project_review_server.py +18 -0
- aria_code/project_tools.py +4 -0
- aria_code/providers/__init__.py +30 -0
- aria_code/providers/google_video_provider.py +256 -0
- aria_code/providers/llm/__init__.py +19 -0
- aria_code/providers/llm/anthropic.py +184 -0
- aria_code/providers/llm/arthera_gateway.py +90 -0
- aria_code/providers/llm/autoconfig.py +213 -0
- aria_code/providers/llm/base.py +139 -0
- aria_code/providers/llm/custom.py +158 -0
- aria_code/providers/llm/ollama.py +137 -0
- aria_code/providers/llm/openai_compat.py +350 -0
- aria_code/providers/llm/registry.py +457 -0
- aria_code/providers/local_image_provider.py +202 -0
- aria_code/providers/local_llm_provider.py +549 -0
- aria_code/providers/ollama_models.py +79 -0
- aria_code/providers/openai_params.py +32 -0
- aria_code/providers/tool_messages.py +100 -0
- aria_code/realty_data_tools.py +4 -0
- aria_code/report_exporters.py +150 -0
- aria_code/report_generator.py +1764 -0
- aria_code/review_service.py +497 -0
- aria_code/runtime/__init__.py +176 -0
- aria_code/runtime/acceptance.py +632 -0
- aria_code/runtime/agent_loop.py +1851 -0
- aria_code/runtime/agent_profiles.py +75 -0
- aria_code/runtime/approval.py +71 -0
- aria_code/runtime/baseline.py +219 -0
- aria_code/runtime/budget.py +232 -0
- aria_code/runtime/checkpoints.py +481 -0
- aria_code/runtime/consult.py +65 -0
- aria_code/runtime/contract.py +282 -0
- aria_code/runtime/delivery.py +432 -0
- aria_code/runtime/events.py +113 -0
- aria_code/runtime/gateway.py +167 -0
- aria_code/runtime/lsp.py +484 -0
- aria_code/runtime/native_index.py +153 -0
- aria_code/runtime/orchestrator.py +55 -0
- aria_code/runtime/processes.py +343 -0
- aria_code/runtime/project_graph.py +614 -0
- aria_code/runtime/repo_map.py +712 -0
- aria_code/runtime/research_bundle.py +105 -0
- aria_code/runtime/review.py +269 -0
- aria_code/runtime/run_state.py +127 -0
- aria_code/runtime/run_store.py +522 -0
- aria_code/runtime/scoped_runs.py +113 -0
- aria_code/runtime/self_healing.py +422 -0
- aria_code/runtime/semantic_diff.py +171 -0
- aria_code/runtime/subagent.py +721 -0
- aria_code/runtime/symbol_edit.py +117 -0
- aria_code/runtime/task_brief.py +46 -0
- aria_code/runtime/task_context.py +145 -0
- aria_code/runtime/task_ledger.py +108 -0
- aria_code/runtime/task_orchestrator.py +90 -0
- aria_code/runtime/task_outcome.py +33 -0
- aria_code/runtime/task_verification.py +266 -0
- aria_code/runtime/task_worktree.py +448 -0
- aria_code/runtime/tool_executor.py +329 -0
- aria_code/runtime/tool_policy.py +107 -0
- aria_code/runtime/transactions.py +216 -0
- aria_code/runtime/windows_job.py +115 -0
- aria_code/runtime/workflows.py +222 -0
- aria_code/runtime/worktrees.py +215 -0
- aria_code/runway_video_client.py +4 -0
- aria_code/safety/__init__.py +27 -0
- aria_code/safety/client_isolation.py +178 -0
- aria_code/safety/permissions.py +339 -0
- aria_code/safety/risk.py +699 -0
- aria_code/safety/sandbox.py +148 -0
- aria_code/safety/service.py +102 -0
- aria_code/service_endpoints.py +14 -0
- aria_code/setup_wizard.py +684 -0
- aria_code/spreadsheet_tools.py +4 -0
- aria_code/strategy_vault.py +4 -0
- aria_code/tools/__init__.py +0 -0
- aria_code/tools/artifact_tools.py +252 -0
- aria_code/tools/broker_tools.py +92 -0
- aria_code/tools/build_quant_engine.py +97 -0
- aria_code/tools/code_audit_tools.py +192 -0
- aria_code/tools/computer_use_tools.py +509 -0
- aria_code/tools/data_analysis_tools.py +831 -0
- aria_code/tools/enterprise_finance_tools.py +202 -0
- aria_code/tools/extended_tools.py +240 -0
- aria_code/tools/file_analysis_tools.py +880 -0
- aria_code/tools/image_gen_tools.py +114 -0
- aria_code/tools/local_finance_tools.py +3488 -0
- aria_code/tools/logistics_carriers.py +11 -0
- aria_code/tools/logistics_inventory.py +11 -0
- aria_code/tools/logistics_io.py +11 -0
- aria_code/tools/logistics_tenancy.py +11 -0
- aria_code/tools/logistics_tools.py +11 -0
- aria_code/tools/macro_tools.py +412 -0
- aria_code/tools/notification_tools.py +249 -0
- aria_code/tools/project_tools.py +525 -0
- aria_code/tools/realty_data_tools.py +662 -0
- aria_code/tools/spreadsheet_tools.py +399 -0
- aria_code/tools/stripe_tools.py +115 -0
- aria_code/tools/video_tools.py +500 -0
- aria_code/training/__init__.py +1 -0
- aria_code/training/compare.py +117 -0
- aria_code/training/prelude_commands.py +111 -0
- aria_code/training/prelude_eval.py +390 -0
- aria_code/training/prelude_real.py +183 -0
- aria_code/training/prelude_train.py +248 -0
- aria_code/training/sft_dataset.py +230 -0
- aria_code/training/trajectory_dataset.py +263 -0
- aria_code/ui/__init__.py +105 -0
- aria_code/ui/banner.py +404 -0
- aria_code/ui/completer.py +571 -0
- aria_code/ui/console.py +285 -0
- aria_code/ui/input_box.py +505 -0
- aria_code/ui/mentions.py +206 -0
- aria_code/ui/picker.py +248 -0
- aria_code/ui/render/__init__.py +11 -0
- aria_code/ui/render/actions.py +297 -0
- aria_code/ui/render/finance.py +1732 -0
- aria_code/ui/render/market.py +253 -0
- aria_code/ui/render/output.py +954 -0
- aria_code/ui/render/responsive.py +75 -0
- aria_code/ui/render/team.py +367 -0
- aria_code/ui/robot.py +239 -0
- aria_code/ui/startup_dashboard.py +110 -0
- aria_code/video_analysis.py +147 -0
- aria_code/video_editor.py +518 -0
- aria_code/video_workflow/__init__.py +8 -0
- aria_code/video_workflow/__main__.py +61 -0
- aria_code/video_workflow/engines/__init__.py +18 -0
- aria_code/video_workflow/engines/base.py +69 -0
- aria_code/video_workflow/engines/custom_model.py +204 -0
- aria_code/video_workflow/engines/google_veo.py +94 -0
- aria_code/video_workflow/engines/local_engine.py +71 -0
- aria_code/video_workflow/engines/registry.py +98 -0
- aria_code/video_workflow/google_models.py +278 -0
- aria_code/video_workflow/music/__init__.py +5 -0
- aria_code/video_workflow/music/foley_service.py +132 -0
- aria_code/video_workflow/music/service.py +212 -0
- aria_code/video_workflow/pipeline.py +620 -0
- aria_code/video_workflow/plan.py +202 -0
- aria_code/video_workflow/session.py +297 -0
- aria_code/workspace/__init__.py +6 -0
- aria_code/workspace/files.py +219 -0
- aria_code/workspace/verify.py +167 -0
- aria_code/workspace_changes.py +199 -0
- aria_code/workspace_service.py +196 -0
- aria_code/workspace_tools.py +150 -0
- aria_code-0.167.0.dist-info/METADATA +330 -0
- aria_code-0.167.0.dist-info/RECORD +601 -0
- aria_code-0.167.0.dist-info/WHEEL +5 -0
- aria_code-0.167.0.dist-info/entry_points.txt +5 -0
- aria_code-0.167.0.dist-info/licenses/LICENSE +201 -0
- aria_code-0.167.0.dist-info/licenses/NOTICE +49 -0
- aria_code-0.167.0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,656 @@
|
|
|
1
|
+
"""System-level tools: run_command, web_fetch, github.
|
|
2
|
+
|
|
3
|
+
All functions are pure (no module-level globals). Console output is
|
|
4
|
+
injected via keyword args so aria_cli.py thin wrappers supply the
|
|
5
|
+
Rich console and global state defaults.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import os
|
|
11
|
+
import pathlib
|
|
12
|
+
import re
|
|
13
|
+
import shlex
|
|
14
|
+
import subprocess
|
|
15
|
+
import sys
|
|
16
|
+
from datetime import datetime
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
_ROOT = Path(__file__).parent.parent.parent.parent # aria-code/
|
|
20
|
+
if str(_ROOT) not in sys.path:
|
|
21
|
+
sys.path.insert(0, str(_ROOT))
|
|
22
|
+
|
|
23
|
+
from aria_code.safety import evaluate_command_policy # noqa: E402
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _persist_command_output(command: str, stdout: str, stderr: str, returncode: int) -> dict:
|
|
27
|
+
"""Persist full command output when it is too large for inline tool context."""
|
|
28
|
+
stdout_lines = stdout.splitlines()
|
|
29
|
+
stderr_lines = stderr.splitlines()
|
|
30
|
+
if (
|
|
31
|
+
len(stdout) <= 2500
|
|
32
|
+
and len(stderr) <= 1200
|
|
33
|
+
and len(stdout_lines) <= 18
|
|
34
|
+
and len(stderr_lines) <= 8
|
|
35
|
+
):
|
|
36
|
+
return {}
|
|
37
|
+
try:
|
|
38
|
+
from aria_code.artifacts import create_artifact, write_artifact_metadata
|
|
39
|
+
|
|
40
|
+
record = create_artifact(
|
|
41
|
+
"command-output",
|
|
42
|
+
"shell",
|
|
43
|
+
"command_output",
|
|
44
|
+
".txt",
|
|
45
|
+
timestamp=datetime.now(),
|
|
46
|
+
)
|
|
47
|
+
text = (
|
|
48
|
+
f"$ {command}\n"
|
|
49
|
+
f"exit_code={returncode}\n\n"
|
|
50
|
+
"===== STDOUT =====\n"
|
|
51
|
+
f"{stdout}"
|
|
52
|
+
"\n\n===== STDERR =====\n"
|
|
53
|
+
f"{stderr}"
|
|
54
|
+
)
|
|
55
|
+
record.path.write_text(text, encoding="utf-8", errors="replace")
|
|
56
|
+
write_artifact_metadata(record, {
|
|
57
|
+
"kind": "command_output",
|
|
58
|
+
"status": "complete" if returncode == 0 else "failed",
|
|
59
|
+
"created_at": datetime.now().isoformat(timespec="seconds"),
|
|
60
|
+
"command": command,
|
|
61
|
+
"exit_code": returncode,
|
|
62
|
+
"stdout_chars": len(stdout),
|
|
63
|
+
"stderr_chars": len(stderr),
|
|
64
|
+
"stdout_truncated_inline": len(stdout) > 5000,
|
|
65
|
+
"stderr_truncated_inline": len(stderr) > 2000,
|
|
66
|
+
})
|
|
67
|
+
return {"full_output_path": str(record.path)}
|
|
68
|
+
except Exception:
|
|
69
|
+
return {}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _cprint(msg: str, *, console, has_rich: bool) -> None:
|
|
73
|
+
if has_rich and console is not None:
|
|
74
|
+
console.print(msg)
|
|
75
|
+
else:
|
|
76
|
+
plain = re.sub(r"\[/?[^\]]+\]", "", msg)
|
|
77
|
+
print(plain)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
OUTPUT_PREVIEW_LINES = 5
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def print_command_outcome(console, returncode: int, stdout: str, stderr: str, full_output_path: str = "") -> None:
|
|
84
|
+
"""One step line and the last few lines of what the command printed.
|
|
85
|
+
|
|
86
|
+
This printed "Command completed (exit 0)", up to six stdout lines and
|
|
87
|
+
"full output saved" — and nothing at all for `python3 -m unittest -v`,
|
|
88
|
+
whose report goes to stderr, so the model pasted the test results into
|
|
89
|
+
its answer instead. Lines are plain text: program output such as
|
|
90
|
+
"[/dim]" is not Rich markup. As Codex does, the tail is kept — that is
|
|
91
|
+
where "OK" or the failure is — and the rest is counted.
|
|
92
|
+
"""
|
|
93
|
+
from rich.text import Text
|
|
94
|
+
|
|
95
|
+
lines = stdout.rstrip().splitlines() + (stderr.rstrip().splitlines() if stderr.strip() else [])
|
|
96
|
+
ok = returncode == 0
|
|
97
|
+
head = Text(" ⎿ ", style="dim")
|
|
98
|
+
head.append(f"exit {returncode}", style="green" if ok else "red")
|
|
99
|
+
if lines:
|
|
100
|
+
head.append(f" · {len(lines)} line{'s' if len(lines) != 1 else ''}", style="dim")
|
|
101
|
+
console.print(head)
|
|
102
|
+
notes = []
|
|
103
|
+
if len(lines) > OUTPUT_PREVIEW_LINES:
|
|
104
|
+
notes.append(f"… +{len(lines) - OUTPUT_PREVIEW_LINES} lines")
|
|
105
|
+
if full_output_path:
|
|
106
|
+
from aria_code.ui.render.output import display_path
|
|
107
|
+
|
|
108
|
+
notes.append(f"full output saved: {display_path(full_output_path)}")
|
|
109
|
+
if notes:
|
|
110
|
+
console.print(Text(" " + " · ".join(notes), style="dim"))
|
|
111
|
+
for line in lines[-OUTPUT_PREVIEW_LINES:]:
|
|
112
|
+
console.print(Text(" " + line[:160], style="dim" if ok else "red"), overflow="ellipsis", no_wrap=True)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def tool_run_command(
|
|
116
|
+
params: dict,
|
|
117
|
+
*,
|
|
118
|
+
console=None,
|
|
119
|
+
has_rich: bool = True,
|
|
120
|
+
quiet: bool = False,
|
|
121
|
+
) -> dict:
|
|
122
|
+
"""Run a shell command and return output.
|
|
123
|
+
|
|
124
|
+
``params`` should contain ``permission_mode`` and ``network_enabled``
|
|
125
|
+
(filled in by the aria_cli.py wrapper from the active globals).
|
|
126
|
+
``quiet`` leaves the outcome to the caller: during a chat turn the
|
|
127
|
+
transcript's Ran cell shows the exit and the output tail itself.
|
|
128
|
+
"""
|
|
129
|
+
command = params.get("command", "")
|
|
130
|
+
# LLMs sometimes send command as a list e.g. ['bash', '-lc', '...'] — normalize to string
|
|
131
|
+
if isinstance(command, list):
|
|
132
|
+
import shlex as _shlex
|
|
133
|
+
command = _shlex.join(str(c) for c in command)
|
|
134
|
+
params["command"] = command
|
|
135
|
+
if not command:
|
|
136
|
+
return {"success": False, "error": "Missing 'command' parameter"}
|
|
137
|
+
|
|
138
|
+
effective_policy = params.get("policy", "safe")
|
|
139
|
+
if params.get("user_approved") and effective_policy == "safe":
|
|
140
|
+
effective_policy = "balanced"
|
|
141
|
+
|
|
142
|
+
decision = evaluate_command_policy(
|
|
143
|
+
command,
|
|
144
|
+
effective_policy,
|
|
145
|
+
# "safe" is a *policy* name, not a mode — it never matched
|
|
146
|
+
# PermissionMode and silently resolved to workspace-write. Both
|
|
147
|
+
# executors supply a real mode, so this default is only reached
|
|
148
|
+
# by a caller that bypasses them; read-only is the right answer
|
|
149
|
+
# there.
|
|
150
|
+
mode=params.get("permission_mode", "read-only"),
|
|
151
|
+
network_enabled=bool(params.get("network_enabled", True)),
|
|
152
|
+
)
|
|
153
|
+
mode = str(params.get("permission_mode", "read-only"))
|
|
154
|
+
network = bool(params.get("network_enabled", True))
|
|
155
|
+
sandbox_hint = ""
|
|
156
|
+
command = decision.normalized_command
|
|
157
|
+
|
|
158
|
+
from aria_code.safety.permissions import writes_a_device
|
|
159
|
+
dangerous = ["rm -rf /", "mkfs", "dd if=", ":(){ :", "fork bomb"]
|
|
160
|
+
if any(d in command for d in dangerous) or writes_a_device(command):
|
|
161
|
+
return {"success": False, "error": f"Blocked dangerous command: {command}"}
|
|
162
|
+
|
|
163
|
+
# Prevent executing text/doc files as Python — they are analysis reports, not scripts
|
|
164
|
+
import re as _re_cmd
|
|
165
|
+
_py3_file = _re_cmd.search(r'\bpython3?\s+["\']?(\S+\.(?:txt|md|docx|csv|json|log))', command)
|
|
166
|
+
if _py3_file:
|
|
167
|
+
_bad_file = _py3_file.group(1)
|
|
168
|
+
return {
|
|
169
|
+
"success": False,
|
|
170
|
+
"error": (
|
|
171
|
+
f"拒绝执行: '{_bad_file}' 是文本/分析文件,不是 Python 脚本。\n"
|
|
172
|
+
"如需展示分析结果,请直接输出文字,或将分析结论写入 .py 文件后执行。"
|
|
173
|
+
),
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if params.get("dry_run"):
|
|
177
|
+
return {"success": True, "data": {
|
|
178
|
+
"command": command,
|
|
179
|
+
"risk": decision.risk,
|
|
180
|
+
"policy": decision.policy,
|
|
181
|
+
"requires_approval": getattr(decision, "requires_approval", False),
|
|
182
|
+
"network": getattr(decision, "network", False),
|
|
183
|
+
"dry_run": True,
|
|
184
|
+
}}
|
|
185
|
+
if not decision.allowed:
|
|
186
|
+
return {"success": False, "error": decision.reason}
|
|
187
|
+
try:
|
|
188
|
+
cwd = params.get("cwd", None)
|
|
189
|
+
timeout = min(params.get("timeout", 120), 300)
|
|
190
|
+
use_shell = True
|
|
191
|
+
argv = None
|
|
192
|
+
# POSIX shlex strips Windows path backslashes. Keep CMD's own parsing
|
|
193
|
+
# on Windows, after the same policy and permission checks above.
|
|
194
|
+
if decision.risk == "low" and os.name != "nt":
|
|
195
|
+
has_shell_meta = any(ch in command for ch in ["|", "&", ";", "<", ">", "$", "`", "\n"])
|
|
196
|
+
if not has_shell_meta:
|
|
197
|
+
try:
|
|
198
|
+
argv = shlex.split(command)
|
|
199
|
+
if argv:
|
|
200
|
+
use_shell = False
|
|
201
|
+
except ValueError:
|
|
202
|
+
use_shell = True
|
|
203
|
+
argv = None
|
|
204
|
+
|
|
205
|
+
sandbox = params.get("sandbox", False)
|
|
206
|
+
if params.get("background"):
|
|
207
|
+
return _start_background(params, command, argv, use_shell, cwd, mode, network,
|
|
208
|
+
docker=bool(sandbox), console=console, has_rich=has_rich)
|
|
209
|
+
if sandbox:
|
|
210
|
+
try:
|
|
211
|
+
from aria_code.apps.cli.sandbox import run_in_docker_sandbox
|
|
212
|
+
result = run_in_docker_sandbox(
|
|
213
|
+
command=command,
|
|
214
|
+
cwd=cwd,
|
|
215
|
+
timeout=timeout,
|
|
216
|
+
image="python:3.11-slim"
|
|
217
|
+
)
|
|
218
|
+
except Exception as e:
|
|
219
|
+
return {"success": False, "error": f"Sandbox execution failed: {e}"}
|
|
220
|
+
else:
|
|
221
|
+
from aria_code.safety import sandbox as _os_sandbox
|
|
222
|
+
confined = _os_sandbox.wrap(
|
|
223
|
+
argv if (argv and not use_shell) else command,
|
|
224
|
+
use_shell=use_shell, mode=mode, network=network, cwd=cwd,
|
|
225
|
+
setting=params.get("os_sandbox"),
|
|
226
|
+
workspace=params.get("_workspace"),
|
|
227
|
+
extra=params.get("_allowed_write_roots", ()),
|
|
228
|
+
)
|
|
229
|
+
# In a task worktree, the worktree's own source comes first on
|
|
230
|
+
# PYTHONPATH, so an editable install of the user's checkout does
|
|
231
|
+
# not answer imports meant for the task's edits.
|
|
232
|
+
from aria_code.runtime.task_worktree import worktree_command_env
|
|
233
|
+
result = subprocess.run(
|
|
234
|
+
confined or (argv if (argv and not use_shell) else command),
|
|
235
|
+
shell=use_shell and not confined,
|
|
236
|
+
capture_output=True,
|
|
237
|
+
text=True,
|
|
238
|
+
timeout=timeout,
|
|
239
|
+
cwd=cwd,
|
|
240
|
+
env=worktree_command_env(params.get("_workspace") or "", params.get("_workspace_origin") or ""),
|
|
241
|
+
)
|
|
242
|
+
if confined and "sandbox-exec: sandbox_apply" in (result.stderr or ""):
|
|
243
|
+
# Never fall back to running it unconfined.
|
|
244
|
+
return {"success": False, "error": "The command sandbox could not start: "
|
|
245
|
+
+ result.stderr.strip()[:300]
|
|
246
|
+
+ " — set os_sandbox=off in the config to run commands without it."}
|
|
247
|
+
if confined and result.returncode != 0:
|
|
248
|
+
sandbox_hint = _os_sandbox.denial_hint(result.stdout + "\n" + result.stderr,
|
|
249
|
+
mode=mode, network=network)
|
|
250
|
+
full_stdout = result.stdout
|
|
251
|
+
full_stderr = result.stderr
|
|
252
|
+
output = full_stdout[-5000:] if len(full_stdout) > 5000 else full_stdout
|
|
253
|
+
stderr = full_stderr[-2000:] if len(full_stderr) > 2000 else full_stderr
|
|
254
|
+
output_artifact = _persist_command_output(command, full_stdout, full_stderr, result.returncode)
|
|
255
|
+
|
|
256
|
+
# A failed command is reported, not repaired here. This used to edit
|
|
257
|
+
# the script (inserting imports, rewriting DataFrame.append) and run
|
|
258
|
+
# `pip3 install <the module named in the error>`, then re-run with
|
|
259
|
+
# shell=True: file writes with no approval and no checkpoint, so /undo
|
|
260
|
+
# could not reverse them, and a package install that ignored network
|
|
261
|
+
# off and the sandbox. The model gets the error and a hint, and makes
|
|
262
|
+
# the change through edit_file or an approved run_command.
|
|
263
|
+
hint = sandbox_hint or (_failure_hint(output + "\n" + stderr) if result.returncode != 0 else "")
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
if quiet:
|
|
267
|
+
pass
|
|
268
|
+
elif has_rich and console is not None:
|
|
269
|
+
print_command_outcome(console, result.returncode, output, stderr,
|
|
270
|
+
output_artifact.get("full_output_path", ""))
|
|
271
|
+
else:
|
|
272
|
+
print(f" Command exit: {result.returncode}")
|
|
273
|
+
data = {
|
|
274
|
+
"command": command, "exit_code": result.returncode,
|
|
275
|
+
"stdout": output, "stderr": stderr,
|
|
276
|
+
"stdout_truncated": len(full_stdout) > 5000,
|
|
277
|
+
"stderr_truncated": len(full_stderr) > 2000,
|
|
278
|
+
}
|
|
279
|
+
data.update(output_artifact)
|
|
280
|
+
if hint:
|
|
281
|
+
data["hint"] = hint
|
|
282
|
+
return {"success": True, "data": data}
|
|
283
|
+
except subprocess.TimeoutExpired:
|
|
284
|
+
return {"success": False, "error": f"Command timed out ({timeout}s)"}
|
|
285
|
+
except KeyboardInterrupt:
|
|
286
|
+
_cprint(" [dim]Command interrupted[/dim]", console=console, has_rich=has_rich)
|
|
287
|
+
return {"success": False, "error": "Command interrupted by user (Ctrl+C)"}
|
|
288
|
+
except Exception as e:
|
|
289
|
+
return {"success": False, "error": str(e)}
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def _start_background(params, command, argv, use_shell, cwd, mode, network, *, docker,
|
|
293
|
+
console, has_rich) -> dict:
|
|
294
|
+
"""Start a long-running command (server, watcher) and return its first output."""
|
|
295
|
+
if docker:
|
|
296
|
+
return {"success": False, "error": "background=true is not available with the Docker sandbox."}
|
|
297
|
+
from aria_code.runtime import processes
|
|
298
|
+
from aria_code.safety import sandbox as _os_sandbox
|
|
299
|
+
|
|
300
|
+
target = argv if (argv and not use_shell) else command
|
|
301
|
+
confined = _os_sandbox.wrap(target, use_shell=use_shell, mode=mode, network=network, cwd=cwd,
|
|
302
|
+
setting=params.get("os_sandbox"), workspace=params.get("_workspace"),
|
|
303
|
+
extra=params.get("_allowed_write_roots", ()))
|
|
304
|
+
result = processes.start(confined or target, shell=use_shell and not confined, cwd=cwd,
|
|
305
|
+
label=command, wait=min(float(params.get("wait_seconds", 3) or 0), 30.0),
|
|
306
|
+
until=params.get("until"))
|
|
307
|
+
if result.get("success"):
|
|
308
|
+
data = result["data"]
|
|
309
|
+
state = "running" if data["running"] else f"exited {data['exit_code']}"
|
|
310
|
+
_cprint(f" [dim]⎿ background {data['process_id']} · {state}[/dim]",
|
|
311
|
+
console=console, has_rich=has_rich)
|
|
312
|
+
if confined and not data["running"]:
|
|
313
|
+
hint = _os_sandbox.denial_hint(data.get("output", ""), mode=mode, network=network)
|
|
314
|
+
if hint:
|
|
315
|
+
data["hint"] = hint
|
|
316
|
+
return result
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
_PIP_NAMES = {
|
|
320
|
+
"sklearn": "scikit-learn", "cv2": "opencv-python", "bs4": "beautifulsoup4",
|
|
321
|
+
"PIL": "Pillow", "yaml": "PyYAML",
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def _failure_hint(text: str) -> str:
|
|
326
|
+
"""What to do about a common failure, for the model to act on with approval."""
|
|
327
|
+
missing = re.search(r"No module named ['\"]?([\w.]+)", text)
|
|
328
|
+
if missing:
|
|
329
|
+
module = missing.group(1).split(".")[0]
|
|
330
|
+
package = _PIP_NAMES.get(module, module)
|
|
331
|
+
return (f"Module '{module}' is not installed. If it is the right dependency, install it with "
|
|
332
|
+
f"run_command (e.g. `python3 -m pip install {package}`; check the package name first).")
|
|
333
|
+
name = re.search(r"NameError: name ['\"](\w+)['\"] is not defined", text)
|
|
334
|
+
if name:
|
|
335
|
+
return f"'{name.group(1)}' is not defined: add the missing import or definition with edit_file."
|
|
336
|
+
if "DataFrame' object has no attribute 'append'" in text:
|
|
337
|
+
return "DataFrame.append was removed in pandas 2: use pd.concat with edit_file."
|
|
338
|
+
return ""
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def tool_web_fetch(params: dict) -> dict:
|
|
342
|
+
"""Fetch the text content of any URL."""
|
|
343
|
+
url = params.get("url", "").strip()
|
|
344
|
+
if not url:
|
|
345
|
+
return {"success": False, "error": "Missing 'url' parameter"}
|
|
346
|
+
if not url.startswith(("http://", "https://")):
|
|
347
|
+
url = "https://" + url
|
|
348
|
+
max_chars = min(int(params.get("max_chars", 4000)), 12000)
|
|
349
|
+
timeout = min(int(params.get("timeout", 15)), 30)
|
|
350
|
+
try:
|
|
351
|
+
import urllib.request as _ur
|
|
352
|
+
import ssl as _ssl
|
|
353
|
+
_prx = _ur.getproxies()
|
|
354
|
+
# SEC EDGAR rejects browser-spoofed UAs from scripts (403) and requires
|
|
355
|
+
# a declarative UA with contact info — the root cause of "verify via
|
|
356
|
+
# 10-Q" tasks silently degrading to aggregator sites. Honor SEC's rule
|
|
357
|
+
# for sec.gov; keep a browser UA for sites that block obvious bots.
|
|
358
|
+
from urllib.parse import urlparse as _urlparse
|
|
359
|
+
_host = (_urlparse(url).hostname or "").lower()
|
|
360
|
+
if _host == "sec.gov" or _host.endswith(".sec.gov"):
|
|
361
|
+
_contact = os.environ.get("ARIA_SEC_CONTACT", "").strip() or "research@aria-code.local"
|
|
362
|
+
_ua = f"aria-code research client ({_contact})"
|
|
363
|
+
else:
|
|
364
|
+
_ua = (
|
|
365
|
+
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
|
|
366
|
+
"AppleWebKit/537.36 (KHTML, like Gecko) "
|
|
367
|
+
"Chrome/124.0 Safari/537.36"
|
|
368
|
+
)
|
|
369
|
+
headers = {
|
|
370
|
+
"User-Agent": _ua,
|
|
371
|
+
"Accept": "text/html,application/xhtml+xml,text/plain;q=0.9,*/*;q=0.8",
|
|
372
|
+
}
|
|
373
|
+
_gh_m = re.match(
|
|
374
|
+
r"https://github\.com/([^/]+/[^/]+)/blob/([^?#]+)", url
|
|
375
|
+
)
|
|
376
|
+
if _gh_m:
|
|
377
|
+
url = f"https://raw.githubusercontent.com/{_gh_m.group(1)}/{_gh_m.group(2)}"
|
|
378
|
+
|
|
379
|
+
import requests as _req
|
|
380
|
+
s = _req.Session()
|
|
381
|
+
s.proxies = _prx
|
|
382
|
+
# Certificate verification ON by default — research data fetched over
|
|
383
|
+
# an unverified channel is tamperable. ARIA_WEB_FETCH_INSECURE=1 is
|
|
384
|
+
# the explicit escape hatch for TLS-intercepting corporate proxies.
|
|
385
|
+
s.verify = os.environ.get("ARIA_WEB_FETCH_INSECURE", "") != "1"
|
|
386
|
+
r = s.get(url, headers=headers, timeout=timeout)
|
|
387
|
+
r.raise_for_status()
|
|
388
|
+
raw = r.text
|
|
389
|
+
|
|
390
|
+
ct = r.headers.get("content-type", "")
|
|
391
|
+
if "json" in ct or raw.lstrip().startswith(("{", "[")):
|
|
392
|
+
return {"success": True, "data": {
|
|
393
|
+
"url": url, "content_type": ct,
|
|
394
|
+
"text": raw[:max_chars], "length": len(raw),
|
|
395
|
+
}}
|
|
396
|
+
|
|
397
|
+
text = re.sub(r"<script[^>]*>.*?</script>", " ", raw, flags=re.DOTALL | re.I)
|
|
398
|
+
text = re.sub(r"<style[^>]*>.*?</style>", " ", text, flags=re.DOTALL | re.I)
|
|
399
|
+
text = re.sub(r"<[^>]+>", " ", text)
|
|
400
|
+
text = re.sub(r" ", " ", text)
|
|
401
|
+
text = re.sub(r"&", "&", text)
|
|
402
|
+
text = re.sub(r"<", "<", text)
|
|
403
|
+
text = re.sub(r">", ">", text)
|
|
404
|
+
text = re.sub(r""", '"', text)
|
|
405
|
+
text = re.sub(r"\s{3,}", "\n", text)
|
|
406
|
+
text = text.strip()
|
|
407
|
+
|
|
408
|
+
return {"success": True, "data": {
|
|
409
|
+
"url": url, "content_type": ct,
|
|
410
|
+
"text": text[:max_chars], "length": len(text),
|
|
411
|
+
"truncated": len(text) > max_chars,
|
|
412
|
+
}}
|
|
413
|
+
except Exception as e:
|
|
414
|
+
return {"success": False, "error": f"web_fetch failed: {e}"}
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def tool_github(
|
|
418
|
+
params: dict,
|
|
419
|
+
*,
|
|
420
|
+
console=None,
|
|
421
|
+
has_rich: bool = True,
|
|
422
|
+
) -> dict:
|
|
423
|
+
"""GitHub API / gh CLI integration.
|
|
424
|
+
|
|
425
|
+
actions: list_prs, list_issues, view_pr, view_issue, create_pr,
|
|
426
|
+
list_commits, read_file, search, pr_diff, pr_checks
|
|
427
|
+
"""
|
|
428
|
+
action = params.get("action", "list_prs").lower().replace("-", "_")
|
|
429
|
+
cwd = params.get("cwd") or None
|
|
430
|
+
policy = "safe"
|
|
431
|
+
|
|
432
|
+
def _gh(cmd: str, timeout: int = 20) -> dict:
|
|
433
|
+
import shutil
|
|
434
|
+
if not shutil.which("gh"):
|
|
435
|
+
return {"success": False,
|
|
436
|
+
"error": "gh CLI not found. Install: brew install gh && gh auth login"}
|
|
437
|
+
return tool_run_command(
|
|
438
|
+
{"command": cmd, "cwd": cwd, "timeout": timeout, "policy": policy},
|
|
439
|
+
console=console,
|
|
440
|
+
has_rich=has_rich,
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
if action in ("list_prs", "prs", "pull_requests"):
|
|
444
|
+
state = params.get("state", "open")
|
|
445
|
+
limit = int(params.get("limit", 20))
|
|
446
|
+
return _gh(f"gh pr list --state {state} --limit {limit} "
|
|
447
|
+
"--json number,title,author,state,headRefName,url")
|
|
448
|
+
|
|
449
|
+
if action in ("list_issues", "issues"):
|
|
450
|
+
state = params.get("state", "open")
|
|
451
|
+
limit = int(params.get("limit", 20))
|
|
452
|
+
label = f' --label "{params["label"]}"' if params.get("label") else ""
|
|
453
|
+
return _gh(f"gh issue list --state {state} --limit {limit}{label} "
|
|
454
|
+
"--json number,title,author,state,labels,url")
|
|
455
|
+
|
|
456
|
+
if action in ("view_pr", "pr"):
|
|
457
|
+
number = params.get("number") or params.get("pr")
|
|
458
|
+
if not number:
|
|
459
|
+
return {"success": False, "error": "Missing 'number' parameter"}
|
|
460
|
+
return _gh(f"gh pr view {number} "
|
|
461
|
+
"--json number,title,body,state,headRefName,baseRefName,additions,deletions,files,url")
|
|
462
|
+
|
|
463
|
+
if action in ("view_issue", "issue"):
|
|
464
|
+
number = params.get("number") or params.get("issue")
|
|
465
|
+
if not number:
|
|
466
|
+
return {"success": False, "error": "Missing 'number' parameter"}
|
|
467
|
+
return _gh(f"gh issue view {number} "
|
|
468
|
+
"--json number,title,body,state,labels,comments,url")
|
|
469
|
+
|
|
470
|
+
if action == "create_pr":
|
|
471
|
+
title = params.get("title", "")
|
|
472
|
+
body = params.get("body", "")
|
|
473
|
+
branch = params.get("branch", "")
|
|
474
|
+
base = params.get("base", "main")
|
|
475
|
+
if not title:
|
|
476
|
+
return {"success": False, "error": "Missing 'title' for create_pr"}
|
|
477
|
+
b_flag = f"--head {shlex.quote(branch)}" if branch else ""
|
|
478
|
+
cmd = (
|
|
479
|
+
f"gh pr create --title {shlex.quote(title)} "
|
|
480
|
+
f"--body {shlex.quote(body)} "
|
|
481
|
+
f"--base {shlex.quote(base)} {b_flag}"
|
|
482
|
+
)
|
|
483
|
+
return _gh(cmd, timeout=30)
|
|
484
|
+
|
|
485
|
+
if action in ("list_commits", "commits", "log"):
|
|
486
|
+
limit = int(params.get("limit", 10))
|
|
487
|
+
return _gh(
|
|
488
|
+
f"gh api repos/{{owner}}/{{repo}}/commits?per_page={limit} "
|
|
489
|
+
"--jq '[.[] | {sha: .sha[:7], "
|
|
490
|
+
'message: .commit.message | split("\\n")[0], '
|
|
491
|
+
"author: .commit.author.name, date: .commit.author.date}]'"
|
|
492
|
+
)
|
|
493
|
+
|
|
494
|
+
if action == "search":
|
|
495
|
+
q = params.get("q") or params.get("query", "")
|
|
496
|
+
kind = params.get("kind", "code")
|
|
497
|
+
if not q:
|
|
498
|
+
return {"success": False, "error": "Missing 'q' parameter"}
|
|
499
|
+
return _gh(f"gh search {kind} {shlex.quote(q)} --limit 10 "
|
|
500
|
+
"--json url,path,textMatches", timeout=15)
|
|
501
|
+
|
|
502
|
+
if action in ("read_file", "file"):
|
|
503
|
+
ref = params.get("ref", "")
|
|
504
|
+
file_path = params.get("path", "")
|
|
505
|
+
if ref:
|
|
506
|
+
m = re.match(r"([^@:]+)@([^:]+):(.+)", ref)
|
|
507
|
+
if m:
|
|
508
|
+
repo, branch, fp = m.groups()
|
|
509
|
+
url = f"https://raw.githubusercontent.com/{repo}/{branch}/{fp}"
|
|
510
|
+
return tool_web_fetch({"url": url, "max_chars": 20000})
|
|
511
|
+
if file_path:
|
|
512
|
+
return _gh(f"gh api repos/{{owner}}/{{repo}}/contents/{file_path} "
|
|
513
|
+
"--jq '.content' | base64 -d")
|
|
514
|
+
return {"success": False, "error": "Provide 'ref' (owner/repo@branch:path) or 'path'"}
|
|
515
|
+
|
|
516
|
+
if action in ("pr_diff", "diff"):
|
|
517
|
+
number = params.get("number") or params.get("pr")
|
|
518
|
+
if not number:
|
|
519
|
+
return {"success": False, "error": "Missing 'number' parameter"}
|
|
520
|
+
return _gh(f"gh pr diff {number}", timeout=30)
|
|
521
|
+
|
|
522
|
+
if action in ("pr_checks", "checks", "ci"):
|
|
523
|
+
number = params.get("number") or params.get("pr")
|
|
524
|
+
return _gh(f"gh pr checks {number or ''}")
|
|
525
|
+
|
|
526
|
+
if action in ("git_status", "status"):
|
|
527
|
+
return tool_run_command(
|
|
528
|
+
{"command": "git status --short && echo '---' && git log --oneline -5",
|
|
529
|
+
"cwd": cwd, "policy": policy},
|
|
530
|
+
console=console, has_rich=has_rich,
|
|
531
|
+
)
|
|
532
|
+
|
|
533
|
+
if action in ("commit_and_push", "commit", "push"):
|
|
534
|
+
message = params.get("message", "")
|
|
535
|
+
branch = params.get("branch", "")
|
|
536
|
+
add_files = params.get("files", [])
|
|
537
|
+
repo = params.get("repo", "") # e.g. "artheras/aria-code"
|
|
538
|
+
coauthor = params.get("coauthor", "")
|
|
539
|
+
|
|
540
|
+
if not message:
|
|
541
|
+
return {"success": False, "error": "Missing 'message' for commit_and_push"}
|
|
542
|
+
|
|
543
|
+
# ── Aria Code[bot] identity via GitHub App ─────────────────────────────
|
|
544
|
+
try:
|
|
545
|
+
from aria_code.apps.cli.github_app_auth import (
|
|
546
|
+
get_installation_token, get_aria_git_url,
|
|
547
|
+
aria_bot_env, ARIA_BOT_NAME, ARIA_BOT_EMAIL,
|
|
548
|
+
)
|
|
549
|
+
owner = (repo.split("/")[0] if repo else None) or "artheras"
|
|
550
|
+
token = get_installation_token(owner)
|
|
551
|
+
bot_env = aria_bot_env()
|
|
552
|
+
auth_available = True
|
|
553
|
+
except Exception as _auth_err:
|
|
554
|
+
# Fall back to local git credentials if App not configured
|
|
555
|
+
token = None
|
|
556
|
+
bot_env = {
|
|
557
|
+
"GIT_AUTHOR_NAME": "Aria Code",
|
|
558
|
+
"GIT_AUTHOR_EMAIL": "aria-code[bot]@artherahq.com",
|
|
559
|
+
"GIT_COMMITTER_NAME": "Aria Code",
|
|
560
|
+
"GIT_COMMITTER_EMAIL": "aria-code[bot]@artherahq.com",
|
|
561
|
+
}
|
|
562
|
+
auth_available = False
|
|
563
|
+
ARIA_BOT_NAME = "Aria Code"
|
|
564
|
+
ARIA_BOT_EMAIL = "aria-code[bot]@artherahq.com"
|
|
565
|
+
|
|
566
|
+
env_prefix = " ".join(f'{k}="{v}"' for k, v in bot_env.items()) + " "
|
|
567
|
+
|
|
568
|
+
# ── Build commit message with co-author attribution ────────────────────
|
|
569
|
+
body = message
|
|
570
|
+
if coauthor:
|
|
571
|
+
body += f"\n\nCo-Authored-By: {coauthor}"
|
|
572
|
+
# Always credit the Aria GitHub account so it appears in Contributors
|
|
573
|
+
if auth_available:
|
|
574
|
+
try:
|
|
575
|
+
from aria_code.apps.cli.github_app_auth import ARIA_GITHUB_LOGIN, ARIA_GITHUB_EMAIL
|
|
576
|
+
body += f"\n\nCo-Authored-By: {ARIA_GITHUB_LOGIN} <{ARIA_GITHUB_EMAIL}>"
|
|
577
|
+
except ImportError:
|
|
578
|
+
pass
|
|
579
|
+
user_name = tool_run_command({"command": "git config user.name", "policy": "safe", "cwd": cwd}).get("output", "").strip()
|
|
580
|
+
user_email = tool_run_command({"command": "git config user.email", "policy": "safe", "cwd": cwd}).get("output", "").strip()
|
|
581
|
+
if user_name and user_email and user_email != ARIA_BOT_EMAIL:
|
|
582
|
+
body += f"\n\nCo-Authored-By: {user_name} <{user_email}>"
|
|
583
|
+
|
|
584
|
+
# ── Stage ──────────────────────────────────────────────────────────────
|
|
585
|
+
stage_cmd = ("git add " + " ".join(shlex.quote(f) for f in add_files)) if add_files else "git add -A"
|
|
586
|
+
stage_result = tool_run_command(
|
|
587
|
+
{"command": stage_cmd, "cwd": cwd, "policy": policy},
|
|
588
|
+
console=console, has_rich=has_rich,
|
|
589
|
+
)
|
|
590
|
+
if not stage_result.get("success"):
|
|
591
|
+
return stage_result
|
|
592
|
+
|
|
593
|
+
# ── Commit ─────────────────────────────────────────────────────────────
|
|
594
|
+
safe_body = body.replace('"', '\\"').replace('$', '\\$')
|
|
595
|
+
commit_result = tool_run_command(
|
|
596
|
+
{"command": f'{env_prefix}git commit -m "{safe_body}"',
|
|
597
|
+
"cwd": cwd, "policy": policy},
|
|
598
|
+
console=console, has_rich=has_rich,
|
|
599
|
+
)
|
|
600
|
+
if not commit_result.get("success"):
|
|
601
|
+
return commit_result
|
|
602
|
+
|
|
603
|
+
# ── Push (use App token remote if available) ───────────────────────────
|
|
604
|
+
push_branch = branch or tool_run_command(
|
|
605
|
+
{"command": "git rev-parse --abbrev-ref HEAD", "policy": "safe", "cwd": cwd}
|
|
606
|
+
).get("output", "").strip() or "main"
|
|
607
|
+
|
|
608
|
+
if auth_available and token and repo:
|
|
609
|
+
auth_url = get_aria_git_url(repo, token)
|
|
610
|
+
push_cmd = f"git push {shlex.quote(auth_url)} {shlex.quote(push_branch)}"
|
|
611
|
+
else:
|
|
612
|
+
push_cmd = f"git push origin {shlex.quote(push_branch)}"
|
|
613
|
+
|
|
614
|
+
push_result = tool_run_command(
|
|
615
|
+
{"command": push_cmd, "cwd": cwd, "policy": policy, "timeout": 60},
|
|
616
|
+
console=console, has_rich=has_rich,
|
|
617
|
+
)
|
|
618
|
+
return {
|
|
619
|
+
**push_result,
|
|
620
|
+
"committed_as": f"{ARIA_BOT_NAME} <{ARIA_BOT_EMAIL}>",
|
|
621
|
+
"branch": push_branch,
|
|
622
|
+
"app_auth": auth_available,
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
return {
|
|
626
|
+
"success": False,
|
|
627
|
+
"error": (
|
|
628
|
+
f"Unknown GitHub action: '{action}'. "
|
|
629
|
+
"Use: list_prs, list_issues, view_pr, view_issue, create_pr, "
|
|
630
|
+
"list_commits, search, read_file, pr_diff, pr_checks, "
|
|
631
|
+
"git_status, commit_and_push"
|
|
632
|
+
),
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
def tool_ask_user(params: dict, *, console=None, has_rich: bool = True) -> dict:
|
|
637
|
+
"""Pause execution and ask the user for clarification or a decision."""
|
|
638
|
+
question = params.get("question", "")
|
|
639
|
+
if not question:
|
|
640
|
+
return {"success": False, "error": "Missing 'question' parameter"}
|
|
641
|
+
|
|
642
|
+
if has_rich and console is not None:
|
|
643
|
+
from rich.prompt import Prompt
|
|
644
|
+
console.print(f"\n[bold magenta]🤔 Agent needs clarification:[/bold magenta] {question}")
|
|
645
|
+
try:
|
|
646
|
+
answer = Prompt.ask("[cyan]Your answer[/cyan]")
|
|
647
|
+
except (KeyboardInterrupt, EOFError):
|
|
648
|
+
return {"success": False, "error": "User cancelled the input."}
|
|
649
|
+
else:
|
|
650
|
+
print(f"\nAgent needs clarification: {question}")
|
|
651
|
+
try:
|
|
652
|
+
answer = input("Your answer: ")
|
|
653
|
+
except (KeyboardInterrupt, EOFError):
|
|
654
|
+
return {"success": False, "error": "User cancelled the input."}
|
|
655
|
+
|
|
656
|
+
return {"success": True, "data": {"user_answer": answer}}
|