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,480 @@
|
|
|
1
|
+
"""WorkflowCommandsMixin — hooks, regen, undo, retry, note, review commands."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import pathlib
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
import asyncio
|
|
16
|
+
import datetime
|
|
17
|
+
import time
|
|
18
|
+
import shlex
|
|
19
|
+
from typing import Dict, Any, Optional
|
|
20
|
+
|
|
21
|
+
def _run_event_hook(*args, **kwargs):
|
|
22
|
+
from aria_cli import _run_event_hook as fn
|
|
23
|
+
return fn(*args, **kwargs)
|
|
24
|
+
def _load_hooks(*args, **kwargs):
|
|
25
|
+
from aria_cli import _load_hooks as fn
|
|
26
|
+
return fn(*args, **kwargs)
|
|
27
|
+
# display_path lives in ui.render.output; aria_cli only re-exports it under a
|
|
28
|
+
# private alias, so going through aria_cli was a pointless second hop.
|
|
29
|
+
from aria_code.ui.render.output import display_path as _display_path
|
|
30
|
+
def _get_MODELS():
|
|
31
|
+
from aria_code.apps.cli.model_catalog import MODELS as val
|
|
32
|
+
return val
|
|
33
|
+
def _get__HAS_JSON_HOOKS():
|
|
34
|
+
from aria_cli import _HAS_JSON_HOOKS as val
|
|
35
|
+
return val
|
|
36
|
+
def _tool_run_command(*args, **kwargs):
|
|
37
|
+
from aria_cli import _tool_run_command as fn
|
|
38
|
+
return fn(*args, **kwargs)
|
|
39
|
+
def resolve_model_key(*args, **kwargs):
|
|
40
|
+
from ..model_catalog import resolve_model_key as fn
|
|
41
|
+
return fn(*args, **kwargs)
|
|
42
|
+
def _load_project_context(*args, **kwargs):
|
|
43
|
+
from aria_code.apps.cli.helpers import _load_project_context as fn
|
|
44
|
+
return fn(*args, **kwargs)
|
|
45
|
+
def _fire_json_hook(*args, **kwargs):
|
|
46
|
+
from aria_cli import _fire_json_hook as fn
|
|
47
|
+
return fn(*args, **kwargs)
|
|
48
|
+
def _print_phase(*args, **kwargs):
|
|
49
|
+
from aria_cli import _print_phase as fn
|
|
50
|
+
return fn(*args, **kwargs)
|
|
51
|
+
def _get_CONFIG_DIR():
|
|
52
|
+
from aria_cli import CONFIG_DIR as val
|
|
53
|
+
return val
|
|
54
|
+
|
|
55
|
+
import json
|
|
56
|
+
import asyncio
|
|
57
|
+
import datetime
|
|
58
|
+
import time
|
|
59
|
+
import shlex
|
|
60
|
+
import sys
|
|
61
|
+
import os
|
|
62
|
+
from typing import Dict, Any, Optional
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
import json
|
|
66
|
+
import asyncio
|
|
67
|
+
import datetime
|
|
68
|
+
import time
|
|
69
|
+
import shlex
|
|
70
|
+
import sys
|
|
71
|
+
import os
|
|
72
|
+
from typing import Dict, Any, Optional
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class WorkflowCommandsMixin:
|
|
76
|
+
"""Mixin: interactive workflow and edit-review commands."""
|
|
77
|
+
|
|
78
|
+
def cmd_hooks(self, args: str):
|
|
79
|
+
global _JSON_HOOKS
|
|
80
|
+
hooks_dirs = [
|
|
81
|
+
_get_CONFIG_DIR() / "hooks",
|
|
82
|
+
pathlib.Path.cwd() / ".aria" / "hooks",
|
|
83
|
+
]
|
|
84
|
+
parts = args.strip().split(maxsplit=1)
|
|
85
|
+
sub = parts[0].lower() if parts else "list"
|
|
86
|
+
rest = parts[1].strip() if len(parts) > 1 else ""
|
|
87
|
+
|
|
88
|
+
if sub == "reload":
|
|
89
|
+
if _get__HAS_JSON_HOOKS():
|
|
90
|
+
try:
|
|
91
|
+
_JSON_HOOKS = _load_hooks()
|
|
92
|
+
n = sum(len(v) for v in _JSON_HOOKS.values())
|
|
93
|
+
if self.context.has_rich:
|
|
94
|
+
self.context.console.print(f" [green]✓[/green] [dim]hooks.json reloaded ({n} entries)[/dim]")
|
|
95
|
+
else:
|
|
96
|
+
print(f" hooks.json reloaded ({n} entries)")
|
|
97
|
+
except Exception as exc:
|
|
98
|
+
if self.context.has_rich:
|
|
99
|
+
self.context.console.print(f" [red]✗ reload failed: {exc}[/red]")
|
|
100
|
+
else:
|
|
101
|
+
print(f" reload failed: {exc}")
|
|
102
|
+
return
|
|
103
|
+
|
|
104
|
+
if sub == "list":
|
|
105
|
+
if _get__HAS_JSON_HOOKS():
|
|
106
|
+
try:
|
|
107
|
+
from apps.cli.hooks import list_hooks as _list_json_hooks
|
|
108
|
+
_json_rows = _list_json_hooks()
|
|
109
|
+
if _json_rows:
|
|
110
|
+
if self.context.has_rich:
|
|
111
|
+
self.context.console.print()
|
|
112
|
+
self.context.console.print(" [bold]JSON Hooks[/bold] [dim](~/.arthera/hooks.json)[/dim]")
|
|
113
|
+
for r in _json_rows:
|
|
114
|
+
_block = " [red][blocking][/red]" if r["blocking"] else ""
|
|
115
|
+
_tool = f"[{r['tool']}]" if r["tool"] != "*" else ""
|
|
116
|
+
self.context.console.print(
|
|
117
|
+
f" [cyan]{r['event']:<16}[/cyan]{_tool:<14} "
|
|
118
|
+
f"[dim]{r['command']}[/dim]{_block}"
|
|
119
|
+
)
|
|
120
|
+
else:
|
|
121
|
+
for r in _json_rows:
|
|
122
|
+
print(f" {r['event']:<16} {r['tool']:<12} {r['command']}")
|
|
123
|
+
except Exception:
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
found: list[tuple] = []
|
|
127
|
+
for hdir in hooks_dirs:
|
|
128
|
+
if hdir.exists():
|
|
129
|
+
for f in sorted(hdir.iterdir()):
|
|
130
|
+
if f.is_file() and not f.name.startswith("."):
|
|
131
|
+
found.append((str(hdir), f.name, str(f)))
|
|
132
|
+
if not found:
|
|
133
|
+
if self.context.has_rich:
|
|
134
|
+
self.context.console.print(" [dim]No hooks found.[/dim]")
|
|
135
|
+
self.context.console.print(" [dim]Hook dirs:[/dim]")
|
|
136
|
+
for d in hooks_dirs:
|
|
137
|
+
self.context.console.print(f" [dim]{_display_path(d, fallback='hook dir')}[/dim]")
|
|
138
|
+
self.context.console.print(" [dim]Events: prompt_submit response_done tool_use compact[/dim]")
|
|
139
|
+
else:
|
|
140
|
+
print("No hooks. Dirs:", [str(d) for d in hooks_dirs])
|
|
141
|
+
return
|
|
142
|
+
if self.context.has_rich:
|
|
143
|
+
self.context.console.print()
|
|
144
|
+
for hdir, name, path in found:
|
|
145
|
+
self.context.console.print(f" [dim]{name:<28}[/dim] {_display_path(path, fallback='hook')}")
|
|
146
|
+
self.context.console.print()
|
|
147
|
+
else:
|
|
148
|
+
for hdir, name, path in found:
|
|
149
|
+
print(f" {name} {_display_path(path, fallback='hook')}")
|
|
150
|
+
|
|
151
|
+
elif sub == "edit":
|
|
152
|
+
if not rest:
|
|
153
|
+
if _get__HAS_JSON_HOOKS():
|
|
154
|
+
from apps.cli.hooks import hooks_file_path, create_example_hooks
|
|
155
|
+
_hpath = hooks_file_path("global")
|
|
156
|
+
create_example_hooks(_hpath)
|
|
157
|
+
editor = os.getenv("EDITOR", "nano")
|
|
158
|
+
try:
|
|
159
|
+
import subprocess as _sp
|
|
160
|
+
_sp.run([editor, str(_hpath)])
|
|
161
|
+
_JSON_HOOKS = _load_hooks()
|
|
162
|
+
except Exception as exc:
|
|
163
|
+
if self.context.has_rich:
|
|
164
|
+
self.context.console.print(f"[red]Could not open editor: {exc}[/red]")
|
|
165
|
+
else:
|
|
166
|
+
print(f"Could not open editor: {exc}")
|
|
167
|
+
return
|
|
168
|
+
event = rest
|
|
169
|
+
hdir = _get_CONFIG_DIR() / "hooks"
|
|
170
|
+
hdir.mkdir(parents=True, exist_ok=True)
|
|
171
|
+
script = hdir / f"{event}.sh"
|
|
172
|
+
if not script.exists():
|
|
173
|
+
script.write_text(
|
|
174
|
+
f"#!/bin/bash\n# Aria hook: {event}\n# "
|
|
175
|
+
f"Env vars: ARIA_EVENT ARIA_TOOL ARIA_TOOL_PARAMS ARIA_RESPONSE ARIA_SESSION\n\n"
|
|
176
|
+
f'echo "Hook {event} fired"\n',
|
|
177
|
+
encoding="utf-8"
|
|
178
|
+
)
|
|
179
|
+
script.chmod(0o755)
|
|
180
|
+
editor = os.getenv("EDITOR", "nano")
|
|
181
|
+
try:
|
|
182
|
+
import subprocess as _sp
|
|
183
|
+
_sp.run([editor, str(script)])
|
|
184
|
+
except Exception as exc:
|
|
185
|
+
self.context.console.print(f"[red]Could not open editor: {exc}[/red]" if self.context.has_rich else str(exc))
|
|
186
|
+
|
|
187
|
+
elif sub == "run":
|
|
188
|
+
event = rest or "ResponseDone"
|
|
189
|
+
if _get__HAS_JSON_HOOKS():
|
|
190
|
+
_fire_json_hook(event, session_id=getattr(self.terminal, "session_id", ""), hooks=_JSON_HOOKS)
|
|
191
|
+
_run_event_hook(event, {"ARIA_EVENT": event, "ARIA_SESSION": getattr(self.terminal, "session_id", "")})
|
|
192
|
+
if self.context.has_rich:
|
|
193
|
+
self.context.console.print(f" [dim]Hook '{event}' triggered[/dim]")
|
|
194
|
+
else:
|
|
195
|
+
print(f"Hook '{event}' triggered")
|
|
196
|
+
|
|
197
|
+
else:
|
|
198
|
+
if self.context.has_rich:
|
|
199
|
+
self.context.console.print("[dim]Usage: /hooks list|edit [event]|reload|run [event][/dim]")
|
|
200
|
+
else:
|
|
201
|
+
print("Usage: /hooks list|edit [event]|reload|run [event]")
|
|
202
|
+
|
|
203
|
+
async def cmd_regen(self, args: str):
|
|
204
|
+
last_user_msg = None
|
|
205
|
+
for i in range(len(self.terminal.conversation) - 1, -1, -1):
|
|
206
|
+
if self.terminal.conversation[i]["role"] == "assistant":
|
|
207
|
+
self.terminal.conversation.pop(i)
|
|
208
|
+
break
|
|
209
|
+
for msg in reversed(self.terminal.conversation):
|
|
210
|
+
if msg["role"] == "user":
|
|
211
|
+
last_user_msg = msg["content"]
|
|
212
|
+
break
|
|
213
|
+
if last_user_msg:
|
|
214
|
+
for i in range(len(self.terminal.conversation) - 1, -1, -1):
|
|
215
|
+
if self.terminal.conversation[i]["role"] == "user" and self.terminal.conversation[i]["content"] == last_user_msg:
|
|
216
|
+
self.terminal.conversation.pop(i)
|
|
217
|
+
break
|
|
218
|
+
self.context.console.print("[dim]Regenerating...[/dim]" if self.context.has_rich else "Regenerating...")
|
|
219
|
+
await self.terminal.send_message(last_user_msg)
|
|
220
|
+
else:
|
|
221
|
+
self.context.console.print("[dim]No message to regenerate[/dim]" if self.context.has_rich else "Nothing to regenerate")
|
|
222
|
+
|
|
223
|
+
def cmd_undo(self, args: str):
|
|
224
|
+
if len(self.terminal.conversation) < 2:
|
|
225
|
+
self.context.console.print("[dim]Nothing to undo[/dim]" if self.context.has_rich else "Nothing to undo")
|
|
226
|
+
return
|
|
227
|
+
removed = 0
|
|
228
|
+
for role in ("assistant", "user"):
|
|
229
|
+
for i in range(len(self.terminal.conversation) - 1, -1, -1):
|
|
230
|
+
if self.terminal.conversation[i]["role"] == role:
|
|
231
|
+
self.terminal.conversation.pop(i)
|
|
232
|
+
removed += 1
|
|
233
|
+
break
|
|
234
|
+
if self.context.has_rich:
|
|
235
|
+
self.context.console.print(f"[dim]Undone ({removed} messages removed, {len(self.terminal.conversation)} remaining)[/dim]")
|
|
236
|
+
else:
|
|
237
|
+
print(f"Undone ({removed} removed)")
|
|
238
|
+
|
|
239
|
+
def cmd_rewind(self, args: str):
|
|
240
|
+
"""Restore code checkpoints, conversation history, or both."""
|
|
241
|
+
from runtime.checkpoints import (
|
|
242
|
+
CheckpointConflictError,
|
|
243
|
+
CheckpointNotFoundError,
|
|
244
|
+
CheckpointStore,
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
parts = [part for part in args.strip().split() if part]
|
|
248
|
+
assume_yes = "--yes" in parts or "-y" in parts
|
|
249
|
+
parts = [part for part in parts if part not in {"--yes", "-y"}]
|
|
250
|
+
mode = parts[0].lower() if parts else "code"
|
|
251
|
+
identifier = parts[1] if len(parts) > 1 else ""
|
|
252
|
+
is_zh = str(self.terminal.config.get("ui_lang", "en")).lower().startswith("zh")
|
|
253
|
+
|
|
254
|
+
if mode in {"conversation", "chat"}:
|
|
255
|
+
self.cmd_undo("")
|
|
256
|
+
return
|
|
257
|
+
if mode not in {"code", "both", "list"}:
|
|
258
|
+
identifier = parts[0]
|
|
259
|
+
mode = "code"
|
|
260
|
+
|
|
261
|
+
try:
|
|
262
|
+
store = CheckpointStore()
|
|
263
|
+
except Exception as exc:
|
|
264
|
+
message = f"无法打开检查点存储: {exc}" if is_zh else f"Cannot open checkpoint store: {exc}"
|
|
265
|
+
self.context.console.print(f"[red]{message}[/red]" if self.context.has_rich else message)
|
|
266
|
+
return
|
|
267
|
+
|
|
268
|
+
if mode == "list":
|
|
269
|
+
records = store.list(session_id=self.terminal.session_id, status="active", limit=12)
|
|
270
|
+
if not records:
|
|
271
|
+
records = store.list(status="active", limit=12)
|
|
272
|
+
if not records:
|
|
273
|
+
message = "没有可恢复的代码检查点" if is_zh else "No active code checkpoints"
|
|
274
|
+
self.context.console.print(f"[dim]{message}[/dim]" if self.context.has_rich else message)
|
|
275
|
+
return
|
|
276
|
+
if self.context.has_rich:
|
|
277
|
+
self.context.console.print()
|
|
278
|
+
self.context.console.print(" [bold]Code checkpoints[/bold]")
|
|
279
|
+
for record in records:
|
|
280
|
+
paths = ", ".join(pathlib.Path(item.path).name for item in record.files)
|
|
281
|
+
run_label = (record.run_id or "standalone")[:10]
|
|
282
|
+
self.context.console.print(
|
|
283
|
+
f" [#C08050]{record.checkpoint_id[:10]}[/#C08050] "
|
|
284
|
+
f"[dim]{run_label:<10} · {record.source:<10} · {paths}[/dim]"
|
|
285
|
+
)
|
|
286
|
+
self.context.console.print()
|
|
287
|
+
else:
|
|
288
|
+
for record in records:
|
|
289
|
+
paths = ", ".join(pathlib.Path(item.path).name for item in record.files)
|
|
290
|
+
print(f"{record.checkpoint_id[:10]} {record.run_id or '-'} {record.source} {paths}")
|
|
291
|
+
return
|
|
292
|
+
|
|
293
|
+
if not assume_yes:
|
|
294
|
+
prompt = (
|
|
295
|
+
" 恢复代码到检查点状态?检查点之后的修改不会被覆盖,存在冲突时会停止。 [y/N] "
|
|
296
|
+
if is_zh else
|
|
297
|
+
" Rewind code to its checkpoint? Later changes are protected by conflict checks. [y/N] "
|
|
298
|
+
)
|
|
299
|
+
try:
|
|
300
|
+
answer = (self.context.console.input(prompt) if self.context.has_rich else input(prompt)).strip().lower()
|
|
301
|
+
except (EOFError, KeyboardInterrupt):
|
|
302
|
+
return
|
|
303
|
+
if answer not in {"y", "yes"}:
|
|
304
|
+
message = "已取消" if is_zh else "Cancelled"
|
|
305
|
+
self.context.console.print(f"[dim]{message}[/dim]" if self.context.has_rich else message)
|
|
306
|
+
return
|
|
307
|
+
|
|
308
|
+
try:
|
|
309
|
+
if identifier:
|
|
310
|
+
checkpoint = store.get(identifier)
|
|
311
|
+
if checkpoint is not None:
|
|
312
|
+
result = store.restore_checkpoint(checkpoint.checkpoint_id)
|
|
313
|
+
else:
|
|
314
|
+
result = store.restore_run(identifier)
|
|
315
|
+
else:
|
|
316
|
+
try:
|
|
317
|
+
result = store.restore_latest(session_id=self.terminal.session_id)
|
|
318
|
+
except CheckpointNotFoundError:
|
|
319
|
+
result = store.restore_latest()
|
|
320
|
+
except CheckpointConflictError as exc:
|
|
321
|
+
message = f"恢复已停止: {exc}" if is_zh else f"Rewind stopped: {exc}"
|
|
322
|
+
self.context.console.print(f"[red]{message}[/red]" if self.context.has_rich else message)
|
|
323
|
+
return
|
|
324
|
+
except CheckpointNotFoundError:
|
|
325
|
+
message = "未找到可恢复的检查点" if is_zh else "No restorable checkpoint found"
|
|
326
|
+
self.context.console.print(f"[dim]{message}[/dim]" if self.context.has_rich else message)
|
|
327
|
+
return
|
|
328
|
+
except Exception as exc:
|
|
329
|
+
message = f"恢复失败: {exc}" if is_zh else f"Rewind failed: {exc}"
|
|
330
|
+
self.context.console.print(f"[red]{message}[/red]" if self.context.has_rich else message)
|
|
331
|
+
return
|
|
332
|
+
|
|
333
|
+
if mode == "both":
|
|
334
|
+
self.cmd_undo("")
|
|
335
|
+
count = len(result.restored_paths)
|
|
336
|
+
message = (
|
|
337
|
+
f"已恢复 {count} 个文件" if is_zh else f"Rewound {count} file{'s' if count != 1 else ''}"
|
|
338
|
+
)
|
|
339
|
+
if self.context.has_rich:
|
|
340
|
+
self.context.console.print(f"[green]✓[/green] [dim]{message}[/dim]")
|
|
341
|
+
for path in result.restored_paths:
|
|
342
|
+
self.context.console.print(f" [dim]{path}[/dim]")
|
|
343
|
+
else:
|
|
344
|
+
print(message)
|
|
345
|
+
for path in result.restored_paths:
|
|
346
|
+
print(f" {path}")
|
|
347
|
+
|
|
348
|
+
async def cmd_retry(self, args: str):
|
|
349
|
+
last_user_msg = None
|
|
350
|
+
for i in range(len(self.terminal.conversation) - 1, -1, -1):
|
|
351
|
+
if self.terminal.conversation[i]["role"] == "assistant":
|
|
352
|
+
self.terminal.conversation.pop(i)
|
|
353
|
+
break
|
|
354
|
+
for msg in reversed(self.terminal.conversation):
|
|
355
|
+
if msg["role"] == "user":
|
|
356
|
+
last_user_msg = msg["content"]
|
|
357
|
+
break
|
|
358
|
+
if not last_user_msg:
|
|
359
|
+
self.context.console.print("[dim]No message to retry[/dim]" if self.context.has_rich else "Nothing to retry")
|
|
360
|
+
return
|
|
361
|
+
for i in range(len(self.terminal.conversation) - 1, -1, -1):
|
|
362
|
+
if self.terminal.conversation[i]["role"] == "user" and self.terminal.conversation[i]["content"] == last_user_msg:
|
|
363
|
+
self.terminal.conversation.pop(i)
|
|
364
|
+
break
|
|
365
|
+
orig_model_key = resolve_model_key(self.terminal.config.get("model", "qwen2.5:7b"))
|
|
366
|
+
_fallback_model = _get_MODELS().get("qwen-fast") or _get_MODELS().get("qwen7b") or next(iter(_get_MODELS().values()))
|
|
367
|
+
orig_temp = _get_MODELS().get(orig_model_key, _fallback_model).get("temperature", 0.3)
|
|
368
|
+
_get_MODELS()[orig_model_key]["temperature"] = min(0.9, orig_temp + 0.3)
|
|
369
|
+
if self.context.has_rich:
|
|
370
|
+
self.context.console.print(f"[dim]Retrying with temperature {_get_MODELS()[orig_model_key]['temperature']:.1f}...[/dim]")
|
|
371
|
+
else:
|
|
372
|
+
print("Retrying (temp +0.3)...")
|
|
373
|
+
try:
|
|
374
|
+
await self.terminal.send_message(last_user_msg)
|
|
375
|
+
finally:
|
|
376
|
+
_get_MODELS()[orig_model_key]["temperature"] = orig_temp
|
|
377
|
+
|
|
378
|
+
def cmd_note(self, args: str):
|
|
379
|
+
text = args.strip()
|
|
380
|
+
if not text:
|
|
381
|
+
self.context.console.print("[dim]Usage: /note <text>[/dim]" if self.context.has_rich else "Usage: /note <text>")
|
|
382
|
+
return
|
|
383
|
+
aria_md = pathlib.Path.cwd() / "ARIA.md"
|
|
384
|
+
now_str = datetime.now().strftime("%Y-%m-%d %H:%M")
|
|
385
|
+
entry = f"\n- [{now_str}] {text}"
|
|
386
|
+
if aria_md.exists():
|
|
387
|
+
content = aria_md.read_text(encoding="utf-8")
|
|
388
|
+
if "## Notes" not in content:
|
|
389
|
+
content += "\n\n## Notes\n"
|
|
390
|
+
content += entry
|
|
391
|
+
else:
|
|
392
|
+
content = f"# Aria Project Notes\n\n## Notes\n{entry}\n"
|
|
393
|
+
aria_md.write_text(content, encoding="utf-8")
|
|
394
|
+
global _PROJECT_CONTEXT
|
|
395
|
+
_PROJECT_CONTEXT = _load_project_context()
|
|
396
|
+
if self.context.has_rich:
|
|
397
|
+
self.context.console.print(f"[dim]Note saved to {aria_md.name}[/dim]")
|
|
398
|
+
else:
|
|
399
|
+
print(f"Saved to {aria_md.name}")
|
|
400
|
+
|
|
401
|
+
async def cmd_review(self, args: str):
|
|
402
|
+
raw = args.strip()
|
|
403
|
+
policy = self.terminal.config.get("command_policy", "safe")
|
|
404
|
+
|
|
405
|
+
if raw and not raw.startswith("--"):
|
|
406
|
+
p = pathlib.Path(raw).expanduser()
|
|
407
|
+
if not p.exists():
|
|
408
|
+
msg = f"File not found: {raw}"
|
|
409
|
+
self.context.console.print(f"[red]{msg}[/red]") if self.context.has_rich else print(msg)
|
|
410
|
+
return
|
|
411
|
+
_print_phase("Reading file")
|
|
412
|
+
try:
|
|
413
|
+
content = p.read_text(errors="replace")[:12000]
|
|
414
|
+
except Exception as e:
|
|
415
|
+
self.context.console.print(f"[red]Cannot read file: {e}[/red]") if self.context.has_rich else print(f"Cannot read: {e}")
|
|
416
|
+
return
|
|
417
|
+
line_count = content.count("\n")
|
|
418
|
+
if self.context.has_rich:
|
|
419
|
+
self.context.console.print(f" [dim]↳ {p.name} · {line_count} lines[/dim]")
|
|
420
|
+
_print_phase("AI Review")
|
|
421
|
+
prompt = (
|
|
422
|
+
f"请对以下 `{p.name}` 的代码进行专业审查,查找 Bug、安全问题和改进点。\n"
|
|
423
|
+
f"每条发现用严重程度标签开头:**BUG**、**IMPROVEMENT**、**NIT**。\n"
|
|
424
|
+
f"按文件组织输出,直接给结论,不要重复贴出全部代码。\n\n"
|
|
425
|
+
f"```\n{content}\n```"
|
|
426
|
+
)
|
|
427
|
+
review_source, review_name, review_is_diff = content, p.name, False
|
|
428
|
+
else:
|
|
429
|
+
diff_cmd = "git diff --staged" if raw.startswith("--staged") else "git diff HEAD"
|
|
430
|
+
_print_phase("Reading diff")
|
|
431
|
+
tr = _tool_run_command({"command": diff_cmd})
|
|
432
|
+
if not tr.get("success"):
|
|
433
|
+
msg = tr.get("error", "git diff failed")
|
|
434
|
+
self.context.console.print(f"[red]{msg}[/red]") if self.context.has_rich else print(msg)
|
|
435
|
+
return
|
|
436
|
+
diff_text = (tr.get("data") or {}).get("stdout", "").strip()
|
|
437
|
+
if not diff_text:
|
|
438
|
+
self.context.console.print("[dim]No changes to review.[/dim]") if self.context.has_rich else print("No changes to review.")
|
|
439
|
+
return
|
|
440
|
+
_adds = diff_text.count("\n+") - diff_text.count("\n+++")
|
|
441
|
+
_dels = diff_text.count("\n-") - diff_text.count("\n---")
|
|
442
|
+
_files = diff_text.count("\ndiff --git")
|
|
443
|
+
if self.context.has_rich:
|
|
444
|
+
self.context.console.print(f" [dim]↳ {_files} files · +{_adds} −{_dels} lines[/dim]")
|
|
445
|
+
diff_text = diff_text[:12000]
|
|
446
|
+
_print_phase("AI Review")
|
|
447
|
+
prompt = (
|
|
448
|
+
"请审查以下 git diff,找出 Bug、潜在回归、安全问题和代码质量问题。\n"
|
|
449
|
+
"每条发现用严重程度标签开头:**BUG**、**IMPROVEMENT**、**NIT**。\n"
|
|
450
|
+
"按文件分组,直接给出结论。\n\n"
|
|
451
|
+
f"```diff\n{diff_text}\n```"
|
|
452
|
+
)
|
|
453
|
+
review_source, review_name, review_is_diff = diff_text, "staged.diff", True
|
|
454
|
+
|
|
455
|
+
# Run a bounded, deterministic first pass. The conversational model
|
|
456
|
+
# receives it as evidence and must not pretend it accessed anything
|
|
457
|
+
# beyond the supplied file or diff.
|
|
458
|
+
try:
|
|
459
|
+
from agents.code_review import CodeReviewAgent
|
|
460
|
+
|
|
461
|
+
findings = CodeReviewAgent.review_source(
|
|
462
|
+
review_source,
|
|
463
|
+
filename=review_name,
|
|
464
|
+
is_diff=review_is_diff,
|
|
465
|
+
)
|
|
466
|
+
static_review = CodeReviewAgent.format_findings(findings)
|
|
467
|
+
if self.context.has_rich:
|
|
468
|
+
self.context.console.print("[bold]Deterministic Review[/bold]")
|
|
469
|
+
self.context.console.print(static_review)
|
|
470
|
+
else:
|
|
471
|
+
print("Deterministic Review\n" + static_review)
|
|
472
|
+
prompt = (
|
|
473
|
+
"以下是只基于提交文本的确定性检查结果。保留有证据的发现,补充语义、"
|
|
474
|
+
"回归和可测试性审查;不要声称执行过测试或读取过其他文件。\n\n"
|
|
475
|
+
f"{static_review}\n\n{prompt}"
|
|
476
|
+
)
|
|
477
|
+
except Exception as exc:
|
|
478
|
+
logger.debug("Deterministic review unavailable: %s", exc)
|
|
479
|
+
|
|
480
|
+
await self.terminal.send_message(prompt)
|