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.
Files changed (601) hide show
  1. aria_bots/__init__.py +7 -0
  2. aria_bots/channels/README.md +97 -0
  3. aria_bots/channels/__init__.py +1 -0
  4. aria_bots/channels/approvals.py +263 -0
  5. aria_bots/channels/conversation.py +280 -0
  6. aria_bots/channels/digest.py +186 -0
  7. aria_bots/channels/registry.py +95 -0
  8. aria_bots/engine.py +144 -0
  9. aria_bots/feishu_bot.py +1385 -0
  10. aria_bots/logistics/__init__.py +1 -0
  11. aria_bots/logistics/carriers.py +253 -0
  12. aria_bots/logistics/freight.py +154 -0
  13. aria_bots/logistics/inventory.py +242 -0
  14. aria_bots/logistics/mcp_server.py +156 -0
  15. aria_bots/logistics/records.py +119 -0
  16. aria_bots/logistics/tenancy.py +152 -0
  17. aria_bots/market.py +91 -0
  18. aria_bots/relay_client.py +326 -0
  19. aria_bots/telegram_bot.py +299 -0
  20. aria_code/__init__.py +111 -0
  21. aria_code/_bin/aria-native.exe +0 -0
  22. aria_code/_bin/aria-runtime.exe +0 -0
  23. aria_code/_version.py +20 -0
  24. aria_code/account_memory.py +296 -0
  25. aria_code/account_session.py +166 -0
  26. aria_code/adk_apps/__init__.py +1 -0
  27. aria_code/adk_apps/aria_code_review/__init__.py +1 -0
  28. aria_code/adk_apps/aria_code_review/agent.py +32 -0
  29. aria_code/adk_apps/aria_research/__init__.py +1 -0
  30. aria_code/adk_apps/aria_research/agent.py +31 -0
  31. aria_code/agents/__init__.py +49 -0
  32. aria_code/agents/base.py +329 -0
  33. aria_code/agents/code_review.py +200 -0
  34. aria_code/agents/deep/__init__.py +37 -0
  35. aria_code/agents/deep/calibration_loop.py +144 -0
  36. aria_code/agents/deep/critic.py +125 -0
  37. aria_code/agents/deep/deepen.py +193 -0
  38. aria_code/agents/deep/models.py +149 -0
  39. aria_code/agents/deep/pipeline.py +164 -0
  40. aria_code/agents/deep/quant_fusion.py +192 -0
  41. aria_code/agents/deep/themes.py +95 -0
  42. aria_code/agents/deep/tiers.py +106 -0
  43. aria_code/agents/engineering/__init__.py +14 -0
  44. aria_code/agents/engineering/coder.py +222 -0
  45. aria_code/agents/engineering/tester.py +145 -0
  46. aria_code/agents/financial/__init__.py +21 -0
  47. aria_code/agents/financial/cashflow_burn.py +119 -0
  48. aria_code/agents/financial/catalyst.py +279 -0
  49. aria_code/agents/financial/corporate_finance.py +175 -0
  50. aria_code/agents/financial/debate.py +224 -0
  51. aria_code/agents/financial/earnings.py +315 -0
  52. aria_code/agents/financial/fundamental.py +178 -0
  53. aria_code/agents/financial/macro.py +111 -0
  54. aria_code/agents/financial/news.py +231 -0
  55. aria_code/agents/financial/risk.py +146 -0
  56. aria_code/agents/financial/sector.py +279 -0
  57. aria_code/agents/financial/strategist.py +121 -0
  58. aria_code/agents/financial/stripe_revenue.py +127 -0
  59. aria_code/agents/financial/synthesis.py +274 -0
  60. aria_code/agents/financial/technical.py +277 -0
  61. aria_code/agents/orchestrator.py +44 -0
  62. aria_code/agents/portfolio_agent.py +392 -0
  63. aria_code/agents/realty/__init__.py +62 -0
  64. aria_code/agents/realty/asset_diagnosis.py +152 -0
  65. aria_code/agents/realty/business_match.py +166 -0
  66. aria_code/agents/realty/cashflow_verify.py +209 -0
  67. aria_code/agents/realty/contract_rules.py +210 -0
  68. aria_code/agents/realty/energy_anomaly.py +189 -0
  69. aria_code/agents/realty/exit_settlement.py +208 -0
  70. aria_code/agents/realty/fulfillment_risk.py +206 -0
  71. aria_code/agents/realty/ops_optimize.py +160 -0
  72. aria_code/agents/realty/revenue_share.py +215 -0
  73. aria_code/agents/registry.py +168 -0
  74. aria_code/agents/signal_scheme.py +111 -0
  75. aria_code/agents/sports/__init__.py +0 -0
  76. aria_code/agents/sports/football_agent.py +197 -0
  77. aria_code/agents/supervisor.py +113 -0
  78. aria_code/agents/team.py +500 -0
  79. aria_code/agents/video/__init__.py +16 -0
  80. aria_code/agents/video/director.py +376 -0
  81. aria_code/agents/video/qa_agent.py +143 -0
  82. aria_code/agents/video/script_doctor.py +112 -0
  83. aria_code/agents/warehouse/__init__.py +25 -0
  84. aria_code/agents/warehouse/contracts.py +26 -0
  85. aria_code/agents/warehouse/dashboard.py +155 -0
  86. aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
  87. aria_code/agents/warehouse/inbound_exceptions.py +25 -0
  88. aria_code/agents/warehouse/inventory_health.py +24 -0
  89. aria_code/agents/warehouse/local_run.py +71 -0
  90. aria_code/agents/warehouse/local_snapshot.py +132 -0
  91. aria_code/agents/warehouse/logistics_cost.py +84 -0
  92. aria_code/agents/warehouse/logistics_sync.py +21 -0
  93. aria_code/agents/warehouse/navigation.schema.json +110 -0
  94. aria_code/agents/warehouse/task_agent.py +172 -0
  95. aria_code/agents/warehouse/workflow.py +31 -0
  96. aria_code/aliyun_data_client.py +4 -0
  97. aria_code/apps/README.md +12 -0
  98. aria_code/apps/__init__.py +2 -0
  99. aria_code/apps/channels/README.md +9 -0
  100. aria_code/apps/channels/__init__.py +17 -0
  101. aria_code/apps/channels/approvals.py +11 -0
  102. aria_code/apps/channels/conversation.py +11 -0
  103. aria_code/apps/channels/digest.py +11 -0
  104. aria_code/apps/channels/intake.py +92 -0
  105. aria_code/apps/channels/registry.py +11 -0
  106. aria_code/apps/channels/tradingview.py +94 -0
  107. aria_code/apps/cli/README.md +13 -0
  108. aria_code/apps/cli/__init__.py +2 -0
  109. aria_code/apps/cli/_optional.py +120 -0
  110. aria_code/apps/cli/app_server.py +656 -0
  111. aria_code/apps/cli/auto_update.py +125 -0
  112. aria_code/apps/cli/bootstrap.py +206 -0
  113. aria_code/apps/cli/broker_render.py +206 -0
  114. aria_code/apps/cli/chat_turn.py +1327 -0
  115. aria_code/apps/cli/cloud_models.py +231 -0
  116. aria_code/apps/cli/codegen_paths.py +29 -0
  117. aria_code/apps/cli/commands/__init__.py +34 -0
  118. aria_code/apps/cli/commands/_business_render.py +78 -0
  119. aria_code/apps/cli/commands/_ui.py +71 -0
  120. aria_code/apps/cli/commands/analysis_cmds.py +378 -0
  121. aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
  122. aria_code/apps/cli/commands/auth_cmds.py +215 -0
  123. aria_code/apps/cli/commands/backtest_cmds.py +2518 -0
  124. aria_code/apps/cli/commands/broker_cmds.py +1236 -0
  125. aria_code/apps/cli/commands/business_workflow_cmds.py +379 -0
  126. aria_code/apps/cli/commands/canvas_cmds.py +77 -0
  127. aria_code/apps/cli/commands/catalog.py +189 -0
  128. aria_code/apps/cli/commands/core_cmds.py +2748 -0
  129. aria_code/apps/cli/commands/data_cmds.py +521 -0
  130. aria_code/apps/cli/commands/diagnostic_cmds.py +285 -0
  131. aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
  132. aria_code/apps/cli/commands/engineering_cmds.py +399 -0
  133. aria_code/apps/cli/commands/file_cmds.py +312 -0
  134. aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
  135. aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
  136. aria_code/apps/cli/commands/market.py +544 -0
  137. aria_code/apps/cli/commands/market_cmds.py +1419 -0
  138. aria_code/apps/cli/commands/market_context.py +432 -0
  139. aria_code/apps/cli/commands/market_render.py +7 -0
  140. aria_code/apps/cli/commands/model_cmds.py +2374 -0
  141. aria_code/apps/cli/commands/ops_cmds.py +721 -0
  142. aria_code/apps/cli/commands/orchestrator_cmds.py +181 -0
  143. aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
  144. aria_code/apps/cli/commands/portfolio_cmds.py +1316 -0
  145. aria_code/apps/cli/commands/report.py +476 -0
  146. aria_code/apps/cli/commands/scaffold_templates.py +617 -0
  147. aria_code/apps/cli/commands/session_cmds.py +236 -0
  148. aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
  149. aria_code/apps/cli/commands/team.py +723 -0
  150. aria_code/apps/cli/commands/team_render.py +8 -0
  151. aria_code/apps/cli/commands/ui_cmds.py +401 -0
  152. aria_code/apps/cli/commands/warehouse_cmds.py +297 -0
  153. aria_code/apps/cli/commands/workflow_cmds.py +629 -0
  154. aria_code/apps/cli/commands/workspace_cmds.py +1543 -0
  155. aria_code/apps/cli/config_paths.py +73 -0
  156. aria_code/apps/cli/config_store.py +158 -0
  157. aria_code/apps/cli/constants.py +88 -0
  158. aria_code/apps/cli/context.py +34 -0
  159. aria_code/apps/cli/conversation_policy.py +53 -0
  160. aria_code/apps/cli/deterministic.py +200 -0
  161. aria_code/apps/cli/direct.py +48 -0
  162. aria_code/apps/cli/earnings_view.py +172 -0
  163. aria_code/apps/cli/endpoint_migration.py +64 -0
  164. aria_code/apps/cli/exec_events.py +255 -0
  165. aria_code/apps/cli/file_references.py +155 -0
  166. aria_code/apps/cli/finance_service_catalog.py +111 -0
  167. aria_code/apps/cli/football_reports.py +231 -0
  168. aria_code/apps/cli/github_app_auth.py +135 -0
  169. aria_code/apps/cli/google_login.py +239 -0
  170. aria_code/apps/cli/handlers/__init__.py +11 -0
  171. aria_code/apps/cli/handlers/broker_handlers.py +122 -0
  172. aria_code/apps/cli/handlers/chart_handlers.py +1314 -0
  173. aria_code/apps/cli/handlers/market_handlers.py +2570 -0
  174. aria_code/apps/cli/handlers/realty_handlers.py +114 -0
  175. aria_code/apps/cli/handlers/sports_handlers.py +22 -0
  176. aria_code/apps/cli/handlers/strategy_advice.py +82 -0
  177. aria_code/apps/cli/headless.py +352 -0
  178. aria_code/apps/cli/helpers.py +326 -0
  179. aria_code/apps/cli/hooks.py +180 -0
  180. aria_code/apps/cli/i18n.py +310 -0
  181. aria_code/apps/cli/intent.py +136 -0
  182. aria_code/apps/cli/intent_router.py +305 -0
  183. aria_code/apps/cli/intent_shadow.py +72 -0
  184. aria_code/apps/cli/intent_signals.py +347 -0
  185. aria_code/apps/cli/lifecycle_hooks.py +48 -0
  186. aria_code/apps/cli/local_tool_schemas.py +550 -0
  187. aria_code/apps/cli/main.py +39 -0
  188. aria_code/apps/cli/market_hours.py +100 -0
  189. aria_code/apps/cli/market_metadata.py +135 -0
  190. aria_code/apps/cli/market_universe.py +487 -0
  191. aria_code/apps/cli/message_processing.py +310 -0
  192. aria_code/apps/cli/mixin_binding.py +32 -0
  193. aria_code/apps/cli/model_catalog.py +652 -0
  194. aria_code/apps/cli/model_probe.py +169 -0
  195. aria_code/apps/cli/model_retirement.py +65 -0
  196. aria_code/apps/cli/native_branding.py +12 -0
  197. aria_code/apps/cli/native_bridge.py +118 -0
  198. aria_code/apps/cli/native_entry.py +58 -0
  199. aria_code/apps/cli/pdf_report.py +977 -0
  200. aria_code/apps/cli/plan_mode.py +139 -0
  201. aria_code/apps/cli/plotly_html.py +15 -0
  202. aria_code/apps/cli/prediction_feedback.py +202 -0
  203. aria_code/apps/cli/preflight.py +502 -0
  204. aria_code/apps/cli/project_aria.py +60 -0
  205. aria_code/apps/cli/prompt_assembly.py +78 -0
  206. aria_code/apps/cli/prompts/__init__.py +0 -0
  207. aria_code/apps/cli/prompts/coding.py +71 -0
  208. aria_code/apps/cli/prompts/select.py +193 -0
  209. aria_code/apps/cli/prompts/system_prompts.py +562 -0
  210. aria_code/apps/cli/prompts/ui.py +436 -0
  211. aria_code/apps/cli/provider_endpoints.py +237 -0
  212. aria_code/apps/cli/provider_keys.py +73 -0
  213. aria_code/apps/cli/providers/__init__.py +1 -0
  214. aria_code/apps/cli/providers/base.py +775 -0
  215. aria_code/apps/cli/providers/chat_routing.py +139 -0
  216. aria_code/apps/cli/providers/collaboration.py +98 -0
  217. aria_code/apps/cli/providers/llm/__init__.py +1 -0
  218. aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
  219. aria_code/apps/cli/providers/llm/ollama_stream.py +1574 -0
  220. aria_code/apps/cli/providers/llm/response_cache.py +60 -0
  221. aria_code/apps/cli/providers/llm/sse_stream.py +298 -0
  222. aria_code/apps/cli/providers/runtime_bridge.py +586 -0
  223. aria_code/apps/cli/providers/vertexai_stream.py +592 -0
  224. aria_code/apps/cli/release_download.py +159 -0
  225. aria_code/apps/cli/review_runner.py +111 -0
  226. aria_code/apps/cli/runtime_consumer.py +769 -0
  227. aria_code/apps/cli/sandbox.py +32 -0
  228. aria_code/apps/cli/session_export.py +120 -0
  229. aria_code/apps/cli/session_jsonl.py +208 -0
  230. aria_code/apps/cli/session_refresh.py +123 -0
  231. aria_code/apps/cli/session_store.py +125 -0
  232. aria_code/apps/cli/skills_catalog.py +273 -0
  233. aria_code/apps/cli/task_isolation.py +211 -0
  234. aria_code/apps/cli/terminal_chrome.py +412 -0
  235. aria_code/apps/cli/todo_tracker.py +190 -0
  236. aria_code/apps/cli/tool_executor.py +932 -0
  237. aria_code/apps/cli/tool_registry.py +34 -0
  238. aria_code/apps/cli/tool_scope.py +113 -0
  239. aria_code/apps/cli/tools/__init__.py +40 -0
  240. aria_code/apps/cli/tools/context.py +46 -0
  241. aria_code/apps/cli/tools/file_tools.py +181 -0
  242. aria_code/apps/cli/tools/market_tools.py +626 -0
  243. aria_code/apps/cli/tools/notebook_tools.py +111 -0
  244. aria_code/apps/cli/tools/system_tools.py +656 -0
  245. aria_code/apps/cli/tools/write_tools.py +961 -0
  246. aria_code/apps/cli/tradingview_bridge.py +529 -0
  247. aria_code/apps/cli/transactions.py +269 -0
  248. aria_code/apps/cli/turn_planning.py +137 -0
  249. aria_code/apps/cli/update_check.py +257 -0
  250. aria_code/apps/cli/updater.py +373 -0
  251. aria_code/apps/cli/utils/__init__.py +0 -0
  252. aria_code/apps/cli/utils/market_detect.py +1663 -0
  253. aria_code/apps/cli/web_login.py +136 -0
  254. aria_code/apps/cli/workflow_runner.py +127 -0
  255. aria_code/apps/cli/workspace_route.py +121 -0
  256. aria_code/apps/daemon/README.md +14 -0
  257. aria_code/apps/vscode/README.md +115 -0
  258. aria_code/apps/vscode/package.json +70 -0
  259. aria_code/aria_cli.py +5244 -0
  260. aria_code/aria_daemon.py +1372 -0
  261. aria_code/aria_feishu_bot.py +16 -0
  262. aria_code/aria_mcp_server.py +61 -0
  263. aria_code/aria_relay_client.py +4 -0
  264. aria_code/aria_telegram_bot.py +11 -0
  265. aria_code/ariarc.py +385 -0
  266. aria_code/artifacts.py +581 -0
  267. aria_code/backtest_engine.py +4 -0
  268. aria_code/backtest_report.py +4 -0
  269. aria_code/brokers/__init__.py +78 -0
  270. aria_code/brokers/automation.py +193 -0
  271. aria_code/brokers/base.py +231 -0
  272. aria_code/brokers/capabilities.py +264 -0
  273. aria_code/brokers/cn/__init__.py +10 -0
  274. aria_code/brokers/cn/easytrader_broker.py +193 -0
  275. aria_code/brokers/cn/futu_broker.py +194 -0
  276. aria_code/brokers/cn/longbridge_broker.py +190 -0
  277. aria_code/brokers/cn/tiger_broker.py +196 -0
  278. aria_code/brokers/cn/xtquant_broker.py +225 -0
  279. aria_code/brokers/config.py +414 -0
  280. aria_code/brokers/intl/__init__.py +5 -0
  281. aria_code/brokers/intl/alpaca_broker.py +183 -0
  282. aria_code/brokers/intl/ibkr_broker.py +215 -0
  283. aria_code/brokers/intl/trading212_broker.py +183 -0
  284. aria_code/brokers/intl/webull_broker.py +156 -0
  285. aria_code/brokers/paper_broker.py +266 -0
  286. aria_code/brokers/planning.py +296 -0
  287. aria_code/brokers/registry.py +213 -0
  288. aria_code/brokers/trading.py +267 -0
  289. aria_code/canva_client.py +4 -0
  290. aria_code/change_store.py +127 -0
  291. aria_code/clients/__init__.py +0 -0
  292. aria_code/clients/aliyun_data_client.py +660 -0
  293. aria_code/clients/aria_relay_client.py +16 -0
  294. aria_code/clients/canva_client.py +284 -0
  295. aria_code/clients/figma_client.py +100 -0
  296. aria_code/clients/football_data_client.py +1671 -0
  297. aria_code/clients/kling_video_client.py +182 -0
  298. aria_code/clients/market_data_client.py +1985 -0
  299. aria_code/clients/openai_image_client.py +242 -0
  300. aria_code/clients/runway_video_client.py +157 -0
  301. aria_code/clients/warehouse_erp_client.py +105 -0
  302. aria_code/cloud_memory.py +190 -0
  303. aria_code/command_safety.py +19 -0
  304. aria_code/computer_use_server.py +276 -0
  305. aria_code/computer_use_tools.py +4 -0
  306. aria_code/dashboard_generator.py +579 -0
  307. aria_code/data_analysis_tools.py +4 -0
  308. aria_code/data_cleaner.py +483 -0
  309. aria_code/data_service.py +513 -0
  310. aria_code/datasources/__init__.py +23 -0
  311. aria_code/datasources/base.py +166 -0
  312. aria_code/datasources/router.py +253 -0
  313. aria_code/datasources/sec_statements.py +217 -0
  314. aria_code/datasources/sources/__init__.py +15 -0
  315. aria_code/datasources/sources/akshare_source.py +269 -0
  316. aria_code/datasources/sources/alpha_vantage_source.py +203 -0
  317. aria_code/datasources/sources/edgar_source.py +219 -0
  318. aria_code/datasources/sources/finnhub_source.py +198 -0
  319. aria_code/datasources/sources/fred_source.py +223 -0
  320. aria_code/datasources/sources/tushare_source.py +143 -0
  321. aria_code/datasources/sources/web_scraper_source.py +278 -0
  322. aria_code/datasources/sources/world_bank_source.py +206 -0
  323. aria_code/datasources/sources/yfinance_source.py +152 -0
  324. aria_code/doctor.py +860 -0
  325. aria_code/domain/__init__.py +0 -0
  326. aria_code/domain/_finance_core/__init__.py +5 -0
  327. aria_code/domain/_finance_core/backtest_engine.py +325 -0
  328. aria_code/domain/_finance_core/performance_stats.py +101 -0
  329. aria_code/domain/backtest_engine.py +75 -0
  330. aria_code/domain/backtest_report.py +488 -0
  331. aria_code/domain/finance_formulas.py +389 -0
  332. aria_code/domain/performance_stats.py +6 -0
  333. aria_code/domain/portfolio_ledger.py +307 -0
  334. aria_code/domain/strategy_vault.py +421 -0
  335. aria_code/evals/__init__.py +37 -0
  336. aria_code/evals/behavior.py +113 -0
  337. aria_code/evals/gap.py +93 -0
  338. aria_code/evals/harness.py +949 -0
  339. aria_code/evals/review_probe.py +132 -0
  340. aria_code/evals/runner.py +425 -0
  341. aria_code/evals/scorecard.py +322 -0
  342. aria_code/evals/summary.py +125 -0
  343. aria_code/external_agent_runner.py +115 -0
  344. aria_code/figma_client.py +4 -0
  345. aria_code/file_analysis_tools.py +4 -0
  346. aria_code/finance_formulas.py +4 -0
  347. aria_code/football_data_client.py +4 -0
  348. aria_code/image_gen_tools.py +4 -0
  349. aria_code/intent_classifier.py +459 -0
  350. aria_code/kling_video_client.py +4 -0
  351. aria_code/licensing.py +151 -0
  352. aria_code/local_finance_tools.py +4 -0
  353. aria_code/local_image_provider.py +4 -0
  354. aria_code/local_llm_provider.py +4 -0
  355. aria_code/macro_tools.py +4 -0
  356. aria_code/markdown_pdf.py +289 -0
  357. aria_code/market_data_client.py +4 -0
  358. aria_code/mcp_client.py +744 -0
  359. aria_code/memory_manager.py +273 -0
  360. aria_code/model_capability.py +512 -0
  361. aria_code/notification_tools.py +4 -0
  362. aria_code/openai_image_client.py +4 -0
  363. aria_code/packages/__init__.py +26 -0
  364. aria_code/packages/adk_bridge/__init__.py +11 -0
  365. aria_code/packages/adk_bridge/code_review_tools.py +49 -0
  366. aria_code/packages/adk_bridge/market_tools.py +125 -0
  367. aria_code/packages/aria_agents/__init__.py +5 -0
  368. aria_code/packages/aria_agents/manifest.py +78 -0
  369. aria_code/packages/aria_core/__init__.py +34 -0
  370. aria_code/packages/aria_core/architecture.py +269 -0
  371. aria_code/packages/aria_core/export.py +147 -0
  372. aria_code/packages/aria_core/manifest.py +65 -0
  373. aria_code/packages/aria_core/paths.py +57 -0
  374. aria_code/packages/aria_core/secure_file.py +68 -0
  375. aria_code/packages/aria_infra/__init__.py +15 -0
  376. aria_code/packages/aria_infra/arthera.py +58 -0
  377. aria_code/packages/aria_infra/doctor.py +246 -0
  378. aria_code/packages/aria_infra/product.py +40 -0
  379. aria_code/packages/aria_mcp/__init__.py +25 -0
  380. aria_code/packages/aria_mcp/bridge.py +232 -0
  381. aria_code/packages/aria_mcp/circuit.py +82 -0
  382. aria_code/packages/aria_mcp/config.py +162 -0
  383. aria_code/packages/aria_mcp/installer.py +95 -0
  384. aria_code/packages/aria_mcp/server.py +1705 -0
  385. aria_code/packages/aria_mcp/tools.py +81 -0
  386. aria_code/packages/aria_sdk/__init__.py +19 -0
  387. aria_code/packages/aria_sdk/client.py +393 -0
  388. aria_code/packages/aria_sdk/providers.py +70 -0
  389. aria_code/packages/aria_sdk/streaming.py +75 -0
  390. aria_code/packages/aria_sdk/types.py +86 -0
  391. aria_code/packages/aria_services/__init__.py +92 -0
  392. aria_code/packages/aria_services/cache.py +60 -0
  393. aria_code/packages/aria_services/context.py +356 -0
  394. aria_code/packages/aria_services/context_checkpoints.py +157 -0
  395. aria_code/packages/aria_services/data.py +11 -0
  396. aria_code/packages/aria_services/provider_health.py +304 -0
  397. aria_code/packages/aria_services/references.py +247 -0
  398. aria_code/packages/aria_services/registry.py +249 -0
  399. aria_code/packages/aria_services/research_protocol.py +137 -0
  400. aria_code/packages/aria_services/research_quality.py +186 -0
  401. aria_code/packages/aria_services/settings.py +160 -0
  402. aria_code/packages/aria_services/usage.py +151 -0
  403. aria_code/packages/aria_skills/__init__.py +46 -0
  404. aria_code/packages/aria_skills/catalog.py +149 -0
  405. aria_code/packages/aria_skills/loader.py +455 -0
  406. aria_code/packages/aria_skills/registry.py +84 -0
  407. aria_code/packages/aria_tools/__init__.py +5 -0
  408. aria_code/packages/aria_tools/financial/__init__.py +5 -0
  409. aria_code/packages/aria_tools/financial/_paths.py +92 -0
  410. aria_code/packages/aria_tools/registry.py +129 -0
  411. aria_code/packages/quant_engine/__init__.py +33 -0
  412. aria_code/packages/quant_engine/_namespace.py +24 -0
  413. aria_code/packages/quant_engine/backtest/__init__.py +10 -0
  414. aria_code/packages/quant_engine/backtest/core.py +53 -0
  415. aria_code/packages/quant_engine/backtest/engine.py +102 -0
  416. aria_code/packages/quant_engine/portfolio/__init__.py +9 -0
  417. aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
  418. aria_code/packages/quant_engine/sports/__init__.py +76 -0
  419. aria_code/packages/quant_engine/sports/calibrator.py +354 -0
  420. aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
  421. aria_code/packages/quant_engine/sports/elo.py +300 -0
  422. aria_code/packages/quant_engine/sports/form.py +188 -0
  423. aria_code/packages/quant_engine/sports/h2h.py +195 -0
  424. aria_code/packages/quant_engine/sports/predictor.py +312 -0
  425. aria_code/packages/quant_engine/sports/tracker.py +665 -0
  426. aria_code/packages/quant_engine/stochastic/__init__.py +31 -0
  427. aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
  428. aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
  429. aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
  430. aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
  431. aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
  432. aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
  433. aria_code/packs/__init__.py +85 -0
  434. aria_code/packs/base.py +168 -0
  435. aria_code/packs/finance/__init__.py +250 -0
  436. aria_code/packs/healthcare/__init__.py +40 -0
  437. aria_code/packs/logistics/__init__.py +171 -0
  438. aria_code/packs/payments/__init__.py +139 -0
  439. aria_code/packs/realty/__init__.py +190 -0
  440. aria_code/packs/registry.py +202 -0
  441. aria_code/packs/rules.py +90 -0
  442. aria_code/plan_utils.py +194 -0
  443. aria_code/plugin_loader.py +328 -0
  444. aria_code/portfolio_ledger.py +4 -0
  445. aria_code/preview_server.py +449 -0
  446. aria_code/privacy/__init__.py +5 -0
  447. aria_code/privacy/feedback.py +123 -0
  448. aria_code/project_review.py +278 -0
  449. aria_code/project_review_api.py +235 -0
  450. aria_code/project_review_server.py +18 -0
  451. aria_code/project_tools.py +4 -0
  452. aria_code/providers/__init__.py +30 -0
  453. aria_code/providers/google_video_provider.py +256 -0
  454. aria_code/providers/llm/__init__.py +19 -0
  455. aria_code/providers/llm/anthropic.py +184 -0
  456. aria_code/providers/llm/arthera_gateway.py +90 -0
  457. aria_code/providers/llm/autoconfig.py +213 -0
  458. aria_code/providers/llm/base.py +139 -0
  459. aria_code/providers/llm/custom.py +158 -0
  460. aria_code/providers/llm/ollama.py +137 -0
  461. aria_code/providers/llm/openai_compat.py +350 -0
  462. aria_code/providers/llm/registry.py +457 -0
  463. aria_code/providers/local_image_provider.py +202 -0
  464. aria_code/providers/local_llm_provider.py +549 -0
  465. aria_code/providers/ollama_models.py +79 -0
  466. aria_code/providers/openai_params.py +32 -0
  467. aria_code/providers/tool_messages.py +100 -0
  468. aria_code/realty_data_tools.py +4 -0
  469. aria_code/report_exporters.py +150 -0
  470. aria_code/report_generator.py +1764 -0
  471. aria_code/review_service.py +497 -0
  472. aria_code/runtime/__init__.py +176 -0
  473. aria_code/runtime/acceptance.py +632 -0
  474. aria_code/runtime/agent_loop.py +1851 -0
  475. aria_code/runtime/agent_profiles.py +75 -0
  476. aria_code/runtime/approval.py +71 -0
  477. aria_code/runtime/baseline.py +219 -0
  478. aria_code/runtime/budget.py +232 -0
  479. aria_code/runtime/checkpoints.py +481 -0
  480. aria_code/runtime/consult.py +65 -0
  481. aria_code/runtime/contract.py +282 -0
  482. aria_code/runtime/delivery.py +432 -0
  483. aria_code/runtime/events.py +113 -0
  484. aria_code/runtime/gateway.py +167 -0
  485. aria_code/runtime/lsp.py +484 -0
  486. aria_code/runtime/native_index.py +153 -0
  487. aria_code/runtime/orchestrator.py +55 -0
  488. aria_code/runtime/processes.py +343 -0
  489. aria_code/runtime/project_graph.py +614 -0
  490. aria_code/runtime/repo_map.py +712 -0
  491. aria_code/runtime/research_bundle.py +105 -0
  492. aria_code/runtime/review.py +269 -0
  493. aria_code/runtime/run_state.py +127 -0
  494. aria_code/runtime/run_store.py +522 -0
  495. aria_code/runtime/scoped_runs.py +113 -0
  496. aria_code/runtime/self_healing.py +422 -0
  497. aria_code/runtime/semantic_diff.py +171 -0
  498. aria_code/runtime/subagent.py +721 -0
  499. aria_code/runtime/symbol_edit.py +117 -0
  500. aria_code/runtime/task_brief.py +46 -0
  501. aria_code/runtime/task_context.py +145 -0
  502. aria_code/runtime/task_ledger.py +108 -0
  503. aria_code/runtime/task_orchestrator.py +90 -0
  504. aria_code/runtime/task_outcome.py +33 -0
  505. aria_code/runtime/task_verification.py +266 -0
  506. aria_code/runtime/task_worktree.py +448 -0
  507. aria_code/runtime/tool_executor.py +329 -0
  508. aria_code/runtime/tool_policy.py +107 -0
  509. aria_code/runtime/transactions.py +216 -0
  510. aria_code/runtime/windows_job.py +115 -0
  511. aria_code/runtime/workflows.py +222 -0
  512. aria_code/runtime/worktrees.py +215 -0
  513. aria_code/runway_video_client.py +4 -0
  514. aria_code/safety/__init__.py +27 -0
  515. aria_code/safety/client_isolation.py +178 -0
  516. aria_code/safety/permissions.py +339 -0
  517. aria_code/safety/risk.py +699 -0
  518. aria_code/safety/sandbox.py +148 -0
  519. aria_code/safety/service.py +102 -0
  520. aria_code/service_endpoints.py +14 -0
  521. aria_code/setup_wizard.py +684 -0
  522. aria_code/spreadsheet_tools.py +4 -0
  523. aria_code/strategy_vault.py +4 -0
  524. aria_code/tools/__init__.py +0 -0
  525. aria_code/tools/artifact_tools.py +252 -0
  526. aria_code/tools/broker_tools.py +92 -0
  527. aria_code/tools/build_quant_engine.py +97 -0
  528. aria_code/tools/code_audit_tools.py +192 -0
  529. aria_code/tools/computer_use_tools.py +509 -0
  530. aria_code/tools/data_analysis_tools.py +831 -0
  531. aria_code/tools/enterprise_finance_tools.py +202 -0
  532. aria_code/tools/extended_tools.py +240 -0
  533. aria_code/tools/file_analysis_tools.py +880 -0
  534. aria_code/tools/image_gen_tools.py +114 -0
  535. aria_code/tools/local_finance_tools.py +3488 -0
  536. aria_code/tools/logistics_carriers.py +11 -0
  537. aria_code/tools/logistics_inventory.py +11 -0
  538. aria_code/tools/logistics_io.py +11 -0
  539. aria_code/tools/logistics_tenancy.py +11 -0
  540. aria_code/tools/logistics_tools.py +11 -0
  541. aria_code/tools/macro_tools.py +412 -0
  542. aria_code/tools/notification_tools.py +249 -0
  543. aria_code/tools/project_tools.py +525 -0
  544. aria_code/tools/realty_data_tools.py +662 -0
  545. aria_code/tools/spreadsheet_tools.py +399 -0
  546. aria_code/tools/stripe_tools.py +115 -0
  547. aria_code/tools/video_tools.py +500 -0
  548. aria_code/training/__init__.py +1 -0
  549. aria_code/training/compare.py +117 -0
  550. aria_code/training/prelude_commands.py +111 -0
  551. aria_code/training/prelude_eval.py +390 -0
  552. aria_code/training/prelude_real.py +183 -0
  553. aria_code/training/prelude_train.py +248 -0
  554. aria_code/training/sft_dataset.py +230 -0
  555. aria_code/training/trajectory_dataset.py +263 -0
  556. aria_code/ui/__init__.py +105 -0
  557. aria_code/ui/banner.py +404 -0
  558. aria_code/ui/completer.py +571 -0
  559. aria_code/ui/console.py +285 -0
  560. aria_code/ui/input_box.py +505 -0
  561. aria_code/ui/mentions.py +206 -0
  562. aria_code/ui/picker.py +248 -0
  563. aria_code/ui/render/__init__.py +11 -0
  564. aria_code/ui/render/actions.py +297 -0
  565. aria_code/ui/render/finance.py +1732 -0
  566. aria_code/ui/render/market.py +253 -0
  567. aria_code/ui/render/output.py +954 -0
  568. aria_code/ui/render/responsive.py +75 -0
  569. aria_code/ui/render/team.py +367 -0
  570. aria_code/ui/robot.py +239 -0
  571. aria_code/ui/startup_dashboard.py +110 -0
  572. aria_code/video_analysis.py +147 -0
  573. aria_code/video_editor.py +518 -0
  574. aria_code/video_workflow/__init__.py +8 -0
  575. aria_code/video_workflow/__main__.py +61 -0
  576. aria_code/video_workflow/engines/__init__.py +18 -0
  577. aria_code/video_workflow/engines/base.py +69 -0
  578. aria_code/video_workflow/engines/custom_model.py +204 -0
  579. aria_code/video_workflow/engines/google_veo.py +94 -0
  580. aria_code/video_workflow/engines/local_engine.py +71 -0
  581. aria_code/video_workflow/engines/registry.py +98 -0
  582. aria_code/video_workflow/google_models.py +278 -0
  583. aria_code/video_workflow/music/__init__.py +5 -0
  584. aria_code/video_workflow/music/foley_service.py +132 -0
  585. aria_code/video_workflow/music/service.py +212 -0
  586. aria_code/video_workflow/pipeline.py +620 -0
  587. aria_code/video_workflow/plan.py +202 -0
  588. aria_code/video_workflow/session.py +297 -0
  589. aria_code/workspace/__init__.py +6 -0
  590. aria_code/workspace/files.py +219 -0
  591. aria_code/workspace/verify.py +167 -0
  592. aria_code/workspace_changes.py +199 -0
  593. aria_code/workspace_service.py +196 -0
  594. aria_code/workspace_tools.py +150 -0
  595. aria_code-0.167.0.dist-info/METADATA +330 -0
  596. aria_code-0.167.0.dist-info/RECORD +601 -0
  597. aria_code-0.167.0.dist-info/WHEEL +5 -0
  598. aria_code-0.167.0.dist-info/entry_points.txt +5 -0
  599. aria_code-0.167.0.dist-info/licenses/LICENSE +201 -0
  600. aria_code-0.167.0.dist-info/licenses/NOTICE +49 -0
  601. aria_code-0.167.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,327 @@
1
+ """CLI bridge for QuantEngine's auditable next-session A-share predictions.
2
+
3
+ The bridge intentionally keeps prediction execution explicit. A market snapshot
4
+ is cheap and safe to show automatically; a cross-sectional prediction run may
5
+ fetch thousands of histories and writes an auditable report, so it only runs
6
+ after the user enters ``/ashare predict``.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ from dataclasses import dataclass
11
+ from datetime import date
12
+ import os
13
+ from pathlib import Path
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class ASharePredictArgs:
18
+ universe: str = "core50"
19
+ limit: int | None = None
20
+ period: str = "1y"
21
+ strategy: str = "momentum"
22
+ include_ai_analysis: bool = True
23
+ include_ml_confirmation: bool = True
24
+ universe_file: str = ""
25
+ live_universe: bool = False
26
+
27
+
28
+ def parse_ashare_predict_args(text: str) -> ASharePredictArgs:
29
+ """Parse ``/ashare predict`` flags without importing the QuantEngine."""
30
+ tokens = str(text or "").split()
31
+ universe = "core50"
32
+ limit: int | None = None
33
+ period, strategy, universe_file = "1y", "momentum", ""
34
+ include_ai_analysis = include_ml_confirmation = True
35
+ live_universe = False
36
+ index = 0
37
+ if tokens and not tokens[0].startswith("--"):
38
+ universe = tokens[0].lower()
39
+ index = 1
40
+ while index < len(tokens):
41
+ token = tokens[index]
42
+ if token in {"--limit", "--period", "--strategy", "--universe-file"}:
43
+ if index + 1 >= len(tokens):
44
+ raise ValueError(f"{token} requires a value")
45
+ value = tokens[index + 1]
46
+ if token == "--limit":
47
+ limit = int(value)
48
+ if limit < 1:
49
+ raise ValueError("--limit must be positive")
50
+ elif token == "--period":
51
+ period = value
52
+ elif token == "--strategy":
53
+ strategy = value
54
+ else:
55
+ universe_file = value
56
+ index += 2
57
+ continue
58
+ if token == "--no-ai":
59
+ include_ai_analysis = False
60
+ elif token == "--no-ml":
61
+ include_ml_confirmation = False
62
+ elif token == "--live-universe":
63
+ live_universe = True
64
+ else:
65
+ raise ValueError(f"unknown option: {token}")
66
+ index += 1
67
+ if universe not in {"core50", "default", "broad", "broad200", "all"}:
68
+ raise ValueError("universe must be core50, broad, broad200, or all")
69
+ return ASharePredictArgs(
70
+ universe=universe, limit=limit, period=period, strategy=strategy,
71
+ include_ai_analysis=include_ai_analysis,
72
+ include_ml_confirmation=include_ml_confirmation,
73
+ universe_file=universe_file,
74
+ live_universe=live_universe,
75
+ )
76
+
77
+
78
+ def load_universe_file(path: str) -> list[str]:
79
+ """Load a simple comma/newline-separated stock universe with no coercion."""
80
+ source = Path(path).expanduser()
81
+ if not source.is_file():
82
+ raise ValueError(f"universe file not found: {source}")
83
+ return list(dict.fromkeys(
84
+ item.strip().upper()
85
+ for item in source.read_text(encoding="utf-8").replace("\n", ",").split(",")
86
+ if item.strip()
87
+ ))
88
+
89
+
90
+ def fetch_live_ashare_universe(*, include_st: bool = False) -> tuple[list[str], dict]:
91
+ """Get the current listed A-share code universe from AkShare's spot feed.
92
+
93
+ This is only universe discovery; it does not claim price history is clean or
94
+ tradeable. The prediction service subsequently applies its own data-quality
95
+ and execution gates before issuing any candidate label.
96
+ """
97
+ try:
98
+ import akshare as ak
99
+ except ImportError as exc:
100
+ raise RuntimeError("AkShare is required: install aria-code[cn]") from exc
101
+ frame = ak.stock_zh_a_spot_em()
102
+ if frame is None or getattr(frame, "empty", True):
103
+ raise RuntimeError("AkShare returned an empty A-share spot universe")
104
+ records = frame.to_dict("records")
105
+ codes, excluded_st = [], 0
106
+ allowed_prefixes = ("000", "001", "002", "003", "300", "301", "600", "601", "603", "605", "688", "689", "4", "8")
107
+ for row in records:
108
+ code = str(row.get("代码") or row.get("code") or "").strip()
109
+ name = str(row.get("名称") or row.get("name") or "").upper()
110
+ if len(code) != 6 or not code.isdigit() or not code.startswith(allowed_prefixes):
111
+ continue
112
+ if not include_st and ("ST" in name or "退" in name):
113
+ excluded_st += 1
114
+ continue
115
+ codes.append(code)
116
+ codes = list(dict.fromkeys(codes))
117
+ if not codes:
118
+ raise RuntimeError("No eligible A-share codes found in AkShare spot feed")
119
+ return codes, {"source": "akshare.stock_zh_a_spot_em", "count": len(codes), "excluded_st": excluded_st}
120
+
121
+
122
+ def prediction_freshness(result: dict, today: date | None = None) -> dict:
123
+ """Classify an existing run without claiming a stale result is live."""
124
+ today = today or date.today()
125
+ quality = result.get("dataQuality") or {}
126
+ latest = str(quality.get("latestDataDate") or "")
127
+ try:
128
+ last_date = date.fromisoformat(f"{latest[:4]}-{latest[4:6]}-{latest[6:8]}")
129
+ age_days = (today - last_date).days
130
+ except (TypeError, ValueError):
131
+ last_date, age_days = None, None
132
+ return {
133
+ "latest_data_date": latest or None,
134
+ "age_days": age_days,
135
+ "is_quality_pass": quality.get("qualityStatus") == "pass",
136
+ "is_current": bool(last_date and age_days is not None and age_days <= 1),
137
+ }
138
+
139
+
140
+ def build_prediction_service(config: dict):
141
+ """Create the platform service with a stable, user-visible report location."""
142
+ from packages.quant_engine.services.daily_ashare_prediction_service import DailyASharePredictionService
143
+
144
+ service = DailyASharePredictionService()
145
+ configured = str(config.get("ashare_prediction_dir") or os.getenv("ARTHERA_DAILY_PREDICTION_DIR") or "").strip()
146
+ if configured:
147
+ service.storage_dir = Path(configured).expanduser()
148
+ else:
149
+ # Existing platform installs wrote their reports here. Prefer that
150
+ # location when present so the CLI can diagnose historical freshness.
151
+ platform_dir = Path(__file__).resolve().parents[4] / "Arthera" / "packages" / "risk_reports" / "ashare_daily"
152
+ if platform_dir.is_dir():
153
+ service.storage_dir = platform_dir
154
+ service.storage_dir.mkdir(parents=True, exist_ok=True)
155
+ return service
156
+
157
+
158
+ import json
159
+ import asyncio
160
+ import datetime
161
+ import time
162
+ import shlex
163
+ from typing import Dict, Any, Optional
164
+
165
+
166
+ import json
167
+ import asyncio
168
+ import datetime
169
+ import time
170
+ import shlex
171
+ import sys
172
+ import os
173
+ from typing import Dict, Any, Optional
174
+
175
+
176
+ import json
177
+ import asyncio
178
+ import datetime
179
+ import time
180
+ import shlex
181
+ import sys
182
+ import os
183
+ from typing import Dict, Any, Optional
184
+
185
+
186
+ class ASharePredictionCommandsMixin:
187
+ """Expose QuantEngine prediction runs to the interactive and direct CLI."""
188
+
189
+ async def cmd_ashare(self, args: str):
190
+ parts = args.strip().split(maxsplit=1)
191
+ action = parts[0].lower() if parts else "status"
192
+ rest = parts[1] if len(parts) > 1 else ""
193
+ if action in {"status", "latest"}:
194
+ self._print_ashare_status(show_candidates=action == "latest")
195
+ return
196
+ if action == "predict":
197
+ try:
198
+ parsed = parse_ashare_predict_args(rest)
199
+ symbols = load_universe_file(parsed.universe_file) if parsed.universe_file else None
200
+ except ValueError as exc:
201
+ msg = f"⚠ {exc}"
202
+ self.context.console.print(f"[yellow]{msg}[/yellow]") if self.context.has_rich else print(msg)
203
+ return
204
+
205
+ # The service's built-in 'all' alias is a curated broad list, not
206
+ # every listed A-share. Do not let the CLI falsely label it 'all'.
207
+ if parsed.universe == "all" and parsed.live_universe:
208
+ try:
209
+ symbols, universe_meta = await asyncio.to_thread(fetch_live_ashare_universe)
210
+ except Exception as exc:
211
+ msg = f"无法构建实时全 A 股股票池:{exc}"
212
+ self.context.console.print(f"[red]{msg}[/red]") if self.context.has_rich else print(msg)
213
+ return
214
+ self.context.console.print(
215
+ f"[dim]已从 {universe_meta['source']} 获取 {universe_meta['count']} 只股票;"
216
+ f"已排除 {universe_meta['excluded_st']} 只 ST/退市风险标的。[/dim]"
217
+ if self.context.has_rich else f"Live universe: {universe_meta['count']} stocks"
218
+ )
219
+ if parsed.universe == "all" and not symbols:
220
+ msg = (
221
+ "全 A 股运行需要 --universe-file <文件>(一行/逗号分隔的完整当日股票池)。\n"
222
+ "内置 all 只是精选 broad 股票池,不能冒充全市场。"
223
+ )
224
+ self.context.console.print(f"[yellow]{msg}[/yellow]") if self.context.has_rich else print(msg)
225
+ return
226
+
227
+ # No hidden 500-stock truncation for an explicit externally supplied
228
+ # full universe. The service still receives a bounded list.
229
+ limit = parsed.limit or (len(symbols) if symbols else 500)
230
+ if symbols:
231
+ symbols = symbols[:limit]
232
+ scope = f"自定义股票池 {len(symbols)} 只" if symbols else f"{parsed.universe}(最多 {limit} 只)"
233
+ notice = (
234
+ f"开始 A 股次交易日预测:{scope} · {parsed.period} · {parsed.strategy}\n"
235
+ "将拉取历史行情并生成可审计报告;结果仅供研究/仿真,不执行交易。"
236
+ )
237
+ self.context.console.print(f"[dim]{notice}[/dim]") if self.context.has_rich else print(notice)
238
+ try:
239
+ service = build_prediction_service(self.terminal.config)
240
+ result = await asyncio.to_thread(
241
+ service.run_once, symbols=symbols, universe=parsed.universe, limit=limit,
242
+ period=parsed.period, strategy=parsed.strategy,
243
+ include_ai_analysis=parsed.include_ai_analysis,
244
+ include_ml_confirmation=parsed.include_ml_confirmation,
245
+ )
246
+ except Exception as exc:
247
+ msg = f"A 股预测引擎未能完成:{exc}"
248
+ self.context.console.print(f"[red]{msg}[/red]") if self.context.has_rich else print(msg)
249
+ return
250
+ self._print_ashare_result(result)
251
+ return
252
+ if action == "evaluate":
253
+ try:
254
+ result = await asyncio.to_thread(build_prediction_service(self.terminal.config).evaluate_latest, rest.strip() or None)
255
+ except Exception as exc:
256
+ msg = f"A 股预测评估未能完成:{exc}"
257
+ self.context.console.print(f"[red]{msg}[/red]") if self.context.has_rich else print(msg)
258
+ return
259
+ self.context.console.print(result) if self.context.has_rich else print(result)
260
+ return
261
+ if action == "universe":
262
+ include_st = "--include-st" in rest.split()
263
+ try:
264
+ symbols, meta = await asyncio.to_thread(fetch_live_ashare_universe, include_st=include_st)
265
+ except Exception as exc:
266
+ msg = f"无法构建实时 A 股股票池:{exc}"
267
+ self.context.console.print(f"[red]{msg}[/red]") if self.context.has_rich else print(msg)
268
+ return
269
+ msg = f"实时 A 股股票池:{meta['count']} 只 · 来源 {meta['source']} · 排除 ST/退市风险 {meta['excluded_st']} 只"
270
+ self.context.console.print(f"[green]{msg}[/green]") if self.context.has_rich else print(msg)
271
+ self.context.console.print("[dim]运行完整扫描:/ashare predict all --live-universe[/dim]" if self.context.has_rich else "Run: /ashare predict all --live-universe")
272
+ return
273
+ msg = "Usage: /ashare [status|latest|universe|predict|evaluate]"
274
+ self.context.console.print(f"[yellow]{msg}[/yellow]") if self.context.has_rich else print(msg)
275
+
276
+ def _print_ashare_status(self, *, show_candidates: bool):
277
+ try:
278
+ result = build_prediction_service(self.terminal.config).latest()
279
+ except Exception as exc:
280
+ result = None
281
+ error = str(exc)
282
+ else:
283
+ error = ""
284
+ if not result:
285
+ msg = f"没有本地预测结果。{'引擎不可用:' + error if error else '运行 /ashare predict core50 开始。'}"
286
+ self.context.console.print(f"[yellow]{msg}[/yellow]") if self.context.has_rich else print(msg)
287
+ return
288
+ freshness = prediction_freshness(result)
289
+ summary = result.get("summary") or {}
290
+ label = "当前/近一日" if freshness["is_current"] else "过期,不能作为当日预测"
291
+ lines = [
292
+ "A 股次交易日预测状态",
293
+ f"运行:{result.get('runId', '-')}",
294
+ f"数据日期:{freshness['latest_data_date'] or '-'} · {label}",
295
+ f"覆盖:{summary.get('succeeded', 0)}/{summary.get('requested', 0)} · 质量:{summary.get('qualityStatus', '-')}",
296
+ f"强候选/候选/弱候选:{summary.get('strongCandidates', 0)}/{summary.get('longCandidates', 0)}/{summary.get('weakCandidates', 0)}",
297
+ ]
298
+ self.context.console.print("\n".join(lines))
299
+ if show_candidates:
300
+ self._print_ashare_result(result, include_header=False)
301
+
302
+ def _print_ashare_result(self, result: dict, *, include_header: bool = True):
303
+ summary = result.get("summary") or {}
304
+ freshness = prediction_freshness(result)
305
+ predictions = result.get("predictions") or []
306
+ candidates = [item for item in predictions if item.get("signal") in {"strong_candidate", "long_candidate", "weak_candidate"}]
307
+ if include_header:
308
+ title = "A 股次交易日预测(质量通过)" if freshness["is_quality_pass"] else "A 股次交易日预测(质量未通过)"
309
+ self.context.console.print(f"[bold]{title}[/bold]" if self.context.has_rich else title)
310
+ self.context.console.print(
311
+ f"覆盖 {summary.get('succeeded', 0)}/{summary.get('requested', 0)} · "
312
+ f"数据 {freshness['latest_data_date'] or '-'} · "
313
+ f"候选 {len(candidates)} · 阻断 {summary.get('blocked', 0)}"
314
+ )
315
+ if not freshness["is_current"]:
316
+ self.context.console.print("[yellow]⚠ 数据不是当前交易日前一日,结果只可作为历史记录。[/yellow]" if self.context.has_rich else "⚠ Result is stale; historical only.")
317
+ for item in candidates[:10]:
318
+ pred = item.get("prediction") or {}
319
+ line = (
320
+ f" {item.get('rank', '-'):>2}. {item.get('symbol', '-')} {item.get('signal', '-')} "
321
+ f"上涨概率 {float(pred.get('upProbability') or 0):.1%} "
322
+ f"预测收益 {float(pred.get('predictedReturn') or 0):+.1%} "
323
+ f"风险 {float(pred.get('riskScore') or 0):.2f}"
324
+ )
325
+ self.context.console.print(line)
326
+ if not candidates:
327
+ self.context.console.print(" 无通过候选;不应以模型名义强行给出买入名单。")
@@ -0,0 +1,215 @@
1
+ """Account commands use the same Firebase UID as Web and desktop."""
2
+
3
+ from __future__ import annotations
4
+ import asyncio
5
+ import sys
6
+ from datetime import datetime, timezone
7
+ from ._ui import print_error
8
+
9
+
10
+ def _esc_watcher():
11
+ from aria_code.aria_cli import _esc_watcher as watcher
12
+
13
+ return watcher
14
+
15
+
16
+ class AuthCommandsMixin:
17
+ """Mixin: authentication commands (/login, /logout, /whoami)."""
18
+
19
+ async def cmd_login(self, args: str):
20
+ """Sign in to Arthera.
21
+
22
+ Usage: /login — sign in or sign up in the browser
23
+ /login <email> — email + password, prompted securely
24
+
25
+ Bare ``/login`` opens the browser, the way Claude Code and Codex do it.
26
+ Signing in there covers signing up too: the gateway serves the model, so
27
+ a new account has a working setup without configuring any API key. The
28
+ email/password path stays for accounts that predate it and for machines
29
+ with no browser.
30
+ """
31
+ import getpass as _getpass
32
+
33
+ parts = args.split()
34
+
35
+ if not parts or parts[0].lower() in {"google", "--google", "-g", "web", "--web"}:
36
+ await self._login_with_google()
37
+ return
38
+
39
+ if parts[0].lower() in {"email", "--email", "password", "--password"}:
40
+ parts = parts[1:]
41
+
42
+ if parts:
43
+ email = parts[0]
44
+ else:
45
+ try:
46
+ prompt_fn = self.context.console.input if self.context.has_rich else input
47
+ email = prompt_fn(" Email: ").strip()
48
+ except (EOFError, KeyboardInterrupt):
49
+ self.context.console.print("[dim]Cancelled[/dim]" if self.context.has_rich else "Cancelled")
50
+ return
51
+ if not email:
52
+ self.context.console.print(
53
+ "[dim]Usage: /login <email>[/dim]" if self.context.has_rich else "Usage: /login <email>"
54
+ )
55
+ return
56
+
57
+ # Always prompt for password — never accept it as a CLI argument (security)
58
+ try:
59
+ _esc_watcher().pause()
60
+ password = _getpass.getpass(" Password: ")
61
+ except (EOFError, KeyboardInterrupt):
62
+ self.context.console.print("[dim]Cancelled[/dim]" if self.context.has_rich else "Cancelled")
63
+ return
64
+ finally:
65
+ _esc_watcher().resume()
66
+
67
+ if not password:
68
+ self.context.console.print(
69
+ "[red]Password cannot be empty[/red]" if self.context.has_rich else "Password cannot be empty"
70
+ )
71
+ return
72
+
73
+ if self.context.has_rich:
74
+ self.context.console.print("[dim]Authenticating...[/dim]")
75
+
76
+ try:
77
+ from aria_code.account_session import password_session
78
+
79
+ session = await asyncio.to_thread(password_session, email.strip(), password)
80
+ self._accept_session(session)
81
+ who = self.terminal.config.get("email") or session["user_id"]
82
+ self.context.console.print(f"Signed in as {who}")
83
+ except Exception:
84
+ print_error(
85
+ self.context, "Sign-in failed. Check your email/password or run /login in the browser.", "login"
86
+ )
87
+
88
+ async def _login_with_google(self):
89
+ """Browser-based account sign-in (see apps/cli/web_login.py).
90
+
91
+ Run off the event loop: the flow blocks on a loopback socket for as long
92
+ as the user takes in the browser, which would otherwise stall every other
93
+ coroutine in the REPL.
94
+ """
95
+ import asyncio as _asyncio
96
+
97
+ from ..google_login import login_api_url
98
+
99
+ from ..web_login import run_web_login
100
+
101
+ rich = self.context.has_rich
102
+ api_url = login_api_url(self.terminal.api_url)
103
+ self.context.console.print(
104
+ "[dim]Opening your browser to sign in or create an account…[/dim]"
105
+ if rich
106
+ else "Opening your browser to sign in or create an account…"
107
+ )
108
+
109
+ try:
110
+ session = await _asyncio.to_thread(run_web_login, api_url)
111
+ except RuntimeError as exc:
112
+ print_error(self.context, str(exc), "login")
113
+ return
114
+ except Exception as exc:
115
+ print_error(self.context, f"Account sign-in failed: {exc}", "login")
116
+ return
117
+
118
+ try:
119
+ self._accept_session(session)
120
+ except ValueError:
121
+ print_error(self.context, "The session identity could not be verified. Run /login again.", "login")
122
+ return
123
+ who = self.terminal.config.get("email") or session["user_id"]
124
+ self.context.console.print(f"[green]✓ Signed in as {who}[/green]" if rich else f"Signed in as {who}")
125
+
126
+ def _reset_account_context(self):
127
+ from aria_code.memory_manager import MemoryManager
128
+
129
+ self.terminal.conversation = []
130
+ self.terminal._last_response = ""
131
+ self.terminal.memory_mgr = MemoryManager(config=self.terminal.config)
132
+ # Personal profile context is resolved per turn, never retained from A.
133
+ from aria_code.apps.cli.helpers import _load_project_context
134
+
135
+ for module_name in ("aria_cli", "aria_code.aria_cli"):
136
+ module = sys.modules.get(module_name)
137
+ if module is not None:
138
+ module._PROJECT_CONTEXT = _load_project_context()
139
+
140
+ def _accept_session(self, session):
141
+ from aria_code.account_session import claims_for
142
+
143
+ token, uid = session.get("auth_token"), session.get("user_id")
144
+ claims = claims_for(token or "")
145
+ if not token or not uid or claims.get("sub") != uid:
146
+ raise ValueError("Missing account identity")
147
+ cfg = self.terminal.config
148
+ cfg.update(
149
+ auth_token=token,
150
+ user_id=uid,
151
+ email=str(claims.get("email") or session.get("email") or "").strip().lower(),
152
+ display_name=session.get("display_name") or claims.get("name") or "",
153
+ auth_provider=session.get("provider") or "firebase",
154
+ )
155
+ cfg.pop("refresh_token", None)
156
+ cfg.pop("token_expires_at", None)
157
+ if session.get("refresh_token"):
158
+ cfg["refresh_token"] = session["refresh_token"]
159
+ if claims.get("exp"):
160
+ cfg["token_expires_at"] = datetime.fromtimestamp(float(claims["exp"]), timezone.utc).isoformat()
161
+ self.context.save_config(cfg)
162
+ self._reset_account_context()
163
+
164
+ def cmd_logout(self, args: str):
165
+ self.terminal.config["auth_token"] = None
166
+ self.terminal.config["user_id"] = None
167
+ self.terminal.config.pop("token_expires_at", None)
168
+ # Added by the Google flow; leaving them behind would let /whoami report
169
+ # a provider for a session that no longer exists.
170
+ self.terminal.config.pop("refresh_token", None)
171
+ self.terminal.config.pop("auth_provider", None)
172
+ self.terminal.config.pop("email", None)
173
+ self.terminal.config.pop("display_name", None)
174
+ self.context.save_config(self.terminal.config)
175
+ self._reset_account_context()
176
+ self.context.console.print("[dim]Logged out[/dim]" if self.context.has_rich else "Logged out")
177
+
178
+ def cmd_whoami(self, args: str):
179
+ """Show current authentication status."""
180
+ cfg = self.terminal.config
181
+ user_id = cfg.get("user_id")
182
+ token = cfg.get("auth_token")
183
+ email = cfg.get("email") or ""
184
+ expires = cfg.get("token_expires_at")
185
+
186
+ if not token:
187
+ self.context.console.print(
188
+ "[dim]Not logged in — use /login <email>[/dim]" if self.context.has_rich else "Not logged in"
189
+ )
190
+ return
191
+
192
+ if self.context.has_rich:
193
+ self.context.console.print()
194
+ self.context.console.print(f" [dim]User:[/dim] {user_id or 'unknown'}")
195
+ self.context.console.print(f" [dim]Email:[/dim] {email or 'unknown'}")
196
+ if expires:
197
+ # Check expiry
198
+ try:
199
+ exp_dt = datetime.fromisoformat(expires.replace("Z", "+00:00"))
200
+ now = datetime.now(exp_dt.tzinfo)
201
+ if now > exp_dt:
202
+ self.context.console.print(f" [dim]Expires:[/dim] [red]EXPIRED ({expires[:10]})[/red]")
203
+ self.context.console.print(" [dim]Run /login to refresh your session[/dim]")
204
+ else:
205
+ delta = exp_dt - now
206
+ hours = int(delta.total_seconds() // 3600)
207
+ self.context.console.print(f" [dim]Expires:[/dim] {expires[:10]} [dim](in {hours}h)[/dim]")
208
+ except Exception:
209
+ self.context.console.print(f" [dim]Expires:[/dim] {expires}")
210
+ self.context.console.print()
211
+ else:
212
+ print(f"User: {user_id or 'unknown'}")
213
+ print(f"Email: {email or 'unknown'}")
214
+ if expires:
215
+ print(f"Expires: {expires}")