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,114 @@
1
+ """Deterministic real-estate query handler extracted from aria_cli.py."""
2
+ from __future__ import annotations
3
+
4
+ from typing import Callable
5
+
6
+
7
+ def handle_realty_query(
8
+ message: str,
9
+ *,
10
+ is_realty_query: Callable[[str], bool],
11
+ cn_cities: tuple | list,
12
+ intl_cities: tuple | list,
13
+ ) -> dict:
14
+ """Deterministic handler for natural-language real-estate / housing questions.
15
+
16
+ Detects city names + real-estate keywords and calls the realty data tools
17
+ directly, returning a formatted response without needing the LLM to parse it.
18
+ """
19
+ if not is_realty_query(message):
20
+ return {"success": False, "error": "not_realty_query"}
21
+
22
+ try:
23
+ from realty_data_tools import get_house_price_index, get_re_investment
24
+ except ImportError:
25
+ return {"success": False, "error": "realty_data_tools_not_available"}
26
+
27
+ cities_found: list[str] = []
28
+ for city in cn_cities:
29
+ if city in message:
30
+ cities_found.append(city)
31
+ if len(cities_found) >= 2:
32
+ break
33
+
34
+ _low_msg = message.lower()
35
+ _intl_found = [c for c in intl_cities if c in _low_msg]
36
+
37
+ if _intl_found and not cities_found:
38
+ _intl_name = _intl_found[0]
39
+ return {
40
+ "success": True,
41
+ "response": (
42
+ f"## 🌍 {_intl_name.title()} 房地产市场\n\n"
43
+ f"国际城市房价数据目前依赖 LLM 知识库分析(无实时数据接入)。\n\n"
44
+ f"**当前支持实时数据的城市:** 中国大陆 70 个主要城市(北上广深等)\n\n"
45
+ f"如需国际市场数据,建议查阅:\n"
46
+ f"- 美国:`/realty us` — 联邦住房数据(Case-Shiller 指数、新屋开工)\n"
47
+ f"- 其他国际城市:可直接提问,Aria 将基于训练知识回答(数据截止至知识库更新时间)\n\n"
48
+ f"---\n\n"
49
+ f"请问您具体想了解 **{_intl_name.title()}** 哪方面的房地产信息?"
50
+ ),
51
+ "tools_used": ["realty_query"],
52
+ }
53
+
54
+ city1 = cities_found[0] if cities_found else "全国"
55
+ city2 = cities_found[1] if len(cities_found) > 1 else ("上海" if city1 != "上海" else "北京")
56
+
57
+ lines: list[str] = []
58
+ lines.append(f"## 🏠 {city1} 房地产市场")
59
+ if len(cities_found) > 1:
60
+ lines[-1] += f" vs {city2}"
61
+ lines.append("")
62
+
63
+ try:
64
+ r = get_house_price_index(city1, city2)
65
+ if r.get("success"):
66
+ for lbl, cd in (
67
+ (city1, r.get("latest_city1", {})),
68
+ (city2, r.get("latest_city2", {})),
69
+ ):
70
+ if not cd:
71
+ continue
72
+ lines.append(f"### {lbl}")
73
+ if cd.get("new_yoy") is not None:
74
+ lines.append(f"- **新房同比**:{float(cd['new_yoy']):+.2f}%")
75
+ if cd.get("new_mom") is not None:
76
+ lines.append(f"- **新房环比**:{float(cd['new_mom']):+.2f}%")
77
+ if cd.get("second_yoy") is not None:
78
+ lines.append(f"- **二手房同比**:{float(cd['second_yoy']):+.2f}%")
79
+ if cd.get("second_mom") is not None:
80
+ lines.append(f"- **二手房环比**:{float(cd['second_mom']):+.2f}%")
81
+ if cd.get("date"):
82
+ lines.append(f"- **数据期**:{cd['date']}")
83
+ lines.append("")
84
+ else:
85
+ lines.append(f"房价指数数据暂时不可用({r.get('error', '数据源未响应')})")
86
+ lines.append("")
87
+ except Exception as _e:
88
+ lines.append(f"获取房价数据失败: {_e}")
89
+ lines.append("")
90
+
91
+ try:
92
+ ri = get_re_investment()
93
+ if ri.get("success") and ri.get("latest"):
94
+ lt = ri["latest"]
95
+ lines.append("### 全国房地产开发投资")
96
+ lines.append(f"- **最新值**:{lt.get('最新值', 'N/A')}")
97
+ lines.append(f"- **日期**:{lt.get('日期', 'N/A')}")
98
+ lines.append(f"- **涨跌幅**:{lt.get('涨跌幅', 'N/A')}")
99
+ lines.append(f"- **近1年涨跌幅**:{lt.get('近1年涨跌幅', 'N/A')}")
100
+ lines.append("")
101
+ except Exception:
102
+ pass
103
+
104
+ lines.append("**更多操作**")
105
+ lines.append(f"- `/realty market {city1}` — 完整城市房价走势图")
106
+ lines.append(f"- `/realty compare {city1} {city2}` — 城市横向对比")
107
+ lines.append("- `/realty rent` — 租金收益率计算")
108
+ lines.append("- `/realty reit` — REIT 市场数据")
109
+
110
+ return {
111
+ "success": True,
112
+ "response": "\n".join(lines),
113
+ "tools_used": ["realty_query"],
114
+ }
@@ -0,0 +1,22 @@
1
+ """Sports context prefetch for the chat path.
2
+
3
+ The market equivalent already lives in handlers/market_handlers.py; this one
4
+ was still inline in aria_cli and borrowed from its globals by stream_ollama,
5
+ so the fallback path (SDK, daemon) raised NameError on any sports query.
6
+
7
+ Kept deliberately quiet: a prefetch is an optimisation, and a missing or
8
+ failing football client must degrade to "no extra context" rather than break
9
+ the turn.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+
15
+ def try_prefetch_sports_data(message: str) -> str:
16
+ """Live sports context for a query, or "" when unavailable."""
17
+ try:
18
+ from football_data_client import get_sports_context_for_query
19
+
20
+ return get_sports_context_for_query(message) or ""
21
+ except Exception:
22
+ return ""
@@ -0,0 +1,82 @@
1
+ """Deterministic strategy-advice responses.
2
+
3
+ This keeps advisory questions from being treated as code-generation tasks.
4
+ When the user asks "how should I write a strategy" or "from which angles",
5
+ the CLI should answer with a framework and explicit next commands, not create
6
+ files or run backtests without a generation/execution intent.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+
12
+ _STRATEGY_TERMS = (
13
+ "量化策略", "交易策略", "美股策略", "回测策略", "策略框架",
14
+ "quant strategy", "trading strategy", "backtest strategy",
15
+ )
16
+
17
+ _ADVICE_TERMS = (
18
+ "几个角度", "哪些角度", "从几个方面", "怎么写", "如何写",
19
+ "思路", "框架", "结构", "要考虑", "你觉得", "建议",
20
+ "how", "what should", "framework", "approach", "angles",
21
+ )
22
+
23
+ _EXECUTION_TERMS = (
24
+ "开始写", "帮我写", "生成", "实现", "创建", "保存", "运行",
25
+ "回测一下", "直接做", "落地", "完善代码",
26
+ "write", "generate", "implement", "create", "save", "run",
27
+ )
28
+
29
+
30
+ def is_strategy_advice_request(message: str) -> bool:
31
+ text = (message or "").strip()
32
+ if not text or text.startswith("/"):
33
+ return False
34
+ low = text.lower()
35
+ has_strategy = any(term in text or term in low for term in _STRATEGY_TERMS)
36
+ has_advice = any(term in text or term in low for term in _ADVICE_TERMS)
37
+ has_execution = any(term in text or term in low for term in _EXECUTION_TERMS)
38
+ return bool(has_strategy and has_advice and not has_execution)
39
+
40
+
41
+ def handle_strategy_advice(message: str) -> dict:
42
+ if not is_strategy_advice_request(message):
43
+ return {"success": False, "error": "not_strategy_advice"}
44
+
45
+ response = """## 美股量化策略写作框架
46
+
47
+ 建议从 8 个层级写,先定义假设,再验证和风控,最后才进入交易执行。
48
+ 当前是咨询型问题,不需要先写文件,也不会自动运行回测。
49
+
50
+ | 层级 | 要解决的问题 | 产物 |
51
+ |---|---|---|
52
+ | 1. 市场假设 | 为什么这个信号可能赚钱 | 策略假设、适用市场、失效条件 |
53
+ | 2. 标的池 | 交易哪些股票/ETF,如何剔除不可交易标的 | universe 规则、流动性/价格过滤 |
54
+ | 3. 数据层 | OHLCV、财报、因子、宏观、新闻是否可得且可信 | 数据源、清洗、复权、缺失处理 |
55
+ | 4. 信号层 | 入场/出场依据是什么 | 因子、阈值、信号延迟、防未来函数 |
56
+ | 5. 组合层 | 单票仓位、行业暴露、相关性怎么控制 | 权重、再平衡、最大持仓、现金规则 |
57
+ | 6. 交易成本 | 手续费、滑点、冲击成本是否吞噬收益 | 成本模型、成交假设 |
58
+ | 7. 回测评估 | 策略是否稳健,而不是只在样本内好看 | CAGR、Sharpe、最大回撤、胜率、换手、分阶段表现 |
59
+ | 8. 风控部署 | 实盘如何限制损失并监控失效 | 止损、熔断、告警、paper/live 分层 |
60
+
61
+ **推荐落地顺序**
62
+
63
+ 1. 先写一页策略说明:假设、标的池、调仓频率、风险边界。
64
+ 2. 再写最小回测脚本:只包含数据、信号、仓位、绩效。
65
+ 3. 加 walk-forward、不同市场阶段、参数敏感性测试。
66
+ 4. 通过后接 paper trading,不直接上实盘。
67
+ 5. 实盘前加入订单预览、资金上限、熔断、审计日志。
68
+
69
+ **下一步命令**
70
+
71
+ - `/scaffold my_us_strategy --template strategy`:生成策略项目骨架。
72
+ - `/backtest momentum SPY --period 1y`:先跑一个内置动量回测。
73
+ - `/auto-strategy momentum SPY --target sharpe=1.2`:进入自动优化流程。
74
+
75
+ *这只是策略设计框架,不构成投资建议。需要我生成代码时,请明确说“生成/实现/写文件”。*"""
76
+
77
+ return {
78
+ "success": True,
79
+ "response": response,
80
+ "tools_used": ["strategy_advice"],
81
+ "analysis_complete": True,
82
+ }
@@ -0,0 +1,352 @@
1
+ """Non-interactive Aria: `aria-code -p "…"` and `--watch`.
2
+
3
+ Moved out of aria_cli.py, where ArtheraTerminal held it alongside the REPL.
4
+ The bodies are unchanged and still use aria_cli's names (console, LOCAL_TOOLS,
5
+ _run_deterministic_chain, …): aria_cli binds a copy of this class to its own
6
+ globals with bind_to() and puts it among ArtheraTerminal's bases. A copy per
7
+ binding, because aria_cli loads under two names (aria_cli and
8
+ aria_code.aria_cli); rebinding one shared class would leave both terminals
9
+ on whichever module loaded last.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ def _headless_approval(config: dict, auto_approve, always_allow, *, on_denied=None):
15
+ """Answer approvals with what the operator granted up front, and nothing more.
16
+
17
+ ``auto_approve`` and ``always_allow`` are read at call time from the module
18
+ that is actually running (aria_cli, aria_code.aria_cli or __main__ under
19
+ ``python -m``), which is where --dangerously-skip-permissions and
20
+ --allow-tools set them.
21
+ """
22
+ from aria_code.runtime.approval import ApprovalDecision
23
+
24
+ def decide(tool_name: str, params: dict):
25
+ if not (auto_approve() or tool_name in (always_allow() or ())):
26
+ reason = "no one is here to approve it; pass --allow-tools or --dangerously-skip-permissions"
27
+ if on_denied is not None:
28
+ on_denied(tool_name, reason)
29
+ return ApprovalDecision.deny(reason)
30
+ if tool_name == "run_command":
31
+ return ApprovalDecision.allow(policy=config.get("command_policy", "safe"), user_approved=True)
32
+ return ApprovalDecision.allow()
33
+
34
+ return decide
35
+
36
+
37
+ def _apply_approval_decision(params: dict, decision) -> dict:
38
+ from aria_code.runtime.approval import apply_approval_decision
39
+
40
+ return apply_approval_decision(params, decision)
41
+
42
+
43
+ class HeadlessMixin:
44
+ """run_prompt, _run_prompt_turn, _finish_prompt and run_watch for ArtheraTerminal."""
45
+
46
+ async def run_prompt(self, prompt: str, json_output: bool = False,
47
+ fmt: str = "table", output_file: str = None, quiet: bool = False,
48
+ machine_out=None):
49
+ """Run a single prompt (non-interactive / pipe mode).
50
+
51
+ ``machine_out`` is the real stdout when the output is JSON (sys.stdout
52
+ then points at stderr). With fmt "jsonl" each step is written there as
53
+ one JSON event per line as it happens.
54
+ """
55
+ from aria_code.apps.cli.exec_events import ExecEvents, json_safe
56
+ events = ExecEvents(machine_out if fmt == "jsonl" else None)
57
+ events.emit("turn.started", prompt=prompt, model=self.config.get("model", ""))
58
+ result = await self._run_prompt_turn(prompt, quiet=quiet, events=events)
59
+ self._finish_prompt(result, json_output=json_output, fmt=fmt, output_file=output_file,
60
+ quiet=quiet, machine_out=machine_out, events=events)
61
+
62
+ async def _run_prompt_turn(self, prompt: str, *, quiet: bool, events) -> dict:
63
+ """The work of run_prompt: a slash command, a deterministic answer, or an agent turn."""
64
+ model = self.config.get("model", "qwen2.5:7b")
65
+ thinking_mode = self.config.get("thinking_mode", "auto")
66
+ from aria_code.account_session import prepare_account
67
+ from aria_code.apps.cli.config_store import save_cli_config
68
+ from aria_code.apps.cli.config_paths import resolve_paths
69
+ save_account = lambda cfg: save_cli_config(resolve_paths(), cfg)
70
+ auth_token = await prepare_account(self.config, save_account)
71
+ auth_token = auth_token or self.config.get("auth_token")
72
+ user_context = _build_user_context(self.config)
73
+
74
+ local_mode = self.config.get("local_mode", False)
75
+
76
+ # Dispatch slash commands in -p mode (same as interactive REPL loop).
77
+ # Without this, /memory /note /init /review are sent to the LLM as plain text.
78
+ _stripped_prompt = prompt.strip()
79
+ if self.commands.is_command(_stripped_prompt):
80
+ self._maybe_show_intent_preflight(_stripped_prompt, quiet=quiet)
81
+ await self.commands.execute(_stripped_prompt)
82
+ return {"success": True, "command": _stripped_prompt.split()[0], "response": ""}
83
+
84
+ _reference_context = ""
85
+ _reference_service = getattr(self, "_reference_service", None)
86
+ if _reference_service is not None and "@" in prompt:
87
+ _prepared_references = _reference_service.prepare(prompt)
88
+ if _prepared_references.errors:
89
+ self._print_reference_errors(_prepared_references)
90
+ return {"success": False, "response": "", "error": "unresolved @ reference"}
91
+ if _prepared_references.references:
92
+ self._print_reference_summary(_prepared_references)
93
+ prompt = _prepared_references.expanded_text
94
+ _reference_context = _prepared_references.context_block
95
+
96
+ # Keep referenced local files as pointers; the model reads them through
97
+ # audited tools instead of silently embedding their contents.
98
+ if _reference_context:
99
+ prompt = f"{prompt}\n\n{_reference_context}"
100
+ else:
101
+ _file_tool_hint = _build_file_tool_hint(prompt)
102
+ if _file_tool_hint:
103
+ prompt = _file_tool_hint + prompt
104
+ self._maybe_show_intent_preflight(prompt, quiet=quiet)
105
+
106
+ _curr_model_id_p = self.config.get("model", "")
107
+ # The route counts as much as the model: on backend_chat the model gets
108
+ # no local tools whatever it could do with them. This only looked at the
109
+ # model, so the deterministic chain skipped its data pre-fetch there.
110
+ from aria_code.apps.cli.workspace_route import no_tools_message, needs_workspace, route_has_tools, workspace_config
111
+ _runtime_config = workspace_config(prompt, _curr_model_id_p, self.config, self.api_url)
112
+ _model_has_tools_p = route_has_tools(_curr_model_id_p, _runtime_config, self.api_url)
113
+
114
+ # ── Broker guide intent: broad discovery should not start an add wizard ──
115
+ if _is_broker_guide_intent(prompt):
116
+ if HAS_RICH:
117
+ console.print("\n[bold]Aria[/bold] [dim] 正在打开券商与服务指南…[/dim]\n")
118
+ await self.commands.cmd_broker("guide")
119
+ await self.commands.cmd_broker("services")
120
+ await self.commands.cmd_packages("services")
121
+ return {"success": True, "command": "/broker guide", "response": ""}
122
+
123
+ # ── Broker setup intent: intercept before LLM / deterministic routing ──
124
+ if _is_broker_setup_intent(prompt):
125
+ _btype_p = _detect_broker_type(prompt)
126
+ if HAS_RICH:
127
+ from apps.cli.utils.market_detect import _BROKER_SETUP_NAMES
128
+ _display_p = _BROKER_SETUP_NAMES.get(_btype_p, ("",))[0] if _btype_p else ""
129
+ _label_p = f" 正在启动{_display_p}配置向导…" if _display_p else " 正在启动券商配置向导…"
130
+ console.print(f"\n[bold]Aria[/bold] [dim]{_label_p}[/dim]\n")
131
+ await self.commands._cmd_broker_add(_btype_p)
132
+ return {"success": True, "command": "/broker add", "response": ""}
133
+
134
+ # ── Football prediction intercept → built-in Poisson handler ──────────
135
+ if await self._try_football_nl_intercept(prompt):
136
+ return {"success": True, "command": "football", "response": ""}
137
+
138
+ deterministic = _run_deterministic_chain(
139
+ prompt, model_has_tools=_model_has_tools_p)
140
+ if deterministic.get("success") or _is_stock_chart_analysis_request(prompt):
141
+ result = deterministic
142
+ else:
143
+ # No one reads a headless answer before a script acts on it. A task
144
+ # about this folder on a model that cannot open it would come back as
145
+ # a confident guess with exit 0; fail before sending it instead.
146
+ if not _model_has_tools_p and needs_workspace(prompt):
147
+ _zh = str(self.config.get("ui_lang", "en")).lower().startswith("zh")
148
+ _why = no_tools_message(self.config, lang="zh" if _zh else "en")
149
+ print(_why, file=sys.stderr)
150
+ return {"success": False, "response": "", "error": "model_cannot_use_tools", "detail": _why}
151
+ # Spinner for terminal usage: gives visual feedback while the model generates.
152
+ # Only starts when we actually need to call the LLM (not for deterministic responses).
153
+ _prompt_spinner = None
154
+ if HAS_RICH and sys.stdout.isatty():
155
+ try:
156
+ _prompt_spinner = console.status("", spinner="dots", spinner_style="dim")
157
+ _prompt_spinner.__enter__()
158
+ except Exception:
159
+ _prompt_spinner = None
160
+ try:
161
+ # Headless -p runs the SAME loop as the REPL.
162
+ #
163
+ # It used to call stream_provider_result directly: one provider
164
+ # round, tool schemas advertised but nothing executing what came
165
+ # back, and a single best-effort pass over tool_calls_pending
166
+ # afterwards whose results the model never saw. So `-p` was not
167
+ # agentic at all — no rounds, no tool results fed back, no loop
168
+ # guard, no acceptance gate. Every non-interactive user (CI, a
169
+ # pipe, the eval harness) got a chat reply where the REPL would
170
+ # have done the work.
171
+ #
172
+ # run_chat_via_runtime is the documented single entry point and
173
+ # already handles provider selection and cloud→Ollama fallback,
174
+ # which is what the two branches here were open-coding.
175
+ from aria_code.apps.cli.providers.runtime_bridge import run_chat_via_runtime
176
+ # This method runs on aria_cli's names; these two live here.
177
+ from aria_code.apps.cli.headless import _apply_approval_decision, _headless_approval
178
+
179
+ import uuid
180
+ _headless_scope = str(getattr(self, "session_id", "") or uuid.uuid4())
181
+ _turn = await run_chat_via_runtime(
182
+ prompt=prompt, history=[],
183
+ local_tools=LOCAL_TOOLS, tool_schemas=LOCAL_TOOL_SCHEMAS,
184
+ model=model, config=_runtime_config, api_url=self.api_url,
185
+ ollama_url=self.config.get("ollama_url", "http://localhost:11434"),
186
+ thinking_mode=thinking_mode, user_context=user_context,
187
+ auth_token=auth_token, project_context=_PROJECT_CONTEXT,
188
+ max_rounds=int(self.config.get("max_rounds", 30) or 30),
189
+ # No approval UI exists in headless mode; the operator opts in
190
+ # with --dangerously-skip-permissions or --allow-tools. Those
191
+ # used to take the tools out of the confirm set, so no
192
+ # approval ever happened — and an approval is what lets
193
+ # run_command past the default "safe" policy (the REPL's
194
+ # "allow" upgrades it to balanced). Every `python3 script.py`
195
+ # was blocked: the evals' agents wrote scripts they could not
196
+ # run, then computed by hand or stopped. Now the confirm set
197
+ # stays, and the pre-approval answers it the way the REPL would.
198
+ confirm_tools=frozenset(_CONFIRM_TOOLS),
199
+ approval_callback=_headless_approval(
200
+ self.config, lambda: _auto_approve_session, lambda: _session_always_allow,
201
+ on_denied=lambda tool, reason: events.status("approval_denied", f"{tool}: {reason}")),
202
+ approval_applier=_apply_approval_decision,
203
+ on_tool_call=events.tool_started,
204
+ on_tool_result=events.tool_completed,
205
+ on_token=events.text_delta if events.streaming else None,
206
+ on_status=events.status if events.streaming else None,
207
+ execution_context=lambda: {"_session_id": _headless_scope},
208
+ return_result=True,
209
+ )
210
+ _tools_used = list(getattr(_turn.final, "tools", []) or [])
211
+ # A missing closing message can count as success only with
212
+ # passing acceptance evidence, never merely because a tool ran.
213
+ _empty_after_work = (
214
+ _turn.error == "empty_response" and bool(_tools_used)
215
+ and (getattr(_turn.final, "acceptance", None) or {}).get("verified") is True
216
+ )
217
+ result = {
218
+ "success": _turn.ok or _empty_after_work,
219
+ "response": (
220
+ _turn.text
221
+ or (f"(模型未给出收尾说明。已执行的工具:{', '.join(_tools_used)})"
222
+ if _empty_after_work else "")
223
+ ),
224
+ "error": "" if _empty_after_work else (_turn.error or ""),
225
+ "provider": getattr(_turn.final, "provider", ""),
226
+ "tools_used": _tools_used,
227
+ "acceptance": getattr(_turn.final, "acceptance", None),
228
+ "delivery": getattr(_turn.final, "delivery", None),
229
+ "contract": getattr(_turn.final, "contract", None),
230
+ "stop_reason": getattr(_turn.final, "stop_reason", "") or _turn.error or "completed",
231
+ }
232
+ finally:
233
+ if _prompt_spinner is not None:
234
+ try:
235
+ _prompt_spinner.__exit__(None, None, None)
236
+ except Exception:
237
+ pass
238
+
239
+ return result
240
+
241
+ def _finish_prompt(self, result: dict, *, json_output: bool, fmt: str, output_file,
242
+ quiet: bool, machine_out, events) -> None:
243
+ """Print or save run_prompt's result, and exit 1 if it failed."""
244
+ from aria_code.apps.cli.exec_events import json_safe
245
+ result = result or {"success": False, "response": "", "error": "no result"}
246
+ # The agent loop executes tools now, so there is nothing left over to
247
+ # run here — only stream_provider_result ever populated
248
+ # tool_calls_pending, and the deterministic chain never does. Keeping
249
+ # the old pass would risk running a write twice.
250
+ #
251
+ # What is worth surfacing instead is the acceptance verdict: in headless
252
+ # mode nobody watched the run, so a turn that changed files and failed
253
+ # its checks must say so on stderr rather than print a confident summary
254
+ # and exit 0.
255
+ _acceptance = (result or {}).get("acceptance") or {}
256
+ if _acceptance.get("verified") is False:
257
+ result["success"] = False
258
+ result["error"] = result.get("error") or "checks_failed"
259
+ result["stop_reason"] = "checks_failed"
260
+ if _acceptance.get("verified") is False and not quiet:
261
+ _zh = str(self.config.get("ui_lang", "en")).lower().startswith("zh")
262
+ print(f"⚠ {'验收未通过' if _zh else 'Checks failed'}: {_acceptance.get('headline', '')}",
263
+ file=sys.stderr)
264
+
265
+ # What this run cost, as the provider reported it. An evaluation harness
266
+ # asks for it in ARIA_USAGE_FILE; imports are local because aria_cli
267
+ # rebinds these methods to its own globals.
268
+ import json as _json
269
+ import os as _os
270
+ _config = getattr(self, "config", {}) or {}
271
+ result["usage"] = {
272
+ "model": str(_config.get("model", "") or ""),
273
+ "provider": str(_config.get("local_provider", "") or ""),
274
+ "input_tokens": int(getattr(self, "_session_input_tokens", 0) or 0),
275
+ "output_tokens": int(getattr(self, "_session_output_tokens", 0) or 0),
276
+ "thinking_tokens": int(getattr(self, "_session_thinking_tokens", 0) or 0),
277
+ "turns": int(getattr(self, "_session_turns", 0) or 0),
278
+ }
279
+ _usage_file = _os.environ.get("ARIA_USAGE_FILE")
280
+ if _usage_file:
281
+ try:
282
+ with open(_usage_file, "w", encoding="utf-8") as _handle:
283
+ _json.dump(result["usage"], _handle)
284
+ except OSError:
285
+ pass
286
+ events.emit("turn.completed", **json_safe(result))
287
+ out = machine_out or sys.stdout
288
+ if fmt == "jsonl":
289
+ content = None # the events were the output
290
+ elif json_output or fmt == "json":
291
+ content = json.dumps(json_safe(result), ensure_ascii=False, indent=2)
292
+ elif fmt == "csv":
293
+ content = f"role,content\nassistant,\"{result.get('response', '').replace(chr(34), chr(34)+chr(34))}\""
294
+ elif fmt == "md":
295
+ content = f"# Aria Code AI Response\n\n{result.get('response', '')}\n"
296
+ else:
297
+ content = result.get("response", "") if result.get("success") else f"Error: {result.get('error', 'Unknown')}"
298
+
299
+ # Output routing
300
+ if content is None or (fmt == "table" and not json_output and result.get("command") and not content):
301
+ pass # jsonl, or a command that printed its own output
302
+ elif output_file:
303
+ with open(output_file, "w") as f:
304
+ f.write(content)
305
+ if not quiet:
306
+ console.print(f"[green]Saved to {output_file}[/green]" if HAS_RICH
307
+ else f"Saved: {output_file}")
308
+ elif not result.get("success") and fmt == "table" and not json_output:
309
+ print(f"Error: {result.get('error', 'Unknown')}", file=sys.stderr)
310
+ # In default (table) format: render with Rich Markdown when output is
311
+ # a terminal. This gives properly formatted headings, bold, and tables
312
+ # in interactive use. When piped/redirected, fall back to plain text
313
+ # for scripting compatibility.
314
+ elif HAS_RICH and fmt == "table" and not json_output and sys.stdout.isatty() and result.get("success"):
315
+ console.print(make_markdown(_strip_latex(content)))
316
+ else:
317
+ print(content, file=out, flush=True)
318
+ # A failed turn exits 1 in every format. Only table did; with --json a
319
+ # script got exit 0 and had to read the body to learn it had failed.
320
+ if not result.get("success"):
321
+ sys.exit(1)
322
+
323
+ async def run_watch(self, command_fn, interval: int, cmd_args: str):
324
+ """Run a command repeatedly with interval (like Unix watch)."""
325
+ try:
326
+ while True:
327
+ if not self.config.get("_quiet"):
328
+ os.system("clear" if os.name == "posix" else "cls")
329
+ ts = datetime.now().strftime("%H:%M:%S")
330
+ if HAS_RICH:
331
+ console.print(f"[dim]Every {interval}s | {ts} | Ctrl+C to stop[/dim]\n")
332
+ else:
333
+ print(f"Every {interval}s | {ts} | Ctrl+C to stop\n")
334
+
335
+ await command_fn(cmd_args)
336
+
337
+ await asyncio.sleep(interval)
338
+ except (KeyboardInterrupt, asyncio.CancelledError):
339
+ if HAS_RICH:
340
+ console.print("\n[dim]Watch stopped[/dim]")
341
+ else:
342
+ print("\nStopped")
343
+
344
+
345
+ def bind_to(namespace: dict) -> type:
346
+ """A copy of HeadlessMixin whose methods resolve bare names in ``namespace``."""
347
+ from aria_code.apps.cli.mixin_binding import bind_mixin
348
+
349
+ return bind_mixin(HeadlessMixin, namespace)
350
+
351
+
352
+ __all__ = ["HeadlessMixin", "bind_to"]