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,629 @@
|
|
|
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 in {"turn", "turns", "green"}:
|
|
258
|
+
self._rewind_transaction(mode, identifier, assume_yes=assume_yes, is_zh=is_zh)
|
|
259
|
+
return
|
|
260
|
+
if mode not in {"code", "both", "list"}:
|
|
261
|
+
identifier = parts[0]
|
|
262
|
+
mode = "code"
|
|
263
|
+
|
|
264
|
+
try:
|
|
265
|
+
store = CheckpointStore()
|
|
266
|
+
except Exception as exc:
|
|
267
|
+
message = f"无法打开检查点存储: {exc}" if is_zh else f"Cannot open checkpoint store: {exc}"
|
|
268
|
+
self.context.console.print(f"[red]{message}[/red]" if self.context.has_rich else message)
|
|
269
|
+
return
|
|
270
|
+
|
|
271
|
+
if mode == "list":
|
|
272
|
+
records = store.list(session_id=self.terminal.session_id, status="active", limit=12)
|
|
273
|
+
if not records:
|
|
274
|
+
records = store.list(status="active", limit=12)
|
|
275
|
+
if not records:
|
|
276
|
+
message = "没有可恢复的代码检查点" if is_zh else "No active code checkpoints"
|
|
277
|
+
self.context.console.print(f"[dim]{message}[/dim]" if self.context.has_rich else message)
|
|
278
|
+
return
|
|
279
|
+
if self.context.has_rich:
|
|
280
|
+
self.context.console.print()
|
|
281
|
+
self.context.console.print(" [bold]Code checkpoints[/bold]")
|
|
282
|
+
for record in records:
|
|
283
|
+
paths = ", ".join(pathlib.Path(item.path).name for item in record.files)
|
|
284
|
+
run_label = (record.run_id or "standalone")[:10]
|
|
285
|
+
self.context.console.print(
|
|
286
|
+
f" [#C08050]{record.checkpoint_id[:10]}[/#C08050] "
|
|
287
|
+
f"[dim]{run_label:<10} · {record.source:<10} · {paths}[/dim]"
|
|
288
|
+
)
|
|
289
|
+
self.context.console.print()
|
|
290
|
+
else:
|
|
291
|
+
for record in records:
|
|
292
|
+
paths = ", ".join(pathlib.Path(item.path).name for item in record.files)
|
|
293
|
+
print(f"{record.checkpoint_id[:10]} {record.run_id or '-'} {record.source} {paths}")
|
|
294
|
+
return
|
|
295
|
+
|
|
296
|
+
if not assume_yes:
|
|
297
|
+
prompt = (
|
|
298
|
+
" 恢复代码到检查点状态?检查点之后的修改不会被覆盖,存在冲突时会停止。 [y/N] "
|
|
299
|
+
if is_zh else
|
|
300
|
+
" Rewind code to its checkpoint? Later changes are protected by conflict checks. [y/N] "
|
|
301
|
+
)
|
|
302
|
+
try:
|
|
303
|
+
answer = (self.context.console.input(prompt) if self.context.has_rich else input(prompt)).strip().lower()
|
|
304
|
+
except (EOFError, KeyboardInterrupt):
|
|
305
|
+
return
|
|
306
|
+
if answer not in {"y", "yes"}:
|
|
307
|
+
message = "已取消" if is_zh else "Cancelled"
|
|
308
|
+
self.context.console.print(f"[dim]{message}[/dim]" if self.context.has_rich else message)
|
|
309
|
+
return
|
|
310
|
+
|
|
311
|
+
try:
|
|
312
|
+
if identifier:
|
|
313
|
+
checkpoint = store.get(identifier)
|
|
314
|
+
if checkpoint is not None:
|
|
315
|
+
result = store.restore_checkpoint(checkpoint.checkpoint_id)
|
|
316
|
+
else:
|
|
317
|
+
result = store.restore_run(identifier)
|
|
318
|
+
else:
|
|
319
|
+
try:
|
|
320
|
+
result = store.restore_latest(session_id=self.terminal.session_id)
|
|
321
|
+
except CheckpointNotFoundError:
|
|
322
|
+
result = store.restore_latest()
|
|
323
|
+
except CheckpointConflictError as exc:
|
|
324
|
+
message = f"恢复已停止: {exc}" if is_zh else f"Rewind stopped: {exc}"
|
|
325
|
+
self.context.console.print(f"[red]{message}[/red]" if self.context.has_rich else message)
|
|
326
|
+
return
|
|
327
|
+
except CheckpointNotFoundError:
|
|
328
|
+
message = "未找到可恢复的检查点" if is_zh else "No restorable checkpoint found"
|
|
329
|
+
self.context.console.print(f"[dim]{message}[/dim]" if self.context.has_rich else message)
|
|
330
|
+
return
|
|
331
|
+
except Exception as exc:
|
|
332
|
+
message = f"恢复失败: {exc}" if is_zh else f"Rewind failed: {exc}"
|
|
333
|
+
self.context.console.print(f"[red]{message}[/red]" if self.context.has_rich else message)
|
|
334
|
+
return
|
|
335
|
+
|
|
336
|
+
if mode == "both":
|
|
337
|
+
self.cmd_undo("")
|
|
338
|
+
count = len(result.restored_paths)
|
|
339
|
+
message = (
|
|
340
|
+
f"已恢复 {count} 个文件" if is_zh else f"Rewound {count} file{'s' if count != 1 else ''}"
|
|
341
|
+
)
|
|
342
|
+
if self.context.has_rich:
|
|
343
|
+
self.context.console.print(f"[green]✓[/green] [dim]{message}[/dim]")
|
|
344
|
+
for path in result.restored_paths:
|
|
345
|
+
self.context.console.print(f" [dim]{path}[/dim]")
|
|
346
|
+
else:
|
|
347
|
+
print(message)
|
|
348
|
+
for path in result.restored_paths:
|
|
349
|
+
print(f" {path}")
|
|
350
|
+
|
|
351
|
+
def _rewind_transaction(self, mode: str, ref: str, *, assume_yes: bool, is_zh: bool) -> None:
|
|
352
|
+
"""``/rewind turns`` · ``/rewind turn [N|id]`` · ``/rewind green``.
|
|
353
|
+
|
|
354
|
+
A turn rewind puts back files, conversation, task list, approvals,
|
|
355
|
+
background tasks and the task worktree as they were before that turn.
|
|
356
|
+
"""
|
|
357
|
+
from apps.cli import transactions
|
|
358
|
+
from aria_code.runtime.checkpoints import CheckpointConflictError
|
|
359
|
+
|
|
360
|
+
con = self.context.console if self.context.has_rich else None
|
|
361
|
+
|
|
362
|
+
def say(text: str, style: str = "dim") -> None:
|
|
363
|
+
if con is not None:
|
|
364
|
+
from rich.markup import escape
|
|
365
|
+
con.print(f"[{style}]{escape(text)}[/{style}]" if style else escape(text))
|
|
366
|
+
else:
|
|
367
|
+
print(text)
|
|
368
|
+
|
|
369
|
+
session_id = str(self.terminal.session_id or "default")
|
|
370
|
+
store = transactions.store()
|
|
371
|
+
if mode == "turns":
|
|
372
|
+
points = store.list(session_id)
|
|
373
|
+
if not points:
|
|
374
|
+
say("还没有可回退的轮次" if is_zh else "No turns to rewind yet")
|
|
375
|
+
return
|
|
376
|
+
say("回退点(✓ 检查通过 ✗ 失败 ≈ 仅改动前已有的失败 · 未验证)" if is_zh
|
|
377
|
+
else "Rewind points (✓ checks passed ✗ failed ≈ only failures that predate it · unverified)", "bold")
|
|
378
|
+
for line in transactions.describe(points):
|
|
379
|
+
say(line, "")
|
|
380
|
+
say("/rewind turn N · /rewind green")
|
|
381
|
+
return
|
|
382
|
+
|
|
383
|
+
point = store.latest_green(session_id) if mode == "green" else store.find(session_id, ref or "1")
|
|
384
|
+
if point is None:
|
|
385
|
+
if mode == "green":
|
|
386
|
+
say("没有检查通过的回退点" if is_zh else "No point where the checks passed")
|
|
387
|
+
else:
|
|
388
|
+
say(f"没有回退点 {ref or '1'}" if is_zh else f"No rewind point {ref or '1'}; see /rewind turns")
|
|
389
|
+
return
|
|
390
|
+
if not assume_yes:
|
|
391
|
+
question = (
|
|
392
|
+
f" 回退到第 {point.turn} 轮之前(文件、对话、待办、授权一起恢复)? [y/N] " if is_zh else
|
|
393
|
+
f" Rewind to before turn {point.turn} — files, conversation, tasks and approvals? [y/N] "
|
|
394
|
+
)
|
|
395
|
+
try:
|
|
396
|
+
answer = (con.input(question) if con is not None else input(question)).strip().lower()
|
|
397
|
+
except (EOFError, KeyboardInterrupt):
|
|
398
|
+
return
|
|
399
|
+
if answer not in {"y", "yes"}:
|
|
400
|
+
say("已取消" if is_zh else "Cancelled")
|
|
401
|
+
return
|
|
402
|
+
try:
|
|
403
|
+
outcome = transactions.rewind(self.terminal, point)
|
|
404
|
+
except CheckpointConflictError as exc:
|
|
405
|
+
say((f"回退已停止,未做任何改动: {exc}" if is_zh else f"Rewind stopped, nothing changed: {exc}"), "red")
|
|
406
|
+
return
|
|
407
|
+
except Exception as exc:
|
|
408
|
+
say((f"回退失败: {exc}" if is_zh else f"Rewind failed: {exc}"), "red")
|
|
409
|
+
return
|
|
410
|
+
for index, line in enumerate(outcome.lines()):
|
|
411
|
+
say(line, "green" if index == 0 else "dim")
|
|
412
|
+
|
|
413
|
+
def _workflow_workspace(self) -> str:
|
|
414
|
+
return self.terminal.config.get("_session_workspace_root") or os.getcwd()
|
|
415
|
+
|
|
416
|
+
def _wf_say(self, text: str, style: str = "dim") -> None:
|
|
417
|
+
if self.context.has_rich:
|
|
418
|
+
from rich.markup import escape
|
|
419
|
+
self.context.console.print(f"[{style}]{escape(text)}[/{style}]" if style else escape(text))
|
|
420
|
+
else:
|
|
421
|
+
print(text)
|
|
422
|
+
|
|
423
|
+
def _wf_ask(self, question: str) -> bool:
|
|
424
|
+
try:
|
|
425
|
+
answer = (self.context.console.input(question) if self.context.has_rich else input(question))
|
|
426
|
+
except (EOFError, KeyboardInterrupt):
|
|
427
|
+
return False
|
|
428
|
+
return answer.strip().lower() in {"y", "yes"}
|
|
429
|
+
|
|
430
|
+
async def cmd_workflow(self, args: str):
|
|
431
|
+
"""/workflow list | show <name> | run <name> [args] | new <name>."""
|
|
432
|
+
from aria_code.runtime import workflows
|
|
433
|
+
|
|
434
|
+
parts = args.strip().split(maxsplit=2)
|
|
435
|
+
sub = parts[0].lower() if parts else "list"
|
|
436
|
+
name = parts[1].lstrip("/").lower() if len(parts) > 1 else ""
|
|
437
|
+
rest = parts[2] if len(parts) > 2 else ""
|
|
438
|
+
workspace = self._workflow_workspace()
|
|
439
|
+
|
|
440
|
+
if sub == "list":
|
|
441
|
+
found = workflows.names(workspace)
|
|
442
|
+
if not found:
|
|
443
|
+
self._wf_say("No workflows. /workflow new <name> creates .aria/workflows/<name>.yaml")
|
|
444
|
+
return
|
|
445
|
+
for item in found:
|
|
446
|
+
try:
|
|
447
|
+
workflow = workflows.find(workspace, item)
|
|
448
|
+
self._wf_say(f" /{item:<14} {workflow.description or ''} ({len(workflow.steps)} steps)", "")
|
|
449
|
+
except workflows.WorkflowError as exc:
|
|
450
|
+
self._wf_say(f" /{item:<14} invalid: {exc}", "red")
|
|
451
|
+
return
|
|
452
|
+
if sub == "new":
|
|
453
|
+
if not name:
|
|
454
|
+
self._wf_say("Usage: /workflow new <name>")
|
|
455
|
+
return
|
|
456
|
+
target = pathlib.Path(workspace) / ".aria" / "workflows" / f"{name}.yaml"
|
|
457
|
+
if target.exists():
|
|
458
|
+
self._wf_say(f"{target} already exists", "yellow")
|
|
459
|
+
return
|
|
460
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
461
|
+
target.write_text(workflows.TEMPLATE.format(name=name), encoding="utf-8")
|
|
462
|
+
self._wf_say(f"Created {target}; edit its steps, then run /{name}", "green")
|
|
463
|
+
return
|
|
464
|
+
if sub not in {"show", "run"} or not name:
|
|
465
|
+
self._wf_say("Usage: /workflow list | show <name> | run <name> [args] | new <name>")
|
|
466
|
+
return
|
|
467
|
+
try:
|
|
468
|
+
workflow = workflows.find(workspace, name)
|
|
469
|
+
except workflows.WorkflowError as exc:
|
|
470
|
+
self._wf_say(str(exc), "red")
|
|
471
|
+
return
|
|
472
|
+
if workflow is None:
|
|
473
|
+
self._wf_say(f"No workflow '{name}' in .aria/workflows; /workflow list", "yellow")
|
|
474
|
+
return
|
|
475
|
+
if sub == "show":
|
|
476
|
+
for line in workflow.outline():
|
|
477
|
+
self._wf_say(line, "")
|
|
478
|
+
return
|
|
479
|
+
await self._run_workflow(workflow, rest)
|
|
480
|
+
|
|
481
|
+
async def _run_workflow(self, workflow, args: str) -> None:
|
|
482
|
+
from aria_code.runtime.workflows import TrustStore
|
|
483
|
+
from aria_code.apps.cli.workflow_runner import run_workflow, summary_lines
|
|
484
|
+
|
|
485
|
+
trust = TrustStore.load()
|
|
486
|
+
if not trust.trusted(workflow):
|
|
487
|
+
self._wf_say("This workflow comes from the repository and has not run here before"
|
|
488
|
+
" (or its file changed). It will run:", "yellow")
|
|
489
|
+
for line in workflow.outline():
|
|
490
|
+
self._wf_say(line, "")
|
|
491
|
+
if not self._wf_ask(" Trust and run it? [y/N] "):
|
|
492
|
+
self._wf_say("Cancelled")
|
|
493
|
+
return
|
|
494
|
+
trust.trust(workflow)
|
|
495
|
+
results = await run_workflow(self.terminal, workflow, args, ask=self._wf_ask, say=self._wf_say)
|
|
496
|
+
for index, line in enumerate(summary_lines(workflow, results)):
|
|
497
|
+
style = ("red" if "FAILED" in line else "yellow" if "STOPPED" in line else "green") if index == 0 else "dim"
|
|
498
|
+
self._wf_say(line, style)
|
|
499
|
+
|
|
500
|
+
async def cmd_retry(self, args: str):
|
|
501
|
+
last_user_msg = None
|
|
502
|
+
for i in range(len(self.terminal.conversation) - 1, -1, -1):
|
|
503
|
+
if self.terminal.conversation[i]["role"] == "assistant":
|
|
504
|
+
self.terminal.conversation.pop(i)
|
|
505
|
+
break
|
|
506
|
+
for msg in reversed(self.terminal.conversation):
|
|
507
|
+
if msg["role"] == "user":
|
|
508
|
+
last_user_msg = msg["content"]
|
|
509
|
+
break
|
|
510
|
+
if not last_user_msg:
|
|
511
|
+
self.context.console.print("[dim]No message to retry[/dim]" if self.context.has_rich else "Nothing to retry")
|
|
512
|
+
return
|
|
513
|
+
for i in range(len(self.terminal.conversation) - 1, -1, -1):
|
|
514
|
+
if self.terminal.conversation[i]["role"] == "user" and self.terminal.conversation[i]["content"] == last_user_msg:
|
|
515
|
+
self.terminal.conversation.pop(i)
|
|
516
|
+
break
|
|
517
|
+
orig_model_key = resolve_model_key(self.terminal.config.get("model", "qwen2.5:7b"))
|
|
518
|
+
_fallback_model = _get_MODELS().get("qwen-fast") or _get_MODELS().get("qwen7b") or next(iter(_get_MODELS().values()))
|
|
519
|
+
orig_temp = _get_MODELS().get(orig_model_key, _fallback_model).get("temperature", 0.3)
|
|
520
|
+
_get_MODELS()[orig_model_key]["temperature"] = min(0.9, orig_temp + 0.3)
|
|
521
|
+
if self.context.has_rich:
|
|
522
|
+
self.context.console.print(f"[dim]Retrying with temperature {_get_MODELS()[orig_model_key]['temperature']:.1f}...[/dim]")
|
|
523
|
+
else:
|
|
524
|
+
print("Retrying (temp +0.3)...")
|
|
525
|
+
try:
|
|
526
|
+
await self.terminal.send_message(last_user_msg)
|
|
527
|
+
finally:
|
|
528
|
+
_get_MODELS()[orig_model_key]["temperature"] = orig_temp
|
|
529
|
+
|
|
530
|
+
def cmd_note(self, args: str):
|
|
531
|
+
text = args.strip()
|
|
532
|
+
if not text:
|
|
533
|
+
self.context.console.print("[dim]Usage: /note <text>[/dim]" if self.context.has_rich else "Usage: /note <text>")
|
|
534
|
+
return
|
|
535
|
+
aria_md = pathlib.Path.cwd() / "ARIA.md"
|
|
536
|
+
now_str = datetime.now().strftime("%Y-%m-%d %H:%M")
|
|
537
|
+
entry = f"\n- [{now_str}] {text}"
|
|
538
|
+
if aria_md.exists():
|
|
539
|
+
content = aria_md.read_text(encoding="utf-8")
|
|
540
|
+
if "## Notes" not in content:
|
|
541
|
+
content += "\n\n## Notes\n"
|
|
542
|
+
content += entry
|
|
543
|
+
else:
|
|
544
|
+
content = f"# Aria Project Notes\n\n## Notes\n{entry}\n"
|
|
545
|
+
aria_md.write_text(content, encoding="utf-8")
|
|
546
|
+
global _PROJECT_CONTEXT
|
|
547
|
+
_PROJECT_CONTEXT = _load_project_context()
|
|
548
|
+
if self.context.has_rich:
|
|
549
|
+
self.context.console.print(f"[dim]Note saved to {aria_md.name}[/dim]")
|
|
550
|
+
else:
|
|
551
|
+
print(f"Saved to {aria_md.name}")
|
|
552
|
+
|
|
553
|
+
async def cmd_review(self, args: str):
|
|
554
|
+
"""Review a change with an isolated reviewer: /review [--staged | --base B | --commit SHA | PATH] [--json]."""
|
|
555
|
+
from aria_code import review_service as rs
|
|
556
|
+
from aria_code.apps.cli.review_runner import make_model_call
|
|
557
|
+
|
|
558
|
+
console = self.context.console if self.context.has_rich else None
|
|
559
|
+
say = (lambda text, style="": console.print(f"[{style}]{text}[/{style}]" if style else text)) if console \
|
|
560
|
+
else (lambda text, style="": print(text))
|
|
561
|
+
lang = "zh" if str(self.terminal.config.get("ui_lang", "en")).lower().startswith("zh") else "en"
|
|
562
|
+
try:
|
|
563
|
+
tokens = shlex.split(args)
|
|
564
|
+
as_json = "--json" in tokens
|
|
565
|
+
target = rs.target_from_args([t for t in tokens if t != "--json"])
|
|
566
|
+
inp = rs.collect(target, pathlib.Path.cwd())
|
|
567
|
+
except (ValueError, rs.ReviewError) as exc:
|
|
568
|
+
say(str(exc), "red")
|
|
569
|
+
say("Usage: /review [--staged | --base BRANCH | --commit SHA | PATH] [--json]", "dim")
|
|
570
|
+
return
|
|
571
|
+
if not inp.diff.strip():
|
|
572
|
+
say("No changes to review." if lang == "en" else "没有可审查的改动。", "dim")
|
|
573
|
+
return
|
|
574
|
+
say(f" ↳ {target.describe()} · {len(inp.files)} files · +{inp.added} −{inp.removed}", "dim")
|
|
575
|
+
if inp.truncated:
|
|
576
|
+
say(f" ↳ too large to review whole; not included: {', '.join(inp.omitted_files)}", "yellow")
|
|
577
|
+
_print_phase("Reviewing")
|
|
578
|
+
try:
|
|
579
|
+
result = await rs.run_review(inp, make_model_call(self.terminal.config), lang=lang)
|
|
580
|
+
except rs.ReviewError as exc:
|
|
581
|
+
say(str(exc), "red")
|
|
582
|
+
return
|
|
583
|
+
if as_json:
|
|
584
|
+
print(json.dumps(result.to_dict(), ensure_ascii=False, indent=2))
|
|
585
|
+
elif console:
|
|
586
|
+
_print_review(console, result, lang)
|
|
587
|
+
else:
|
|
588
|
+
print(rs.render_text(result, lang=lang))
|
|
589
|
+
# The main conversation remembers the review, so "fix finding 2" works.
|
|
590
|
+
self.terminal.conversation.append({"role": "user", "content": f"/review {args}".strip()})
|
|
591
|
+
self.terminal.conversation.append({"role": "assistant", "content": rs.history_note(result)})
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
_PRIORITY_STYLE = {0: "bold red", 1: "red", 2: "yellow", 3: "dim"}
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
def _print_review(console, result, lang: str) -> None:
|
|
598
|
+
from rich.markup import escape
|
|
599
|
+
|
|
600
|
+
from aria_code import review_service as rs
|
|
601
|
+
|
|
602
|
+
if not result.structured:
|
|
603
|
+
console.print(escape(rs.render_text(result, lang=lang)))
|
|
604
|
+
return
|
|
605
|
+
t = rs._TEXT["zh" if lang == "zh" else "en"]
|
|
606
|
+
verdict, style = ((t["unknown"], "dim") if result.correct is None else
|
|
607
|
+
(t["correct"], "green") if result.correct else (t["incorrect"], "red"))
|
|
608
|
+
console.print(f"[bold {style}]{verdict}[/bold {style}] [dim]· {t['confidence']} {result.confidence:.2f}[/dim]")
|
|
609
|
+
if result.explanation:
|
|
610
|
+
console.print(escape(result.explanation))
|
|
611
|
+
if not result.findings:
|
|
612
|
+
console.print(f"[dim]{t['none']}[/dim]")
|
|
613
|
+
shown_outside = False
|
|
614
|
+
for number, f in enumerate(result.findings, 1):
|
|
615
|
+
if not f.in_change and not shown_outside:
|
|
616
|
+
console.print(f"[dim]— {t['outside']} —[/dim]")
|
|
617
|
+
shown_outside = True
|
|
618
|
+
style = _PRIORITY_STYLE.get(f.priority, "dim")
|
|
619
|
+
console.print(f"\n[{style}]{number}. {escape('[' + f.label + ']')}[/{style}] [bold]{escape(f.title)}[/bold] "
|
|
620
|
+
f"[dim]{escape(f.location)} · {f.confidence:.2f}[/dim]")
|
|
621
|
+
# Under the finding's title, wrapped rows included: printed with
|
|
622
|
+
# three leading spaces, a long explanation fell back to column 0.
|
|
623
|
+
from aria_code.ui.render.output import print_hanging
|
|
624
|
+
|
|
625
|
+
for line in f.body.splitlines():
|
|
626
|
+
if line.strip():
|
|
627
|
+
print_hanging(console, " ", line.strip())
|
|
628
|
+
if result.omitted_files:
|
|
629
|
+
console.print(f"\n[yellow]{t['omitted']}: {escape(', '.join(result.omitted_files))}[/yellow]")
|