aria-code 0.52.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.
- aria_code/__init__.py +42 -0
- aria_code/_version.py +20 -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 +34 -0
- aria_code/agents/base.py +318 -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 +303 -0
- aria_code/agents/financial/fundamental.py +191 -0
- aria_code/agents/financial/macro.py +99 -0
- aria_code/agents/financial/news.py +207 -0
- aria_code/agents/financial/risk.py +165 -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 +258 -0
- aria_code/agents/orchestrator.py +44 -0
- aria_code/agents/portfolio_agent.py +363 -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 +158 -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 +492 -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/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 +15 -0
- aria_code/apps/channels/__init__.py +17 -0
- aria_code/apps/channels/intake.py +92 -0
- aria_code/apps/channels/registry.py +95 -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/bootstrap.py +145 -0
- aria_code/apps/cli/broker_render.py +206 -0
- aria_code/apps/cli/codegen_paths.py +29 -0
- aria_code/apps/cli/commands/__init__.py +16 -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 +369 -0
- aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
- aria_code/apps/cli/commands/auth_cmds.py +239 -0
- aria_code/apps/cli/commands/backtest_cmds.py +2543 -0
- aria_code/apps/cli/commands/broker_cmds.py +1234 -0
- aria_code/apps/cli/commands/business_workflow_cmds.py +319 -0
- aria_code/apps/cli/commands/canvas_cmds.py +77 -0
- aria_code/apps/cli/commands/catalog.py +87 -0
- aria_code/apps/cli/commands/core_cmds.py +2520 -0
- aria_code/apps/cli/commands/data_cmds.py +457 -0
- aria_code/apps/cli/commands/diagnostic_cmds.py +230 -0
- aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -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 +434 -0
- aria_code/apps/cli/commands/market_cmds.py +1381 -0
- aria_code/apps/cli/commands/market_context.py +425 -0
- aria_code/apps/cli/commands/market_render.py +7 -0
- aria_code/apps/cli/commands/model_cmds.py +2153 -0
- aria_code/apps/cli/commands/ops_cmds.py +721 -0
- aria_code/apps/cli/commands/orchestrator_cmds.py +179 -0
- aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
- aria_code/apps/cli/commands/portfolio_cmds.py +1278 -0
- aria_code/apps/cli/commands/report.py +437 -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 +669 -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 +79 -0
- aria_code/apps/cli/commands/workflow_cmds.py +480 -0
- aria_code/apps/cli/commands/workspace_cmds.py +1494 -0
- aria_code/apps/cli/config_paths.py +73 -0
- aria_code/apps/cli/config_store.py +78 -0
- aria_code/apps/cli/constants.py +88 -0
- aria_code/apps/cli/context.py +34 -0
- aria_code/apps/cli/deterministic.py +191 -0
- aria_code/apps/cli/direct.py +48 -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 +196 -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 +1309 -0
- aria_code/apps/cli/handlers/market_handlers.py +2513 -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/helpers.py +302 -0
- aria_code/apps/cli/hooks.py +180 -0
- aria_code/apps/cli/i18n.py +297 -0
- aria_code/apps/cli/intent.py +136 -0
- aria_code/apps/cli/intent_router.py +276 -0
- aria_code/apps/cli/intent_signals.py +344 -0
- aria_code/apps/cli/lifecycle_hooks.py +48 -0
- aria_code/apps/cli/local_tool_schemas.py +536 -0
- aria_code/apps/cli/main.py +29 -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/model_catalog.py +620 -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 +59 -0
- aria_code/apps/cli/prompts/__init__.py +0 -0
- aria_code/apps/cli/prompts/coding.py +53 -0
- aria_code/apps/cli/prompts/select.py +142 -0
- aria_code/apps/cli/prompts/system_prompts.py +552 -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 +521 -0
- aria_code/apps/cli/providers/chat_routing.py +128 -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 +1594 -0
- aria_code/apps/cli/providers/llm/response_cache.py +60 -0
- aria_code/apps/cli/providers/llm/sse_stream.py +257 -0
- aria_code/apps/cli/providers/runtime_bridge.py +353 -0
- aria_code/apps/cli/providers/vertexai_stream.py +316 -0
- aria_code/apps/cli/runtime_consumer.py +657 -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_store.py +112 -0
- aria_code/apps/cli/skills_catalog.py +273 -0
- aria_code/apps/cli/todo_tracker.py +190 -0
- aria_code/apps/cli/tool_executor.py +823 -0
- aria_code/apps/cli/tool_registry.py +34 -0
- aria_code/apps/cli/tool_scope.py +106 -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 +180 -0
- aria_code/apps/cli/tools/market_tools.py +620 -0
- aria_code/apps/cli/tools/notebook_tools.py +111 -0
- aria_code/apps/cli/tools/system_tools.py +726 -0
- aria_code/apps/cli/tools/write_tools.py +845 -0
- aria_code/apps/cli/tradingview_bridge.py +529 -0
- aria_code/apps/cli/turn_planning.py +137 -0
- aria_code/apps/cli/update_check.py +153 -0
- aria_code/apps/cli/utils/__init__.py +0 -0
- aria_code/apps/cli/utils/market_detect.py +1597 -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 +6743 -0
- aria_code/aria_daemon.py +1398 -0
- aria_code/aria_feishu_bot.py +1423 -0
- aria_code/aria_mcp_server.py +7 -0
- aria_code/aria_relay_client.py +4 -0
- aria_code/aria_relay_server.py +490 -0
- aria_code/aria_telegram_bot.py +202 -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 +182 -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 +1976 -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 +181 -0
- aria_code/command_safety.py +19 -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/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/demo_player.py +207 -0
- aria_code/doctor.py +813 -0
- aria_code/domain/__init__.py +0 -0
- aria_code/domain/backtest_engine.py +354 -0
- aria_code/domain/backtest_report.py +472 -0
- aria_code/domain/finance_formulas.py +389 -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/harness.py +598 -0
- aria_code/evals/runner.py +238 -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 +386 -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 +639 -0
- aria_code/memory_manager.py +246 -0
- aria_code/model_capability.py +486 -0
- aria_code/notification_tools.py +4 -0
- aria_code/openai_image_client.py +4 -0
- aria_code/packages/__init__.py +23 -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 +52 -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 +201 -0
- aria_code/packages/aria_mcp/circuit.py +82 -0
- aria_code/packages/aria_mcp/config.py +111 -0
- aria_code/packages/aria_mcp/installer.py +95 -0
- aria_code/packages/aria_mcp/server.py +1550 -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 +396 -0
- aria_code/packages/aria_sdk/providers.py +70 -0
- aria_code/packages/aria_sdk/streaming.py +79 -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 +268 -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 +57 -0
- aria_code/packages/aria_services/research_quality.py +186 -0
- aria_code/packages/aria_services/settings.py +157 -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 +8 -0
- aria_code/packages/aria_tools/financial/_paths.py +130 -0
- aria_code/packages/aria_tools/financial/compliance.py +31 -0
- aria_code/packages/aria_tools/financial/factors.py +33 -0
- aria_code/packages/aria_tools/financial/risk_tools.py +33 -0
- aria_code/packages/aria_tools/financial/strategy.py +31 -0
- aria_code/packages/aria_tools/registry.py +128 -0
- aria_code/packages/quant_engine/__init__.py +34 -0
- aria_code/packages/quant_engine/_namespace.py +62 -0
- aria_code/packages/quant_engine/backtest/__init__.py +14 -0
- aria_code/packages/quant_engine/backtest/core.py +53 -0
- aria_code/packages/quant_engine/backtest/engine.py +96 -0
- aria_code/packages/quant_engine/portfolio/__init__.py +13 -0
- aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
- aria_code/packages/quant_engine/sports/__init__.py +80 -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/ml_model.py +377 -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 +35 -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/logistics/__init__.py +169 -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/llm/__init__.py +19 -0
- aria_code/providers/llm/anthropic.py +184 -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 +129 -0
- aria_code/providers/llm/openai_compat.py +313 -0
- aria_code/providers/llm/registry.py +444 -0
- aria_code/providers/local_image_provider.py +202 -0
- aria_code/providers/local_llm_provider.py +589 -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/runtime/__init__.py +169 -0
- aria_code/runtime/acceptance.py +481 -0
- aria_code/runtime/agent_loop.py +1520 -0
- aria_code/runtime/approval.py +57 -0
- aria_code/runtime/budget.py +232 -0
- aria_code/runtime/checkpoints.py +432 -0
- aria_code/runtime/crash_report.py +174 -0
- aria_code/runtime/events.py +113 -0
- aria_code/runtime/gateway.py +150 -0
- aria_code/runtime/lsp.py +484 -0
- aria_code/runtime/orchestrator.py +55 -0
- aria_code/runtime/repo_map.py +700 -0
- aria_code/runtime/run_state.py +127 -0
- aria_code/runtime/run_store.py +450 -0
- aria_code/runtime/self_healing.py +422 -0
- aria_code/runtime/subagent.py +547 -0
- aria_code/runtime/task_ledger.py +86 -0
- aria_code/runtime/task_orchestrator.py +90 -0
- aria_code/runtime/tool_executor.py +217 -0
- aria_code/runtime/tool_policy.py +107 -0
- aria_code/runtime/worktrees.py +215 -0
- aria_code/runway_video_client.py +4 -0
- aria_code/safety/__init__.py +23 -0
- aria_code/safety/permissions.py +306 -0
- aria_code/safety/service.py +102 -0
- aria_code/setup_wizard.py +673 -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 +504 -0
- aria_code/tools/data_analysis_tools.py +809 -0
- aria_code/tools/enterprise_finance_tools.py +156 -0
- aria_code/tools/extended_tools.py +240 -0
- aria_code/tools/file_analysis_tools.py +885 -0
- aria_code/tools/image_gen_tools.py +114 -0
- aria_code/tools/local_finance_tools.py +3417 -0
- aria_code/tools/logistics_tools.py +135 -0
- aria_code/tools/macro_tools.py +369 -0
- aria_code/tools/notification_tools.py +249 -0
- aria_code/tools/project_tools.py +525 -0
- aria_code/tools/realty_data_tools.py +659 -0
- aria_code/tools/spreadsheet_tools.py +388 -0
- aria_code/tools/stripe_tools.py +115 -0
- aria_code/ui/__init__.py +105 -0
- aria_code/ui/banner.py +508 -0
- aria_code/ui/completer.py +501 -0
- aria_code/ui/console.py +281 -0
- aria_code/ui/image_render.py +243 -0
- aria_code/ui/input_box.py +488 -0
- aria_code/ui/picker.py +201 -0
- aria_code/ui/render/__init__.py +11 -0
- aria_code/ui/render/finance.py +1705 -0
- aria_code/ui/render/market.py +225 -0
- aria_code/ui/render/output.py +775 -0
- aria_code/ui/render/responsive.py +75 -0
- aria_code/ui/render/team.py +354 -0
- aria_code/ui/robot.py +235 -0
- aria_code/ui/startup_dashboard.py +109 -0
- aria_code/utils/vscode_uri.py +37 -0
- aria_code/video_analysis.py +147 -0
- aria_code/video_editor.py +271 -0
- aria_code/workspace/__init__.py +6 -0
- aria_code/workspace/files.py +193 -0
- aria_code/workspace/verify.py +113 -0
- aria_code/workspace_changes.py +199 -0
- aria_code/workspace_context.py +233 -0
- aria_code/workspace_service.py +196 -0
- aria_code/workspace_tools.py +150 -0
- aria_code-0.52.0.dist-info/METADATA +237 -0
- aria_code-0.52.0.dist-info/RECORD +478 -0
- aria_code-0.52.0.dist-info/WHEEL +5 -0
- aria_code-0.52.0.dist-info/entry_points.txt +3 -0
- aria_code-0.52.0.dist-info/licenses/LICENSE +201 -0
- aria_code-0.52.0.dist-info/licenses/NOTICE +49 -0
- aria_code-0.52.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Channel Apps
|
|
2
|
+
|
|
3
|
+
Target role: adapters for non-terminal entrypoints.
|
|
4
|
+
|
|
5
|
+
Examples:
|
|
6
|
+
|
|
7
|
+
- relay server/client;
|
|
8
|
+
- Feishu bot;
|
|
9
|
+
- Telegram bot;
|
|
10
|
+
- webhooks;
|
|
11
|
+
- future desktop or browser UI.
|
|
12
|
+
|
|
13
|
+
Each channel should translate inbound messages into gateway requests and render
|
|
14
|
+
gateway responses back to the channel. It should not bypass safety, runtime, or
|
|
15
|
+
artifact policies.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Aria channels — external entrypoints as structured-task producers."""
|
|
2
|
+
|
|
3
|
+
from .registry import (
|
|
4
|
+
CHANNEL_TASK_SCHEMA,
|
|
5
|
+
ChannelSpec,
|
|
6
|
+
channel_map,
|
|
7
|
+
default_channels,
|
|
8
|
+
enabled_channels,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"CHANNEL_TASK_SCHEMA",
|
|
13
|
+
"ChannelSpec",
|
|
14
|
+
"channel_map",
|
|
15
|
+
"default_channels",
|
|
16
|
+
"enabled_channels",
|
|
17
|
+
]
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""Channel intake policy + gateway submission (the daemon-facing half).
|
|
2
|
+
|
|
3
|
+
Completes the channels contract loop: the daemon's webhook endpoint hands
|
|
4
|
+
verified channel tasks to ``runtime.run_turn`` instead of poking CLI
|
|
5
|
+
internals, and refuses unauthenticated ("open mode") intake from anywhere
|
|
6
|
+
but localhost.
|
|
7
|
+
|
|
8
|
+
Two pieces, both dependency-light so the daemon can import them without
|
|
9
|
+
dragging in aria_cli:
|
|
10
|
+
|
|
11
|
+
• should_refuse_open_intake() — pure policy: when neither an intake token
|
|
12
|
+
nor ARIA_WEBHOOK_SECRET is configured, only loopback clients may submit.
|
|
13
|
+
• analyze_alert_via_gateway() — submits a task prompt through the shared
|
|
14
|
+
runtime gateway with an EMPTY tool set: channel-triggered turns get
|
|
15
|
+
model analysis but can never execute tools from the daemon context.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
from typing import Any, Callable, Dict, Optional
|
|
21
|
+
|
|
22
|
+
_LOOPBACK_HOSTS = {"127.0.0.1", "::1", "localhost"}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def should_refuse_open_intake(
|
|
26
|
+
client_host: Optional[str],
|
|
27
|
+
*,
|
|
28
|
+
token_configured: bool,
|
|
29
|
+
secret_configured: bool,
|
|
30
|
+
) -> bool:
|
|
31
|
+
"""True when an unauthenticated intake must be rejected.
|
|
32
|
+
|
|
33
|
+
With any credential configured (endpoint token or webhook passphrase),
|
|
34
|
+
authentication handles trust and remote clients are fine. With neither
|
|
35
|
+
configured the endpoint is running "open", which is only acceptable from
|
|
36
|
+
the loopback interface — an open endpoint reachable off-host would let
|
|
37
|
+
anyone on the network inject buy/sell alerts.
|
|
38
|
+
"""
|
|
39
|
+
if token_configured or secret_configured:
|
|
40
|
+
return False
|
|
41
|
+
host = str(client_host or "").strip().lower()
|
|
42
|
+
if host.startswith("[") and host.endswith("]"): # bracketed IPv6
|
|
43
|
+
host = host[1:-1]
|
|
44
|
+
return host not in _LOOPBACK_HOSTS
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
async def analyze_alert_via_gateway(
|
|
48
|
+
prompt: str,
|
|
49
|
+
config: Dict[str, Any],
|
|
50
|
+
*,
|
|
51
|
+
run_turn_fn: Optional[Callable] = None,
|
|
52
|
+
max_rounds: int = 4,
|
|
53
|
+
) -> str:
|
|
54
|
+
"""Run one tool-less analysis turn for a channel task; returns the text.
|
|
55
|
+
|
|
56
|
+
``run_turn_fn`` is injectable for tests; the default builds the same
|
|
57
|
+
provider selection the CLI uses (chat_routing via runtime_bridge) and
|
|
58
|
+
drives ``runtime.gateway.run_turn``. Raises on failure — the caller
|
|
59
|
+
decides its own fallback (the daemon keeps its legacy quick summary).
|
|
60
|
+
"""
|
|
61
|
+
if run_turn_fn is None:
|
|
62
|
+
# stream_ollama borrows 47 bare names from aria_cli's module globals
|
|
63
|
+
# (verified by AST audit) and only works after aria_cli's import-time
|
|
64
|
+
# rebinding. Until that module is untangled, any out-of-CLI consumer
|
|
65
|
+
# of the default Ollama path must import aria_cli first — a one-time
|
|
66
|
+
# ~1s cost the long-lived daemon amortizes.
|
|
67
|
+
import aria_cli # noqa: F401 (side effect: binds stream_ollama globals)
|
|
68
|
+
from apps.cli.providers.runtime_bridge import build_tool_executor, make_provider_fn
|
|
69
|
+
from runtime.gateway import run_turn as run_turn_fn_impl
|
|
70
|
+
|
|
71
|
+
provider_fn = make_provider_fn(
|
|
72
|
+
model=str(config.get("model", "qwen2.5:7b")),
|
|
73
|
+
config=config,
|
|
74
|
+
api_url=config.get("api_url"),
|
|
75
|
+
ollama_url=str(config.get("ollama_url", "http://localhost:11434")),
|
|
76
|
+
tool_schemas=[],
|
|
77
|
+
)
|
|
78
|
+
executor = build_tool_executor({}, config)
|
|
79
|
+
|
|
80
|
+
async def run_turn_fn(prompt_, history_, **kw):
|
|
81
|
+
return await run_turn_fn_impl(
|
|
82
|
+
prompt_, history_,
|
|
83
|
+
provider_fn=provider_fn, tool_executor=executor,
|
|
84
|
+
tool_schemas=[], max_rounds=max_rounds,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
result = await run_turn_fn(prompt, [])
|
|
88
|
+
text = (getattr(result, "text", "") or "").strip()
|
|
89
|
+
error = getattr(result, "error", None)
|
|
90
|
+
if error or not text:
|
|
91
|
+
raise RuntimeError(f"gateway turn failed: {error or 'empty response'}")
|
|
92
|
+
return text
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""Channel registry — the declared inventory of external entrypoints.
|
|
2
|
+
|
|
3
|
+
First slice of the channels layer (contract: "Channels submit structured
|
|
4
|
+
tasks to gateway/runtime and never call CLI internals directly"). The
|
|
5
|
+
registry is pure data + config resolution: it names each channel, its
|
|
6
|
+
direction, the config/env that enables it, and which capability it maps to,
|
|
7
|
+
so the daemon and doctor can reason about channels uniformly instead of each
|
|
8
|
+
integration hard-coding its own discovery.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from dataclasses import dataclass, field
|
|
14
|
+
from typing import Any, Dict, List, Mapping, Tuple
|
|
15
|
+
|
|
16
|
+
CHANNEL_TASK_SCHEMA = "aria.channel_task.v1"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass(frozen=True)
|
|
20
|
+
class ChannelSpec:
|
|
21
|
+
name: str
|
|
22
|
+
direction: str # "inbound" | "outbound" | "both"
|
|
23
|
+
description: str
|
|
24
|
+
capabilities: Tuple[str, ...] = ()
|
|
25
|
+
# Any of these config keys (or env vars) being truthy enables the channel.
|
|
26
|
+
config_keys: Tuple[str, ...] = ()
|
|
27
|
+
env_keys: Tuple[str, ...] = ()
|
|
28
|
+
|
|
29
|
+
def enabled(self, config: Mapping[str, Any], env: Mapping[str, str]) -> bool:
|
|
30
|
+
for key in self.config_keys:
|
|
31
|
+
if config.get(key):
|
|
32
|
+
return True
|
|
33
|
+
for key in self.env_keys:
|
|
34
|
+
if str(env.get(key, "") or "").strip():
|
|
35
|
+
return True
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def default_channels() -> List[ChannelSpec]:
|
|
40
|
+
return [
|
|
41
|
+
ChannelSpec(
|
|
42
|
+
name="tradingview",
|
|
43
|
+
direction="inbound",
|
|
44
|
+
description="TradingView alert webhooks → structured alert tasks",
|
|
45
|
+
capabilities=("alerts.ingest", "orders.preview"),
|
|
46
|
+
config_keys=("tradingview_webhook",),
|
|
47
|
+
env_keys=("ARIA_WEBHOOK_SECRET",),
|
|
48
|
+
),
|
|
49
|
+
ChannelSpec(
|
|
50
|
+
name="webhook_jobs",
|
|
51
|
+
direction="inbound",
|
|
52
|
+
description="Generic daemon webhook job queue (/webhook/trigger)",
|
|
53
|
+
capabilities=("tasks.enqueue",),
|
|
54
|
+
env_keys=("WEBHOOK_TOKEN",),
|
|
55
|
+
),
|
|
56
|
+
ChannelSpec(
|
|
57
|
+
name="telegram",
|
|
58
|
+
direction="both",
|
|
59
|
+
description="Telegram bot push + command intake via the daemon",
|
|
60
|
+
capabilities=("notify.push", "chat.intake"),
|
|
61
|
+
config_keys=("telegram_bot_token",),
|
|
62
|
+
env_keys=("TELEGRAM_BOT_TOKEN",),
|
|
63
|
+
),
|
|
64
|
+
ChannelSpec(
|
|
65
|
+
name="feishu",
|
|
66
|
+
direction="outbound",
|
|
67
|
+
description="Feishu webhook card push",
|
|
68
|
+
capabilities=("notify.push",),
|
|
69
|
+
config_keys=("feishu_webhook",),
|
|
70
|
+
env_keys=("FEISHU_WEBHOOK_URL",),
|
|
71
|
+
),
|
|
72
|
+
ChannelSpec(
|
|
73
|
+
name="macos_notify",
|
|
74
|
+
direction="outbound",
|
|
75
|
+
description="Local macOS notification center",
|
|
76
|
+
capabilities=("notify.push",),
|
|
77
|
+
config_keys=("macos_notifications",),
|
|
78
|
+
),
|
|
79
|
+
ChannelSpec(
|
|
80
|
+
name="email",
|
|
81
|
+
direction="outbound",
|
|
82
|
+
description="SMTP email push",
|
|
83
|
+
capabilities=("notify.push",),
|
|
84
|
+
config_keys=("email_smtp_host",),
|
|
85
|
+
env_keys=("ARIA_SMTP_HOST",),
|
|
86
|
+
),
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def channel_map() -> Dict[str, ChannelSpec]:
|
|
91
|
+
return {spec.name: spec for spec in default_channels()}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def enabled_channels(config: Mapping[str, Any], env: Mapping[str, str]) -> List[ChannelSpec]:
|
|
95
|
+
return [spec for spec in default_channels() if spec.enabled(config, env)]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""TradingView alert → structured channel task (aria.channel_task.v1).
|
|
2
|
+
|
|
3
|
+
The channels contract requires external entrypoints to submit *structured
|
|
4
|
+
tasks* to the gateway instead of poking CLI internals. This adapter turns a
|
|
5
|
+
raw TradingView webhook payload into that task shape, reusing the hardened
|
|
6
|
+
primitives that already live in apps/cli/tradingview_bridge.py (field-tolerant
|
|
7
|
+
parsing, passphrase + HMAC verification, dedup keys).
|
|
8
|
+
|
|
9
|
+
Verification posture mirrors the bridge's documented semantics: with
|
|
10
|
+
ARIA_WEBHOOK_SECRET unset verification is open (localhost-only assumption),
|
|
11
|
+
but the task carries explicit ``verified`` / ``open_mode`` flags so a
|
|
12
|
+
downstream gate (daemon, SafetyService) can refuse open-mode tasks in
|
|
13
|
+
non-local deployments.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import time
|
|
19
|
+
from typing import Any, Callable, Dict, Optional
|
|
20
|
+
|
|
21
|
+
from aria_code.apps.cli.tradingview_bridge import (
|
|
22
|
+
_alert_dedup_key as alert_dedup_key,
|
|
23
|
+
_expected_webhook_secret,
|
|
24
|
+
parse_tradingview_alert,
|
|
25
|
+
verify_webhook_hmac,
|
|
26
|
+
verify_webhook_secret,
|
|
27
|
+
)
|
|
28
|
+
from aria_code.apps.channels.registry import CHANNEL_TASK_SCHEMA
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def alert_to_task(
|
|
32
|
+
payload: Dict[str, Any] | str,
|
|
33
|
+
*,
|
|
34
|
+
raw_body: Optional[bytes | str] = None,
|
|
35
|
+
signature: Optional[str] = None,
|
|
36
|
+
clock: Callable[[], float] = time.time,
|
|
37
|
+
) -> Dict[str, Any]:
|
|
38
|
+
"""Normalize + authenticate one webhook delivery.
|
|
39
|
+
|
|
40
|
+
Returns ``{"success": True, "task": {...}}`` or
|
|
41
|
+
``{"success": False, "error": ...}`` (tool-result convention).
|
|
42
|
+
"""
|
|
43
|
+
alert = parse_tradingview_alert(payload)
|
|
44
|
+
raw = alert.get("raw") or {}
|
|
45
|
+
|
|
46
|
+
secret_configured = bool(_expected_webhook_secret())
|
|
47
|
+
if signature is not None:
|
|
48
|
+
# A fronting signer supplied an HMAC — it must verify (never open).
|
|
49
|
+
if not verify_webhook_hmac(raw_body if raw_body is not None else "", signature):
|
|
50
|
+
return {"success": False, "error": "tradingview alert rejected: HMAC signature mismatch"}
|
|
51
|
+
verified = True
|
|
52
|
+
else:
|
|
53
|
+
if not verify_webhook_secret(raw):
|
|
54
|
+
return {"success": False, "error": "tradingview alert rejected: passphrase missing or wrong"}
|
|
55
|
+
verified = secret_configured # open mode when no secret is configured
|
|
56
|
+
|
|
57
|
+
if not alert.get("symbol"):
|
|
58
|
+
return {"success": False, "error": "tradingview alert rejected: no symbol in payload"}
|
|
59
|
+
|
|
60
|
+
task = {
|
|
61
|
+
"schema": CHANNEL_TASK_SCHEMA,
|
|
62
|
+
"channel": "tradingview",
|
|
63
|
+
"kind": "alert",
|
|
64
|
+
"received_at": clock(),
|
|
65
|
+
"verified": verified,
|
|
66
|
+
"open_mode": not secret_configured and signature is None,
|
|
67
|
+
"dedup_key": alert_dedup_key(alert),
|
|
68
|
+
"symbol": alert["symbol"],
|
|
69
|
+
"action": alert["action"],
|
|
70
|
+
"price": alert.get("price"),
|
|
71
|
+
"time": alert.get("time"),
|
|
72
|
+
"message": alert.get("message") or "",
|
|
73
|
+
"prompt": task_prompt(alert),
|
|
74
|
+
}
|
|
75
|
+
return {"success": True, "task": task}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def task_prompt(alert: Dict[str, Any]) -> str:
|
|
79
|
+
"""Render the gateway-facing natural-language task for this alert.
|
|
80
|
+
|
|
81
|
+
The daemon submits this prompt to runtime's ``run_turn`` — the agent then
|
|
82
|
+
analyses the alert with its normal tools; nothing here places orders.
|
|
83
|
+
"""
|
|
84
|
+
symbol = alert.get("symbol", "")
|
|
85
|
+
action = alert.get("action", "ALERT")
|
|
86
|
+
price = alert.get("price")
|
|
87
|
+
at = f" at {price}" if price not in (None, "") else ""
|
|
88
|
+
msg = str(alert.get("message") or "").strip()
|
|
89
|
+
tail = f' Alert message: "{msg}".' if msg else ""
|
|
90
|
+
return (
|
|
91
|
+
f"TradingView alert received: {action} signal for {symbol}{at}.{tail} "
|
|
92
|
+
f"Assess the signal against current market data and the portfolio, and "
|
|
93
|
+
f"summarize whether it warrants action. Do not place any orders."
|
|
94
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# CLI App
|
|
2
|
+
|
|
3
|
+
Target role: terminal UI and command parsing only.
|
|
4
|
+
|
|
5
|
+
The CLI should depend on these services:
|
|
6
|
+
|
|
7
|
+
- `gateway`: session routing and task orchestration.
|
|
8
|
+
- `runtime`: agent loop and tool execution.
|
|
9
|
+
- `ui`: terminal rendering and input.
|
|
10
|
+
- `reports`: local artifact and report output.
|
|
11
|
+
|
|
12
|
+
Migration rule: new slash commands should call package services instead of
|
|
13
|
+
adding more business logic to `aria_cli.py`.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""Guarded imports for optional dependencies.
|
|
2
|
+
|
|
3
|
+
These try/except blocks sat in aria_cli.py, so five command mixins reached into
|
|
4
|
+
a 7000-line module to ask "is the market-data client available?". Nothing about
|
|
5
|
+
that question is session state — it is a fact about the install.
|
|
6
|
+
|
|
7
|
+
Import form matters here and is not incidental. market_data_client keeps a
|
|
8
|
+
module-level singleton, and the package is reachable under two roots whose
|
|
9
|
+
module objects are distinct — so importing it as aria_code.clients.
|
|
10
|
+
market_data_client would build a *second* MarketDataClient with its own
|
|
11
|
+
connections and caches. Every caller in the tree currently uses the bare
|
|
12
|
+
`market_data_client` shim, so there is one client today; this module uses the
|
|
13
|
+
same form deliberately to keep it that way. Converging the two roots is a
|
|
14
|
+
separate, repo-wide job (26 root modules use the same sys.modules shim trick).
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"MarketDataClient", "get_mdc", "HAS_MDC",
|
|
21
|
+
"HAS_BROKERS", "get_registry", "list_broker_configs", "get_broker_config",
|
|
22
|
+
"add_broker_config", "remove_broker_config", "set_default_broker",
|
|
23
|
+
"validate_broker_config", "supported_broker_types", "get_config_template",
|
|
24
|
+
"BROKERS_CONFIG_PATH",
|
|
25
|
+
"HAS_MODEL_CAP", "get_model_capability",
|
|
26
|
+
"HAS_MCP", "MCPToolRegistry", "MCP_CONFIG_PATH", "init_mcp",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
from market_data_client import MarketDataClient, get_mdc # noqa: F401
|
|
31
|
+
|
|
32
|
+
HAS_MDC = True
|
|
33
|
+
except ImportError: # pragma: no cover - exercised only without the client installed
|
|
34
|
+
MarketDataClient = None # type: ignore[assignment]
|
|
35
|
+
get_mdc = None # type: ignore[assignment]
|
|
36
|
+
HAS_MDC = False
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# ── Brokers ──────────────────────────────────────────────────────────────────
|
|
40
|
+
# Same reasoning as above, and the stakes are higher: brokers.registry keeps a
|
|
41
|
+
# module-level BrokerRegistry singleton holding *live broker connections*, and
|
|
42
|
+
# `brokers` / `aria_code.brokers` are distinct module objects with separate
|
|
43
|
+
# singletons. Connecting through one and querying the other would report "not
|
|
44
|
+
# connected" for a session that is. All 37 call sites in the tree use the bare
|
|
45
|
+
# form, so there is one registry today; this module uses the same form to keep
|
|
46
|
+
# it that way.
|
|
47
|
+
try:
|
|
48
|
+
from brokers import ( # noqa: F401
|
|
49
|
+
BROKERS_CONFIG_PATH,
|
|
50
|
+
add_broker_config,
|
|
51
|
+
get_broker_config,
|
|
52
|
+
get_config_template,
|
|
53
|
+
get_registry,
|
|
54
|
+
list_broker_configs,
|
|
55
|
+
remove_broker_config,
|
|
56
|
+
set_default_broker,
|
|
57
|
+
supported_broker_types,
|
|
58
|
+
validate_broker_config,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
HAS_BROKERS = True
|
|
62
|
+
except ImportError: # pragma: no cover - exercised only without the broker stack
|
|
63
|
+
HAS_BROKERS = False
|
|
64
|
+
BROKERS_CONFIG_PATH = None # type: ignore[assignment]
|
|
65
|
+
|
|
66
|
+
# aria_cli's version of this block only supplied three of the ten fallbacks,
|
|
67
|
+
# so a build without the broker stack would raise NameError rather than
|
|
68
|
+
# degrade — on add/remove/validate/template, i.e. exactly the paths a user
|
|
69
|
+
# hits while trying to set a broker up. All ten are covered here.
|
|
70
|
+
def get_registry(): # type: ignore[misc]
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
def list_broker_configs(): # type: ignore[misc]
|
|
74
|
+
return []
|
|
75
|
+
|
|
76
|
+
def get_broker_config(broker_id: str): # type: ignore[misc]
|
|
77
|
+
return None
|
|
78
|
+
|
|
79
|
+
def add_broker_config(cfg): # type: ignore[misc]
|
|
80
|
+
raise RuntimeError("Broker support is not installed")
|
|
81
|
+
|
|
82
|
+
def remove_broker_config(broker_id: str): # type: ignore[misc]
|
|
83
|
+
raise RuntimeError("Broker support is not installed")
|
|
84
|
+
|
|
85
|
+
def set_default_broker(broker_id: str): # type: ignore[misc]
|
|
86
|
+
raise RuntimeError("Broker support is not installed")
|
|
87
|
+
|
|
88
|
+
def validate_broker_config(cfg): # type: ignore[misc]
|
|
89
|
+
return ["Broker support is not installed"]
|
|
90
|
+
|
|
91
|
+
def supported_broker_types(): # type: ignore[misc]
|
|
92
|
+
return []
|
|
93
|
+
|
|
94
|
+
def get_config_template(broker_type: str): # type: ignore[misc]
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# ── Model capability registry ────────────────────────────────────────────────
|
|
99
|
+
# Another guarded import that happened to live in aria_cli. Used by the model
|
|
100
|
+
# and UI commands to describe a community Ollama model that is not in the
|
|
101
|
+
# MODELS table.
|
|
102
|
+
try:
|
|
103
|
+
from model_capability import get_model_capability # noqa: F401
|
|
104
|
+
|
|
105
|
+
HAS_MODEL_CAP = True
|
|
106
|
+
except ImportError: # pragma: no cover - exercised only without model_capability
|
|
107
|
+
get_model_capability = None # type: ignore[assignment]
|
|
108
|
+
HAS_MODEL_CAP = False
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# ── MCP ──────────────────────────────────────────────────────────────────────
|
|
112
|
+
try:
|
|
113
|
+
from mcp_client import MCP_CONFIG_PATH, MCPToolRegistry, init_mcp # noqa: F401
|
|
114
|
+
|
|
115
|
+
HAS_MCP = True
|
|
116
|
+
except ImportError: # pragma: no cover - exercised only without mcp_client
|
|
117
|
+
MCPToolRegistry = None # type: ignore[assignment]
|
|
118
|
+
MCP_CONFIG_PATH = None # type: ignore[assignment]
|
|
119
|
+
init_mcp = None # type: ignore[assignment]
|
|
120
|
+
HAS_MCP = False
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""CLI bootstrap utilities shared by legacy and packaged entrypoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import socket
|
|
7
|
+
import urllib.parse
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from aria_code.apps.cli.config_paths import resolve_paths
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def load_aria_env(env_file: Path | None = None) -> None:
|
|
14
|
+
"""Load persisted CLI environment values without overriding the process."""
|
|
15
|
+
target = env_file or (Path.home() / ".aria" / ".env")
|
|
16
|
+
if not target.exists():
|
|
17
|
+
return
|
|
18
|
+
try:
|
|
19
|
+
for line in target.read_text(encoding="utf-8").splitlines():
|
|
20
|
+
line = line.strip()
|
|
21
|
+
if not line or line.startswith("#") or "=" not in line:
|
|
22
|
+
continue
|
|
23
|
+
key, _, value = line.partition("=")
|
|
24
|
+
key = key.strip()
|
|
25
|
+
value = value.strip()
|
|
26
|
+
if key and value:
|
|
27
|
+
os.environ.setdefault(key, value)
|
|
28
|
+
except Exception:
|
|
29
|
+
return
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def disable_broken_proxy(timeout: float = 1.5) -> None:
|
|
33
|
+
"""Unset proxy variables when the configured proxy cannot be reached."""
|
|
34
|
+
proxy = (
|
|
35
|
+
os.environ.get("HTTPS_PROXY")
|
|
36
|
+
or os.environ.get("https_proxy")
|
|
37
|
+
or os.environ.get("HTTP_PROXY")
|
|
38
|
+
or os.environ.get("http_proxy")
|
|
39
|
+
)
|
|
40
|
+
if not proxy:
|
|
41
|
+
return
|
|
42
|
+
try:
|
|
43
|
+
parsed = urllib.parse.urlparse(proxy if "://" in proxy else f"http://{proxy}")
|
|
44
|
+
host = parsed.hostname
|
|
45
|
+
port = parsed.port or 80
|
|
46
|
+
if not host:
|
|
47
|
+
return
|
|
48
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
49
|
+
sock.settimeout(timeout)
|
|
50
|
+
alive = sock.connect_ex((host, port)) == 0
|
|
51
|
+
sock.close()
|
|
52
|
+
except Exception:
|
|
53
|
+
alive = False
|
|
54
|
+
if not alive:
|
|
55
|
+
for name in ("HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy", "ALL_PROXY", "all_proxy"):
|
|
56
|
+
os.environ.pop(name, None)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def use_system_trust_store() -> bool:
|
|
60
|
+
"""Verify TLS against the OS trust store instead of certifi's bundle.
|
|
61
|
+
|
|
62
|
+
Corporate and local TLS-intercepting proxies present their own CA. That CA
|
|
63
|
+
is installed in the system keychain — which is why ``curl`` works on such a
|
|
64
|
+
machine — but Python verifies against certifi, which has never heard of it,
|
|
65
|
+
so every HTTPS call fails with CERTIFICATE_VERIFY_FAILED.
|
|
66
|
+
|
|
67
|
+
This was not hypothetical: on a machine behind an intercepting proxy,
|
|
68
|
+
``oauth2.googleapis.com`` failed 5 times out of 5 from Python and returned
|
|
69
|
+
404 from curl, so roughly a third of Vertex turns died fetching an OAuth
|
|
70
|
+
token. Trusting the OS store fixed it without disabling verification —
|
|
71
|
+
which is the tempting wrong fix, and would accept any certificate at all.
|
|
72
|
+
|
|
73
|
+
Returns whether the injection happened, and never raises: an environment
|
|
74
|
+
without ``truststore`` keeps certifi's behaviour exactly as before.
|
|
75
|
+
"""
|
|
76
|
+
try:
|
|
77
|
+
import truststore
|
|
78
|
+
|
|
79
|
+
truststore.inject_into_ssl()
|
|
80
|
+
return True
|
|
81
|
+
except Exception:
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def initialize_cli_environment() -> None:
|
|
86
|
+
os.environ.setdefault("TQDM_DISABLE", "1")
|
|
87
|
+
load_aria_env()
|
|
88
|
+
disable_broken_proxy()
|
|
89
|
+
use_system_trust_store()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# The model used when nothing has been configured yet.
|
|
93
|
+
#
|
|
94
|
+
# This exists so there is ONE place that answers "which model by default".
|
|
95
|
+
# Call sites used to spell their own fallback — `config.get("model",
|
|
96
|
+
# "qwen2.5:7b")`, ten times over — which quietly made Ollama the answer
|
|
97
|
+
# whenever a config key was missing, no matter what the user had chosen.
|
|
98
|
+
# Provider configuration is the user's to make (that is what `/model` and
|
|
99
|
+
# `.ariarc` are for); the code's job is to have a sane default and then get
|
|
100
|
+
# out of the way.
|
|
101
|
+
DEFAULT_MODEL = os.getenv("ARIA_DEFAULT_MODEL", "google/gemini-2.5-pro")
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def default_config() -> dict:
|
|
105
|
+
return {
|
|
106
|
+
"api_url": os.getenv(
|
|
107
|
+
"ARTHERA_API_URL",
|
|
108
|
+
"http://localhost:8000",
|
|
109
|
+
),
|
|
110
|
+
"local_url": "http://localhost:8000",
|
|
111
|
+
"ollama_url": os.getenv("OLLAMA_URL", "http://localhost:11434"),
|
|
112
|
+
# Which backend serves a bare, unprefixed model name. Only consulted
|
|
113
|
+
# for names that do not name their own provider ("qwen2.5:7b"); a
|
|
114
|
+
# prefixed id like "google/gemini-2.5-pro" always wins.
|
|
115
|
+
"local_provider": os.getenv("ARIA_LLM_PROVIDER", "ollama"),
|
|
116
|
+
"provider_fallback": "configured",
|
|
117
|
+
"model": DEFAULT_MODEL,
|
|
118
|
+
"thinking_mode": "auto",
|
|
119
|
+
"watchlist": ["AAPL", "MSFT", "GOOGL", "TSLA", "NVDA"],
|
|
120
|
+
"auth_token": None,
|
|
121
|
+
"user_id": None,
|
|
122
|
+
"last_session_id": None,
|
|
123
|
+
"auto_save_sessions": True,
|
|
124
|
+
"auto_compact_context": True,
|
|
125
|
+
"auto_compact_threshold": 0.78,
|
|
126
|
+
"command_policy": "safe",
|
|
127
|
+
"permission_mode": "workspace-write",
|
|
128
|
+
"network_enabled": True,
|
|
129
|
+
"data_sharing": False,
|
|
130
|
+
"feedback_upload": False,
|
|
131
|
+
"write_policy": "desktop_only",
|
|
132
|
+
"lsp_autocheck": False,
|
|
133
|
+
"input_style": "panel",
|
|
134
|
+
"input_theme": "auto",
|
|
135
|
+
"response_footer": "compact",
|
|
136
|
+
"report_agent_timeout": 40.0,
|
|
137
|
+
"report_synthesis_timeout": 20.0,
|
|
138
|
+
"local_mode": False,
|
|
139
|
+
"conversation_history": [],
|
|
140
|
+
"ui_lang": "",
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def runtime_paths():
|
|
145
|
+
return resolve_paths()
|