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,379 @@
|
|
|
1
|
+
"""BusinessWorkflowCommandsMixin — research, earnings, realty, ops workflow commands."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from aria_code.apps.cli.i18n import ui_text
|
|
6
|
+
|
|
7
|
+
from ._business_render import p, print_realty_result, print_risk_scan
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import asyncio
|
|
12
|
+
import datetime
|
|
13
|
+
import time
|
|
14
|
+
import shlex
|
|
15
|
+
from typing import Dict, Any, Optional
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
import asyncio
|
|
20
|
+
import datetime
|
|
21
|
+
import time
|
|
22
|
+
import shlex
|
|
23
|
+
import sys
|
|
24
|
+
import os
|
|
25
|
+
from typing import Dict, Any, Optional
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
import json
|
|
29
|
+
import asyncio
|
|
30
|
+
import datetime
|
|
31
|
+
import time
|
|
32
|
+
import shlex
|
|
33
|
+
import sys
|
|
34
|
+
import os
|
|
35
|
+
from typing import Dict, Any, Optional
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class BusinessWorkflowCommandsMixin:
|
|
39
|
+
"""Mixin: financial research and realty/operations workflow commands."""
|
|
40
|
+
|
|
41
|
+
async def cmd_research(self, args: str):
|
|
42
|
+
sym = args.strip().upper() or "AAPL"
|
|
43
|
+
# Route research through the deterministic team workflow so data
|
|
44
|
+
# fetching, rendering, and artifact saving happen in one service path.
|
|
45
|
+
await self.cmd_team(f"{sym} --full")
|
|
46
|
+
|
|
47
|
+
async def cmd_earnings_workflow(self, args: str):
|
|
48
|
+
"""/earnings SYMBOL — the earnings themselves; --report writes the Markdown report."""
|
|
49
|
+
parts = args.strip().split()
|
|
50
|
+
sym = next((t.upper() for t in parts if not t.startswith("--")), "AAPL")
|
|
51
|
+
if "--report" in parts:
|
|
52
|
+
period = " ".join(t for t in parts[1:] if not t.startswith("--")) or "最近一个季度"
|
|
53
|
+
report_type = "deep" if any(k in period.lower() for k in ("deep", "深度", "全年", "年报", "10-k")) else "standard"
|
|
54
|
+
await self.cmd_report(f"{sym} --format md --type {report_type}")
|
|
55
|
+
return
|
|
56
|
+
from aria_code.apps.cli.earnings_view import fetch_earnings, render_earnings
|
|
57
|
+
|
|
58
|
+
lang = "zh" if str(self.terminal.config.get("ui_lang", "en")).lower().startswith("zh") else "en"
|
|
59
|
+
status = ui_text(self, f"获取 {sym} 财报数据", f"Fetching {sym} earnings")
|
|
60
|
+
if self.context.has_rich:
|
|
61
|
+
with self.context.console.status(f"[dim]{status}…[/dim]", spinner="dots"):
|
|
62
|
+
data = await asyncio.get_event_loop().run_in_executor(None, fetch_earnings, sym)
|
|
63
|
+
else:
|
|
64
|
+
data = await asyncio.get_event_loop().run_in_executor(None, fetch_earnings, sym)
|
|
65
|
+
if not data.get("success"):
|
|
66
|
+
from ._ui import print_error
|
|
67
|
+
print_error(self.context, data.get("error", "No earnings data"),
|
|
68
|
+
ui_text(self, f"可以试试 /report {sym}", f"Try /report {sym} instead"))
|
|
69
|
+
return
|
|
70
|
+
if self.context.has_rich:
|
|
71
|
+
render_earnings(data, self.context.console, lang)
|
|
72
|
+
else:
|
|
73
|
+
for row in data.get("history", []):
|
|
74
|
+
print(f" {row['date']} est {row.get('estimate')} actual {row['reported']} "
|
|
75
|
+
f"surprise {row.get('surprise_pct')}")
|
|
76
|
+
|
|
77
|
+
async def cmd_asset_diag(self, args: str):
|
|
78
|
+
asset_id = args.strip()
|
|
79
|
+
if not asset_id:
|
|
80
|
+
p(self.context, "用法: /asset-diag <资产ID或名称> 例: /asset-diag asset_000001", "dim")
|
|
81
|
+
return
|
|
82
|
+
asset_info = {}
|
|
83
|
+
api_url = self.terminal.config.get("api_url", "http://localhost:8000")
|
|
84
|
+
try:
|
|
85
|
+
import aiohttp
|
|
86
|
+
async with aiohttp.ClientSession(trust_env=True) as sess:
|
|
87
|
+
async with sess.get(
|
|
88
|
+
f"{api_url}/api/realty/assets/{asset_id}",
|
|
89
|
+
timeout=aiohttp.ClientTimeout(total=5)
|
|
90
|
+
) as resp:
|
|
91
|
+
if resp.status == 200:
|
|
92
|
+
body = await resp.json()
|
|
93
|
+
raw = body.get("data", {})
|
|
94
|
+
asset_info = {
|
|
95
|
+
"area": raw.get("area_sqm", 0),
|
|
96
|
+
"location": raw.get("address", asset_id),
|
|
97
|
+
"vacancy_days": raw.get("vacancy_days", 0),
|
|
98
|
+
"expected_rent": raw.get("monthly_rent_market", 0),
|
|
99
|
+
"allowed_business": raw.get("allowed_business_types", []),
|
|
100
|
+
"property_state": raw.get("property_state", "正常"),
|
|
101
|
+
"floor_height": raw.get("floor_height", 0),
|
|
102
|
+
}
|
|
103
|
+
p(self.context, f"已从 API 加载资产: {raw.get('name', asset_id)}", "ok")
|
|
104
|
+
except Exception:
|
|
105
|
+
pass
|
|
106
|
+
if not asset_info:
|
|
107
|
+
self._realty_needs(asset_id, "Usage: /asset-diag <asset_id>")
|
|
108
|
+
return
|
|
109
|
+
await self._run_realty_agent("asset_diagnosis", asset_id, {"asset_info": asset_info})
|
|
110
|
+
|
|
111
|
+
async def cmd_contract_draft(self, args: str):
|
|
112
|
+
parts = args.split() if args else []
|
|
113
|
+
project_id = parts[0] if parts and not parts[0].startswith("--") else ""
|
|
114
|
+
nego = {"guaranteed_amount": 0, "revenue_share_pct": 0}
|
|
115
|
+
for i, p in enumerate(parts):
|
|
116
|
+
if p == "--guaranteed" and i + 1 < len(parts):
|
|
117
|
+
try:
|
|
118
|
+
nego["guaranteed_amount"] = float(parts[i + 1])
|
|
119
|
+
except ValueError:
|
|
120
|
+
pass
|
|
121
|
+
elif p == "--share" and i + 1 < len(parts):
|
|
122
|
+
try:
|
|
123
|
+
nego["revenue_share_pct"] = float(parts[i + 1])
|
|
124
|
+
except ValueError:
|
|
125
|
+
pass
|
|
126
|
+
if not project_id or not (nego["guaranteed_amount"] or nego["revenue_share_pct"]):
|
|
127
|
+
from ._ui import print_error
|
|
128
|
+
print_error(self.context,
|
|
129
|
+
ui_text(self, "起草合同需要项目 ID 和至少一项条款。", "A draft needs a project ID and at least one term."),
|
|
130
|
+
"Usage: /contract-draft <project_id> --guaranteed 30000 --share 10")
|
|
131
|
+
return
|
|
132
|
+
await self._run_realty_agent("contract_rules", project_id, {
|
|
133
|
+
"negotiation": nego,
|
|
134
|
+
"asset_info": {"name": project_id},
|
|
135
|
+
"operator_info": {},
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
async def cmd_revenue_calc(self, args: str):
|
|
139
|
+
parts = args.split() if args else []
|
|
140
|
+
if len(parts) < 2:
|
|
141
|
+
p(self.context, "用法: /revenue-calc <project_id> <总流水> [退款] 例: /revenue-calc proj_001 200000", "dim")
|
|
142
|
+
return
|
|
143
|
+
project_id = parts[0]
|
|
144
|
+
try:
|
|
145
|
+
gross = float(parts[1])
|
|
146
|
+
refunds = float(parts[2]) if len(parts) > 2 else 0.0
|
|
147
|
+
except ValueError:
|
|
148
|
+
p(self.context, "流水金额必须为数字", "error")
|
|
149
|
+
return
|
|
150
|
+
api_url = self.terminal.config.get("api_url", "http://localhost:8000")
|
|
151
|
+
rules = {}
|
|
152
|
+
try:
|
|
153
|
+
import aiohttp
|
|
154
|
+
async with aiohttp.ClientSession(trust_env=True) as sess:
|
|
155
|
+
async with sess.get(f"{api_url}/api/realty/contracts/{project_id}",
|
|
156
|
+
timeout=aiohttp.ClientTimeout(total=5)) as resp:
|
|
157
|
+
if resp.status == 200:
|
|
158
|
+
body = await resp.json()
|
|
159
|
+
rules = body.get("data", {})
|
|
160
|
+
except Exception:
|
|
161
|
+
pass
|
|
162
|
+
if not rules:
|
|
163
|
+
self._realty_needs(project_id, "Usage: /revenue-calc <project_id> <gross> [refunds]")
|
|
164
|
+
return
|
|
165
|
+
await self._run_realty_agent("revenue_share", project_id, {
|
|
166
|
+
"contract_rules": rules,
|
|
167
|
+
"transaction_data": {"gross_revenue": gross, "refunds": refunds},
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
async def cmd_realty_risk_scan(self, args: str):
|
|
171
|
+
project_id = args.strip()
|
|
172
|
+
if not project_id:
|
|
173
|
+
self._realty_needs(None, "Usage: /risk-scan <project_id>")
|
|
174
|
+
return
|
|
175
|
+
if self.context.has_rich:
|
|
176
|
+
self.context.console.print(f"\n [bold]{ui_text(self, '风险扫描', 'Risk scan')}[/bold] "
|
|
177
|
+
f"{ui_text(self, '项目', 'project')}: [cyan]{project_id}[/cyan]")
|
|
178
|
+
api_url = self.terminal.config.get("api_url", "http://localhost:8000")
|
|
179
|
+
try:
|
|
180
|
+
import aiohttp
|
|
181
|
+
async with aiohttp.ClientSession(trust_env=True) as sess:
|
|
182
|
+
async with sess.get(
|
|
183
|
+
f"{api_url}/api/realty/risks/scan/{project_id}",
|
|
184
|
+
timeout=aiohttp.ClientTimeout(total=10)
|
|
185
|
+
) as resp:
|
|
186
|
+
if resp.status == 200:
|
|
187
|
+
data = await resp.json()
|
|
188
|
+
print_risk_scan(self.context, data)
|
|
189
|
+
return
|
|
190
|
+
except Exception:
|
|
191
|
+
pass
|
|
192
|
+
# Running the team on {} produced findings about a project it knew
|
|
193
|
+
# nothing of.
|
|
194
|
+
self._realty_needs(project_id, "Usage: /risk-scan <project_id>")
|
|
195
|
+
|
|
196
|
+
async def cmd_ops_report(self, args: str):
|
|
197
|
+
project_id = args.strip()
|
|
198
|
+
if not project_id:
|
|
199
|
+
self._realty_needs(None, "Usage: /ops-report <project_id>")
|
|
200
|
+
return
|
|
201
|
+
api_url = self.terminal.config.get("api_url", "http://localhost:8000")
|
|
202
|
+
project_info = {"name": project_id, "area": 0, "business_type": "未知"}
|
|
203
|
+
performance_data = {}
|
|
204
|
+
marketing_data = {}
|
|
205
|
+
try:
|
|
206
|
+
import aiohttp
|
|
207
|
+
async with aiohttp.ClientSession(trust_env=True) as sess:
|
|
208
|
+
async with sess.get(
|
|
209
|
+
f"{api_url}/api/realty/assets/{project_id}",
|
|
210
|
+
timeout=aiohttp.ClientTimeout(total=5)
|
|
211
|
+
) as resp:
|
|
212
|
+
if resp.status == 200:
|
|
213
|
+
raw = (await resp.json()).get("data", {})
|
|
214
|
+
project_info = {
|
|
215
|
+
"name": raw.get("name", project_id),
|
|
216
|
+
"area": raw.get("area_sqm", 0),
|
|
217
|
+
"business_type": raw.get("current_business_type", "未知"),
|
|
218
|
+
"open_date": raw.get("open_date", ""),
|
|
219
|
+
}
|
|
220
|
+
async with sess.get(
|
|
221
|
+
f"{api_url}/api/realty/revenue/splits?project_id={project_id}&page_size=3",
|
|
222
|
+
timeout=aiohttp.ClientTimeout(total=5)
|
|
223
|
+
) as resp2:
|
|
224
|
+
if resp2.status == 200:
|
|
225
|
+
splits = (await resp2.json()).get("data", {}).get("splits", [])
|
|
226
|
+
if splits:
|
|
227
|
+
revenues = [s["split_result"].get("gross_revenue", 0) for s in splits]
|
|
228
|
+
avg_rev = sum(revenues) / len(revenues)
|
|
229
|
+
performance_data = {"monthly_revenue": avg_rev, "daily_visits": 0}
|
|
230
|
+
p(self.context, f"已加载近 {len(splits)} 期分账数据,月均流水 {avg_rev:,.0f}元", "ok")
|
|
231
|
+
except Exception:
|
|
232
|
+
pass
|
|
233
|
+
if not performance_data:
|
|
234
|
+
self._realty_needs(project_id, "Usage: /ops-report <project_id>")
|
|
235
|
+
return
|
|
236
|
+
await self._run_realty_agent("ops_optimize", project_id, {
|
|
237
|
+
"project_info": project_info,
|
|
238
|
+
"performance_data": performance_data,
|
|
239
|
+
"marketing_data": marketing_data,
|
|
240
|
+
"peer_benchmarks": {"revenue_per_sqm": 300},
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
async def cmd_exit_calc(self, args: str):
|
|
244
|
+
parts = args.split() if args else []
|
|
245
|
+
project_id = parts[0] if parts and not parts[0].startswith("--") else ""
|
|
246
|
+
if not project_id:
|
|
247
|
+
self._realty_needs(None, "Usage: /exit-calc <project_id> [--reason …]")
|
|
248
|
+
return
|
|
249
|
+
contract_loaded = False
|
|
250
|
+
reason = "到期终止"
|
|
251
|
+
for i, p in enumerate(parts):
|
|
252
|
+
if p == "--reason" and i + 1 < len(parts):
|
|
253
|
+
reason = " ".join(parts[i + 1:])
|
|
254
|
+
break
|
|
255
|
+
api_url = self.terminal.config.get("api_url", "http://localhost:8000")
|
|
256
|
+
project_info = {"name": project_id}
|
|
257
|
+
financials = {"deposit_amount": 0, "unpaid_invoices": 0,
|
|
258
|
+
"guaranteed_monthly": 0, "exit_penalty_months": 3,
|
|
259
|
+
"prepayment_received": 0, "renovation_cost": 0}
|
|
260
|
+
try:
|
|
261
|
+
import aiohttp
|
|
262
|
+
async with aiohttp.ClientSession(trust_env=True) as sess:
|
|
263
|
+
async with sess.get(
|
|
264
|
+
f"{api_url}/api/realty/contracts/{project_id}",
|
|
265
|
+
timeout=aiohttp.ClientTimeout(total=5)
|
|
266
|
+
) as resp:
|
|
267
|
+
if resp.status == 200:
|
|
268
|
+
ctr = (await resp.json()).get("data", {})
|
|
269
|
+
from datetime import date
|
|
270
|
+
start = ctr.get("start_date", "")
|
|
271
|
+
used_months = 0
|
|
272
|
+
if start:
|
|
273
|
+
try:
|
|
274
|
+
from dateutil.relativedelta import relativedelta
|
|
275
|
+
d0 = date.fromisoformat(start)
|
|
276
|
+
delta = relativedelta(date.today(), d0)
|
|
277
|
+
used_months = delta.years * 12 + delta.months
|
|
278
|
+
except Exception:
|
|
279
|
+
pass
|
|
280
|
+
project_info.update({
|
|
281
|
+
"contract_years": ctr.get("contract_years", 1),
|
|
282
|
+
"used_months": used_months,
|
|
283
|
+
"contract_end": ctr.get("end_date", ""),
|
|
284
|
+
})
|
|
285
|
+
financials.update({
|
|
286
|
+
"deposit_amount": ctr.get("deposit_amount", 0),
|
|
287
|
+
"guaranteed_monthly": ctr.get("guaranteed_monthly", 0),
|
|
288
|
+
"exit_penalty_months": ctr.get("exit_penalty_months", 3),
|
|
289
|
+
})
|
|
290
|
+
contract_loaded = True
|
|
291
|
+
p(self.context, f"已加载合同规则: 保底 {ctr.get('guaranteed_monthly',0):,}元/月", "ok")
|
|
292
|
+
async with sess.get(
|
|
293
|
+
f"{api_url}/api/realty/invoices?project_id={project_id}&status=unpaid",
|
|
294
|
+
timeout=aiohttp.ClientTimeout(total=5)
|
|
295
|
+
) as resp2:
|
|
296
|
+
if resp2.status == 200:
|
|
297
|
+
body2 = await resp2.json()
|
|
298
|
+
summary = body2.get("data", {}).get("summary", {})
|
|
299
|
+
unpaid = summary.get("total_amount", 0) - summary.get("paid_amount", 0)
|
|
300
|
+
financials["unpaid_invoices"] = unpaid
|
|
301
|
+
if unpaid > 0:
|
|
302
|
+
p(self.context, f"发现未结账单合计: {unpaid:,.2f}元", "ok")
|
|
303
|
+
except Exception:
|
|
304
|
+
pass
|
|
305
|
+
if not contract_loaded:
|
|
306
|
+
self._realty_needs(project_id, "Usage: /exit-calc <project_id> [--reason …]")
|
|
307
|
+
return
|
|
308
|
+
await self._run_realty_agent("exit_settlement", project_id, {
|
|
309
|
+
"project_info": project_info,
|
|
310
|
+
"financials": financials,
|
|
311
|
+
"asset_condition": {},
|
|
312
|
+
"exit_reason": reason,
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
def _realty_needs(self, project_id: str | None, usage: str) -> bool:
|
|
316
|
+
"""Say what is missing and return True when a realty command has nothing to work on.
|
|
317
|
+
|
|
318
|
+
These commands ran their agents on "demo_project", zeros or a made-up
|
|
319
|
+
contract (30,000 a month, 10% share) when the Arthera realty backend
|
|
320
|
+
had nothing, and the agent then gave a verdict: /ops-report called a
|
|
321
|
+
project with no data "very high risk" with "member repurchase rate
|
|
322
|
+
is low".
|
|
323
|
+
"""
|
|
324
|
+
if project_id:
|
|
325
|
+
msg = ui_text(self, f"没有找到 {project_id} 的数据:这项功能读取 Arthera 不动产后端里的项目数据,"
|
|
326
|
+
f"没有数据就不做分析。",
|
|
327
|
+
f"No data found for {project_id}: this reads project data from the Arthera realty "
|
|
328
|
+
f"backend and does not analyse without it.")
|
|
329
|
+
else:
|
|
330
|
+
msg = ui_text(self, "需要项目 ID。", "A project ID is needed.")
|
|
331
|
+
from ._ui import print_error
|
|
332
|
+
print_error(self.context, msg, usage)
|
|
333
|
+
return True
|
|
334
|
+
|
|
335
|
+
async def _run_realty_agent(self, agent_name: str, project_id: str, input_data: dict):
|
|
336
|
+
if self.context.has_rich:
|
|
337
|
+
with self.context.console.status(f"[dim]{ui_text(self, f'运行 {agent_name} Agent', f'Running the {agent_name} agent')}...[/dim]", spinner="dots"):
|
|
338
|
+
result = await self._call_realty_agent(agent_name, project_id, input_data)
|
|
339
|
+
else:
|
|
340
|
+
print(f"Running {agent_name}...")
|
|
341
|
+
result = await self._call_realty_agent(agent_name, project_id, input_data)
|
|
342
|
+
if result:
|
|
343
|
+
print_realty_result(self.context, result, agent_name)
|
|
344
|
+
|
|
345
|
+
async def _run_realty_team(self, agents: list, project_id: str, input_data: dict):
|
|
346
|
+
import asyncio
|
|
347
|
+
if self.context.has_rich:
|
|
348
|
+
_names = ', '.join(agents)
|
|
349
|
+
with self.context.console.status(f"[dim]{ui_text(self, f'并行扫描 {_names}', f'Scanning {_names} in parallel')}...[/dim]", spinner="dots"):
|
|
350
|
+
tasks = [self._call_realty_agent(n, project_id, input_data) for n in agents]
|
|
351
|
+
results = await asyncio.gather(*tasks, return_exceptions=False)
|
|
352
|
+
else:
|
|
353
|
+
tasks = [self._call_realty_agent(n, project_id, input_data) for n in agents]
|
|
354
|
+
results = await asyncio.gather(*tasks, return_exceptions=False)
|
|
355
|
+
for res, name in zip(results, agents):
|
|
356
|
+
if res:
|
|
357
|
+
print_realty_result(self.context, res, name)
|
|
358
|
+
|
|
359
|
+
async def _call_realty_agent(self, agent_name: str, project_id: str, input_data: dict):
|
|
360
|
+
try:
|
|
361
|
+
from agents.registry import get_registry
|
|
362
|
+
cls = get_registry().get(agent_name)
|
|
363
|
+
if not cls:
|
|
364
|
+
p(self.context, f"Agent '{agent_name}' 未注册", "error")
|
|
365
|
+
return None
|
|
366
|
+
llm = None
|
|
367
|
+
try:
|
|
368
|
+
from providers.llm.registry import list_available_providers, get_provider
|
|
369
|
+
avail = [p for p in list_available_providers() if p.get("available")]
|
|
370
|
+
if avail:
|
|
371
|
+
llm = get_provider(avail[0]["name"])
|
|
372
|
+
except Exception:
|
|
373
|
+
pass
|
|
374
|
+
agent = cls(llm_provider=llm)
|
|
375
|
+
result = await agent.analyze(project_id, input_data)
|
|
376
|
+
return result
|
|
377
|
+
except Exception as e:
|
|
378
|
+
p(self.context, f"Agent {agent_name} 执行失败: {e}", "error")
|
|
379
|
+
return None
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""CanvasCommandsMixin — /canvas command (live artifact preview server).
|
|
2
|
+
|
|
3
|
+
Extracted following the same convention as broker_cmds.py/backtest_cmds.py:
|
|
4
|
+
module globals (self.context.has_rich, self.context.console, etc.) are imported lazily inside each
|
|
5
|
+
method body to avoid circular imports at load time.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from ._ui import print_error
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
import asyncio
|
|
15
|
+
import datetime
|
|
16
|
+
import time
|
|
17
|
+
import shlex
|
|
18
|
+
import sys
|
|
19
|
+
import os
|
|
20
|
+
from typing import Dict, Any, Optional
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
import json
|
|
24
|
+
import asyncio
|
|
25
|
+
import datetime
|
|
26
|
+
import time
|
|
27
|
+
import shlex
|
|
28
|
+
import sys
|
|
29
|
+
import os
|
|
30
|
+
from typing import Dict, Any, Optional
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class CanvasCommandsMixin:
|
|
34
|
+
"""Mixin providing the /canvas live-preview-server command.
|
|
35
|
+
|
|
36
|
+
Off by default — nothing in preview_server.py runs until this command
|
|
37
|
+
is explicitly typed. See preview_server.py's module docstring for why
|
|
38
|
+
this stays opt-in rather than auto-starting.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
async def cmd_canvas(self, args: str):
|
|
42
|
+
"""实时预览面板: /canvas [stop] —— 启动/停止本地预览服务器,报告和图表生成后会自动在浏览器里实时更新。"""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
sub = args.strip().lower()
|
|
46
|
+
import preview_server
|
|
47
|
+
|
|
48
|
+
if sub == "stop":
|
|
49
|
+
session = preview_server.get_active_session()
|
|
50
|
+
if session is None:
|
|
51
|
+
msg = "预览服务器未在运行"
|
|
52
|
+
self.context.console.print(f"[yellow]{msg}[/yellow]") if self.context.has_rich else print(msg)
|
|
53
|
+
return
|
|
54
|
+
await preview_server.stop_session()
|
|
55
|
+
msg = "✓ 已停止预览服务器"
|
|
56
|
+
self.context.console.print(f"[green]{msg}[/green]") if self.context.has_rich else print(msg)
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
existing = preview_server.get_active_session()
|
|
60
|
+
if existing is not None and existing.url:
|
|
61
|
+
msg = f"预览服务器已在运行: {existing.url}"
|
|
62
|
+
self.context.console.print(f"[cyan]{msg}[/cyan]") if self.context.has_rich else print(msg)
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
session = await preview_server.start_session()
|
|
67
|
+
except Exception as exc:
|
|
68
|
+
print_error(self.context, f"预览服务器启动失败: {exc}", "换个端口范围或检查网络配置后重试")
|
|
69
|
+
return
|
|
70
|
+
|
|
71
|
+
preview_server.open_in_browser(session.url)
|
|
72
|
+
msg = (
|
|
73
|
+
f"✓ 预览服务器已启动: {session.url}\n"
|
|
74
|
+
f"之后生成的报告/图表会自动在这个浏览器标签里实时更新,无需手动刷新。\n"
|
|
75
|
+
f"/canvas stop 可以随时关闭。"
|
|
76
|
+
)
|
|
77
|
+
self.context.console.print(f"[green]{msg}[/green]") if self.context.has_rich else print(msg)
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"""Shared CLI command metadata.
|
|
2
|
+
|
|
3
|
+
This module is intentionally UI-free so future channel adapters such as Feishu
|
|
4
|
+
or a local gateway can reuse the same command categories without importing the
|
|
5
|
+
large terminal implementation.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from typing import FrozenSet, Tuple
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class DirectCommandSpec:
|
|
16
|
+
name: str
|
|
17
|
+
method_name: str
|
|
18
|
+
async_method: bool = False
|
|
19
|
+
watchable: bool = False
|
|
20
|
+
aliases: Tuple[str, ...] = ()
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def names(self) -> Tuple[str, ...]:
|
|
24
|
+
return (self.name, *self.aliases)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
DIRECT_COMMANDS: Tuple[DirectCommandSpec, ...] = (
|
|
28
|
+
DirectCommandSpec("quote", "cmd_quote", async_method=True, watchable=True),
|
|
29
|
+
DirectCommandSpec("backtest", "cmd_backtest", async_method=True),
|
|
30
|
+
DirectCommandSpec("health", "cmd_health", async_method=True, watchable=True),
|
|
31
|
+
DirectCommandSpec("doctor", "cmd_doctor"),
|
|
32
|
+
DirectCommandSpec("tools", "cmd_tools"),
|
|
33
|
+
DirectCommandSpec("skills", "cmd_skills"),
|
|
34
|
+
DirectCommandSpec("sessions", "cmd_sessions"),
|
|
35
|
+
DirectCommandSpec("watch", "cmd_watch", aliases=("watchlist",)),
|
|
36
|
+
DirectCommandSpec("export", "cmd_export", async_method=True),
|
|
37
|
+
DirectCommandSpec("tv", "cmd_tv", async_method=True),
|
|
38
|
+
DirectCommandSpec("ashare", "cmd_ashare", async_method=True, aliases=("a-share",)),
|
|
39
|
+
DirectCommandSpec("markets", "cmd_markets"),
|
|
40
|
+
DirectCommandSpec("orchestrate", "cmd_orchestrate"),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
DIRECT_COMMAND_MAP = {
|
|
45
|
+
alias: spec
|
|
46
|
+
for spec in DIRECT_COMMANDS
|
|
47
|
+
for alias in spec.names
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
WATCHABLE_DIRECT_COMMANDS: FrozenSet[str] = frozenset(
|
|
52
|
+
alias
|
|
53
|
+
for spec in DIRECT_COMMANDS
|
|
54
|
+
if spec.watchable
|
|
55
|
+
for alias in spec.names
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# Commands shown by default in /help. Other slash commands remain executable but
|
|
60
|
+
# are hidden to keep the startup surface compact.
|
|
61
|
+
VISIBLE_SLASH_COMMANDS: FrozenSet[str] = frozenset({
|
|
62
|
+
# Session
|
|
63
|
+
"/help", "/clear", "/compact", "/cost", "/status", "/health",
|
|
64
|
+
"/regen", "/undo", "/rewind", "/copy", "/recap", "/btw",
|
|
65
|
+
# Sessions
|
|
66
|
+
"/save", "/load", "/sessions", "/recall", "/export",
|
|
67
|
+
# Config
|
|
68
|
+
"/model", "/thinking", "/config", "/permissions", "/privacy",
|
|
69
|
+
# Setup & discovery
|
|
70
|
+
"/setup", "/apikey", "/doctor", "/architecture", "/mcp", "/skills", "/tools", "/packages", "/markets",
|
|
71
|
+
# Auth
|
|
72
|
+
"/login", "/logout", "/whoami",
|
|
73
|
+
# Persistent data (direct writes)
|
|
74
|
+
"/alert", "/journal", "/watch", "/note", "/todo", "/memory",
|
|
75
|
+
# Broker
|
|
76
|
+
"/broker", "/account", "/positions", "/orders", "/paper", "/trade",
|
|
77
|
+
# Code & project
|
|
78
|
+
"/project", "/init", "/review", "/code", "/plan", "/orchestrate", "/run", "/task", "/tasks", "/impact", "/workflow", "/delegate",
|
|
79
|
+
"/diff", "/commit", "/pr", "/checkpoint", "/worktree", "/graph", "/agents", "/test", "/build", "/sim", "/consult", "/fix", "/canva", "/completions", "/lsp",
|
|
80
|
+
# Research
|
|
81
|
+
"/team", "/warehouse", "/deep",
|
|
82
|
+
# Quant
|
|
83
|
+
"/backtest", "/wf", "/tv", "/ashare",
|
|
84
|
+
# UI generation
|
|
85
|
+
"/ui",
|
|
86
|
+
# Other
|
|
87
|
+
"/artifacts", "/vision", "/upload-image", "/file", "/strategy", "/accuracy",
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# ── What "/" shows ────────────────────────────────────────────────────────────
|
|
92
|
+
# The "/" popup listed every command — 167 of them plus 14 skills, 92 without
|
|
93
|
+
# a category — and /help printed about 90 lines. Codex lists only session
|
|
94
|
+
# controls under "/", shows eight rows, and takes tasks in plain language.
|
|
95
|
+
# Aria keeps every command runnable by name; the popup opens on these two
|
|
96
|
+
# tiers, and typing narrows it over everything.
|
|
97
|
+
|
|
98
|
+
# Session and setup controls, in popup order.
|
|
99
|
+
CORE_SLASH_COMMANDS: Tuple[str, ...] = (
|
|
100
|
+
"/help", "/model", "/review", "/plan", "/init", "/status", "/sessions", "/clear",
|
|
101
|
+
"/compact", "/copy", "/rewind", "/permissions", "/config", "/doctor", "/login",
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# One way into each capability: building code, financial analysis, logistics.
|
|
105
|
+
ENTRY_SLASH_COMMANDS: Tuple[str, ...] = (
|
|
106
|
+
"/code", "/ta", "/backtest", "/team", "/report", "/portfolio", "/inventory", "/carriers",
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
# Second names for a command; the popup lists the command once.
|
|
110
|
+
COMMAND_ALIASES = {"/upload-image": "/vision"}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@dataclass(frozen=True)
|
|
114
|
+
class HelpTopic:
|
|
115
|
+
key: str
|
|
116
|
+
title_en: str
|
|
117
|
+
title_zh: str
|
|
118
|
+
commands: Tuple[str, ...]
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
HELP_TOPICS: Tuple[HelpTopic, ...] = (
|
|
122
|
+
HelpTopic("code", "Code and projects", "代码与项目", (
|
|
123
|
+
"/code", "/project", "/init", "/review", "/plan", "/run", "/read", "/write", "/edit", "/ls",
|
|
124
|
+
"/search", "/verify", "/scaffold", "/apply", "/changes", "/git",
|
|
125
|
+
"/diff", "/commit", "/pr", "/test", "/build", "/sim", "/consult", "/fix", "/graph", "/impact", "/agents", "/task", "/worktree", "/checkpoint")),
|
|
126
|
+
HelpTopic("market", "Market research", "市场研究", (
|
|
127
|
+
"/quote", "/analyze", "/ta", "/chart", "/tv", "/deep", "/team", "/report", "/news", "/markets",
|
|
128
|
+
"/watch", "/alert")),
|
|
129
|
+
HelpTopic("quant", "Quant and portfolios", "量化与组合", (
|
|
130
|
+
"/backtest", "/wf", "/compare", "/auto-strategy", "/execution", "/portfolio", "/risk",
|
|
131
|
+
"/optimize", "/stress", "/factors")),
|
|
132
|
+
HelpTopic("logistics", "Logistics", "物流", ("/inventory", "/carriers", "/warehouse")),
|
|
133
|
+
HelpTopic("data", "Notes, files and artifacts", "笔记、文件与产物", (
|
|
134
|
+
"/journal", "/note", "/todo", "/memory", "/artifacts", "/strategy", "/accuracy", "/file",
|
|
135
|
+
"/vision", "/ui")),
|
|
136
|
+
HelpTopic("broker", "Broker and trading", "券商与交易", (
|
|
137
|
+
"/broker", "/paper", "/trade", "/account", "/positions", "/orders")),
|
|
138
|
+
HelpTopic("session", "Session", "会话", (
|
|
139
|
+
"/clear", "/compact", "/cost", "/status", "/health", "/regen", "/undo", "/rewind", "/copy",
|
|
140
|
+
"/recap", "/btw", "/save", "/load", "/sessions", "/export", "/export-pdf")),
|
|
141
|
+
HelpTopic("config", "Setup", "设置", (
|
|
142
|
+
"/model", "/thinking", "/config", "/permissions", "/privacy", "/local", "/update", "/setup",
|
|
143
|
+
"/apikey", "/doctor", "/mcp", "/login", "/logout", "/skills", "/tools", "/packages")),
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
HELP_TOPIC_MAP = {topic.key: topic for topic in HELP_TOPICS}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def popup_rank(name: str) -> int:
|
|
150
|
+
"""0 for a core command, 1 for an entry point, 2 for everything else."""
|
|
151
|
+
if name in CORE_SLASH_COMMANDS:
|
|
152
|
+
return 0
|
|
153
|
+
if name in ENTRY_SLASH_COMMANDS:
|
|
154
|
+
return 1
|
|
155
|
+
return 2
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def short_description(description: str) -> str:
|
|
159
|
+
"""The description without its usage tail: "Technical indicators: /ta AAPL …" → "Technical indicators"."""
|
|
160
|
+
text = str(description or "")
|
|
161
|
+
cut = text.find(": /")
|
|
162
|
+
return (text[:cut] if cut > 0 else text).strip()
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
# What /help and the "/" popup say about the commands they show, in the Chinese
|
|
166
|
+
# UI: the descriptions in the command table are English, so a Chinese session
|
|
167
|
+
# read "Show commands and examples" under 命令.
|
|
168
|
+
COMMAND_DESCRIPTIONS_ZH = {
|
|
169
|
+
"/help": "命令与示例", "/model": "切换模型", "/review": "代码审查", "/plan": "起草计划",
|
|
170
|
+
"/init": "为当前项目生成 ARIA.md", "/status": "运行状态:引擎 · 模型 · 工具 · 上下文",
|
|
171
|
+
"/sessions": "查看与搜索会话", "/clear": "清空对话", "/compact": "压缩上下文",
|
|
172
|
+
"/copy": "复制上一条回答", "/rewind": "恢复代码或对话", "/permissions": "工具权限",
|
|
173
|
+
"/config": "查看与修改配置", "/doctor": "诊断安装、模型与 API Key", "/login": "登录",
|
|
174
|
+
"/code": "生成并运行代码", "/ta": "技术指标", "/backtest": "回测并生成 HTML 报告",
|
|
175
|
+
"/team": "多智能体研究团队", "/report": "研究报告", "/portfolio": "投资组合",
|
|
176
|
+
"/diff": "查看改动:摘要或补丁", "/commit": "提交所有改动", "/pr": "当前分支的 Pull Request",
|
|
177
|
+
"/checkpoint": "检查点与回合还原点", "/worktree": "编码任务的工作树", "/graph": "项目图谱与改动影响",
|
|
178
|
+
"/agents": "项目智能体与后台任务", "/test": "运行项目测试", "/build": "运行项目构建",
|
|
179
|
+
"/fix": "定位原因、最小改动、验证", "/sim": "运行项目声明的仿真", "/consult": "向另一个模型征求第二意见",
|
|
180
|
+
"/inventory": "3PL 库存策略:补货点、安全库存、ABC/XYZ、呆滞库存",
|
|
181
|
+
"/carriers": "3PL 承运商评分:按线路排名、成本异常与节省",
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def describe(name: str, description: str, lang: str = "en") -> str:
|
|
186
|
+
"""The short description to show for a command, in the UI language."""
|
|
187
|
+
if str(lang).lower().startswith("zh") and name in COMMAND_DESCRIPTIONS_ZH:
|
|
188
|
+
return COMMAND_DESCRIPTIONS_ZH[name]
|
|
189
|
+
return short_description(description)
|