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,249 @@
|
|
|
1
|
+
"""Product-level service contracts for Aria Code.
|
|
2
|
+
|
|
3
|
+
These manifests describe stable service boundaries. They intentionally wrap the
|
|
4
|
+
current modules instead of moving code all at once, so the CLI can migrate away
|
|
5
|
+
from the large legacy entrypoint incrementally.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from typing import Dict, List
|
|
12
|
+
|
|
13
|
+
from aria_code.packages.aria_core import CapabilityManifest, PackageLink, PermissionLevel, ServiceKind
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class ServiceSpec:
|
|
18
|
+
name: str
|
|
19
|
+
description: str
|
|
20
|
+
owner_package: str
|
|
21
|
+
module: str
|
|
22
|
+
capabilities: List[str] = field(default_factory=list)
|
|
23
|
+
permissions: List[PermissionLevel] = field(default_factory=list)
|
|
24
|
+
required: bool = True
|
|
25
|
+
migration_target: str = ""
|
|
26
|
+
|
|
27
|
+
def manifest(self) -> CapabilityManifest:
|
|
28
|
+
tags = ["service"]
|
|
29
|
+
if self.required:
|
|
30
|
+
tags.append("required")
|
|
31
|
+
return CapabilityManifest(
|
|
32
|
+
name=self.name,
|
|
33
|
+
kind=ServiceKind.DATA if self.name == "data" else ServiceKind.SERVICE,
|
|
34
|
+
description=self.description,
|
|
35
|
+
capabilities=self.capabilities,
|
|
36
|
+
permissions=self.permissions,
|
|
37
|
+
package_link=PackageLink(
|
|
38
|
+
package=self.owner_package,
|
|
39
|
+
module=self.module,
|
|
40
|
+
object_name=self.migration_target,
|
|
41
|
+
notes="Facade over existing modules; migrate implementation behind this boundary.",
|
|
42
|
+
),
|
|
43
|
+
tags=tags,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def list_service_specs() -> List[ServiceSpec]:
|
|
48
|
+
"""Return stable service boundaries for the Aria Code product."""
|
|
49
|
+
|
|
50
|
+
return [
|
|
51
|
+
ServiceSpec(
|
|
52
|
+
name="gateway",
|
|
53
|
+
description="Local-first control plane for CLI, daemon, MCP, and channel entrypoints.",
|
|
54
|
+
owner_package="packages.aria_services",
|
|
55
|
+
module="apps.gateway",
|
|
56
|
+
capabilities=["session.routing", "task.queue", "mcp.routing", "channel.routing"],
|
|
57
|
+
permissions=[PermissionLevel.READ_ONLY, PermissionLevel.WORKSPACE_WRITE],
|
|
58
|
+
migration_target="GatewayService",
|
|
59
|
+
),
|
|
60
|
+
ServiceSpec(
|
|
61
|
+
name="runtime",
|
|
62
|
+
description="Agent turn loop, tool execution, approvals, traces, and parallel tool orchestration.",
|
|
63
|
+
owner_package="runtime",
|
|
64
|
+
module="runtime",
|
|
65
|
+
capabilities=["agent.loop", "tool.execution", "approval.policy", "trace"],
|
|
66
|
+
permissions=[PermissionLevel.READ_ONLY, PermissionLevel.WORKSPACE_WRITE],
|
|
67
|
+
migration_target="AgentRuntime",
|
|
68
|
+
),
|
|
69
|
+
ServiceSpec(
|
|
70
|
+
name="settings",
|
|
71
|
+
description="Configuration, secrets, model profiles, runtime flags, and permission policy resolution.",
|
|
72
|
+
owner_package="packages.aria_services",
|
|
73
|
+
module="packages.aria_services.settings",
|
|
74
|
+
capabilities=[
|
|
75
|
+
"settings.config",
|
|
76
|
+
"settings.secrets",
|
|
77
|
+
"settings.model_profiles",
|
|
78
|
+
"settings.permission_policy",
|
|
79
|
+
],
|
|
80
|
+
permissions=[PermissionLevel.READ_ONLY],
|
|
81
|
+
migration_target="SettingsService",
|
|
82
|
+
),
|
|
83
|
+
ServiceSpec(
|
|
84
|
+
name="context",
|
|
85
|
+
description="Conversation memory, context pressure checks, compaction, and resumable summary envelopes.",
|
|
86
|
+
owner_package="packages.aria_services",
|
|
87
|
+
module="packages.aria_services.context",
|
|
88
|
+
capabilities=[
|
|
89
|
+
"context.memory",
|
|
90
|
+
"context.compaction",
|
|
91
|
+
"context.resume",
|
|
92
|
+
"context.checkpoint",
|
|
93
|
+
],
|
|
94
|
+
permissions=[PermissionLevel.READ_ONLY, PermissionLevel.WORKSPACE_WRITE],
|
|
95
|
+
migration_target="ContextService",
|
|
96
|
+
),
|
|
97
|
+
ServiceSpec(
|
|
98
|
+
name="references",
|
|
99
|
+
description="Typed read-only @ references for files, folders, assets, and research artifacts.",
|
|
100
|
+
owner_package="packages.aria_services",
|
|
101
|
+
module="packages.aria_services.references",
|
|
102
|
+
capabilities=[
|
|
103
|
+
"context.reference.parse",
|
|
104
|
+
"context.reference.resolve",
|
|
105
|
+
"context.reference.tool_plan",
|
|
106
|
+
"context.reference.complete",
|
|
107
|
+
],
|
|
108
|
+
permissions=[PermissionLevel.READ_ONLY],
|
|
109
|
+
migration_target="ReferenceService",
|
|
110
|
+
),
|
|
111
|
+
ServiceSpec(
|
|
112
|
+
name="tools",
|
|
113
|
+
description="Typed tool manifests, schemas, permissions, local tool adapters, and MCP tool conversion.",
|
|
114
|
+
owner_package="packages.aria_tools",
|
|
115
|
+
module="packages.aria_tools",
|
|
116
|
+
capabilities=[
|
|
117
|
+
"tool.registry",
|
|
118
|
+
"tool.schema",
|
|
119
|
+
"tool.permissions",
|
|
120
|
+
"tool.local_adapter",
|
|
121
|
+
"tool.mcp_adapter",
|
|
122
|
+
],
|
|
123
|
+
permissions=[PermissionLevel.READ_ONLY, PermissionLevel.WORKSPACE_WRITE, PermissionLevel.NETWORK],
|
|
124
|
+
migration_target="ToolRegistry",
|
|
125
|
+
),
|
|
126
|
+
ServiceSpec(
|
|
127
|
+
name="data",
|
|
128
|
+
description="Multi-source market data with timestamps, provider attribution, and stale-data flags.",
|
|
129
|
+
owner_package="packages.aria_services",
|
|
130
|
+
module="data_service",
|
|
131
|
+
capabilities=["market.quote", "market.history", "technical.indicators", "data.quality"],
|
|
132
|
+
permissions=[PermissionLevel.NETWORK],
|
|
133
|
+
migration_target="MarketDataService",
|
|
134
|
+
),
|
|
135
|
+
ServiceSpec(
|
|
136
|
+
name="reports",
|
|
137
|
+
description="Report, chart, and artifact generation with local workspace storage policies.",
|
|
138
|
+
owner_package="packages.aria_services",
|
|
139
|
+
module="report_generator",
|
|
140
|
+
capabilities=[
|
|
141
|
+
"report.markdown",
|
|
142
|
+
"report.html",
|
|
143
|
+
"chart.render",
|
|
144
|
+
"artifact.storage",
|
|
145
|
+
],
|
|
146
|
+
permissions=[PermissionLevel.READ_ONLY, PermissionLevel.WORKSPACE_WRITE],
|
|
147
|
+
migration_target="ReportService",
|
|
148
|
+
),
|
|
149
|
+
ServiceSpec(
|
|
150
|
+
name="research_quality",
|
|
151
|
+
description="Deterministic report completion, plausibility, coverage, and provenance gates.",
|
|
152
|
+
owner_package="packages.aria_services",
|
|
153
|
+
module="packages.aria_services.research_quality",
|
|
154
|
+
capabilities=["report.quality_gate", "report.provenance", "report.plausibility"],
|
|
155
|
+
permissions=[PermissionLevel.READ_ONLY],
|
|
156
|
+
migration_target="ReportQualityAssessment",
|
|
157
|
+
),
|
|
158
|
+
ServiceSpec(
|
|
159
|
+
name="brokers",
|
|
160
|
+
description="Broker account reads, paper trading, order previews, guarded execution, and audit trails.",
|
|
161
|
+
owner_package="brokers",
|
|
162
|
+
module="brokers",
|
|
163
|
+
capabilities=[
|
|
164
|
+
"broker.account",
|
|
165
|
+
"broker.positions",
|
|
166
|
+
"broker.orders",
|
|
167
|
+
"broker.paper",
|
|
168
|
+
"broker.trade_preview",
|
|
169
|
+
"broker.confirmed_execution",
|
|
170
|
+
"broker.audit",
|
|
171
|
+
],
|
|
172
|
+
permissions=[PermissionLevel.BROKER_READ, PermissionLevel.BROKER_TRADE],
|
|
173
|
+
migration_target="BrokerService",
|
|
174
|
+
),
|
|
175
|
+
ServiceSpec(
|
|
176
|
+
name="skills",
|
|
177
|
+
description="Workflow recipes that bind tools, agents, data, reports, and brokers.",
|
|
178
|
+
owner_package="packages.aria_skills",
|
|
179
|
+
module="packages.aria_skills",
|
|
180
|
+
capabilities=[
|
|
181
|
+
"skill.registry",
|
|
182
|
+
"skill.discovery",
|
|
183
|
+
"skill.metadata_route",
|
|
184
|
+
"skill.namespace",
|
|
185
|
+
"skill.integrity",
|
|
186
|
+
"skill.activation_trace",
|
|
187
|
+
"workflow.binding",
|
|
188
|
+
],
|
|
189
|
+
permissions=[PermissionLevel.READ_ONLY],
|
|
190
|
+
migration_target="SkillRegistry",
|
|
191
|
+
),
|
|
192
|
+
ServiceSpec(
|
|
193
|
+
name="mcp",
|
|
194
|
+
description="MCP server discovery, health, tool provenance, reconnect policy, and manifest conversion.",
|
|
195
|
+
owner_package="packages.aria_mcp",
|
|
196
|
+
module="packages.aria_mcp",
|
|
197
|
+
capabilities=[
|
|
198
|
+
"mcp.discovery",
|
|
199
|
+
"mcp.health",
|
|
200
|
+
"mcp.tool_manifests",
|
|
201
|
+
"mcp.reconnect",
|
|
202
|
+
"mcp.provenance",
|
|
203
|
+
],
|
|
204
|
+
permissions=[PermissionLevel.READ_ONLY, PermissionLevel.NETWORK],
|
|
205
|
+
migration_target="MCPService",
|
|
206
|
+
),
|
|
207
|
+
ServiceSpec(
|
|
208
|
+
name="channels",
|
|
209
|
+
description="Optional external entrypoints such as daemon, relay, Feishu, Telegram, and webhooks.",
|
|
210
|
+
owner_package="apps.channels",
|
|
211
|
+
module="apps.channels",
|
|
212
|
+
capabilities=["channel.daemon", "channel.relay", "channel.feishu", "channel.telegram"],
|
|
213
|
+
permissions=[PermissionLevel.NETWORK],
|
|
214
|
+
required=False,
|
|
215
|
+
migration_target="ChannelRegistry",
|
|
216
|
+
),
|
|
217
|
+
ServiceSpec(
|
|
218
|
+
name="safety",
|
|
219
|
+
description="Sandbox, workspace permissions, command policy, privacy controls, and audit hooks.",
|
|
220
|
+
owner_package="safety",
|
|
221
|
+
module="safety",
|
|
222
|
+
capabilities=["sandbox", "command.policy", "privacy", "audit"],
|
|
223
|
+
permissions=[PermissionLevel.READ_ONLY],
|
|
224
|
+
migration_target="SafetyService",
|
|
225
|
+
),
|
|
226
|
+
ServiceSpec(
|
|
227
|
+
name="observability",
|
|
228
|
+
description="Doctor checks, runtime traces, provider health, architecture coverage, and support bundles.",
|
|
229
|
+
owner_package="packages.aria_infra",
|
|
230
|
+
module="packages.aria_infra.doctor",
|
|
231
|
+
capabilities=[
|
|
232
|
+
"doctor.checks",
|
|
233
|
+
"trace.export",
|
|
234
|
+
"provider.health",
|
|
235
|
+
"architecture.coverage",
|
|
236
|
+
"support.bundle",
|
|
237
|
+
],
|
|
238
|
+
permissions=[PermissionLevel.READ_ONLY, PermissionLevel.WORKSPACE_WRITE],
|
|
239
|
+
migration_target="ObservabilityService",
|
|
240
|
+
),
|
|
241
|
+
]
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def service_map() -> Dict[str, ServiceSpec]:
|
|
245
|
+
return {service.name: service for service in list_service_specs()}
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def required_service_names() -> List[str]:
|
|
249
|
+
return [service.name for service in list_service_specs() if service.required]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Financial-research grounding policy shared by Aria adapters."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from collections.abc import Iterable, Mapping
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
_MARKET_IDENTIFIER = re.compile(
|
|
10
|
+
r"\b[A-Z]{1,5}(?:\.[A-Z]{1,4})?\b|\b\d{6}(?:\.(?:SH|SZ|SS|HK))?\b"
|
|
11
|
+
)
|
|
12
|
+
_FINANCIAL_SUBJECTS = (
|
|
13
|
+
"stock", "share", "equity", "market", "portfolio", "holding", "fund",
|
|
14
|
+
"option", "bond", "forex", "crypto", "price", "volume", "valuation",
|
|
15
|
+
"股票", "股价", "行情", "市场", "持仓", "组合", "基金", "期权", "债券",
|
|
16
|
+
"外汇", "加密", "成交量", "估值", "市值", "财报", "基本面",
|
|
17
|
+
)
|
|
18
|
+
_EVIDENCE_INTENTS = (
|
|
19
|
+
"analyze", "analysis", "forecast", "predict", "recommend", "buy", "sell",
|
|
20
|
+
"current", "latest", "today", "trend", "risk", "target", "outlook",
|
|
21
|
+
"分析", "预测", "推荐", "买入", "卖出", "最新", "当前", "今天", "走势",
|
|
22
|
+
"趋势", "风险", "目标价", "前景", "成交量", "全面分析",
|
|
23
|
+
)
|
|
24
|
+
_GROUNDING_TOOL_FRAGMENTS = (
|
|
25
|
+
"market", "quote", "price", "ohlcv", "fundamental", "filing", "news",
|
|
26
|
+
"factor", "risk", "backtest", "portfolio", "prediction", "signal",
|
|
27
|
+
"regime", "financial", "earnings", "valuation", "macro", "flow",
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def requires_financial_evidence(query: str) -> bool:
|
|
32
|
+
"""Return whether a request needs current external financial evidence."""
|
|
33
|
+
text = str(query or "").strip()
|
|
34
|
+
if not text:
|
|
35
|
+
return False
|
|
36
|
+
lowered = text.lower()
|
|
37
|
+
has_subject = bool(_MARKET_IDENTIFIER.search(text)) or any(
|
|
38
|
+
term in lowered for term in _FINANCIAL_SUBJECTS
|
|
39
|
+
)
|
|
40
|
+
return has_subject and any(term in lowered for term in _EVIDENCE_INTENTS)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def grounding_tool_names(tool_schemas: Iterable[Mapping]) -> frozenset[str]:
|
|
44
|
+
"""Select registered tools whose outputs can ground a financial conclusion."""
|
|
45
|
+
names: set[str] = set()
|
|
46
|
+
for schema in tool_schemas:
|
|
47
|
+
function = schema.get("function") if isinstance(schema, Mapping) else None
|
|
48
|
+
name = str(
|
|
49
|
+
(function or {}).get("name")
|
|
50
|
+
if isinstance(function, Mapping)
|
|
51
|
+
else schema.get("name", "")
|
|
52
|
+
)
|
|
53
|
+
canonical = name.rsplit("__", 1)[-1].lower()
|
|
54
|
+
if name and any(fragment in canonical for fragment in _GROUNDING_TOOL_FRAGMENTS):
|
|
55
|
+
names.add(name)
|
|
56
|
+
return frozenset(names)
|
|
57
|
+
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"""Deterministic completion gates for multi-agent research reports."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import asdict, dataclass, field
|
|
6
|
+
from datetime import datetime, timezone
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from typing import Any, Iterable
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ReportQualityDecision(str, Enum):
|
|
12
|
+
COMPLETE = "complete"
|
|
13
|
+
PARTIAL = "partial"
|
|
14
|
+
BLOCKED = "blocked"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _utc_timestamp() -> str:
|
|
18
|
+
return datetime.now(timezone.utc).isoformat(timespec="seconds")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(frozen=True)
|
|
22
|
+
class ReportQualityPolicy:
|
|
23
|
+
min_agent_coverage: float = 0.60
|
|
24
|
+
min_core_coverage: float = 2 / 3
|
|
25
|
+
core_agents: tuple[str, ...] = ("technical", "fundamental", "risk")
|
|
26
|
+
max_degraded_ratio: float = 0.50
|
|
27
|
+
require_quote: bool = True
|
|
28
|
+
allow_stale: bool = False
|
|
29
|
+
max_market_cap: float = 100_000_000_000_000.0
|
|
30
|
+
max_implied_shares: float = 100_000_000_000.0
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass(frozen=True)
|
|
34
|
+
class ReportQualityAssessment:
|
|
35
|
+
decision: ReportQualityDecision
|
|
36
|
+
requested_agents: tuple[str, ...]
|
|
37
|
+
usable_agents: tuple[str, ...]
|
|
38
|
+
degraded_agents: tuple[str, ...]
|
|
39
|
+
failed_agents: tuple[str, ...]
|
|
40
|
+
agent_coverage: float
|
|
41
|
+
core_coverage: float
|
|
42
|
+
reasons: tuple[str, ...] = field(default_factory=tuple)
|
|
43
|
+
warnings: tuple[str, ...] = field(default_factory=tuple)
|
|
44
|
+
blocking_reasons: tuple[str, ...] = field(default_factory=tuple)
|
|
45
|
+
assessed_at: str = field(default_factory=_utc_timestamp)
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def metadata_status(self) -> str:
|
|
49
|
+
if self.decision is ReportQualityDecision.BLOCKED:
|
|
50
|
+
return "data_unavailable"
|
|
51
|
+
return self.decision.value
|
|
52
|
+
|
|
53
|
+
def to_dict(self) -> dict[str, Any]:
|
|
54
|
+
data = asdict(self)
|
|
55
|
+
data["decision"] = self.decision.value
|
|
56
|
+
data["metadata_status"] = self.metadata_status
|
|
57
|
+
data["core_agent_coverage"] = data["core_coverage"]
|
|
58
|
+
data["_contract_type"] = "ResearchQualityAssessment"
|
|
59
|
+
data["_contract_version"] = "1.0.0"
|
|
60
|
+
return data
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _as_float(value: Any) -> float | None:
|
|
64
|
+
try:
|
|
65
|
+
if value in (None, ""):
|
|
66
|
+
return None
|
|
67
|
+
return float(value)
|
|
68
|
+
except (TypeError, ValueError):
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _unique(values: Iterable[str]) -> tuple[str, ...]:
|
|
73
|
+
return tuple(dict.fromkeys(value for value in values if value))
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def assess_team_report(
|
|
77
|
+
team_result: Any,
|
|
78
|
+
data_bundle: Any = None,
|
|
79
|
+
policy: ReportQualityPolicy | None = None,
|
|
80
|
+
) -> ReportQualityAssessment:
|
|
81
|
+
"""Assess whether a report is complete, usable with caveats, or blocked."""
|
|
82
|
+
policy = policy or ReportQualityPolicy()
|
|
83
|
+
requested = _unique(
|
|
84
|
+
str(name)
|
|
85
|
+
for name in (getattr(team_result, "agents_run", None) or [])
|
|
86
|
+
if name not in {"synthesis", "debate"}
|
|
87
|
+
)
|
|
88
|
+
results = list(getattr(team_result, "results", None) or [])
|
|
89
|
+
if not requested:
|
|
90
|
+
requested = _unique(
|
|
91
|
+
str(getattr(result, "agent", ""))
|
|
92
|
+
for result in results
|
|
93
|
+
if getattr(result, "agent", "") not in {"synthesis", "debate"}
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
result_by_agent = {
|
|
97
|
+
str(getattr(result, "agent", "")): result
|
|
98
|
+
for result in results
|
|
99
|
+
if getattr(result, "agent", "")
|
|
100
|
+
}
|
|
101
|
+
usable = _unique(
|
|
102
|
+
name
|
|
103
|
+
for name in requested
|
|
104
|
+
if name in result_by_agent
|
|
105
|
+
and bool(getattr(result_by_agent[name], "success", False))
|
|
106
|
+
and bool(str(getattr(result_by_agent[name], "analysis", "") or "").strip())
|
|
107
|
+
)
|
|
108
|
+
degraded = _unique(
|
|
109
|
+
name for name in usable if bool(getattr(result_by_agent[name], "degraded", False))
|
|
110
|
+
)
|
|
111
|
+
failed = _unique(name for name in requested if name not in usable)
|
|
112
|
+
coverage = len(usable) / len(requested) if requested else 0.0
|
|
113
|
+
expected_core = tuple(name for name in policy.core_agents if name in requested)
|
|
114
|
+
core_coverage = (
|
|
115
|
+
sum(1 for name in expected_core if name in usable) / len(expected_core)
|
|
116
|
+
if expected_core else 1.0
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
warnings: list[str] = []
|
|
120
|
+
blocking: list[str] = []
|
|
121
|
+
reasons: list[str] = []
|
|
122
|
+
|
|
123
|
+
quote = dict(getattr(data_bundle, "quote", {}) or {}) if data_bundle else {}
|
|
124
|
+
price = _as_float(quote.get("price") or quote.get("current_price"))
|
|
125
|
+
volume = _as_float(quote.get("volume"))
|
|
126
|
+
market_cap = _as_float(quote.get("market_cap") or quote.get("marketCap"))
|
|
127
|
+
data_status = str(getattr(data_bundle, "status", "") or "").lower() if data_bundle else ""
|
|
128
|
+
stale = bool((getattr(data_bundle, "quality", {}) or {}).get("stale", False)) if data_bundle else False
|
|
129
|
+
|
|
130
|
+
if policy.require_quote and (price is None or price <= 0):
|
|
131
|
+
blocking.append("missing or invalid reference price")
|
|
132
|
+
if volume is not None and volume < 0:
|
|
133
|
+
blocking.append("negative volume")
|
|
134
|
+
if market_cap is not None:
|
|
135
|
+
if market_cap <= 0:
|
|
136
|
+
warnings.append("invalid market capitalization")
|
|
137
|
+
elif market_cap > policy.max_market_cap:
|
|
138
|
+
warnings.append("market capitalization exceeds plausibility limit")
|
|
139
|
+
if price and price > 0 and market_cap / price > policy.max_implied_shares:
|
|
140
|
+
warnings.append("implied share count exceeds plausibility limit")
|
|
141
|
+
|
|
142
|
+
if data_status in {"data_unavailable", "unavailable", "failed"}:
|
|
143
|
+
blocking.append("market data bundle unavailable")
|
|
144
|
+
elif data_status in {"partial", "stale"}:
|
|
145
|
+
warnings.append(f"market data status is {data_status}")
|
|
146
|
+
if stale and not policy.allow_stale:
|
|
147
|
+
warnings.append("market data is stale")
|
|
148
|
+
if not usable:
|
|
149
|
+
blocking.append("no agent produced usable analysis")
|
|
150
|
+
if coverage < policy.min_agent_coverage:
|
|
151
|
+
warnings.append(
|
|
152
|
+
f"agent coverage {coverage:.0%} is below {policy.min_agent_coverage:.0%}"
|
|
153
|
+
)
|
|
154
|
+
if core_coverage < policy.min_core_coverage:
|
|
155
|
+
warnings.append(
|
|
156
|
+
f"core-agent coverage {core_coverage:.0%} is below {policy.min_core_coverage:.0%}"
|
|
157
|
+
)
|
|
158
|
+
degraded_ratio = len(degraded) / len(usable) if usable else 0.0
|
|
159
|
+
if degraded_ratio > policy.max_degraded_ratio:
|
|
160
|
+
warnings.append(f"degraded-agent ratio {degraded_ratio:.0%} is too high")
|
|
161
|
+
|
|
162
|
+
if blocking:
|
|
163
|
+
decision = ReportQualityDecision.BLOCKED
|
|
164
|
+
elif warnings:
|
|
165
|
+
decision = ReportQualityDecision.PARTIAL
|
|
166
|
+
else:
|
|
167
|
+
decision = ReportQualityDecision.COMPLETE
|
|
168
|
+
|
|
169
|
+
reasons.append(f"usable agents: {len(usable)}/{len(requested)}")
|
|
170
|
+
if degraded:
|
|
171
|
+
reasons.append(f"degraded agents: {', '.join(degraded)}")
|
|
172
|
+
if failed:
|
|
173
|
+
reasons.append(f"failed agents: {', '.join(failed)}")
|
|
174
|
+
|
|
175
|
+
return ReportQualityAssessment(
|
|
176
|
+
decision=decision,
|
|
177
|
+
requested_agents=requested,
|
|
178
|
+
usable_agents=usable,
|
|
179
|
+
degraded_agents=degraded,
|
|
180
|
+
failed_agents=failed,
|
|
181
|
+
agent_coverage=round(coverage, 4),
|
|
182
|
+
core_coverage=round(core_coverage, 4),
|
|
183
|
+
reasons=_unique(reasons),
|
|
184
|
+
warnings=_unique(warnings),
|
|
185
|
+
blocking_reasons=_unique(blocking),
|
|
186
|
+
)
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""SettingsService — single owner of persistent Aria configuration.
|
|
2
|
+
|
|
3
|
+
This is the concrete implementation behind the ``settings`` ServiceSpec in
|
|
4
|
+
``packages.aria_services.registry`` (capability ``settings.config``). It owns
|
|
5
|
+
the merge/normalize/persist mechanics that previously lived in
|
|
6
|
+
``apps/cli/config_store.py``; that module is now a thin CLI adapter which
|
|
7
|
+
constructs this service with CLI-specific hooks.
|
|
8
|
+
|
|
9
|
+
Layering: this package must stay importable by launcher, daemon, brokers and
|
|
10
|
+
MCP without dragging in the CLI. Anything CLI-flavored (provider-name
|
|
11
|
+
normalization, i18n language detection, model auto-selection, policy sync) is
|
|
12
|
+
injected as an optional callable rather than imported from ``apps.cli``.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import json
|
|
18
|
+
from collections.abc import Callable
|
|
19
|
+
from dataclasses import dataclass, field
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from typing import Any, Optional
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Models that no longer exist / were renamed; a saved config pointing at one
|
|
25
|
+
# is silently reset to the caller's default so the CLI never boots into a
|
|
26
|
+
# permanently-broken model selection.
|
|
27
|
+
STALE_ARIA_MODEL_PREFIXES = ("aria-opus", "aria-prelude", "aria-sonata:3", "aria-sonata:4")
|
|
28
|
+
|
|
29
|
+
# Keys that are session state, not configuration — never persisted.
|
|
30
|
+
NEVER_PERSIST = frozenset({"conversation_history"})
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class SettingsService:
|
|
35
|
+
"""Load, normalize, persist, and hand out the Aria config dict.
|
|
36
|
+
|
|
37
|
+
``config_dir``/``config_file``/``sessions_dir`` duck-type
|
|
38
|
+
``apps.cli.config_paths.AriaConfigPaths`` so the CLI can pass its existing
|
|
39
|
+
paths object fields straight through.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
config_dir: Path
|
|
43
|
+
config_file: Path
|
|
44
|
+
sessions_dir: Path
|
|
45
|
+
defaults: dict = field(default_factory=dict)
|
|
46
|
+
# Optional environment hooks (all safe to omit):
|
|
47
|
+
normalize_provider: Optional[Callable[[str], str]] = None
|
|
48
|
+
detect_lang: Optional[Callable[[], str]] = None
|
|
49
|
+
# There was an auto_select_model hook here. It probed Ollama on first run
|
|
50
|
+
# and replaced the caller's default model with whatever was installed; see
|
|
51
|
+
# load(). Removed rather than left unwired, so it is not reconnected by
|
|
52
|
+
# someone who finds an unused hook and assumes it should be doing something.
|
|
53
|
+
on_loaded: Optional[Callable[[dict], None]] = None # e.g. CLI policy sync
|
|
54
|
+
stale_model_prefixes: tuple = STALE_ARIA_MODEL_PREFIXES
|
|
55
|
+
|
|
56
|
+
_snapshot: Optional[dict] = field(default=None, repr=False)
|
|
57
|
+
|
|
58
|
+
# ── core API ─────────────────────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
def load(self) -> dict:
|
|
61
|
+
"""Read config file, merge over defaults, normalize, fire on_loaded."""
|
|
62
|
+
self.config_dir.mkdir(parents=True, exist_ok=True)
|
|
63
|
+
self.sessions_dir.mkdir(parents=True, exist_ok=True)
|
|
64
|
+
if self.config_file.exists():
|
|
65
|
+
try:
|
|
66
|
+
saved = json.loads(self.config_file.read_text(encoding="utf-8"))
|
|
67
|
+
merged = {**self.defaults, **saved}
|
|
68
|
+
self._infer_local_provider(merged, saved)
|
|
69
|
+
self._reset_stale_model(merged)
|
|
70
|
+
self._ensure_ui_lang(merged)
|
|
71
|
+
self._finish_load(merged)
|
|
72
|
+
return merged
|
|
73
|
+
except Exception:
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
# First run: the defaults stand as written. This used to probe Ollama
|
|
77
|
+
# here and overwrite cfg["model"] with whatever was installed, which
|
|
78
|
+
# contradicted the comment above DEFAULT_MODEL in apps/cli/bootstrap.py
|
|
79
|
+
# -- "provider configuration is the user's to make ... the code's job is
|
|
80
|
+
# to have a sane default and then get out of the way". It also cost a
|
|
81
|
+
# 3s HTTP timeout on every first start, and it was not needed for
|
|
82
|
+
# discoverability: the banner already reports "Ollama online · N models"
|
|
83
|
+
# (ui/banner.ollama_status_label), so a user with local models can see
|
|
84
|
+
# them and run /model.
|
|
85
|
+
cfg = dict(self.defaults)
|
|
86
|
+
try:
|
|
87
|
+
if self.detect_lang is not None:
|
|
88
|
+
cfg["ui_lang"] = self.detect_lang()
|
|
89
|
+
except Exception:
|
|
90
|
+
cfg["ui_lang"] = "en"
|
|
91
|
+
cfg.setdefault("ui_lang", "en")
|
|
92
|
+
self._finish_load(cfg)
|
|
93
|
+
return cfg
|
|
94
|
+
|
|
95
|
+
def save(self, cfg: dict) -> None:
|
|
96
|
+
self.config_dir.mkdir(parents=True, exist_ok=True)
|
|
97
|
+
payload = {k: v for k, v in cfg.items() if k not in NEVER_PERSIST}
|
|
98
|
+
# config.json holds auth_token / refresh_token from /login, so it is
|
|
99
|
+
# written owner-only like the other credential files.
|
|
100
|
+
from aria_code.packages.aria_core.secure_file import write_secret_json
|
|
101
|
+
|
|
102
|
+
write_secret_json(self.config_file, payload)
|
|
103
|
+
self._snapshot = dict(cfg)
|
|
104
|
+
|
|
105
|
+
def get(self, key: str, default: Any = None) -> Any:
|
|
106
|
+
"""Read one key from the last-loaded snapshot (loads on first use)."""
|
|
107
|
+
if self._snapshot is None:
|
|
108
|
+
self.load()
|
|
109
|
+
return self._snapshot.get(key, default)
|
|
110
|
+
|
|
111
|
+
def set(self, key: str, value: Any) -> dict:
|
|
112
|
+
"""Update one key and persist immediately; returns the new snapshot."""
|
|
113
|
+
if self._snapshot is None:
|
|
114
|
+
self.load()
|
|
115
|
+
cfg = dict(self._snapshot)
|
|
116
|
+
cfg[key] = value
|
|
117
|
+
self.save(cfg)
|
|
118
|
+
return cfg
|
|
119
|
+
|
|
120
|
+
def snapshot(self) -> dict:
|
|
121
|
+
"""The last-loaded/saved config dict (loads on first use)."""
|
|
122
|
+
if self._snapshot is None:
|
|
123
|
+
self.load()
|
|
124
|
+
return dict(self._snapshot)
|
|
125
|
+
|
|
126
|
+
# ── normalization steps (extracted verbatim from the CLI loader) ─────────
|
|
127
|
+
|
|
128
|
+
def _infer_local_provider(self, merged: dict, saved: dict) -> None:
|
|
129
|
+
saved_model = merged.get("model", "")
|
|
130
|
+
if "local_provider" not in saved:
|
|
131
|
+
merged["local_provider"] = (
|
|
132
|
+
saved_model.split("/", 1)[0].lower() if "/" in saved_model else "ollama"
|
|
133
|
+
)
|
|
134
|
+
if self.normalize_provider is not None:
|
|
135
|
+
try:
|
|
136
|
+
merged["local_provider"] = (
|
|
137
|
+
self.normalize_provider(merged.get("local_provider")) or "ollama"
|
|
138
|
+
)
|
|
139
|
+
except Exception:
|
|
140
|
+
pass
|
|
141
|
+
|
|
142
|
+
def _reset_stale_model(self, merged: dict) -> None:
|
|
143
|
+
model = merged.get("model", "")
|
|
144
|
+
if any(model.startswith(p) for p in self.stale_model_prefixes):
|
|
145
|
+
merged["model"] = self.defaults.get("model", "")
|
|
146
|
+
|
|
147
|
+
def _ensure_ui_lang(self, merged: dict) -> None:
|
|
148
|
+
if not merged.get("ui_lang"):
|
|
149
|
+
try:
|
|
150
|
+
merged["ui_lang"] = self.detect_lang() if self.detect_lang else "en"
|
|
151
|
+
except Exception:
|
|
152
|
+
merged["ui_lang"] = "en"
|
|
153
|
+
|
|
154
|
+
def _finish_load(self, cfg: dict) -> None:
|
|
155
|
+
self._snapshot = dict(cfg)
|
|
156
|
+
if self.on_loaded is not None:
|
|
157
|
+
self.on_loaded(cfg)
|