aria-code 0.52.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (478) hide show
  1. aria_code/__init__.py +42 -0
  2. aria_code/_version.py +20 -0
  3. aria_code/adk_apps/__init__.py +1 -0
  4. aria_code/adk_apps/aria_code_review/__init__.py +1 -0
  5. aria_code/adk_apps/aria_code_review/agent.py +32 -0
  6. aria_code/adk_apps/aria_research/__init__.py +1 -0
  7. aria_code/adk_apps/aria_research/agent.py +31 -0
  8. aria_code/agents/__init__.py +34 -0
  9. aria_code/agents/base.py +318 -0
  10. aria_code/agents/code_review.py +200 -0
  11. aria_code/agents/deep/__init__.py +37 -0
  12. aria_code/agents/deep/calibration_loop.py +144 -0
  13. aria_code/agents/deep/critic.py +125 -0
  14. aria_code/agents/deep/deepen.py +193 -0
  15. aria_code/agents/deep/models.py +149 -0
  16. aria_code/agents/deep/pipeline.py +164 -0
  17. aria_code/agents/deep/quant_fusion.py +192 -0
  18. aria_code/agents/deep/themes.py +95 -0
  19. aria_code/agents/deep/tiers.py +106 -0
  20. aria_code/agents/engineering/__init__.py +14 -0
  21. aria_code/agents/engineering/coder.py +222 -0
  22. aria_code/agents/engineering/tester.py +145 -0
  23. aria_code/agents/financial/__init__.py +21 -0
  24. aria_code/agents/financial/cashflow_burn.py +119 -0
  25. aria_code/agents/financial/catalyst.py +279 -0
  26. aria_code/agents/financial/corporate_finance.py +175 -0
  27. aria_code/agents/financial/debate.py +224 -0
  28. aria_code/agents/financial/earnings.py +303 -0
  29. aria_code/agents/financial/fundamental.py +191 -0
  30. aria_code/agents/financial/macro.py +99 -0
  31. aria_code/agents/financial/news.py +207 -0
  32. aria_code/agents/financial/risk.py +165 -0
  33. aria_code/agents/financial/sector.py +279 -0
  34. aria_code/agents/financial/strategist.py +121 -0
  35. aria_code/agents/financial/stripe_revenue.py +127 -0
  36. aria_code/agents/financial/synthesis.py +274 -0
  37. aria_code/agents/financial/technical.py +258 -0
  38. aria_code/agents/orchestrator.py +44 -0
  39. aria_code/agents/portfolio_agent.py +363 -0
  40. aria_code/agents/realty/__init__.py +62 -0
  41. aria_code/agents/realty/asset_diagnosis.py +152 -0
  42. aria_code/agents/realty/business_match.py +166 -0
  43. aria_code/agents/realty/cashflow_verify.py +209 -0
  44. aria_code/agents/realty/contract_rules.py +210 -0
  45. aria_code/agents/realty/energy_anomaly.py +189 -0
  46. aria_code/agents/realty/exit_settlement.py +208 -0
  47. aria_code/agents/realty/fulfillment_risk.py +206 -0
  48. aria_code/agents/realty/ops_optimize.py +160 -0
  49. aria_code/agents/realty/revenue_share.py +215 -0
  50. aria_code/agents/registry.py +158 -0
  51. aria_code/agents/signal_scheme.py +111 -0
  52. aria_code/agents/sports/__init__.py +0 -0
  53. aria_code/agents/sports/football_agent.py +197 -0
  54. aria_code/agents/supervisor.py +113 -0
  55. aria_code/agents/team.py +492 -0
  56. aria_code/agents/warehouse/__init__.py +25 -0
  57. aria_code/agents/warehouse/contracts.py +26 -0
  58. aria_code/agents/warehouse/dashboard.py +155 -0
  59. aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
  60. aria_code/agents/warehouse/inbound_exceptions.py +25 -0
  61. aria_code/agents/warehouse/inventory_health.py +24 -0
  62. aria_code/agents/warehouse/local_run.py +71 -0
  63. aria_code/agents/warehouse/local_snapshot.py +132 -0
  64. aria_code/agents/warehouse/logistics_cost.py +84 -0
  65. aria_code/agents/warehouse/logistics_sync.py +21 -0
  66. aria_code/agents/warehouse/workflow.py +31 -0
  67. aria_code/aliyun_data_client.py +4 -0
  68. aria_code/apps/README.md +12 -0
  69. aria_code/apps/__init__.py +2 -0
  70. aria_code/apps/channels/README.md +15 -0
  71. aria_code/apps/channels/__init__.py +17 -0
  72. aria_code/apps/channels/intake.py +92 -0
  73. aria_code/apps/channels/registry.py +95 -0
  74. aria_code/apps/channels/tradingview.py +94 -0
  75. aria_code/apps/cli/README.md +13 -0
  76. aria_code/apps/cli/__init__.py +2 -0
  77. aria_code/apps/cli/_optional.py +120 -0
  78. aria_code/apps/cli/bootstrap.py +145 -0
  79. aria_code/apps/cli/broker_render.py +206 -0
  80. aria_code/apps/cli/codegen_paths.py +29 -0
  81. aria_code/apps/cli/commands/__init__.py +16 -0
  82. aria_code/apps/cli/commands/_business_render.py +78 -0
  83. aria_code/apps/cli/commands/_ui.py +71 -0
  84. aria_code/apps/cli/commands/analysis_cmds.py +369 -0
  85. aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
  86. aria_code/apps/cli/commands/auth_cmds.py +239 -0
  87. aria_code/apps/cli/commands/backtest_cmds.py +2543 -0
  88. aria_code/apps/cli/commands/broker_cmds.py +1234 -0
  89. aria_code/apps/cli/commands/business_workflow_cmds.py +319 -0
  90. aria_code/apps/cli/commands/canvas_cmds.py +77 -0
  91. aria_code/apps/cli/commands/catalog.py +87 -0
  92. aria_code/apps/cli/commands/core_cmds.py +2520 -0
  93. aria_code/apps/cli/commands/data_cmds.py +457 -0
  94. aria_code/apps/cli/commands/diagnostic_cmds.py +230 -0
  95. aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
  96. aria_code/apps/cli/commands/file_cmds.py +312 -0
  97. aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
  98. aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
  99. aria_code/apps/cli/commands/market.py +434 -0
  100. aria_code/apps/cli/commands/market_cmds.py +1381 -0
  101. aria_code/apps/cli/commands/market_context.py +425 -0
  102. aria_code/apps/cli/commands/market_render.py +7 -0
  103. aria_code/apps/cli/commands/model_cmds.py +2153 -0
  104. aria_code/apps/cli/commands/ops_cmds.py +721 -0
  105. aria_code/apps/cli/commands/orchestrator_cmds.py +179 -0
  106. aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
  107. aria_code/apps/cli/commands/portfolio_cmds.py +1278 -0
  108. aria_code/apps/cli/commands/report.py +437 -0
  109. aria_code/apps/cli/commands/scaffold_templates.py +617 -0
  110. aria_code/apps/cli/commands/session_cmds.py +236 -0
  111. aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
  112. aria_code/apps/cli/commands/team.py +669 -0
  113. aria_code/apps/cli/commands/team_render.py +8 -0
  114. aria_code/apps/cli/commands/ui_cmds.py +401 -0
  115. aria_code/apps/cli/commands/warehouse_cmds.py +79 -0
  116. aria_code/apps/cli/commands/workflow_cmds.py +480 -0
  117. aria_code/apps/cli/commands/workspace_cmds.py +1494 -0
  118. aria_code/apps/cli/config_paths.py +73 -0
  119. aria_code/apps/cli/config_store.py +78 -0
  120. aria_code/apps/cli/constants.py +88 -0
  121. aria_code/apps/cli/context.py +34 -0
  122. aria_code/apps/cli/deterministic.py +191 -0
  123. aria_code/apps/cli/direct.py +48 -0
  124. aria_code/apps/cli/finance_service_catalog.py +111 -0
  125. aria_code/apps/cli/football_reports.py +231 -0
  126. aria_code/apps/cli/github_app_auth.py +135 -0
  127. aria_code/apps/cli/google_login.py +196 -0
  128. aria_code/apps/cli/handlers/__init__.py +11 -0
  129. aria_code/apps/cli/handlers/broker_handlers.py +122 -0
  130. aria_code/apps/cli/handlers/chart_handlers.py +1309 -0
  131. aria_code/apps/cli/handlers/market_handlers.py +2513 -0
  132. aria_code/apps/cli/handlers/realty_handlers.py +114 -0
  133. aria_code/apps/cli/handlers/sports_handlers.py +22 -0
  134. aria_code/apps/cli/handlers/strategy_advice.py +82 -0
  135. aria_code/apps/cli/helpers.py +302 -0
  136. aria_code/apps/cli/hooks.py +180 -0
  137. aria_code/apps/cli/i18n.py +297 -0
  138. aria_code/apps/cli/intent.py +136 -0
  139. aria_code/apps/cli/intent_router.py +276 -0
  140. aria_code/apps/cli/intent_signals.py +344 -0
  141. aria_code/apps/cli/lifecycle_hooks.py +48 -0
  142. aria_code/apps/cli/local_tool_schemas.py +536 -0
  143. aria_code/apps/cli/main.py +29 -0
  144. aria_code/apps/cli/market_metadata.py +135 -0
  145. aria_code/apps/cli/market_universe.py +487 -0
  146. aria_code/apps/cli/message_processing.py +310 -0
  147. aria_code/apps/cli/model_catalog.py +620 -0
  148. aria_code/apps/cli/pdf_report.py +977 -0
  149. aria_code/apps/cli/plan_mode.py +139 -0
  150. aria_code/apps/cli/plotly_html.py +15 -0
  151. aria_code/apps/cli/prediction_feedback.py +202 -0
  152. aria_code/apps/cli/preflight.py +502 -0
  153. aria_code/apps/cli/project_aria.py +60 -0
  154. aria_code/apps/cli/prompt_assembly.py +59 -0
  155. aria_code/apps/cli/prompts/__init__.py +0 -0
  156. aria_code/apps/cli/prompts/coding.py +53 -0
  157. aria_code/apps/cli/prompts/select.py +142 -0
  158. aria_code/apps/cli/prompts/system_prompts.py +552 -0
  159. aria_code/apps/cli/prompts/ui.py +436 -0
  160. aria_code/apps/cli/provider_endpoints.py +237 -0
  161. aria_code/apps/cli/provider_keys.py +73 -0
  162. aria_code/apps/cli/providers/__init__.py +1 -0
  163. aria_code/apps/cli/providers/base.py +521 -0
  164. aria_code/apps/cli/providers/chat_routing.py +128 -0
  165. aria_code/apps/cli/providers/collaboration.py +98 -0
  166. aria_code/apps/cli/providers/llm/__init__.py +1 -0
  167. aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
  168. aria_code/apps/cli/providers/llm/ollama_stream.py +1594 -0
  169. aria_code/apps/cli/providers/llm/response_cache.py +60 -0
  170. aria_code/apps/cli/providers/llm/sse_stream.py +257 -0
  171. aria_code/apps/cli/providers/runtime_bridge.py +353 -0
  172. aria_code/apps/cli/providers/vertexai_stream.py +316 -0
  173. aria_code/apps/cli/runtime_consumer.py +657 -0
  174. aria_code/apps/cli/sandbox.py +32 -0
  175. aria_code/apps/cli/session_export.py +120 -0
  176. aria_code/apps/cli/session_jsonl.py +208 -0
  177. aria_code/apps/cli/session_store.py +112 -0
  178. aria_code/apps/cli/skills_catalog.py +273 -0
  179. aria_code/apps/cli/todo_tracker.py +190 -0
  180. aria_code/apps/cli/tool_executor.py +823 -0
  181. aria_code/apps/cli/tool_registry.py +34 -0
  182. aria_code/apps/cli/tool_scope.py +106 -0
  183. aria_code/apps/cli/tools/__init__.py +40 -0
  184. aria_code/apps/cli/tools/context.py +46 -0
  185. aria_code/apps/cli/tools/file_tools.py +180 -0
  186. aria_code/apps/cli/tools/market_tools.py +620 -0
  187. aria_code/apps/cli/tools/notebook_tools.py +111 -0
  188. aria_code/apps/cli/tools/system_tools.py +726 -0
  189. aria_code/apps/cli/tools/write_tools.py +845 -0
  190. aria_code/apps/cli/tradingview_bridge.py +529 -0
  191. aria_code/apps/cli/turn_planning.py +137 -0
  192. aria_code/apps/cli/update_check.py +153 -0
  193. aria_code/apps/cli/utils/__init__.py +0 -0
  194. aria_code/apps/cli/utils/market_detect.py +1597 -0
  195. aria_code/apps/daemon/README.md +14 -0
  196. aria_code/apps/vscode/README.md +115 -0
  197. aria_code/apps/vscode/package.json +70 -0
  198. aria_code/aria_cli.py +6743 -0
  199. aria_code/aria_daemon.py +1398 -0
  200. aria_code/aria_feishu_bot.py +1423 -0
  201. aria_code/aria_mcp_server.py +7 -0
  202. aria_code/aria_relay_client.py +4 -0
  203. aria_code/aria_relay_server.py +490 -0
  204. aria_code/aria_telegram_bot.py +202 -0
  205. aria_code/ariarc.py +385 -0
  206. aria_code/artifacts.py +581 -0
  207. aria_code/backtest_engine.py +4 -0
  208. aria_code/backtest_report.py +4 -0
  209. aria_code/brokers/__init__.py +78 -0
  210. aria_code/brokers/automation.py +193 -0
  211. aria_code/brokers/base.py +231 -0
  212. aria_code/brokers/capabilities.py +264 -0
  213. aria_code/brokers/cn/__init__.py +10 -0
  214. aria_code/brokers/cn/easytrader_broker.py +193 -0
  215. aria_code/brokers/cn/futu_broker.py +194 -0
  216. aria_code/brokers/cn/longbridge_broker.py +190 -0
  217. aria_code/brokers/cn/tiger_broker.py +196 -0
  218. aria_code/brokers/cn/xtquant_broker.py +225 -0
  219. aria_code/brokers/config.py +414 -0
  220. aria_code/brokers/intl/__init__.py +5 -0
  221. aria_code/brokers/intl/alpaca_broker.py +183 -0
  222. aria_code/brokers/intl/ibkr_broker.py +215 -0
  223. aria_code/brokers/intl/trading212_broker.py +183 -0
  224. aria_code/brokers/intl/webull_broker.py +156 -0
  225. aria_code/brokers/paper_broker.py +266 -0
  226. aria_code/brokers/planning.py +296 -0
  227. aria_code/brokers/registry.py +213 -0
  228. aria_code/brokers/trading.py +267 -0
  229. aria_code/canva_client.py +4 -0
  230. aria_code/change_store.py +127 -0
  231. aria_code/clients/__init__.py +0 -0
  232. aria_code/clients/aliyun_data_client.py +660 -0
  233. aria_code/clients/aria_relay_client.py +182 -0
  234. aria_code/clients/canva_client.py +284 -0
  235. aria_code/clients/figma_client.py +100 -0
  236. aria_code/clients/football_data_client.py +1671 -0
  237. aria_code/clients/kling_video_client.py +182 -0
  238. aria_code/clients/market_data_client.py +1976 -0
  239. aria_code/clients/openai_image_client.py +242 -0
  240. aria_code/clients/runway_video_client.py +157 -0
  241. aria_code/clients/warehouse_erp_client.py +105 -0
  242. aria_code/cloud_memory.py +181 -0
  243. aria_code/command_safety.py +19 -0
  244. aria_code/computer_use_tools.py +4 -0
  245. aria_code/dashboard_generator.py +579 -0
  246. aria_code/data_analysis_tools.py +4 -0
  247. aria_code/data_cleaner.py +483 -0
  248. aria_code/data_service.py +513 -0
  249. aria_code/datasources/__init__.py +23 -0
  250. aria_code/datasources/base.py +166 -0
  251. aria_code/datasources/router.py +253 -0
  252. aria_code/datasources/sources/__init__.py +15 -0
  253. aria_code/datasources/sources/akshare_source.py +269 -0
  254. aria_code/datasources/sources/alpha_vantage_source.py +203 -0
  255. aria_code/datasources/sources/edgar_source.py +219 -0
  256. aria_code/datasources/sources/finnhub_source.py +198 -0
  257. aria_code/datasources/sources/fred_source.py +223 -0
  258. aria_code/datasources/sources/tushare_source.py +143 -0
  259. aria_code/datasources/sources/web_scraper_source.py +278 -0
  260. aria_code/datasources/sources/world_bank_source.py +206 -0
  261. aria_code/datasources/sources/yfinance_source.py +152 -0
  262. aria_code/demo_player.py +207 -0
  263. aria_code/doctor.py +813 -0
  264. aria_code/domain/__init__.py +0 -0
  265. aria_code/domain/backtest_engine.py +354 -0
  266. aria_code/domain/backtest_report.py +472 -0
  267. aria_code/domain/finance_formulas.py +389 -0
  268. aria_code/domain/portfolio_ledger.py +307 -0
  269. aria_code/domain/strategy_vault.py +421 -0
  270. aria_code/evals/__init__.py +37 -0
  271. aria_code/evals/harness.py +598 -0
  272. aria_code/evals/runner.py +238 -0
  273. aria_code/external_agent_runner.py +115 -0
  274. aria_code/figma_client.py +4 -0
  275. aria_code/file_analysis_tools.py +4 -0
  276. aria_code/finance_formulas.py +4 -0
  277. aria_code/football_data_client.py +4 -0
  278. aria_code/image_gen_tools.py +4 -0
  279. aria_code/intent_classifier.py +386 -0
  280. aria_code/kling_video_client.py +4 -0
  281. aria_code/licensing.py +151 -0
  282. aria_code/local_finance_tools.py +4 -0
  283. aria_code/local_image_provider.py +4 -0
  284. aria_code/local_llm_provider.py +4 -0
  285. aria_code/macro_tools.py +4 -0
  286. aria_code/markdown_pdf.py +289 -0
  287. aria_code/market_data_client.py +4 -0
  288. aria_code/mcp_client.py +639 -0
  289. aria_code/memory_manager.py +246 -0
  290. aria_code/model_capability.py +486 -0
  291. aria_code/notification_tools.py +4 -0
  292. aria_code/openai_image_client.py +4 -0
  293. aria_code/packages/__init__.py +23 -0
  294. aria_code/packages/adk_bridge/__init__.py +11 -0
  295. aria_code/packages/adk_bridge/code_review_tools.py +49 -0
  296. aria_code/packages/adk_bridge/market_tools.py +125 -0
  297. aria_code/packages/aria_agents/__init__.py +5 -0
  298. aria_code/packages/aria_agents/manifest.py +78 -0
  299. aria_code/packages/aria_core/__init__.py +34 -0
  300. aria_code/packages/aria_core/architecture.py +269 -0
  301. aria_code/packages/aria_core/export.py +147 -0
  302. aria_code/packages/aria_core/manifest.py +65 -0
  303. aria_code/packages/aria_core/paths.py +57 -0
  304. aria_code/packages/aria_core/secure_file.py +68 -0
  305. aria_code/packages/aria_infra/__init__.py +15 -0
  306. aria_code/packages/aria_infra/arthera.py +52 -0
  307. aria_code/packages/aria_infra/doctor.py +246 -0
  308. aria_code/packages/aria_infra/product.py +40 -0
  309. aria_code/packages/aria_mcp/__init__.py +25 -0
  310. aria_code/packages/aria_mcp/bridge.py +201 -0
  311. aria_code/packages/aria_mcp/circuit.py +82 -0
  312. aria_code/packages/aria_mcp/config.py +111 -0
  313. aria_code/packages/aria_mcp/installer.py +95 -0
  314. aria_code/packages/aria_mcp/server.py +1550 -0
  315. aria_code/packages/aria_mcp/tools.py +81 -0
  316. aria_code/packages/aria_sdk/__init__.py +19 -0
  317. aria_code/packages/aria_sdk/client.py +396 -0
  318. aria_code/packages/aria_sdk/providers.py +70 -0
  319. aria_code/packages/aria_sdk/streaming.py +79 -0
  320. aria_code/packages/aria_sdk/types.py +86 -0
  321. aria_code/packages/aria_services/__init__.py +92 -0
  322. aria_code/packages/aria_services/cache.py +60 -0
  323. aria_code/packages/aria_services/context.py +356 -0
  324. aria_code/packages/aria_services/context_checkpoints.py +157 -0
  325. aria_code/packages/aria_services/data.py +11 -0
  326. aria_code/packages/aria_services/provider_health.py +268 -0
  327. aria_code/packages/aria_services/references.py +247 -0
  328. aria_code/packages/aria_services/registry.py +249 -0
  329. aria_code/packages/aria_services/research_protocol.py +57 -0
  330. aria_code/packages/aria_services/research_quality.py +186 -0
  331. aria_code/packages/aria_services/settings.py +157 -0
  332. aria_code/packages/aria_services/usage.py +151 -0
  333. aria_code/packages/aria_skills/__init__.py +46 -0
  334. aria_code/packages/aria_skills/catalog.py +149 -0
  335. aria_code/packages/aria_skills/loader.py +455 -0
  336. aria_code/packages/aria_skills/registry.py +84 -0
  337. aria_code/packages/aria_tools/__init__.py +5 -0
  338. aria_code/packages/aria_tools/financial/__init__.py +8 -0
  339. aria_code/packages/aria_tools/financial/_paths.py +130 -0
  340. aria_code/packages/aria_tools/financial/compliance.py +31 -0
  341. aria_code/packages/aria_tools/financial/factors.py +33 -0
  342. aria_code/packages/aria_tools/financial/risk_tools.py +33 -0
  343. aria_code/packages/aria_tools/financial/strategy.py +31 -0
  344. aria_code/packages/aria_tools/registry.py +128 -0
  345. aria_code/packages/quant_engine/__init__.py +34 -0
  346. aria_code/packages/quant_engine/_namespace.py +62 -0
  347. aria_code/packages/quant_engine/backtest/__init__.py +14 -0
  348. aria_code/packages/quant_engine/backtest/core.py +53 -0
  349. aria_code/packages/quant_engine/backtest/engine.py +96 -0
  350. aria_code/packages/quant_engine/portfolio/__init__.py +13 -0
  351. aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
  352. aria_code/packages/quant_engine/sports/__init__.py +80 -0
  353. aria_code/packages/quant_engine/sports/calibrator.py +354 -0
  354. aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
  355. aria_code/packages/quant_engine/sports/elo.py +300 -0
  356. aria_code/packages/quant_engine/sports/form.py +188 -0
  357. aria_code/packages/quant_engine/sports/h2h.py +195 -0
  358. aria_code/packages/quant_engine/sports/ml_model.py +377 -0
  359. aria_code/packages/quant_engine/sports/predictor.py +312 -0
  360. aria_code/packages/quant_engine/sports/tracker.py +665 -0
  361. aria_code/packages/quant_engine/stochastic/__init__.py +35 -0
  362. aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
  363. aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
  364. aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
  365. aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
  366. aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
  367. aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
  368. aria_code/packs/__init__.py +85 -0
  369. aria_code/packs/base.py +168 -0
  370. aria_code/packs/finance/__init__.py +250 -0
  371. aria_code/packs/logistics/__init__.py +169 -0
  372. aria_code/packs/payments/__init__.py +139 -0
  373. aria_code/packs/realty/__init__.py +190 -0
  374. aria_code/packs/registry.py +202 -0
  375. aria_code/packs/rules.py +90 -0
  376. aria_code/plan_utils.py +194 -0
  377. aria_code/plugin_loader.py +328 -0
  378. aria_code/portfolio_ledger.py +4 -0
  379. aria_code/preview_server.py +449 -0
  380. aria_code/privacy/__init__.py +5 -0
  381. aria_code/privacy/feedback.py +123 -0
  382. aria_code/project_review.py +278 -0
  383. aria_code/project_review_api.py +235 -0
  384. aria_code/project_review_server.py +18 -0
  385. aria_code/project_tools.py +4 -0
  386. aria_code/providers/__init__.py +30 -0
  387. aria_code/providers/llm/__init__.py +19 -0
  388. aria_code/providers/llm/anthropic.py +184 -0
  389. aria_code/providers/llm/autoconfig.py +213 -0
  390. aria_code/providers/llm/base.py +139 -0
  391. aria_code/providers/llm/custom.py +158 -0
  392. aria_code/providers/llm/ollama.py +129 -0
  393. aria_code/providers/llm/openai_compat.py +313 -0
  394. aria_code/providers/llm/registry.py +444 -0
  395. aria_code/providers/local_image_provider.py +202 -0
  396. aria_code/providers/local_llm_provider.py +589 -0
  397. aria_code/realty_data_tools.py +4 -0
  398. aria_code/report_exporters.py +150 -0
  399. aria_code/report_generator.py +1764 -0
  400. aria_code/runtime/__init__.py +169 -0
  401. aria_code/runtime/acceptance.py +481 -0
  402. aria_code/runtime/agent_loop.py +1520 -0
  403. aria_code/runtime/approval.py +57 -0
  404. aria_code/runtime/budget.py +232 -0
  405. aria_code/runtime/checkpoints.py +432 -0
  406. aria_code/runtime/crash_report.py +174 -0
  407. aria_code/runtime/events.py +113 -0
  408. aria_code/runtime/gateway.py +150 -0
  409. aria_code/runtime/lsp.py +484 -0
  410. aria_code/runtime/orchestrator.py +55 -0
  411. aria_code/runtime/repo_map.py +700 -0
  412. aria_code/runtime/run_state.py +127 -0
  413. aria_code/runtime/run_store.py +450 -0
  414. aria_code/runtime/self_healing.py +422 -0
  415. aria_code/runtime/subagent.py +547 -0
  416. aria_code/runtime/task_ledger.py +86 -0
  417. aria_code/runtime/task_orchestrator.py +90 -0
  418. aria_code/runtime/tool_executor.py +217 -0
  419. aria_code/runtime/tool_policy.py +107 -0
  420. aria_code/runtime/worktrees.py +215 -0
  421. aria_code/runway_video_client.py +4 -0
  422. aria_code/safety/__init__.py +23 -0
  423. aria_code/safety/permissions.py +306 -0
  424. aria_code/safety/service.py +102 -0
  425. aria_code/setup_wizard.py +673 -0
  426. aria_code/spreadsheet_tools.py +4 -0
  427. aria_code/strategy_vault.py +4 -0
  428. aria_code/tools/__init__.py +0 -0
  429. aria_code/tools/artifact_tools.py +252 -0
  430. aria_code/tools/broker_tools.py +92 -0
  431. aria_code/tools/build_quant_engine.py +97 -0
  432. aria_code/tools/code_audit_tools.py +192 -0
  433. aria_code/tools/computer_use_tools.py +504 -0
  434. aria_code/tools/data_analysis_tools.py +809 -0
  435. aria_code/tools/enterprise_finance_tools.py +156 -0
  436. aria_code/tools/extended_tools.py +240 -0
  437. aria_code/tools/file_analysis_tools.py +885 -0
  438. aria_code/tools/image_gen_tools.py +114 -0
  439. aria_code/tools/local_finance_tools.py +3417 -0
  440. aria_code/tools/logistics_tools.py +135 -0
  441. aria_code/tools/macro_tools.py +369 -0
  442. aria_code/tools/notification_tools.py +249 -0
  443. aria_code/tools/project_tools.py +525 -0
  444. aria_code/tools/realty_data_tools.py +659 -0
  445. aria_code/tools/spreadsheet_tools.py +388 -0
  446. aria_code/tools/stripe_tools.py +115 -0
  447. aria_code/ui/__init__.py +105 -0
  448. aria_code/ui/banner.py +508 -0
  449. aria_code/ui/completer.py +501 -0
  450. aria_code/ui/console.py +281 -0
  451. aria_code/ui/image_render.py +243 -0
  452. aria_code/ui/input_box.py +488 -0
  453. aria_code/ui/picker.py +201 -0
  454. aria_code/ui/render/__init__.py +11 -0
  455. aria_code/ui/render/finance.py +1705 -0
  456. aria_code/ui/render/market.py +225 -0
  457. aria_code/ui/render/output.py +775 -0
  458. aria_code/ui/render/responsive.py +75 -0
  459. aria_code/ui/render/team.py +354 -0
  460. aria_code/ui/robot.py +235 -0
  461. aria_code/ui/startup_dashboard.py +109 -0
  462. aria_code/utils/vscode_uri.py +37 -0
  463. aria_code/video_analysis.py +147 -0
  464. aria_code/video_editor.py +271 -0
  465. aria_code/workspace/__init__.py +6 -0
  466. aria_code/workspace/files.py +193 -0
  467. aria_code/workspace/verify.py +113 -0
  468. aria_code/workspace_changes.py +199 -0
  469. aria_code/workspace_context.py +233 -0
  470. aria_code/workspace_service.py +196 -0
  471. aria_code/workspace_tools.py +150 -0
  472. aria_code-0.52.0.dist-info/METADATA +237 -0
  473. aria_code-0.52.0.dist-info/RECORD +478 -0
  474. aria_code-0.52.0.dist-info/WHEEL +5 -0
  475. aria_code-0.52.0.dist-info/entry_points.txt +3 -0
  476. aria_code-0.52.0.dist-info/licenses/LICENSE +201 -0
  477. aria_code-0.52.0.dist-info/licenses/NOTICE +49 -0
  478. aria_code-0.52.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,73 @@
1
+ """Shared config path resolution for Aria CLI components."""
2
+ from __future__ import annotations
3
+
4
+ import os
5
+ from dataclasses import dataclass
6
+ from pathlib import Path
7
+ from typing import Optional
8
+
9
+
10
+ @dataclass(frozen=True)
11
+ class AriaConfigPaths:
12
+ config_dir: Path
13
+ config_file: Path
14
+ history_file: Path
15
+ sessions_dir: Path
16
+ providers_file: Path
17
+ hooks_file: Path
18
+ user_output_root: Path
19
+ user_generated_dir: Path
20
+ user_projects_dir: Path
21
+
22
+
23
+ def resolve_config_dir() -> Path:
24
+ """Resolve the user config directory with stable precedence.
25
+
26
+ 实现已收敛到 packages/aria_core/paths.aria_home():同一套优先级此前只有
27
+ 配置文件走,另外 38 个文件直接写死 Path.home()/".arthera" 绕过了它,导致
28
+ 新用户的 config 落在 ~/.aria-code 而凭证落在 ~/.arthera。这里保留函数名做
29
+ 兼容,逻辑不再各自维护一份。
30
+ """
31
+ from packages.aria_core.paths import aria_home
32
+
33
+ return aria_home()
34
+
35
+
36
+ def resolve_user_output_root() -> Path:
37
+ """Resolve the per-user output root for generated code and user artifacts."""
38
+ configured = os.getenv("ARIA_USER_OUTPUT_ROOT")
39
+ if configured:
40
+ return Path(configured).expanduser()
41
+ return Path.home() / "Documents" / "Aria Code"
42
+
43
+
44
+ def resolve_paths(config_dir: Optional[Path] = None) -> AriaConfigPaths:
45
+ root = Path(config_dir).expanduser() if config_dir else resolve_config_dir()
46
+ user_output_root = resolve_user_output_root()
47
+ return AriaConfigPaths(
48
+ config_dir=root,
49
+ config_file=root / "config.json",
50
+ history_file=root / "history",
51
+ sessions_dir=root / "sessions",
52
+ providers_file=root / "providers.json",
53
+ hooks_file=root / "hooks.json",
54
+ user_output_root=user_output_root,
55
+ user_generated_dir=user_output_root / "generated",
56
+ user_projects_dir=user_output_root / "projects",
57
+ )
58
+
59
+
60
+ def config_snapshot(config_dir: Optional[Path] = None) -> dict[str, str]:
61
+ """Return a JSON-serializable snapshot of resolved config paths."""
62
+ paths = resolve_paths(config_dir)
63
+ return {
64
+ "config_dir": str(paths.config_dir),
65
+ "config_file": str(paths.config_file),
66
+ "history_file": str(paths.history_file),
67
+ "sessions_dir": str(paths.sessions_dir),
68
+ "providers_file": str(paths.providers_file),
69
+ "hooks_file": str(paths.hooks_file),
70
+ "user_output_root": str(paths.user_output_root),
71
+ "user_generated_dir": str(paths.user_generated_dir),
72
+ "user_projects_dir": str(paths.user_projects_dir),
73
+ }
@@ -0,0 +1,78 @@
1
+ """Persistent CLI configuration loading and saving.
2
+
3
+ CLI adapter for :class:`packages.aria_services.settings.SettingsService` —
4
+ the service owns the merge/normalize/persist mechanics; this module supplies
5
+ the CLI-specific hooks (provider-name normalization, i18n detection, model
6
+ auto-selection) and keeps the historical ``load_cli_config``/``save_cli_config``
7
+ API so existing call sites are untouched.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from collections.abc import Callable
13
+
14
+ from aria_code.apps.cli.config_paths import AriaConfigPaths
15
+ from aria_code.packages.aria_services.settings import ( # noqa: F401 (re-exported)
16
+ STALE_ARIA_MODEL_PREFIXES,
17
+ SettingsService,
18
+ )
19
+
20
+
21
+ def _normalize_provider(name: str) -> str:
22
+ from apps.cli.providers.chat_routing import normalize_provider_name
23
+ return normalize_provider_name(name)
24
+
25
+
26
+ def _detect_lang() -> str:
27
+ from apps.cli.i18n import detect_system_lang
28
+ return detect_system_lang()
29
+
30
+
31
+ def build_settings_service(
32
+ paths: AriaConfigPaths,
33
+ defaults: dict,
34
+ *,
35
+ sync_policy: Callable[[dict], None] | None = None,
36
+ ) -> SettingsService:
37
+ """Construct the SettingsService with the CLI's environment hooks."""
38
+ return SettingsService(
39
+ config_dir=paths.config_dir,
40
+ config_file=paths.config_file,
41
+ sessions_dir=paths.sessions_dir,
42
+ defaults=defaults,
43
+ normalize_provider=_normalize_provider,
44
+ detect_lang=_detect_lang,
45
+ on_loaded=sync_policy,
46
+ )
47
+
48
+
49
+ def load_cli_config(
50
+ paths: AriaConfigPaths,
51
+ defaults: dict,
52
+ *,
53
+ sync_policy: Callable[[dict], None] | None = None,
54
+ ) -> dict:
55
+ """Load config.json, merge with defaults, then apply the project's .ariarc.
56
+
57
+ The i18n/chat_routing imports below are bare on purpose: the tests
58
+ patch those modules, and the packaged root is a different module
59
+ object, so the packaged form left detect_system_lang unpatched.
60
+
61
+ The .ariarc overlay goes last so a repo that pins a model gets it for
62
+ everyone who opens it, without each developer editing their global config.
63
+ It is best-effort: a malformed project file must not stop the CLI from
64
+ starting, because the user would then have no way to run the tool that
65
+ would fix it.
66
+ """
67
+ config = build_settings_service(paths, defaults, sync_policy=sync_policy).load()
68
+ try:
69
+ from aria_code.ariarc import apply_to_config
70
+
71
+ apply_to_config(config)
72
+ except Exception:
73
+ pass
74
+ return config
75
+
76
+
77
+ def save_cli_config(paths: AriaConfigPaths, cfg: dict) -> None:
78
+ build_settings_service(paths, {}).save(cfg)
@@ -0,0 +1,88 @@
1
+ from typing import Dict
2
+
3
+ _PROVIDER_KEY_MAP: Dict[str, str] = {
4
+ "deepseek": "DEEPSEEK_API_KEY",
5
+ "openai": "OPENAI_API_KEY",
6
+ "anthropic": "ANTHROPIC_API_KEY",
7
+ "claude": "ANTHROPIC_API_KEY",
8
+ "groq": "GROQ_API_KEY",
9
+ "together": "TOGETHER_API_KEY",
10
+ "google": "GOOGLE_API_KEY",
11
+ "gemini": "GOOGLE_API_KEY",
12
+ "xai": "XAI_API_KEY",
13
+ "grok": "XAI_API_KEY",
14
+ "mistral": "MISTRAL_API_KEY",
15
+ "cohere": "COHERE_API_KEY",
16
+ "perplexity": "PERPLEXITY_API_KEY",
17
+ "dashscope": "DASHSCOPE_API_KEY",
18
+ "aliyun": "DASHSCOPE_API_KEY",
19
+ "siliconflow": "SILICONFLOW_API_KEY",
20
+ "moonshot": "MOONSHOT_API_KEY",
21
+ "zhipu": "ZHIPUAI_API_KEY",
22
+ "glm": "ZHIPUAI_API_KEY",
23
+ "baidu": "QIANFAN_ACCESS_KEY",
24
+ "ernie": "QIANFAN_ACCESS_KEY",
25
+ "qianfan": "QIANFAN_ACCESS_KEY",
26
+ "bytedance": "ARK_API_KEY",
27
+ "doubao": "ARK_API_KEY",
28
+ "ark": "ARK_API_KEY",
29
+ "minimax": "MINIMAX_API_KEY",
30
+ "stepfun": "STEPFUN_API_KEY",
31
+ "01ai": "ONEAI_API_KEY",
32
+ "yi": "ONEAI_API_KEY",
33
+ }
34
+
35
+ _DATA_KEY_MAP: Dict[str, str] = {
36
+ "finnhub": "FINNHUB_API_KEY",
37
+ "newsapi": "NEWS_API_KEY",
38
+ "brave": "BRAVE_SEARCH_API_KEY",
39
+ "tavily": "TAVILY_API_KEY",
40
+ "coingecko": "COINGECKO_API_KEY",
41
+ "alphavantage": "ALPHA_VANTAGE_API_KEY",
42
+ "polygon": "POLYGON_API_KEY",
43
+ "fmp": "FMP_API_KEY",
44
+ "twelvedata": "TWELVEDATA_API_KEY",
45
+ "figma": "FIGMA_API_KEY",
46
+ }
47
+
48
+ _DATA_SIGNUP_URLS: Dict[str, str] = {
49
+ "finnhub": "https://finnhub.io/register",
50
+ "newsapi": "https://newsapi.org/register",
51
+ "brave": "https://api.search.brave.com/app/keys",
52
+ "tavily": "https://app.tavily.com",
53
+ "coingecko": "https://www.coingecko.com/en/api",
54
+ "alphavantage": "https://www.alphavantage.co/support/#api-key",
55
+ "polygon": "https://polygon.io/signup",
56
+ "fmp": "https://financialmodelingprep.com/register",
57
+ "twelvedata": "https://twelvedata.com/register",
58
+ "figma": "https://www.figma.com/developers/api#access-tokens",
59
+ }
60
+
61
+ _LLM_SIGNUP_URLS: Dict[str, str] = {
62
+ "deepseek": "https://platform.deepseek.com/api_keys",
63
+ "openai": "https://platform.openai.com/api-keys",
64
+ "anthropic": "https://console.anthropic.com/settings/keys",
65
+ "claude": "https://console.anthropic.com/settings/keys",
66
+ "groq": "https://console.groq.com/keys",
67
+ "together": "https://api.together.ai/settings/api-keys",
68
+ "google": "https://aistudio.google.com/app/apikey",
69
+ "gemini": "https://aistudio.google.com/app/apikey",
70
+ "xai": "https://console.x.ai",
71
+ "grok": "https://console.x.ai",
72
+ "mistral": "https://console.mistral.ai/api-keys",
73
+ "cohere": "https://dashboard.cohere.com/api-keys",
74
+ "perplexity": "https://www.perplexity.ai/settings/api",
75
+ "dashscope": "https://dashscope.console.aliyun.com/apiKey",
76
+ "aliyun": "https://dashscope.console.aliyun.com/apiKey",
77
+ "siliconflow": "https://cloud.siliconflow.cn/account/ak",
78
+ "moonshot": "https://platform.moonshot.cn/console/api-keys",
79
+ "zhipu": "https://open.bigmodel.cn/usercenter/apikeys",
80
+ "baidu": "https://qianfan.cloud.baidu.com/user/accessToken",
81
+ "ernie": "https://qianfan.cloud.baidu.com/user/accessToken",
82
+ "bytedance": "https://ark.volcengine.com/api-key",
83
+ "doubao": "https://ark.volcengine.com/api-key",
84
+ "minimax": "https://platform.minimaxi.com/user-center/basic-information/interface-key",
85
+ "stepfun": "https://platform.stepfun.com/interface-key",
86
+ "01ai": "https://platform.lingyiwanwu.com/apikeys",
87
+ "yi": "https://platform.lingyiwanwu.com/apikeys",
88
+ }
@@ -0,0 +1,34 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import Any, Dict, Callable
3
+
4
+ @dataclass
5
+ class AriaContext:
6
+ """
7
+ Unified context for Aria CLI commands.
8
+ This replaces the dynamic `__globals__` injection pattern.
9
+ Commands should accept this context to access console, workspace, and config.
10
+ """
11
+ console: Any = None
12
+ workspace: Any = None
13
+ config: Dict[str, Any] = field(default_factory=dict)
14
+ has_rich: bool = False
15
+
16
+ # Callbacks for config
17
+ save_config_cb: Callable[[Dict[str, Any]], None] = None
18
+ load_config_cb: Callable[[], Dict[str, Any]] = None
19
+
20
+ def save_config(self, cfg: dict):
21
+ if self.save_config_cb:
22
+ self.save_config_cb(cfg)
23
+
24
+ def load_config(self) -> dict:
25
+ if self.load_config_cb:
26
+ return self.load_config_cb()
27
+ return {}
28
+
29
+ def __post_init__(self):
30
+ if self.config is None:
31
+ self.config = {}
32
+ if self.has_rich is False and self.console is not None:
33
+ self.has_rich = True
34
+
@@ -0,0 +1,191 @@
1
+ """Shared deterministic routing for Aria agent entrypoints.
2
+
3
+ This module is intentionally UI-free. The legacy CLI, future daemon/webhook
4
+ entrypoints, and the public SDK can all use the same routing order without
5
+ importing the terminal implementation from ``aria_cli.py``.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from dataclasses import dataclass
11
+ from typing import Any, Callable
12
+
13
+ from aria_code.apps.cli.handlers.broker_handlers import handle_broker_query
14
+ from aria_code.apps.cli.handlers.chart_handlers import handle_stock_chart_analysis
15
+ from aria_code.apps.cli.handlers.market_handlers import (
16
+ _try_handle_market_overview,
17
+ _try_handle_market_snapshot_analysis,
18
+ )
19
+ from aria_code.apps.cli.handlers.realty_handlers import handle_realty_query
20
+ from aria_code.apps.cli.handlers.strategy_advice import handle_strategy_advice
21
+ from aria_code.apps.cli.utils.market_detect import (
22
+ _CN_CITIES,
23
+ _INTL_CITIES,
24
+ _extract_market_symbol,
25
+ _is_broker_intent,
26
+ _is_realty_query,
27
+ _is_stock_chart_analysis_request,
28
+ )
29
+
30
+
31
+ BrokerRegistryFactory = Callable[[], Any]
32
+
33
+
34
+ def _pack_handlers(message: str) -> tuple:
35
+ """Deterministic handlers contributed by the packs this message activates.
36
+
37
+ Falls back to the legacy finance handlers if the pack layer is unavailable,
38
+ so an import problem degrades to the previous behaviour rather than
39
+ silently dropping domain routing.
40
+ """
41
+ try:
42
+ from aria_code.packs import (
43
+ activate_packs,
44
+ active_handlers,
45
+ load_builtin_packs,
46
+ )
47
+
48
+ load_builtin_packs()
49
+ return active_handlers(activate_packs(message))
50
+ except Exception:
51
+ return (handle_strategy_advice, _handle_stock_chart_analysis)
52
+
53
+
54
+ # Names of the handlers that decide for themselves whether a message is theirs
55
+ # and answer without fetching anything. They need no pack activation; see the
56
+ # call site for why.
57
+ #
58
+ # Names rather than function objects, resolved at call time: a module-level
59
+ # tuple of references captures whatever was imported and then ignores anything
60
+ # that replaces the module attribute later, which silently defeats both
61
+ # monkeypatching in tests and any runtime substitution.
62
+ _SELF_GATED_HANDLER_NAMES = ("handle_strategy_advice",)
63
+
64
+
65
+ def _self_gated_handlers() -> tuple:
66
+ return tuple(globals()[name] for name in _SELF_GATED_HANDLER_NAMES)
67
+
68
+
69
+ def _missing_broker_registry() -> None:
70
+ return None
71
+
72
+
73
+ @dataclass(frozen=True)
74
+ class DeterministicRouterConfig:
75
+ """Configuration for deterministic routing outside the model loop."""
76
+
77
+ model_has_tools: bool = True
78
+ has_brokers: bool = False
79
+ get_broker_registry: BrokerRegistryFactory | None = None
80
+
81
+
82
+ def _handle_broker_query(message: str, config: DeterministicRouterConfig) -> dict:
83
+ return handle_broker_query(
84
+ message,
85
+ has_brokers=config.has_brokers,
86
+ is_broker_intent=_is_broker_intent,
87
+ get_broker_registry=config.get_broker_registry or _missing_broker_registry,
88
+ )
89
+
90
+
91
+ def _handle_realty_query(message: str) -> dict:
92
+ return handle_realty_query(
93
+ message,
94
+ is_realty_query=_is_realty_query,
95
+ cn_cities=_CN_CITIES,
96
+ intl_cities=_INTL_CITIES,
97
+ )
98
+
99
+
100
+ def _handle_stock_chart_analysis(message: str) -> dict:
101
+ return handle_stock_chart_analysis(
102
+ message,
103
+ is_chart_request=_is_stock_chart_analysis_request,
104
+ extract_symbol=_extract_market_symbol,
105
+ )
106
+
107
+
108
+ def run_deterministic_chain(
109
+ message: str,
110
+ *,
111
+ model_has_tools: bool,
112
+ history: list | None = None,
113
+ has_brokers: bool = False,
114
+ get_broker_registry: BrokerRegistryFactory | None = None,
115
+ ) -> dict:
116
+ """Run the deterministic routing chain used before LLM fallback.
117
+
118
+ Order matters:
119
+ - broker account reads are only used when the model cannot call tools;
120
+ - realty must run before market parsing, so housing questions do not inherit
121
+ a ticker;
122
+ - chart requests run before snapshots;
123
+ - whole-market overview runs before single-symbol snapshot parsing, so
124
+ "分析A股" is treated as the A-share market instead of ticker ``A``.
125
+ """
126
+
127
+ config = DeterministicRouterConfig(
128
+ model_has_tools=model_has_tools,
129
+ has_brokers=has_brokers,
130
+ get_broker_registry=get_broker_registry,
131
+ )
132
+
133
+ deterministic: dict = {"success": False}
134
+ if not config.model_has_tools:
135
+ deterministic = _handle_broker_query(message, config)
136
+
137
+ # Domain handlers run only for packs the message actually activated. They
138
+ # used to run against every message: a question about this repository was
139
+ # walked through the strategy, realty and stock-chart handlers before the
140
+ # model saw it, which is how a code request came back as a stock quote.
141
+ # Activation is entity-gated, so a message that names no instrument never
142
+ # reaches the finance handlers at all. See aria_code.packs.
143
+ #
144
+ # Realty was the last handler still running ungated here, and it moved
145
+ # behind the same gate in the realty pack: a message must name a city and
146
+ # a housing term, or name the national market outright. A property-domain
147
+ # word on its own ("物业", "地产") no longer reaches it, because that word
148
+ # also appears in the source of every property-management codebase.
149
+ for handler in _pack_handlers(message):
150
+ if deterministic.get("success"):
151
+ break
152
+ deterministic = handler(message)
153
+
154
+ # Self-gated handlers run without a pack activation, because they do not
155
+ # depend on one.
156
+ #
157
+ # The entity gate exists to stop a handler that ANSWERS WITH DATA from
158
+ # firing when no instrument was named — that is how a question about this
159
+ # repository came back as a MongoDB stock quote. handle_strategy_advice
160
+ # answers with static methodology text, names no instrument, and fetches
161
+ # nothing, so it carries none of that risk. Gating it anyway simply broke
162
+ # it: "如果我要写一个美股量化策略,你觉得要从几个角度去写" names no ticker,
163
+ # so no pack activated and the handler was unreachable.
164
+ #
165
+ # Its own gate is a three-way conjunction (strategy term AND advice term
166
+ # AND NOT execution term) that rejects every software-engineering use of
167
+ # 策略/建议 — "帮我写一个缓存策略", "数据库索引策略有什么建议",
168
+ # "给我一些代码风格建议" all fall through untouched.
169
+ for handler in _self_gated_handlers():
170
+ if deterministic.get("success"):
171
+ break
172
+ deterministic = handler(message)
173
+
174
+ # Tool-capable models should resolve symbols and fetch market data through
175
+ # the audited tool loop. The deterministic market handlers can refresh a
176
+ # large remote symbol universe, which blocks the REPL before the model ever
177
+ # receives the request. Keep them as the fallback for text-only models.
178
+ if not deterministic.get("success") and not config.model_has_tools:
179
+ deterministic = _try_handle_market_overview(message)
180
+
181
+ if not deterministic.get("success") and not config.model_has_tools:
182
+ deterministic = _try_handle_market_snapshot_analysis(message, history=history)
183
+
184
+ return deterministic
185
+
186
+
187
+ __all__ = [
188
+ "BrokerRegistryFactory",
189
+ "DeterministicRouterConfig",
190
+ "run_deterministic_chain",
191
+ ]
@@ -0,0 +1,48 @@
1
+ """Direct command dispatcher for non-interactive CLI entrypoints."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import inspect
6
+ from typing import Any
7
+
8
+ from aria_code.apps.cli.commands.catalog import DIRECT_COMMAND_MAP, WATCHABLE_DIRECT_COMMANDS
9
+
10
+
11
+ def is_watchable_direct_command(command: str) -> bool:
12
+ return command.strip().lower() in WATCHABLE_DIRECT_COMMANDS
13
+
14
+
15
+ async def dispatch_direct_command(
16
+ terminal: Any,
17
+ command: str,
18
+ command_args: str = "",
19
+ *,
20
+ json_output: bool = False,
21
+ fmt: str = "table",
22
+ output_file: str | None = None,
23
+ quiet: bool = False,
24
+ ) -> bool:
25
+ """Dispatch a direct CLI command.
26
+
27
+ Returns True when the command was handled by a known direct command handler.
28
+ Unknown direct commands fall back to the normal prompt path and return False.
29
+ """
30
+
31
+ cmd = command.strip().lower()
32
+ spec = DIRECT_COMMAND_MAP.get(cmd)
33
+ if spec is None:
34
+ await terminal.run_prompt(
35
+ f"{command} {command_args}".strip(),
36
+ json_output=json_output,
37
+ fmt=fmt,
38
+ output_file=output_file,
39
+ quiet=quiet,
40
+ )
41
+ return False
42
+
43
+ handler = getattr(terminal.commands, spec.method_name)
44
+ result = handler(command_args)
45
+ if inspect.isawaitable(result):
46
+ await result
47
+ return True
48
+
@@ -0,0 +1,111 @@
1
+ """One explicit capability contract for every supported financial market.
2
+
3
+ This avoids asking an LLM to infer whether an A-share prediction engine, a
4
+ crypto funding-rate feed, or a foreign-exchange quote is applicable. Routing
5
+ is deterministic and descriptions only advertise data the CLI can actually
6
+ request through its existing tools.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from dataclasses import dataclass
12
+ import re
13
+
14
+ from aria_code.apps.cli.market_universe import resolve_market_mentions
15
+
16
+
17
+ @dataclass(frozen=True)
18
+ class FinanceMarketService:
19
+ key: str
20
+ label: str
21
+ aliases: tuple[str, ...]
22
+ services: tuple[str, ...]
23
+ analysis: tuple[str, ...]
24
+ prediction: str = ""
25
+
26
+
27
+ MARKET_SERVICES: tuple[FinanceMarketService, ...] = (
28
+ FinanceMarketService(
29
+ "CN", "A 股", ("a股", "沪深", "上证", "深证", "创业板", "科创板"),
30
+ ("实时行情", "历史K线", "技术指标", "基本面", "公告/新闻", "回测", "组合风控"),
31
+ ("行情与成交量", "基本面与监管公告", "板块与资金流", "T+1/涨跌停约束回测"),
32
+ "次交易日预测(覆盖率、数据日期、回测质量必须同时披露)",
33
+ ),
34
+ FinanceMarketService(
35
+ "HK", "港股", ("港股", "恒生", "h股"),
36
+ ("实时行情", "历史K线", "技术指标", "基本面", "新闻", "组合风控"),
37
+ ("港币计价与交易时段", "中概/内地政策传导", "公司基本面与行业比较"),
38
+ ),
39
+ FinanceMarketService(
40
+ "US", "美股", ("美股", "纳斯达克", "纽交所", "标普", "道指"),
41
+ ("实时行情", "历史K线", "技术指标", "财报", "新闻", "回测", "组合风控"),
42
+ ("财报和指引", "宏观利率与行业估值", "盘前/盘后与公司事件"),
43
+ ),
44
+ FinanceMarketService(
45
+ "GLOBAL", "全球股票与指数", ("欧股", "日股", "全球市场", "指数"),
46
+ ("实时行情", "历史K线", "技术指标", "新闻", "组合风控"),
47
+ ("本币与汇率", "本地交易时段", "指数/行业相对表现"),
48
+ ),
49
+ FinanceMarketService(
50
+ "CRYPTO", "加密资产", ("加密", "比特币", "以太坊", "btc", "eth", "币安", "okx"),
51
+ ("现货行情", "历史K线", "技术指标", "交易所账户只读查询", "资金费率/衍生品(数据源可用时)"),
52
+ ("24/7市场与流动性", "交易所及对手方风险", "杠杆/资金费率与波动"),
53
+ ),
54
+ FinanceMarketService(
55
+ "FX", "外汇", ("外汇", "汇率", "美元兑", "eur/", "usd/", "jpy"),
56
+ ("实时汇率", "历史K线", "技术指标", "宏观/新闻"),
57
+ ("利差与央行政策", "汇率方向和报价惯例", "跨币种风险"),
58
+ ),
59
+ FinanceMarketService(
60
+ "FUTURES", "商品与期货", ("期货", "商品", "黄金", "白银", "原油", "铜", "天然气"),
61
+ ("连续合约行情", "历史K线", "技术指标", "宏观/新闻"),
62
+ ("合约月份与展期", "库存/供需/地缘事件", "保证金和杠杆风险"),
63
+ ),
64
+ )
65
+
66
+ _BY_KEY = {service.key: service for service in MARKET_SERVICES}
67
+
68
+
69
+ def classify_finance_market(text: str) -> FinanceMarketService | None:
70
+ """Classify a request without network calls; named symbols win over words."""
71
+ query = str(text or "")
72
+ mentions = resolve_market_mentions(query, limit=1, load_universe=lambda: [])
73
+ if mentions:
74
+ key = mentions[0][1].market
75
+ if key == "INDEX":
76
+ symbol = mentions[0][1].symbol.upper()
77
+ if symbol.endswith((".SS", ".SZ")):
78
+ key = "CN"
79
+ elif symbol in {"^HSI", "^HSCE"}:
80
+ key = "HK"
81
+ else:
82
+ key = "GLOBAL"
83
+ return _BY_KEY.get(key)
84
+ low = query.lower()
85
+ for service in MARKET_SERVICES:
86
+ if any(alias in low for alias in service.aliases):
87
+ return service
88
+ if re.search(r"\b\d{6}(?:\.(?:sh|sz|ss))?\b", low):
89
+ return _BY_KEY["CN"]
90
+ if re.search(r"\b[A-Z]{1,5}(?:\.[A-Z]{1,4})?\b", query):
91
+ return _BY_KEY["US"]
92
+ return None
93
+
94
+
95
+ def market_service_summary(text: str = "") -> dict[str, object]:
96
+ """Return a display-ready and machine-readable market service contract."""
97
+ selected = classify_finance_market(text)
98
+ services = (selected,) if selected else MARKET_SERVICES
99
+ return {
100
+ "selected": selected.key if selected else None,
101
+ "markets": [
102
+ {
103
+ "key": item.key,
104
+ "label": item.label,
105
+ "services": item.services,
106
+ "analysis": item.analysis,
107
+ "prediction": item.prediction or None,
108
+ }
109
+ for item in services
110
+ ],
111
+ }