aria-code 0.167.0__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aria_bots/__init__.py +7 -0
- aria_bots/channels/README.md +97 -0
- aria_bots/channels/__init__.py +1 -0
- aria_bots/channels/approvals.py +263 -0
- aria_bots/channels/conversation.py +280 -0
- aria_bots/channels/digest.py +186 -0
- aria_bots/channels/registry.py +95 -0
- aria_bots/engine.py +144 -0
- aria_bots/feishu_bot.py +1385 -0
- aria_bots/logistics/__init__.py +1 -0
- aria_bots/logistics/carriers.py +253 -0
- aria_bots/logistics/freight.py +154 -0
- aria_bots/logistics/inventory.py +242 -0
- aria_bots/logistics/mcp_server.py +156 -0
- aria_bots/logistics/records.py +119 -0
- aria_bots/logistics/tenancy.py +152 -0
- aria_bots/market.py +91 -0
- aria_bots/relay_client.py +326 -0
- aria_bots/telegram_bot.py +299 -0
- aria_code/__init__.py +111 -0
- aria_code/_bin/aria-native.exe +0 -0
- aria_code/_bin/aria-runtime.exe +0 -0
- aria_code/_version.py +20 -0
- aria_code/account_memory.py +296 -0
- aria_code/account_session.py +166 -0
- aria_code/adk_apps/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/agent.py +32 -0
- aria_code/adk_apps/aria_research/__init__.py +1 -0
- aria_code/adk_apps/aria_research/agent.py +31 -0
- aria_code/agents/__init__.py +49 -0
- aria_code/agents/base.py +329 -0
- aria_code/agents/code_review.py +200 -0
- aria_code/agents/deep/__init__.py +37 -0
- aria_code/agents/deep/calibration_loop.py +144 -0
- aria_code/agents/deep/critic.py +125 -0
- aria_code/agents/deep/deepen.py +193 -0
- aria_code/agents/deep/models.py +149 -0
- aria_code/agents/deep/pipeline.py +164 -0
- aria_code/agents/deep/quant_fusion.py +192 -0
- aria_code/agents/deep/themes.py +95 -0
- aria_code/agents/deep/tiers.py +106 -0
- aria_code/agents/engineering/__init__.py +14 -0
- aria_code/agents/engineering/coder.py +222 -0
- aria_code/agents/engineering/tester.py +145 -0
- aria_code/agents/financial/__init__.py +21 -0
- aria_code/agents/financial/cashflow_burn.py +119 -0
- aria_code/agents/financial/catalyst.py +279 -0
- aria_code/agents/financial/corporate_finance.py +175 -0
- aria_code/agents/financial/debate.py +224 -0
- aria_code/agents/financial/earnings.py +315 -0
- aria_code/agents/financial/fundamental.py +178 -0
- aria_code/agents/financial/macro.py +111 -0
- aria_code/agents/financial/news.py +231 -0
- aria_code/agents/financial/risk.py +146 -0
- aria_code/agents/financial/sector.py +279 -0
- aria_code/agents/financial/strategist.py +121 -0
- aria_code/agents/financial/stripe_revenue.py +127 -0
- aria_code/agents/financial/synthesis.py +274 -0
- aria_code/agents/financial/technical.py +277 -0
- aria_code/agents/orchestrator.py +44 -0
- aria_code/agents/portfolio_agent.py +392 -0
- aria_code/agents/realty/__init__.py +62 -0
- aria_code/agents/realty/asset_diagnosis.py +152 -0
- aria_code/agents/realty/business_match.py +166 -0
- aria_code/agents/realty/cashflow_verify.py +209 -0
- aria_code/agents/realty/contract_rules.py +210 -0
- aria_code/agents/realty/energy_anomaly.py +189 -0
- aria_code/agents/realty/exit_settlement.py +208 -0
- aria_code/agents/realty/fulfillment_risk.py +206 -0
- aria_code/agents/realty/ops_optimize.py +160 -0
- aria_code/agents/realty/revenue_share.py +215 -0
- aria_code/agents/registry.py +168 -0
- aria_code/agents/signal_scheme.py +111 -0
- aria_code/agents/sports/__init__.py +0 -0
- aria_code/agents/sports/football_agent.py +197 -0
- aria_code/agents/supervisor.py +113 -0
- aria_code/agents/team.py +500 -0
- aria_code/agents/video/__init__.py +16 -0
- aria_code/agents/video/director.py +376 -0
- aria_code/agents/video/qa_agent.py +143 -0
- aria_code/agents/video/script_doctor.py +112 -0
- aria_code/agents/warehouse/__init__.py +25 -0
- aria_code/agents/warehouse/contracts.py +26 -0
- aria_code/agents/warehouse/dashboard.py +155 -0
- aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
- aria_code/agents/warehouse/inbound_exceptions.py +25 -0
- aria_code/agents/warehouse/inventory_health.py +24 -0
- aria_code/agents/warehouse/local_run.py +71 -0
- aria_code/agents/warehouse/local_snapshot.py +132 -0
- aria_code/agents/warehouse/logistics_cost.py +84 -0
- aria_code/agents/warehouse/logistics_sync.py +21 -0
- aria_code/agents/warehouse/navigation.schema.json +110 -0
- aria_code/agents/warehouse/task_agent.py +172 -0
- aria_code/agents/warehouse/workflow.py +31 -0
- aria_code/aliyun_data_client.py +4 -0
- aria_code/apps/README.md +12 -0
- aria_code/apps/__init__.py +2 -0
- aria_code/apps/channels/README.md +9 -0
- aria_code/apps/channels/__init__.py +17 -0
- aria_code/apps/channels/approvals.py +11 -0
- aria_code/apps/channels/conversation.py +11 -0
- aria_code/apps/channels/digest.py +11 -0
- aria_code/apps/channels/intake.py +92 -0
- aria_code/apps/channels/registry.py +11 -0
- aria_code/apps/channels/tradingview.py +94 -0
- aria_code/apps/cli/README.md +13 -0
- aria_code/apps/cli/__init__.py +2 -0
- aria_code/apps/cli/_optional.py +120 -0
- aria_code/apps/cli/app_server.py +656 -0
- aria_code/apps/cli/auto_update.py +125 -0
- aria_code/apps/cli/bootstrap.py +206 -0
- aria_code/apps/cli/broker_render.py +206 -0
- aria_code/apps/cli/chat_turn.py +1327 -0
- aria_code/apps/cli/cloud_models.py +231 -0
- aria_code/apps/cli/codegen_paths.py +29 -0
- aria_code/apps/cli/commands/__init__.py +34 -0
- aria_code/apps/cli/commands/_business_render.py +78 -0
- aria_code/apps/cli/commands/_ui.py +71 -0
- aria_code/apps/cli/commands/analysis_cmds.py +378 -0
- aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
- aria_code/apps/cli/commands/auth_cmds.py +215 -0
- aria_code/apps/cli/commands/backtest_cmds.py +2518 -0
- aria_code/apps/cli/commands/broker_cmds.py +1236 -0
- aria_code/apps/cli/commands/business_workflow_cmds.py +379 -0
- aria_code/apps/cli/commands/canvas_cmds.py +77 -0
- aria_code/apps/cli/commands/catalog.py +189 -0
- aria_code/apps/cli/commands/core_cmds.py +2748 -0
- aria_code/apps/cli/commands/data_cmds.py +521 -0
- aria_code/apps/cli/commands/diagnostic_cmds.py +285 -0
- aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
- aria_code/apps/cli/commands/engineering_cmds.py +399 -0
- aria_code/apps/cli/commands/file_cmds.py +312 -0
- aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
- aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
- aria_code/apps/cli/commands/market.py +544 -0
- aria_code/apps/cli/commands/market_cmds.py +1419 -0
- aria_code/apps/cli/commands/market_context.py +432 -0
- aria_code/apps/cli/commands/market_render.py +7 -0
- aria_code/apps/cli/commands/model_cmds.py +2374 -0
- aria_code/apps/cli/commands/ops_cmds.py +721 -0
- aria_code/apps/cli/commands/orchestrator_cmds.py +181 -0
- aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
- aria_code/apps/cli/commands/portfolio_cmds.py +1316 -0
- aria_code/apps/cli/commands/report.py +476 -0
- aria_code/apps/cli/commands/scaffold_templates.py +617 -0
- aria_code/apps/cli/commands/session_cmds.py +236 -0
- aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
- aria_code/apps/cli/commands/team.py +723 -0
- aria_code/apps/cli/commands/team_render.py +8 -0
- aria_code/apps/cli/commands/ui_cmds.py +401 -0
- aria_code/apps/cli/commands/warehouse_cmds.py +297 -0
- aria_code/apps/cli/commands/workflow_cmds.py +629 -0
- aria_code/apps/cli/commands/workspace_cmds.py +1543 -0
- aria_code/apps/cli/config_paths.py +73 -0
- aria_code/apps/cli/config_store.py +158 -0
- aria_code/apps/cli/constants.py +88 -0
- aria_code/apps/cli/context.py +34 -0
- aria_code/apps/cli/conversation_policy.py +53 -0
- aria_code/apps/cli/deterministic.py +200 -0
- aria_code/apps/cli/direct.py +48 -0
- aria_code/apps/cli/earnings_view.py +172 -0
- aria_code/apps/cli/endpoint_migration.py +64 -0
- aria_code/apps/cli/exec_events.py +255 -0
- aria_code/apps/cli/file_references.py +155 -0
- aria_code/apps/cli/finance_service_catalog.py +111 -0
- aria_code/apps/cli/football_reports.py +231 -0
- aria_code/apps/cli/github_app_auth.py +135 -0
- aria_code/apps/cli/google_login.py +239 -0
- aria_code/apps/cli/handlers/__init__.py +11 -0
- aria_code/apps/cli/handlers/broker_handlers.py +122 -0
- aria_code/apps/cli/handlers/chart_handlers.py +1314 -0
- aria_code/apps/cli/handlers/market_handlers.py +2570 -0
- aria_code/apps/cli/handlers/realty_handlers.py +114 -0
- aria_code/apps/cli/handlers/sports_handlers.py +22 -0
- aria_code/apps/cli/handlers/strategy_advice.py +82 -0
- aria_code/apps/cli/headless.py +352 -0
- aria_code/apps/cli/helpers.py +326 -0
- aria_code/apps/cli/hooks.py +180 -0
- aria_code/apps/cli/i18n.py +310 -0
- aria_code/apps/cli/intent.py +136 -0
- aria_code/apps/cli/intent_router.py +305 -0
- aria_code/apps/cli/intent_shadow.py +72 -0
- aria_code/apps/cli/intent_signals.py +347 -0
- aria_code/apps/cli/lifecycle_hooks.py +48 -0
- aria_code/apps/cli/local_tool_schemas.py +550 -0
- aria_code/apps/cli/main.py +39 -0
- aria_code/apps/cli/market_hours.py +100 -0
- aria_code/apps/cli/market_metadata.py +135 -0
- aria_code/apps/cli/market_universe.py +487 -0
- aria_code/apps/cli/message_processing.py +310 -0
- aria_code/apps/cli/mixin_binding.py +32 -0
- aria_code/apps/cli/model_catalog.py +652 -0
- aria_code/apps/cli/model_probe.py +169 -0
- aria_code/apps/cli/model_retirement.py +65 -0
- aria_code/apps/cli/native_branding.py +12 -0
- aria_code/apps/cli/native_bridge.py +118 -0
- aria_code/apps/cli/native_entry.py +58 -0
- aria_code/apps/cli/pdf_report.py +977 -0
- aria_code/apps/cli/plan_mode.py +139 -0
- aria_code/apps/cli/plotly_html.py +15 -0
- aria_code/apps/cli/prediction_feedback.py +202 -0
- aria_code/apps/cli/preflight.py +502 -0
- aria_code/apps/cli/project_aria.py +60 -0
- aria_code/apps/cli/prompt_assembly.py +78 -0
- aria_code/apps/cli/prompts/__init__.py +0 -0
- aria_code/apps/cli/prompts/coding.py +71 -0
- aria_code/apps/cli/prompts/select.py +193 -0
- aria_code/apps/cli/prompts/system_prompts.py +562 -0
- aria_code/apps/cli/prompts/ui.py +436 -0
- aria_code/apps/cli/provider_endpoints.py +237 -0
- aria_code/apps/cli/provider_keys.py +73 -0
- aria_code/apps/cli/providers/__init__.py +1 -0
- aria_code/apps/cli/providers/base.py +775 -0
- aria_code/apps/cli/providers/chat_routing.py +139 -0
- aria_code/apps/cli/providers/collaboration.py +98 -0
- aria_code/apps/cli/providers/llm/__init__.py +1 -0
- aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
- aria_code/apps/cli/providers/llm/ollama_stream.py +1574 -0
- aria_code/apps/cli/providers/llm/response_cache.py +60 -0
- aria_code/apps/cli/providers/llm/sse_stream.py +298 -0
- aria_code/apps/cli/providers/runtime_bridge.py +586 -0
- aria_code/apps/cli/providers/vertexai_stream.py +592 -0
- aria_code/apps/cli/release_download.py +159 -0
- aria_code/apps/cli/review_runner.py +111 -0
- aria_code/apps/cli/runtime_consumer.py +769 -0
- aria_code/apps/cli/sandbox.py +32 -0
- aria_code/apps/cli/session_export.py +120 -0
- aria_code/apps/cli/session_jsonl.py +208 -0
- aria_code/apps/cli/session_refresh.py +123 -0
- aria_code/apps/cli/session_store.py +125 -0
- aria_code/apps/cli/skills_catalog.py +273 -0
- aria_code/apps/cli/task_isolation.py +211 -0
- aria_code/apps/cli/terminal_chrome.py +412 -0
- aria_code/apps/cli/todo_tracker.py +190 -0
- aria_code/apps/cli/tool_executor.py +932 -0
- aria_code/apps/cli/tool_registry.py +34 -0
- aria_code/apps/cli/tool_scope.py +113 -0
- aria_code/apps/cli/tools/__init__.py +40 -0
- aria_code/apps/cli/tools/context.py +46 -0
- aria_code/apps/cli/tools/file_tools.py +181 -0
- aria_code/apps/cli/tools/market_tools.py +626 -0
- aria_code/apps/cli/tools/notebook_tools.py +111 -0
- aria_code/apps/cli/tools/system_tools.py +656 -0
- aria_code/apps/cli/tools/write_tools.py +961 -0
- aria_code/apps/cli/tradingview_bridge.py +529 -0
- aria_code/apps/cli/transactions.py +269 -0
- aria_code/apps/cli/turn_planning.py +137 -0
- aria_code/apps/cli/update_check.py +257 -0
- aria_code/apps/cli/updater.py +373 -0
- aria_code/apps/cli/utils/__init__.py +0 -0
- aria_code/apps/cli/utils/market_detect.py +1663 -0
- aria_code/apps/cli/web_login.py +136 -0
- aria_code/apps/cli/workflow_runner.py +127 -0
- aria_code/apps/cli/workspace_route.py +121 -0
- aria_code/apps/daemon/README.md +14 -0
- aria_code/apps/vscode/README.md +115 -0
- aria_code/apps/vscode/package.json +70 -0
- aria_code/aria_cli.py +5244 -0
- aria_code/aria_daemon.py +1372 -0
- aria_code/aria_feishu_bot.py +16 -0
- aria_code/aria_mcp_server.py +61 -0
- aria_code/aria_relay_client.py +4 -0
- aria_code/aria_telegram_bot.py +11 -0
- aria_code/ariarc.py +385 -0
- aria_code/artifacts.py +581 -0
- aria_code/backtest_engine.py +4 -0
- aria_code/backtest_report.py +4 -0
- aria_code/brokers/__init__.py +78 -0
- aria_code/brokers/automation.py +193 -0
- aria_code/brokers/base.py +231 -0
- aria_code/brokers/capabilities.py +264 -0
- aria_code/brokers/cn/__init__.py +10 -0
- aria_code/brokers/cn/easytrader_broker.py +193 -0
- aria_code/brokers/cn/futu_broker.py +194 -0
- aria_code/brokers/cn/longbridge_broker.py +190 -0
- aria_code/brokers/cn/tiger_broker.py +196 -0
- aria_code/brokers/cn/xtquant_broker.py +225 -0
- aria_code/brokers/config.py +414 -0
- aria_code/brokers/intl/__init__.py +5 -0
- aria_code/brokers/intl/alpaca_broker.py +183 -0
- aria_code/brokers/intl/ibkr_broker.py +215 -0
- aria_code/brokers/intl/trading212_broker.py +183 -0
- aria_code/brokers/intl/webull_broker.py +156 -0
- aria_code/brokers/paper_broker.py +266 -0
- aria_code/brokers/planning.py +296 -0
- aria_code/brokers/registry.py +213 -0
- aria_code/brokers/trading.py +267 -0
- aria_code/canva_client.py +4 -0
- aria_code/change_store.py +127 -0
- aria_code/clients/__init__.py +0 -0
- aria_code/clients/aliyun_data_client.py +660 -0
- aria_code/clients/aria_relay_client.py +16 -0
- aria_code/clients/canva_client.py +284 -0
- aria_code/clients/figma_client.py +100 -0
- aria_code/clients/football_data_client.py +1671 -0
- aria_code/clients/kling_video_client.py +182 -0
- aria_code/clients/market_data_client.py +1985 -0
- aria_code/clients/openai_image_client.py +242 -0
- aria_code/clients/runway_video_client.py +157 -0
- aria_code/clients/warehouse_erp_client.py +105 -0
- aria_code/cloud_memory.py +190 -0
- aria_code/command_safety.py +19 -0
- aria_code/computer_use_server.py +276 -0
- aria_code/computer_use_tools.py +4 -0
- aria_code/dashboard_generator.py +579 -0
- aria_code/data_analysis_tools.py +4 -0
- aria_code/data_cleaner.py +483 -0
- aria_code/data_service.py +513 -0
- aria_code/datasources/__init__.py +23 -0
- aria_code/datasources/base.py +166 -0
- aria_code/datasources/router.py +253 -0
- aria_code/datasources/sec_statements.py +217 -0
- aria_code/datasources/sources/__init__.py +15 -0
- aria_code/datasources/sources/akshare_source.py +269 -0
- aria_code/datasources/sources/alpha_vantage_source.py +203 -0
- aria_code/datasources/sources/edgar_source.py +219 -0
- aria_code/datasources/sources/finnhub_source.py +198 -0
- aria_code/datasources/sources/fred_source.py +223 -0
- aria_code/datasources/sources/tushare_source.py +143 -0
- aria_code/datasources/sources/web_scraper_source.py +278 -0
- aria_code/datasources/sources/world_bank_source.py +206 -0
- aria_code/datasources/sources/yfinance_source.py +152 -0
- aria_code/doctor.py +860 -0
- aria_code/domain/__init__.py +0 -0
- aria_code/domain/_finance_core/__init__.py +5 -0
- aria_code/domain/_finance_core/backtest_engine.py +325 -0
- aria_code/domain/_finance_core/performance_stats.py +101 -0
- aria_code/domain/backtest_engine.py +75 -0
- aria_code/domain/backtest_report.py +488 -0
- aria_code/domain/finance_formulas.py +389 -0
- aria_code/domain/performance_stats.py +6 -0
- aria_code/domain/portfolio_ledger.py +307 -0
- aria_code/domain/strategy_vault.py +421 -0
- aria_code/evals/__init__.py +37 -0
- aria_code/evals/behavior.py +113 -0
- aria_code/evals/gap.py +93 -0
- aria_code/evals/harness.py +949 -0
- aria_code/evals/review_probe.py +132 -0
- aria_code/evals/runner.py +425 -0
- aria_code/evals/scorecard.py +322 -0
- aria_code/evals/summary.py +125 -0
- aria_code/external_agent_runner.py +115 -0
- aria_code/figma_client.py +4 -0
- aria_code/file_analysis_tools.py +4 -0
- aria_code/finance_formulas.py +4 -0
- aria_code/football_data_client.py +4 -0
- aria_code/image_gen_tools.py +4 -0
- aria_code/intent_classifier.py +459 -0
- aria_code/kling_video_client.py +4 -0
- aria_code/licensing.py +151 -0
- aria_code/local_finance_tools.py +4 -0
- aria_code/local_image_provider.py +4 -0
- aria_code/local_llm_provider.py +4 -0
- aria_code/macro_tools.py +4 -0
- aria_code/markdown_pdf.py +289 -0
- aria_code/market_data_client.py +4 -0
- aria_code/mcp_client.py +744 -0
- aria_code/memory_manager.py +273 -0
- aria_code/model_capability.py +512 -0
- aria_code/notification_tools.py +4 -0
- aria_code/openai_image_client.py +4 -0
- aria_code/packages/__init__.py +26 -0
- aria_code/packages/adk_bridge/__init__.py +11 -0
- aria_code/packages/adk_bridge/code_review_tools.py +49 -0
- aria_code/packages/adk_bridge/market_tools.py +125 -0
- aria_code/packages/aria_agents/__init__.py +5 -0
- aria_code/packages/aria_agents/manifest.py +78 -0
- aria_code/packages/aria_core/__init__.py +34 -0
- aria_code/packages/aria_core/architecture.py +269 -0
- aria_code/packages/aria_core/export.py +147 -0
- aria_code/packages/aria_core/manifest.py +65 -0
- aria_code/packages/aria_core/paths.py +57 -0
- aria_code/packages/aria_core/secure_file.py +68 -0
- aria_code/packages/aria_infra/__init__.py +15 -0
- aria_code/packages/aria_infra/arthera.py +58 -0
- aria_code/packages/aria_infra/doctor.py +246 -0
- aria_code/packages/aria_infra/product.py +40 -0
- aria_code/packages/aria_mcp/__init__.py +25 -0
- aria_code/packages/aria_mcp/bridge.py +232 -0
- aria_code/packages/aria_mcp/circuit.py +82 -0
- aria_code/packages/aria_mcp/config.py +162 -0
- aria_code/packages/aria_mcp/installer.py +95 -0
- aria_code/packages/aria_mcp/server.py +1705 -0
- aria_code/packages/aria_mcp/tools.py +81 -0
- aria_code/packages/aria_sdk/__init__.py +19 -0
- aria_code/packages/aria_sdk/client.py +393 -0
- aria_code/packages/aria_sdk/providers.py +70 -0
- aria_code/packages/aria_sdk/streaming.py +75 -0
- aria_code/packages/aria_sdk/types.py +86 -0
- aria_code/packages/aria_services/__init__.py +92 -0
- aria_code/packages/aria_services/cache.py +60 -0
- aria_code/packages/aria_services/context.py +356 -0
- aria_code/packages/aria_services/context_checkpoints.py +157 -0
- aria_code/packages/aria_services/data.py +11 -0
- aria_code/packages/aria_services/provider_health.py +304 -0
- aria_code/packages/aria_services/references.py +247 -0
- aria_code/packages/aria_services/registry.py +249 -0
- aria_code/packages/aria_services/research_protocol.py +137 -0
- aria_code/packages/aria_services/research_quality.py +186 -0
- aria_code/packages/aria_services/settings.py +160 -0
- aria_code/packages/aria_services/usage.py +151 -0
- aria_code/packages/aria_skills/__init__.py +46 -0
- aria_code/packages/aria_skills/catalog.py +149 -0
- aria_code/packages/aria_skills/loader.py +455 -0
- aria_code/packages/aria_skills/registry.py +84 -0
- aria_code/packages/aria_tools/__init__.py +5 -0
- aria_code/packages/aria_tools/financial/__init__.py +5 -0
- aria_code/packages/aria_tools/financial/_paths.py +92 -0
- aria_code/packages/aria_tools/registry.py +129 -0
- aria_code/packages/quant_engine/__init__.py +33 -0
- aria_code/packages/quant_engine/_namespace.py +24 -0
- aria_code/packages/quant_engine/backtest/__init__.py +10 -0
- aria_code/packages/quant_engine/backtest/core.py +53 -0
- aria_code/packages/quant_engine/backtest/engine.py +102 -0
- aria_code/packages/quant_engine/portfolio/__init__.py +9 -0
- aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
- aria_code/packages/quant_engine/sports/__init__.py +76 -0
- aria_code/packages/quant_engine/sports/calibrator.py +354 -0
- aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
- aria_code/packages/quant_engine/sports/elo.py +300 -0
- aria_code/packages/quant_engine/sports/form.py +188 -0
- aria_code/packages/quant_engine/sports/h2h.py +195 -0
- aria_code/packages/quant_engine/sports/predictor.py +312 -0
- aria_code/packages/quant_engine/sports/tracker.py +665 -0
- aria_code/packages/quant_engine/stochastic/__init__.py +31 -0
- aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
- aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
- aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
- aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
- aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
- aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
- aria_code/packs/__init__.py +85 -0
- aria_code/packs/base.py +168 -0
- aria_code/packs/finance/__init__.py +250 -0
- aria_code/packs/healthcare/__init__.py +40 -0
- aria_code/packs/logistics/__init__.py +171 -0
- aria_code/packs/payments/__init__.py +139 -0
- aria_code/packs/realty/__init__.py +190 -0
- aria_code/packs/registry.py +202 -0
- aria_code/packs/rules.py +90 -0
- aria_code/plan_utils.py +194 -0
- aria_code/plugin_loader.py +328 -0
- aria_code/portfolio_ledger.py +4 -0
- aria_code/preview_server.py +449 -0
- aria_code/privacy/__init__.py +5 -0
- aria_code/privacy/feedback.py +123 -0
- aria_code/project_review.py +278 -0
- aria_code/project_review_api.py +235 -0
- aria_code/project_review_server.py +18 -0
- aria_code/project_tools.py +4 -0
- aria_code/providers/__init__.py +30 -0
- aria_code/providers/google_video_provider.py +256 -0
- aria_code/providers/llm/__init__.py +19 -0
- aria_code/providers/llm/anthropic.py +184 -0
- aria_code/providers/llm/arthera_gateway.py +90 -0
- aria_code/providers/llm/autoconfig.py +213 -0
- aria_code/providers/llm/base.py +139 -0
- aria_code/providers/llm/custom.py +158 -0
- aria_code/providers/llm/ollama.py +137 -0
- aria_code/providers/llm/openai_compat.py +350 -0
- aria_code/providers/llm/registry.py +457 -0
- aria_code/providers/local_image_provider.py +202 -0
- aria_code/providers/local_llm_provider.py +549 -0
- aria_code/providers/ollama_models.py +79 -0
- aria_code/providers/openai_params.py +32 -0
- aria_code/providers/tool_messages.py +100 -0
- aria_code/realty_data_tools.py +4 -0
- aria_code/report_exporters.py +150 -0
- aria_code/report_generator.py +1764 -0
- aria_code/review_service.py +497 -0
- aria_code/runtime/__init__.py +176 -0
- aria_code/runtime/acceptance.py +632 -0
- aria_code/runtime/agent_loop.py +1851 -0
- aria_code/runtime/agent_profiles.py +75 -0
- aria_code/runtime/approval.py +71 -0
- aria_code/runtime/baseline.py +219 -0
- aria_code/runtime/budget.py +232 -0
- aria_code/runtime/checkpoints.py +481 -0
- aria_code/runtime/consult.py +65 -0
- aria_code/runtime/contract.py +282 -0
- aria_code/runtime/delivery.py +432 -0
- aria_code/runtime/events.py +113 -0
- aria_code/runtime/gateway.py +167 -0
- aria_code/runtime/lsp.py +484 -0
- aria_code/runtime/native_index.py +153 -0
- aria_code/runtime/orchestrator.py +55 -0
- aria_code/runtime/processes.py +343 -0
- aria_code/runtime/project_graph.py +614 -0
- aria_code/runtime/repo_map.py +712 -0
- aria_code/runtime/research_bundle.py +105 -0
- aria_code/runtime/review.py +269 -0
- aria_code/runtime/run_state.py +127 -0
- aria_code/runtime/run_store.py +522 -0
- aria_code/runtime/scoped_runs.py +113 -0
- aria_code/runtime/self_healing.py +422 -0
- aria_code/runtime/semantic_diff.py +171 -0
- aria_code/runtime/subagent.py +721 -0
- aria_code/runtime/symbol_edit.py +117 -0
- aria_code/runtime/task_brief.py +46 -0
- aria_code/runtime/task_context.py +145 -0
- aria_code/runtime/task_ledger.py +108 -0
- aria_code/runtime/task_orchestrator.py +90 -0
- aria_code/runtime/task_outcome.py +33 -0
- aria_code/runtime/task_verification.py +266 -0
- aria_code/runtime/task_worktree.py +448 -0
- aria_code/runtime/tool_executor.py +329 -0
- aria_code/runtime/tool_policy.py +107 -0
- aria_code/runtime/transactions.py +216 -0
- aria_code/runtime/windows_job.py +115 -0
- aria_code/runtime/workflows.py +222 -0
- aria_code/runtime/worktrees.py +215 -0
- aria_code/runway_video_client.py +4 -0
- aria_code/safety/__init__.py +27 -0
- aria_code/safety/client_isolation.py +178 -0
- aria_code/safety/permissions.py +339 -0
- aria_code/safety/risk.py +699 -0
- aria_code/safety/sandbox.py +148 -0
- aria_code/safety/service.py +102 -0
- aria_code/service_endpoints.py +14 -0
- aria_code/setup_wizard.py +684 -0
- aria_code/spreadsheet_tools.py +4 -0
- aria_code/strategy_vault.py +4 -0
- aria_code/tools/__init__.py +0 -0
- aria_code/tools/artifact_tools.py +252 -0
- aria_code/tools/broker_tools.py +92 -0
- aria_code/tools/build_quant_engine.py +97 -0
- aria_code/tools/code_audit_tools.py +192 -0
- aria_code/tools/computer_use_tools.py +509 -0
- aria_code/tools/data_analysis_tools.py +831 -0
- aria_code/tools/enterprise_finance_tools.py +202 -0
- aria_code/tools/extended_tools.py +240 -0
- aria_code/tools/file_analysis_tools.py +880 -0
- aria_code/tools/image_gen_tools.py +114 -0
- aria_code/tools/local_finance_tools.py +3488 -0
- aria_code/tools/logistics_carriers.py +11 -0
- aria_code/tools/logistics_inventory.py +11 -0
- aria_code/tools/logistics_io.py +11 -0
- aria_code/tools/logistics_tenancy.py +11 -0
- aria_code/tools/logistics_tools.py +11 -0
- aria_code/tools/macro_tools.py +412 -0
- aria_code/tools/notification_tools.py +249 -0
- aria_code/tools/project_tools.py +525 -0
- aria_code/tools/realty_data_tools.py +662 -0
- aria_code/tools/spreadsheet_tools.py +399 -0
- aria_code/tools/stripe_tools.py +115 -0
- aria_code/tools/video_tools.py +500 -0
- aria_code/training/__init__.py +1 -0
- aria_code/training/compare.py +117 -0
- aria_code/training/prelude_commands.py +111 -0
- aria_code/training/prelude_eval.py +390 -0
- aria_code/training/prelude_real.py +183 -0
- aria_code/training/prelude_train.py +248 -0
- aria_code/training/sft_dataset.py +230 -0
- aria_code/training/trajectory_dataset.py +263 -0
- aria_code/ui/__init__.py +105 -0
- aria_code/ui/banner.py +404 -0
- aria_code/ui/completer.py +571 -0
- aria_code/ui/console.py +285 -0
- aria_code/ui/input_box.py +505 -0
- aria_code/ui/mentions.py +206 -0
- aria_code/ui/picker.py +248 -0
- aria_code/ui/render/__init__.py +11 -0
- aria_code/ui/render/actions.py +297 -0
- aria_code/ui/render/finance.py +1732 -0
- aria_code/ui/render/market.py +253 -0
- aria_code/ui/render/output.py +954 -0
- aria_code/ui/render/responsive.py +75 -0
- aria_code/ui/render/team.py +367 -0
- aria_code/ui/robot.py +239 -0
- aria_code/ui/startup_dashboard.py +110 -0
- aria_code/video_analysis.py +147 -0
- aria_code/video_editor.py +518 -0
- aria_code/video_workflow/__init__.py +8 -0
- aria_code/video_workflow/__main__.py +61 -0
- aria_code/video_workflow/engines/__init__.py +18 -0
- aria_code/video_workflow/engines/base.py +69 -0
- aria_code/video_workflow/engines/custom_model.py +204 -0
- aria_code/video_workflow/engines/google_veo.py +94 -0
- aria_code/video_workflow/engines/local_engine.py +71 -0
- aria_code/video_workflow/engines/registry.py +98 -0
- aria_code/video_workflow/google_models.py +278 -0
- aria_code/video_workflow/music/__init__.py +5 -0
- aria_code/video_workflow/music/foley_service.py +132 -0
- aria_code/video_workflow/music/service.py +212 -0
- aria_code/video_workflow/pipeline.py +620 -0
- aria_code/video_workflow/plan.py +202 -0
- aria_code/video_workflow/session.py +297 -0
- aria_code/workspace/__init__.py +6 -0
- aria_code/workspace/files.py +219 -0
- aria_code/workspace/verify.py +167 -0
- aria_code/workspace_changes.py +199 -0
- aria_code/workspace_service.py +196 -0
- aria_code/workspace_tools.py +150 -0
- aria_code-0.167.0.dist-info/METADATA +330 -0
- aria_code-0.167.0.dist-info/RECORD +601 -0
- aria_code-0.167.0.dist-info/WHEEL +5 -0
- aria_code-0.167.0.dist-info/entry_points.txt +5 -0
- aria_code-0.167.0.dist-info/licenses/LICENSE +201 -0
- aria_code-0.167.0.dist-info/licenses/NOTICE +49 -0
- aria_code-0.167.0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
"""What frames the conversation: the banner, the status line, the toolbar, the keys.
|
|
2
|
+
|
|
3
|
+
Moved out of aria_cli.py unchanged: ArtheraTerminal.print_header, _status_line,
|
|
4
|
+
_build_keybindings, _workspace_git_state and _bottom_toolbar. They still use
|
|
5
|
+
aria_cli's module-level names; aria_cli binds a copy of ChromeMixin to its own
|
|
6
|
+
namespace with mixin_binding.bind_mixin and ArtheraTerminal inherits it.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ChromeMixin:
|
|
13
|
+
"""The terminal's banner, status line, bottom toolbar and key bindings."""
|
|
14
|
+
|
|
15
|
+
def print_header(self):
|
|
16
|
+
# Resolve current model info
|
|
17
|
+
current_id = self.config.get("model", "qwen2.5:7b")
|
|
18
|
+
|
|
19
|
+
# ── 模型自动配对(仅限本地模型)──────────────────────────────────────
|
|
20
|
+
# 检测本机已安装的 Ollama 模型;若配置的**本地**模型未安装,配对到
|
|
21
|
+
# 一个能力足够的可用模型并持久化(与运行时 fallback 共用选择逻辑)。
|
|
22
|
+
#
|
|
23
|
+
# 云端模型不参与配对。Ollama 的列表里永远没有 google/gemini-2.5-pro,
|
|
24
|
+
# 所以这个判断对云端配置恒为真 —— 以前它会把用户显式选的云端模型改掉
|
|
25
|
+
# 并 save_config() 落盘,每次启动都改一次。pick_best_installed_model
|
|
26
|
+
# 现在对 provider 前缀的 id 直接返回 None。
|
|
27
|
+
self._auto_healed_from: Optional[str] = None # 原配置模型(仅本次显示用)
|
|
28
|
+
self._ollama_alive = False
|
|
29
|
+
self._installed_models: set = set()
|
|
30
|
+
try:
|
|
31
|
+
_rm, _ = detect_ollama_models_rich(
|
|
32
|
+
self.config.get("ollama_url", "http://localhost:11434"))
|
|
33
|
+
self._installed_models = {_x["name"] for _x in _rm}
|
|
34
|
+
self._ollama_alive = bool(self._installed_models)
|
|
35
|
+
except Exception:
|
|
36
|
+
pass
|
|
37
|
+
# Only a model this session would run on Ollama is paired. The check
|
|
38
|
+
# below it looks for a provider prefix, so a bare cloud id such as
|
|
39
|
+
# "gemini-3.8-flash" (with local_provider=vertex, or backend_chat on)
|
|
40
|
+
# read as a missing local model: it was replaced by whatever Ollama
|
|
41
|
+
# had installed — a 1.5B model — and the change saved to the config.
|
|
42
|
+
try:
|
|
43
|
+
from aria_code.apps.cli.providers.chat_routing import first_round_route
|
|
44
|
+
_runs_on_ollama = first_round_route(current_id, self.config, self.api_url) == "ollama"
|
|
45
|
+
except Exception:
|
|
46
|
+
_runs_on_ollama = False
|
|
47
|
+
if _runs_on_ollama and self._installed_models and current_id not in self._installed_models:
|
|
48
|
+
_resolved = _pick_best_installed_model(self._installed_models, current_id)
|
|
49
|
+
if _resolved:
|
|
50
|
+
self._auto_healed_from = current_id
|
|
51
|
+
current_id = _resolved
|
|
52
|
+
self.config["model"] = _resolved
|
|
53
|
+
self._actual_model = None # config now matches reality
|
|
54
|
+
try:
|
|
55
|
+
save_config(self.config)
|
|
56
|
+
except Exception:
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
current_key = next((k for k, v in MODELS.items() if v["id"] == current_id), None)
|
|
60
|
+
_default_m = MODELS.get("qwen7b") or MODELS.get("qwen-fast") or next(iter(MODELS.values()))
|
|
61
|
+
m = MODELS.get(current_key, _default_m) if current_key else _default_m
|
|
62
|
+
cwd = os.getcwd()
|
|
63
|
+
_git_branch, _git_dirty = self._workspace_git_state()
|
|
64
|
+
# Shorten home directory to ~
|
|
65
|
+
home = os.path.expanduser("~")
|
|
66
|
+
if cwd.startswith(home):
|
|
67
|
+
cwd = "~" + cwd[len(home):]
|
|
68
|
+
wl = self.config.get("watchlist", [])
|
|
69
|
+
tool_count = len(ARIA_TOOLS) + len(LOCAL_TOOLS)
|
|
70
|
+
skill_count = len(SKILLS)
|
|
71
|
+
_mcp_configured = 0
|
|
72
|
+
if _HAS_MCP:
|
|
73
|
+
try:
|
|
74
|
+
_mcp_cfg = json.loads(MCP_CONFIG_PATH.read_text(encoding="utf-8"))
|
|
75
|
+
_mcp_configured = sum(
|
|
76
|
+
1 for item in (_mcp_cfg.get("servers") or [])
|
|
77
|
+
if isinstance(item, dict) and item.get("enabled", True)
|
|
78
|
+
)
|
|
79
|
+
except Exception:
|
|
80
|
+
pass
|
|
81
|
+
|
|
82
|
+
# Watchlist string
|
|
83
|
+
wl_str = ""
|
|
84
|
+
if wl:
|
|
85
|
+
wl_str = ", ".join(wl[:5])
|
|
86
|
+
if len(wl) > 5:
|
|
87
|
+
wl_str += f" +{len(wl) - 5}"
|
|
88
|
+
|
|
89
|
+
from apps.cli.providers.chat_routing import model_provider
|
|
90
|
+
_provider = model_provider(current_id)
|
|
91
|
+
_cloud_provider = bool(_provider and _provider not in {"ollama", "lmstudio"})
|
|
92
|
+
_runtime = (
|
|
93
|
+
"cloud" if self.config.get("backend_chat") or _cloud_provider
|
|
94
|
+
or m.get("badge") == "Cloud" or "cloud" in current_id.lower()
|
|
95
|
+
else "local"
|
|
96
|
+
)
|
|
97
|
+
_badge = "Cloud" if _runtime == "cloud" else m.get("badge", "")
|
|
98
|
+
_uses_google = (
|
|
99
|
+
_provider in {"google", "vertexai", "vertex-ai", "google-genai"}
|
|
100
|
+
or current_id.lower().startswith("gemini")
|
|
101
|
+
or self.config.get("local_provider") in {"vertex", "google"}
|
|
102
|
+
)
|
|
103
|
+
_missing = ""
|
|
104
|
+
if _uses_google and not self.config.get("backend_chat"):
|
|
105
|
+
from apps.cli.providers.base import google_readiness
|
|
106
|
+
_missing = google_readiness(self.config)
|
|
107
|
+
_health_status = (
|
|
108
|
+
("Google Cloud · via Arthera API" if _uses_google else "Arthera API · cloud")
|
|
109
|
+
if self.config.get("backend_chat") else
|
|
110
|
+
f"⚠ {_missing} · /model" if _missing else
|
|
111
|
+
"Cloud model configured" if _cloud_provider else
|
|
112
|
+
self._ollama_status_label(rich=True)
|
|
113
|
+
)
|
|
114
|
+
_banner_mode = self._session_banner_mode or self.config.get("banner", "full")
|
|
115
|
+
_mascot = "[bold #C08050]▣[/bold #C08050]"
|
|
116
|
+
|
|
117
|
+
if _banner_mode == "off":
|
|
118
|
+
return # Silent startup for scripts / automation
|
|
119
|
+
|
|
120
|
+
if HAS_RICH:
|
|
121
|
+
console.print()
|
|
122
|
+
|
|
123
|
+
_ui_lang = self.config.get("ui_lang", "en") or "en"
|
|
124
|
+
if _banner_mode == "compact":
|
|
125
|
+
_model_label = f"{m['name']} {m['version']}" if current_key else current_id
|
|
126
|
+
from ui.banner import render_compact_banner as _rcb
|
|
127
|
+
try:
|
|
128
|
+
from apps.cli.update_check import get_update_notice as _gun
|
|
129
|
+
_update_notice = _gun(wait_ms=0)
|
|
130
|
+
except Exception:
|
|
131
|
+
_update_notice = None
|
|
132
|
+
_rcb(
|
|
133
|
+
version=__version__,
|
|
134
|
+
model_label=_model_label,
|
|
135
|
+
runtime=_runtime,
|
|
136
|
+
cwd=cwd,
|
|
137
|
+
control_status_rich=self._control_status_label(rich=True),
|
|
138
|
+
tool_count=tool_count,
|
|
139
|
+
update_notice=_update_notice,
|
|
140
|
+
console=console,
|
|
141
|
+
has_rich=HAS_RICH,
|
|
142
|
+
lang=_ui_lang,
|
|
143
|
+
)
|
|
144
|
+
else:
|
|
145
|
+
_model_label = f"{m['name']} {m['version']}" if current_key else current_id
|
|
146
|
+
try:
|
|
147
|
+
from apps.cli.i18n import t as _i18n_t
|
|
148
|
+
_lite_word = _i18n_t("lite", lang=_ui_lang)
|
|
149
|
+
_cloud_word = _i18n_t("cloud", lang=_ui_lang)
|
|
150
|
+
_local_word = _i18n_t("local", lang=_ui_lang)
|
|
151
|
+
except Exception:
|
|
152
|
+
_lite_word, _cloud_word, _local_word = "lite", "cloud", "local"
|
|
153
|
+
if _badge == "Fast":
|
|
154
|
+
_rt_label = f"{_model_label} [dim]{_lite_word}[/dim]"
|
|
155
|
+
elif _badge == "Cloud":
|
|
156
|
+
_rt_label = f"{_model_label} [dim]{_cloud_word}[/dim]"
|
|
157
|
+
else:
|
|
158
|
+
_rt_label = f"{_model_label} [dim]{_local_word}[/dim]"
|
|
159
|
+
|
|
160
|
+
_best_id = (MODELS.get("qwen7b") or {}).get("id", "qwen2.5:7b")
|
|
161
|
+
from ui.banner import render_startup_dashboard as _rsd, render_try_hints as _rth
|
|
162
|
+
from ui.startup_dashboard import StartupDashboardViewModel as _StartupDashboardViewModel
|
|
163
|
+
try:
|
|
164
|
+
from apps.cli.update_check import get_update_notice as _gun
|
|
165
|
+
_update_notice = _gun(wait_ms=0)
|
|
166
|
+
except Exception:
|
|
167
|
+
_update_notice = None
|
|
168
|
+
_first_run = not bool(self.config.get("first_run_seen"))
|
|
169
|
+
_dashboard = _StartupDashboardViewModel(
|
|
170
|
+
version=__version__,
|
|
171
|
+
runtime_label=_rt_label,
|
|
172
|
+
cwd=cwd,
|
|
173
|
+
control_status=self._control_status_label(rich=True),
|
|
174
|
+
health_status=_health_status,
|
|
175
|
+
tool_count=tool_count,
|
|
176
|
+
skill_count=skill_count,
|
|
177
|
+
lang=_ui_lang,
|
|
178
|
+
first_run=_first_run,
|
|
179
|
+
update_notice=_update_notice,
|
|
180
|
+
auto_healed_from=self._auto_healed_from or "",
|
|
181
|
+
current_id=current_id,
|
|
182
|
+
badge=_badge,
|
|
183
|
+
best_lite_id=_best_id,
|
|
184
|
+
best_lite_installed=_best_id in self._installed_models,
|
|
185
|
+
git_branch=_git_branch,
|
|
186
|
+
git_dirty=_git_dirty,
|
|
187
|
+
mcp_server_count=_mcp_configured,
|
|
188
|
+
)
|
|
189
|
+
_rsd(
|
|
190
|
+
_dashboard,
|
|
191
|
+
console=console,
|
|
192
|
+
has_rich=HAS_RICH,
|
|
193
|
+
rich_box=rich_box,
|
|
194
|
+
)
|
|
195
|
+
_rth(console, HAS_RICH, lang=_ui_lang)
|
|
196
|
+
if not self.config.get("first_run_seen"):
|
|
197
|
+
self.config["first_run_seen"] = True
|
|
198
|
+
save_config(self.config)
|
|
199
|
+
# One-time transparency note. Unlike Claude Code (which does
|
|
200
|
+
# NOT train on feedback), Aria may use opted-in feedback to
|
|
201
|
+
# improve its finance model — so disclose it up front.
|
|
202
|
+
import os as _os
|
|
203
|
+
if not _os.environ.get("ARIA_NO_TELEMETRY"):
|
|
204
|
+
# Padded, not prefixed with spaces: in 80 columns the
|
|
205
|
+
# second line fell back to column 0.
|
|
206
|
+
from rich.padding import Padding as _Pad
|
|
207
|
+
from rich.text import Text as _Txt
|
|
208
|
+
console.print(_Pad(_Txt.from_markup(
|
|
209
|
+
"[dim]隐私:反馈默认[bold]仅存本地[/bold],不上传。"
|
|
210
|
+
"opt-in 后可用于改进金融模型 · /privacy 查看与开关 · /bug 报告问题[/dim]"
|
|
211
|
+
if str(_ui_lang).lower().startswith("zh") else
|
|
212
|
+
"[dim]Feedback stays [bold]on this machine[/bold] unless you opt in to "
|
|
213
|
+
"help improve Aria · /privacy · /bug[/dim]"
|
|
214
|
+
), (0, 0, 0, 2)))
|
|
215
|
+
else:
|
|
216
|
+
if _banner_mode != "off":
|
|
217
|
+
from ui.banner import render_full_banner as _rfb
|
|
218
|
+
_rfb(
|
|
219
|
+
version=__version__,
|
|
220
|
+
rt_label=_runtime,
|
|
221
|
+
cwd=cwd,
|
|
222
|
+
control_status_rich=self._control_status_label(),
|
|
223
|
+
ollama_status_rich=self._ollama_status_label(),
|
|
224
|
+
tool_count=tool_count,
|
|
225
|
+
skill_count=skill_count,
|
|
226
|
+
console=console,
|
|
227
|
+
has_rich=HAS_RICH,
|
|
228
|
+
rich_box=rich_box,
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
def _status_line(self) -> str:
|
|
232
|
+
current_id = self.config.get("model", "qwen2.5:7b")
|
|
233
|
+
# If Ollama switched to a different model, show the actual running model
|
|
234
|
+
display_id = self._actual_model or current_id
|
|
235
|
+
model_name = display_id # fallback: raw model ID
|
|
236
|
+
for k, v in MODELS.items():
|
|
237
|
+
if v["id"] == display_id:
|
|
238
|
+
model_name = v["name"].replace("Aria ", "")
|
|
239
|
+
break
|
|
240
|
+
# also match by actual model ID (e.g. gpt-oss:120b-cloud)
|
|
241
|
+
if v["id"] == current_id and self._actual_model is None:
|
|
242
|
+
model_name = v["name"].replace("Aria ", "")
|
|
243
|
+
break
|
|
244
|
+
# If actual_model differs from config, append a ⚑ warning marker
|
|
245
|
+
_mismatch = (self._actual_model is not None and self._actual_model != current_id)
|
|
246
|
+
if _mismatch:
|
|
247
|
+
model_name = f"{self._actual_model} ⚑"
|
|
248
|
+
# Determine runtime label
|
|
249
|
+
_lp = self._last_provider or ""
|
|
250
|
+
_model_badge = next(
|
|
251
|
+
(v.get("badge", "") for v in MODELS.values() if v["id"] == current_id), ""
|
|
252
|
+
)
|
|
253
|
+
if _lp == "ollama":
|
|
254
|
+
runtime = "local"
|
|
255
|
+
elif _lp in ("deepseek", "openai", "anthropic", "groq", "dashscope", "together"):
|
|
256
|
+
runtime = "cloud"
|
|
257
|
+
elif _model_badge == "Cloud" or "cloud" in current_id.lower():
|
|
258
|
+
runtime = "cloud"
|
|
259
|
+
elif not _lp:
|
|
260
|
+
runtime = "local" if getattr(self, "_ollama_alive", False) else "—"
|
|
261
|
+
else:
|
|
262
|
+
runtime = "cloud"
|
|
263
|
+
# Context source tags
|
|
264
|
+
_ctx_tags = []
|
|
265
|
+
if getattr(self, "_project_session", None):
|
|
266
|
+
_ctx_tags.append(f"proj:{self._project_session.name}")
|
|
267
|
+
elif getattr(self, "_file_session", None) and self._file_session.get_active():
|
|
268
|
+
_ctx_tags.append(f"file:{self._file_session.get_active().filename}")
|
|
269
|
+
_ctx = f" · {_ctx_tags[0]}" if _ctx_tags else ""
|
|
270
|
+
privacy = "share" if bool(self.config.get("data_sharing", False)) else "local-only"
|
|
271
|
+
permission = self.config.get("permission_mode", "workspace-write")
|
|
272
|
+
return f"aria · {runtime} · {permission} · {privacy}{_ctx}"
|
|
273
|
+
|
|
274
|
+
def _build_keybindings(self):
|
|
275
|
+
"""Build prompt_toolkit KeyBindings for REPL shortcuts."""
|
|
276
|
+
kb = _PTKeyBindings()
|
|
277
|
+
|
|
278
|
+
@kb.add("s-tab")
|
|
279
|
+
def _cycle_permission(event):
|
|
280
|
+
"""Shift+Tab → cycle permission mode."""
|
|
281
|
+
cur = _ACTIVE_PERMISSION_MODE[0]
|
|
282
|
+
try:
|
|
283
|
+
idx = _PERMISSION_CYCLE.index(cur)
|
|
284
|
+
except ValueError:
|
|
285
|
+
idx = 0
|
|
286
|
+
nxt = _PERMISSION_CYCLE[(idx + 1) % len(_PERMISSION_CYCLE)]
|
|
287
|
+
_ACTIVE_PERMISSION_MODE[0] = nxt
|
|
288
|
+
self.config["permission_mode"] = nxt
|
|
289
|
+
label = {"read-only": "🔒 read-only", "workspace-write": "✏️ workspace-write", "full-access": "⚡ full-access"}.get(nxt, nxt)
|
|
290
|
+
event.app.current_buffer.text = ""
|
|
291
|
+
# Print inline so user sees the change immediately
|
|
292
|
+
import sys as _sys
|
|
293
|
+
_sys.stderr.write(f"\r Mode → {label} \n")
|
|
294
|
+
_sys.stderr.flush()
|
|
295
|
+
|
|
296
|
+
@kb.add("escape", "t")
|
|
297
|
+
def _toggle_thinking(event):
|
|
298
|
+
"""Alt+T → toggle thinking mode."""
|
|
299
|
+
cur = self.config.get("thinking", False)
|
|
300
|
+
self.config["thinking"] = not cur
|
|
301
|
+
state = "ON" if not cur else "OFF"
|
|
302
|
+
import sys as _sys
|
|
303
|
+
_sys.stderr.write(f"\r Thinking → {state} \n")
|
|
304
|
+
_sys.stderr.flush()
|
|
305
|
+
|
|
306
|
+
@kb.add("escape", "p")
|
|
307
|
+
def _switch_model(event):
|
|
308
|
+
"""Alt+P → insert /model into prompt buffer."""
|
|
309
|
+
buf = event.app.current_buffer
|
|
310
|
+
if not buf.text:
|
|
311
|
+
buf.text = "/model "
|
|
312
|
+
buf.cursor_position = len(buf.text)
|
|
313
|
+
|
|
314
|
+
@kb.add("c-l")
|
|
315
|
+
def _redraw(event):
|
|
316
|
+
"""Ctrl+L → clear and redraw screen."""
|
|
317
|
+
event.app.renderer.clear()
|
|
318
|
+
|
|
319
|
+
@kb.add("c-o")
|
|
320
|
+
def _toggle_transcript(event):
|
|
321
|
+
"""Ctrl+O → show/hide recent tool calls + full thinking of last turn."""
|
|
322
|
+
self._transcript_visible = not self._transcript_visible
|
|
323
|
+
_details = list(getattr(self, "_action_details", None) or [])
|
|
324
|
+
if self._transcript_visible and (self._transcript_log or self._last_thinking or _details):
|
|
325
|
+
import sys as _sys
|
|
326
|
+
_sys.stderr.write("\n")
|
|
327
|
+
if self._last_thinking:
|
|
328
|
+
_sys.stderr.write(" ✻ Thinking\n")
|
|
329
|
+
for tline in self._last_thinking.splitlines() or [self._last_thinking]:
|
|
330
|
+
# wrap-soft: indent each line, cap very long lines
|
|
331
|
+
_sys.stderr.write(f" {tline[:200]}\n")
|
|
332
|
+
_sys.stderr.write("\n")
|
|
333
|
+
if _details:
|
|
334
|
+
# Every action of the last turn in full: commands with
|
|
335
|
+
# their whole output, edits with their whole diff.
|
|
336
|
+
from aria_code.ui.render.actions import format_action_details
|
|
337
|
+
_sys.stderr.write(" ⏺ Actions\n")
|
|
338
|
+
for _style, line in format_action_details(_details):
|
|
339
|
+
_sys.stderr.write(f" {line}\n")
|
|
340
|
+
elif self._transcript_log:
|
|
341
|
+
_sys.stderr.write(" ⏺ Tool calls\n")
|
|
342
|
+
for line in self._transcript_log[-20:]:
|
|
343
|
+
_sys.stderr.write(f" {line}\n")
|
|
344
|
+
_sys.stderr.write(" [Ctrl+O to close]\n\n")
|
|
345
|
+
_sys.stderr.flush()
|
|
346
|
+
else:
|
|
347
|
+
self._transcript_visible = False
|
|
348
|
+
|
|
349
|
+
@kb.add("c-t")
|
|
350
|
+
def _toggle_tasklist(event):
|
|
351
|
+
"""Ctrl+T → show/hide task list."""
|
|
352
|
+
self._task_list_visible = not self._task_list_visible
|
|
353
|
+
if self._task_list_visible and self._task_list:
|
|
354
|
+
import sys as _sys
|
|
355
|
+
_sys.stderr.write("\n 📋 Tasks:\n")
|
|
356
|
+
icons = {"pending": "○", "in_progress": "◉", "completed": "✓", "failed": "✗"}
|
|
357
|
+
for t in self._task_list:
|
|
358
|
+
icon = icons.get(t.get("status", "pending"), "○")
|
|
359
|
+
_sys.stderr.write(f" {icon} {t.get('title', '')}\n")
|
|
360
|
+
_sys.stderr.write("\n")
|
|
361
|
+
_sys.stderr.flush()
|
|
362
|
+
|
|
363
|
+
return kb
|
|
364
|
+
|
|
365
|
+
def _workspace_git_state(self) -> tuple[str, bool]:
|
|
366
|
+
"""Return the current branch and tracked-worktree dirty state."""
|
|
367
|
+
try:
|
|
368
|
+
import subprocess as _sp
|
|
369
|
+
branch = _sp.check_output(
|
|
370
|
+
["git", "rev-parse", "--abbrev-ref", "HEAD"],
|
|
371
|
+
stderr=_sp.DEVNULL,
|
|
372
|
+
timeout=1,
|
|
373
|
+
).decode().strip()
|
|
374
|
+
if not branch or branch == "HEAD":
|
|
375
|
+
return "", False
|
|
376
|
+
dirty = bool(_sp.check_output(
|
|
377
|
+
["git", "status", "--porcelain", "--untracked-files=no"],
|
|
378
|
+
stderr=_sp.DEVNULL,
|
|
379
|
+
timeout=1,
|
|
380
|
+
).decode().strip())
|
|
381
|
+
return branch, dirty
|
|
382
|
+
except Exception:
|
|
383
|
+
return "", False
|
|
384
|
+
|
|
385
|
+
def _bottom_toolbar(self):
|
|
386
|
+
"""Bottom toolbar content for prompt_toolkit."""
|
|
387
|
+
model_label, cwd, privacy, est_tokens, max_ctx = self._bottom_toolbar_parts()
|
|
388
|
+
ctx_color = "#606060" if est_tokens / max_ctx < 0.6 else (
|
|
389
|
+
"#aa8800" if est_tokens / max_ctx < 0.85 else "#cc4444"
|
|
390
|
+
)
|
|
391
|
+
perm = _ACTIVE_PERMISSION_MODE[0]
|
|
392
|
+
perm_color = {"read-only": "#888800", "workspace-write": "#606060", "full-access": "#cc4444"}.get(perm, "#606060")
|
|
393
|
+
perm_short = {"read-only": "ro", "workspace-write": "rw", "full-access": "full"}.get(perm, perm)
|
|
394
|
+
# PR / git branch info
|
|
395
|
+
_branch_name, _git_dirty = self._workspace_git_state()
|
|
396
|
+
_branch = f" ⎇ {_branch_name}{'*' if _git_dirty else ''}" if _branch_name else ""
|
|
397
|
+
# Task list indicator
|
|
398
|
+
_tasks = ""
|
|
399
|
+
if self._task_list:
|
|
400
|
+
_done = sum(1 for t in self._task_list if t.get("status") == "completed")
|
|
401
|
+
_total = len(self._task_list)
|
|
402
|
+
_tasks = f" · ✓{_done}/{_total}"
|
|
403
|
+
return HTML(
|
|
404
|
+
f'<style fg="#C08050">{model_label}</style>'
|
|
405
|
+
f'<style fg="#8a8a8a"> · {cwd}{_branch}{_tasks} · </style>'
|
|
406
|
+
f'<style fg="{perm_color}">{perm_short}</style>'
|
|
407
|
+
f'<style fg="#8a8a8a"> · {privacy} · /help · </style>'
|
|
408
|
+
f'<style fg="{ctx_color}">{est_tokens:,}/{max_ctx:,}</style>'
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
__all__ = ["ChromeMixin"]
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"""Structured task tracking for the Aria agent loop (Claude Code TodoWrite parity).
|
|
2
|
+
|
|
3
|
+
The model calls the ``update_todos`` tool with the full current task list each
|
|
4
|
+
time progress changes. We keep the latest list in a module-global so the
|
|
5
|
+
renderer (and any UI surface) can show a live checklist of multi-step work.
|
|
6
|
+
|
|
7
|
+
Design notes
|
|
8
|
+
------------
|
|
9
|
+
* State is intentionally a process-global, mirroring how the screenshot tool
|
|
10
|
+
stashes a pending image. Tool handlers only receive ``params``; they have no
|
|
11
|
+
reference to the terminal, so a module global is the pragmatic channel.
|
|
12
|
+
* The list is replaced wholesale on every call (not merged) so the model owns
|
|
13
|
+
the source of truth and we never drift out of sync with its plan.
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from typing import Any, Dict, List
|
|
18
|
+
|
|
19
|
+
_VALID_STATUS = ("pending", "in_progress", "completed")
|
|
20
|
+
|
|
21
|
+
# Latest task list the model published this turn.
|
|
22
|
+
_ACTIVE_TODOS: List[Dict[str, str]] = []
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_active_todos() -> List[Dict[str, str]]:
|
|
26
|
+
"""Return a copy of the current task list."""
|
|
27
|
+
return list(_ACTIVE_TODOS)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def clear_todos() -> None:
|
|
31
|
+
"""Reset the task list (call at the start of a new user turn)."""
|
|
32
|
+
_ACTIVE_TODOS.clear()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _normalize(todos: Any) -> List[Dict[str, str]]:
|
|
36
|
+
"""Coerce model-supplied todos into a clean list of {content, status}."""
|
|
37
|
+
out: List[Dict[str, str]] = []
|
|
38
|
+
if not isinstance(todos, list):
|
|
39
|
+
return out
|
|
40
|
+
for item in todos:
|
|
41
|
+
if isinstance(item, str):
|
|
42
|
+
content, status = item, "pending"
|
|
43
|
+
elif isinstance(item, dict):
|
|
44
|
+
content = str(
|
|
45
|
+
item.get("content")
|
|
46
|
+
or item.get("task")
|
|
47
|
+
or item.get("title")
|
|
48
|
+
or item.get("step")
|
|
49
|
+
or ""
|
|
50
|
+
).strip()
|
|
51
|
+
status = str(item.get("status", "pending")).strip().lower()
|
|
52
|
+
else:
|
|
53
|
+
continue
|
|
54
|
+
if not content:
|
|
55
|
+
continue
|
|
56
|
+
if status not in _VALID_STATUS:
|
|
57
|
+
# Accept a few common synonyms
|
|
58
|
+
status = {
|
|
59
|
+
"done": "completed", "complete": "completed", "finished": "completed",
|
|
60
|
+
"doing": "in_progress", "active": "in_progress", "wip": "in_progress",
|
|
61
|
+
"todo": "pending", "open": "pending", "not_started": "pending",
|
|
62
|
+
}.get(status, "pending")
|
|
63
|
+
out.append({"content": content, "status": status})
|
|
64
|
+
return out
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def update_todos(params: dict) -> dict:
|
|
68
|
+
"""Tool handler: replace the active task list with the model's latest plan."""
|
|
69
|
+
todos = _normalize(params.get("todos", params.get("tasks", [])))
|
|
70
|
+
if not todos:
|
|
71
|
+
return {
|
|
72
|
+
"success": False,
|
|
73
|
+
"error": "update_todos 需要非空的 todos 数组,每项形如 "
|
|
74
|
+
"{\"content\": \"步骤描述\", \"status\": \"pending|in_progress|completed\"}",
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# At most one in_progress is the convention — demote extras to pending order
|
|
78
|
+
seen_in_progress = False
|
|
79
|
+
for t in todos:
|
|
80
|
+
if t["status"] == "in_progress":
|
|
81
|
+
if seen_in_progress:
|
|
82
|
+
t["status"] = "pending"
|
|
83
|
+
else:
|
|
84
|
+
seen_in_progress = True
|
|
85
|
+
|
|
86
|
+
_ACTIVE_TODOS.clear()
|
|
87
|
+
_ACTIVE_TODOS.extend(todos)
|
|
88
|
+
|
|
89
|
+
_render(todos)
|
|
90
|
+
|
|
91
|
+
done = sum(1 for t in todos if t["status"] == "completed")
|
|
92
|
+
total = len(todos)
|
|
93
|
+
return {
|
|
94
|
+
"success": True,
|
|
95
|
+
"data": {
|
|
96
|
+
"total": total,
|
|
97
|
+
"completed": done,
|
|
98
|
+
"in_progress": sum(1 for t in todos if t["status"] == "in_progress"),
|
|
99
|
+
"pending": sum(1 for t in todos if t["status"] == "pending"),
|
|
100
|
+
"todos": todos,
|
|
101
|
+
},
|
|
102
|
+
# Compact text the model reads back so it knows the tracked state
|
|
103
|
+
"summary": f"任务进度 {done}/{total} 已完成",
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _render(todos: List[Dict[str, str]]) -> None:
|
|
108
|
+
"""Print the task list as a checklist. Uses rich when available."""
|
|
109
|
+
try:
|
|
110
|
+
import aria_cli as _ac
|
|
111
|
+
console = getattr(_ac, "console", None)
|
|
112
|
+
has_rich = getattr(_ac, "HAS_RICH", False)
|
|
113
|
+
except Exception:
|
|
114
|
+
console, has_rich = None, False
|
|
115
|
+
|
|
116
|
+
_icons = {
|
|
117
|
+
"completed": ("[green]✓[/green]", "✓"),
|
|
118
|
+
"in_progress": ("[yellow]▶[/yellow]", "▶"),
|
|
119
|
+
"pending": ("[dim]○[/dim]", "○"),
|
|
120
|
+
}
|
|
121
|
+
done = sum(1 for t in todos if t["status"] == "completed")
|
|
122
|
+
total = len(todos)
|
|
123
|
+
|
|
124
|
+
if has_rich and console is not None:
|
|
125
|
+
from rich.panel import Panel
|
|
126
|
+
from rich.text import Text
|
|
127
|
+
body = Text()
|
|
128
|
+
for i, t in enumerate(todos):
|
|
129
|
+
icon_rich, _ = _icons.get(t["status"], _icons["pending"])
|
|
130
|
+
style = (
|
|
131
|
+
"green" if t["status"] == "completed"
|
|
132
|
+
else "bold yellow" if t["status"] == "in_progress"
|
|
133
|
+
else "dim"
|
|
134
|
+
)
|
|
135
|
+
line = Text.from_markup(f"{icon_rich} ")
|
|
136
|
+
content = t["content"]
|
|
137
|
+
if t["status"] == "completed":
|
|
138
|
+
line.append(content, style="dim strike")
|
|
139
|
+
else:
|
|
140
|
+
line.append(content, style=style)
|
|
141
|
+
body.append_text(line)
|
|
142
|
+
if i < len(todos) - 1:
|
|
143
|
+
body.append("\n")
|
|
144
|
+
console.print(Panel(
|
|
145
|
+
body,
|
|
146
|
+
title=f"[bold]任务清单[/bold] [dim]{done}/{total}[/dim]",
|
|
147
|
+
border_style="cyan",
|
|
148
|
+
padding=(0, 1),
|
|
149
|
+
))
|
|
150
|
+
else:
|
|
151
|
+
print(f"\n任务清单 ({done}/{total}):")
|
|
152
|
+
for t in todos:
|
|
153
|
+
_, icon_plain = _icons.get(t["status"], _icons["pending"])
|
|
154
|
+
print(f" {icon_plain} {t['content']}")
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
UPDATE_TODOS_SCHEMA = {
|
|
158
|
+
"type": "function",
|
|
159
|
+
"function": {
|
|
160
|
+
"name": "update_todos",
|
|
161
|
+
"description": (
|
|
162
|
+
"Track progress on a multi-step task as a live checklist. Call this when a task "
|
|
163
|
+
"has 3+ distinct steps: first to lay out the plan (all pending), then again each "
|
|
164
|
+
"time you start a step (mark it in_progress) or finish one (mark it completed). "
|
|
165
|
+
"Keep exactly one step in_progress at a time. Always send the FULL list every call."
|
|
166
|
+
),
|
|
167
|
+
"parameters": {
|
|
168
|
+
"type": "object",
|
|
169
|
+
"properties": {
|
|
170
|
+
"todos": {
|
|
171
|
+
"type": "array",
|
|
172
|
+
"description": "The complete current task list (replaces the previous list).",
|
|
173
|
+
"items": {
|
|
174
|
+
"type": "object",
|
|
175
|
+
"properties": {
|
|
176
|
+
"content": {"type": "string", "description": "Short step description"},
|
|
177
|
+
"status": {
|
|
178
|
+
"type": "string",
|
|
179
|
+
"enum": list(_VALID_STATUS),
|
|
180
|
+
"description": "pending | in_progress | completed",
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
"required": ["content", "status"],
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
"required": ["todos"],
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
}
|