aria-code 0.52.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (478) hide show
  1. aria_code/__init__.py +42 -0
  2. aria_code/_version.py +20 -0
  3. aria_code/adk_apps/__init__.py +1 -0
  4. aria_code/adk_apps/aria_code_review/__init__.py +1 -0
  5. aria_code/adk_apps/aria_code_review/agent.py +32 -0
  6. aria_code/adk_apps/aria_research/__init__.py +1 -0
  7. aria_code/adk_apps/aria_research/agent.py +31 -0
  8. aria_code/agents/__init__.py +34 -0
  9. aria_code/agents/base.py +318 -0
  10. aria_code/agents/code_review.py +200 -0
  11. aria_code/agents/deep/__init__.py +37 -0
  12. aria_code/agents/deep/calibration_loop.py +144 -0
  13. aria_code/agents/deep/critic.py +125 -0
  14. aria_code/agents/deep/deepen.py +193 -0
  15. aria_code/agents/deep/models.py +149 -0
  16. aria_code/agents/deep/pipeline.py +164 -0
  17. aria_code/agents/deep/quant_fusion.py +192 -0
  18. aria_code/agents/deep/themes.py +95 -0
  19. aria_code/agents/deep/tiers.py +106 -0
  20. aria_code/agents/engineering/__init__.py +14 -0
  21. aria_code/agents/engineering/coder.py +222 -0
  22. aria_code/agents/engineering/tester.py +145 -0
  23. aria_code/agents/financial/__init__.py +21 -0
  24. aria_code/agents/financial/cashflow_burn.py +119 -0
  25. aria_code/agents/financial/catalyst.py +279 -0
  26. aria_code/agents/financial/corporate_finance.py +175 -0
  27. aria_code/agents/financial/debate.py +224 -0
  28. aria_code/agents/financial/earnings.py +303 -0
  29. aria_code/agents/financial/fundamental.py +191 -0
  30. aria_code/agents/financial/macro.py +99 -0
  31. aria_code/agents/financial/news.py +207 -0
  32. aria_code/agents/financial/risk.py +165 -0
  33. aria_code/agents/financial/sector.py +279 -0
  34. aria_code/agents/financial/strategist.py +121 -0
  35. aria_code/agents/financial/stripe_revenue.py +127 -0
  36. aria_code/agents/financial/synthesis.py +274 -0
  37. aria_code/agents/financial/technical.py +258 -0
  38. aria_code/agents/orchestrator.py +44 -0
  39. aria_code/agents/portfolio_agent.py +363 -0
  40. aria_code/agents/realty/__init__.py +62 -0
  41. aria_code/agents/realty/asset_diagnosis.py +152 -0
  42. aria_code/agents/realty/business_match.py +166 -0
  43. aria_code/agents/realty/cashflow_verify.py +209 -0
  44. aria_code/agents/realty/contract_rules.py +210 -0
  45. aria_code/agents/realty/energy_anomaly.py +189 -0
  46. aria_code/agents/realty/exit_settlement.py +208 -0
  47. aria_code/agents/realty/fulfillment_risk.py +206 -0
  48. aria_code/agents/realty/ops_optimize.py +160 -0
  49. aria_code/agents/realty/revenue_share.py +215 -0
  50. aria_code/agents/registry.py +158 -0
  51. aria_code/agents/signal_scheme.py +111 -0
  52. aria_code/agents/sports/__init__.py +0 -0
  53. aria_code/agents/sports/football_agent.py +197 -0
  54. aria_code/agents/supervisor.py +113 -0
  55. aria_code/agents/team.py +492 -0
  56. aria_code/agents/warehouse/__init__.py +25 -0
  57. aria_code/agents/warehouse/contracts.py +26 -0
  58. aria_code/agents/warehouse/dashboard.py +155 -0
  59. aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
  60. aria_code/agents/warehouse/inbound_exceptions.py +25 -0
  61. aria_code/agents/warehouse/inventory_health.py +24 -0
  62. aria_code/agents/warehouse/local_run.py +71 -0
  63. aria_code/agents/warehouse/local_snapshot.py +132 -0
  64. aria_code/agents/warehouse/logistics_cost.py +84 -0
  65. aria_code/agents/warehouse/logistics_sync.py +21 -0
  66. aria_code/agents/warehouse/workflow.py +31 -0
  67. aria_code/aliyun_data_client.py +4 -0
  68. aria_code/apps/README.md +12 -0
  69. aria_code/apps/__init__.py +2 -0
  70. aria_code/apps/channels/README.md +15 -0
  71. aria_code/apps/channels/__init__.py +17 -0
  72. aria_code/apps/channels/intake.py +92 -0
  73. aria_code/apps/channels/registry.py +95 -0
  74. aria_code/apps/channels/tradingview.py +94 -0
  75. aria_code/apps/cli/README.md +13 -0
  76. aria_code/apps/cli/__init__.py +2 -0
  77. aria_code/apps/cli/_optional.py +120 -0
  78. aria_code/apps/cli/bootstrap.py +145 -0
  79. aria_code/apps/cli/broker_render.py +206 -0
  80. aria_code/apps/cli/codegen_paths.py +29 -0
  81. aria_code/apps/cli/commands/__init__.py +16 -0
  82. aria_code/apps/cli/commands/_business_render.py +78 -0
  83. aria_code/apps/cli/commands/_ui.py +71 -0
  84. aria_code/apps/cli/commands/analysis_cmds.py +369 -0
  85. aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
  86. aria_code/apps/cli/commands/auth_cmds.py +239 -0
  87. aria_code/apps/cli/commands/backtest_cmds.py +2543 -0
  88. aria_code/apps/cli/commands/broker_cmds.py +1234 -0
  89. aria_code/apps/cli/commands/business_workflow_cmds.py +319 -0
  90. aria_code/apps/cli/commands/canvas_cmds.py +77 -0
  91. aria_code/apps/cli/commands/catalog.py +87 -0
  92. aria_code/apps/cli/commands/core_cmds.py +2520 -0
  93. aria_code/apps/cli/commands/data_cmds.py +457 -0
  94. aria_code/apps/cli/commands/diagnostic_cmds.py +230 -0
  95. aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
  96. aria_code/apps/cli/commands/file_cmds.py +312 -0
  97. aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
  98. aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
  99. aria_code/apps/cli/commands/market.py +434 -0
  100. aria_code/apps/cli/commands/market_cmds.py +1381 -0
  101. aria_code/apps/cli/commands/market_context.py +425 -0
  102. aria_code/apps/cli/commands/market_render.py +7 -0
  103. aria_code/apps/cli/commands/model_cmds.py +2153 -0
  104. aria_code/apps/cli/commands/ops_cmds.py +721 -0
  105. aria_code/apps/cli/commands/orchestrator_cmds.py +179 -0
  106. aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
  107. aria_code/apps/cli/commands/portfolio_cmds.py +1278 -0
  108. aria_code/apps/cli/commands/report.py +437 -0
  109. aria_code/apps/cli/commands/scaffold_templates.py +617 -0
  110. aria_code/apps/cli/commands/session_cmds.py +236 -0
  111. aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
  112. aria_code/apps/cli/commands/team.py +669 -0
  113. aria_code/apps/cli/commands/team_render.py +8 -0
  114. aria_code/apps/cli/commands/ui_cmds.py +401 -0
  115. aria_code/apps/cli/commands/warehouse_cmds.py +79 -0
  116. aria_code/apps/cli/commands/workflow_cmds.py +480 -0
  117. aria_code/apps/cli/commands/workspace_cmds.py +1494 -0
  118. aria_code/apps/cli/config_paths.py +73 -0
  119. aria_code/apps/cli/config_store.py +78 -0
  120. aria_code/apps/cli/constants.py +88 -0
  121. aria_code/apps/cli/context.py +34 -0
  122. aria_code/apps/cli/deterministic.py +191 -0
  123. aria_code/apps/cli/direct.py +48 -0
  124. aria_code/apps/cli/finance_service_catalog.py +111 -0
  125. aria_code/apps/cli/football_reports.py +231 -0
  126. aria_code/apps/cli/github_app_auth.py +135 -0
  127. aria_code/apps/cli/google_login.py +196 -0
  128. aria_code/apps/cli/handlers/__init__.py +11 -0
  129. aria_code/apps/cli/handlers/broker_handlers.py +122 -0
  130. aria_code/apps/cli/handlers/chart_handlers.py +1309 -0
  131. aria_code/apps/cli/handlers/market_handlers.py +2513 -0
  132. aria_code/apps/cli/handlers/realty_handlers.py +114 -0
  133. aria_code/apps/cli/handlers/sports_handlers.py +22 -0
  134. aria_code/apps/cli/handlers/strategy_advice.py +82 -0
  135. aria_code/apps/cli/helpers.py +302 -0
  136. aria_code/apps/cli/hooks.py +180 -0
  137. aria_code/apps/cli/i18n.py +297 -0
  138. aria_code/apps/cli/intent.py +136 -0
  139. aria_code/apps/cli/intent_router.py +276 -0
  140. aria_code/apps/cli/intent_signals.py +344 -0
  141. aria_code/apps/cli/lifecycle_hooks.py +48 -0
  142. aria_code/apps/cli/local_tool_schemas.py +536 -0
  143. aria_code/apps/cli/main.py +29 -0
  144. aria_code/apps/cli/market_metadata.py +135 -0
  145. aria_code/apps/cli/market_universe.py +487 -0
  146. aria_code/apps/cli/message_processing.py +310 -0
  147. aria_code/apps/cli/model_catalog.py +620 -0
  148. aria_code/apps/cli/pdf_report.py +977 -0
  149. aria_code/apps/cli/plan_mode.py +139 -0
  150. aria_code/apps/cli/plotly_html.py +15 -0
  151. aria_code/apps/cli/prediction_feedback.py +202 -0
  152. aria_code/apps/cli/preflight.py +502 -0
  153. aria_code/apps/cli/project_aria.py +60 -0
  154. aria_code/apps/cli/prompt_assembly.py +59 -0
  155. aria_code/apps/cli/prompts/__init__.py +0 -0
  156. aria_code/apps/cli/prompts/coding.py +53 -0
  157. aria_code/apps/cli/prompts/select.py +142 -0
  158. aria_code/apps/cli/prompts/system_prompts.py +552 -0
  159. aria_code/apps/cli/prompts/ui.py +436 -0
  160. aria_code/apps/cli/provider_endpoints.py +237 -0
  161. aria_code/apps/cli/provider_keys.py +73 -0
  162. aria_code/apps/cli/providers/__init__.py +1 -0
  163. aria_code/apps/cli/providers/base.py +521 -0
  164. aria_code/apps/cli/providers/chat_routing.py +128 -0
  165. aria_code/apps/cli/providers/collaboration.py +98 -0
  166. aria_code/apps/cli/providers/llm/__init__.py +1 -0
  167. aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
  168. aria_code/apps/cli/providers/llm/ollama_stream.py +1594 -0
  169. aria_code/apps/cli/providers/llm/response_cache.py +60 -0
  170. aria_code/apps/cli/providers/llm/sse_stream.py +257 -0
  171. aria_code/apps/cli/providers/runtime_bridge.py +353 -0
  172. aria_code/apps/cli/providers/vertexai_stream.py +316 -0
  173. aria_code/apps/cli/runtime_consumer.py +657 -0
  174. aria_code/apps/cli/sandbox.py +32 -0
  175. aria_code/apps/cli/session_export.py +120 -0
  176. aria_code/apps/cli/session_jsonl.py +208 -0
  177. aria_code/apps/cli/session_store.py +112 -0
  178. aria_code/apps/cli/skills_catalog.py +273 -0
  179. aria_code/apps/cli/todo_tracker.py +190 -0
  180. aria_code/apps/cli/tool_executor.py +823 -0
  181. aria_code/apps/cli/tool_registry.py +34 -0
  182. aria_code/apps/cli/tool_scope.py +106 -0
  183. aria_code/apps/cli/tools/__init__.py +40 -0
  184. aria_code/apps/cli/tools/context.py +46 -0
  185. aria_code/apps/cli/tools/file_tools.py +180 -0
  186. aria_code/apps/cli/tools/market_tools.py +620 -0
  187. aria_code/apps/cli/tools/notebook_tools.py +111 -0
  188. aria_code/apps/cli/tools/system_tools.py +726 -0
  189. aria_code/apps/cli/tools/write_tools.py +845 -0
  190. aria_code/apps/cli/tradingview_bridge.py +529 -0
  191. aria_code/apps/cli/turn_planning.py +137 -0
  192. aria_code/apps/cli/update_check.py +153 -0
  193. aria_code/apps/cli/utils/__init__.py +0 -0
  194. aria_code/apps/cli/utils/market_detect.py +1597 -0
  195. aria_code/apps/daemon/README.md +14 -0
  196. aria_code/apps/vscode/README.md +115 -0
  197. aria_code/apps/vscode/package.json +70 -0
  198. aria_code/aria_cli.py +6743 -0
  199. aria_code/aria_daemon.py +1398 -0
  200. aria_code/aria_feishu_bot.py +1423 -0
  201. aria_code/aria_mcp_server.py +7 -0
  202. aria_code/aria_relay_client.py +4 -0
  203. aria_code/aria_relay_server.py +490 -0
  204. aria_code/aria_telegram_bot.py +202 -0
  205. aria_code/ariarc.py +385 -0
  206. aria_code/artifacts.py +581 -0
  207. aria_code/backtest_engine.py +4 -0
  208. aria_code/backtest_report.py +4 -0
  209. aria_code/brokers/__init__.py +78 -0
  210. aria_code/brokers/automation.py +193 -0
  211. aria_code/brokers/base.py +231 -0
  212. aria_code/brokers/capabilities.py +264 -0
  213. aria_code/brokers/cn/__init__.py +10 -0
  214. aria_code/brokers/cn/easytrader_broker.py +193 -0
  215. aria_code/brokers/cn/futu_broker.py +194 -0
  216. aria_code/brokers/cn/longbridge_broker.py +190 -0
  217. aria_code/brokers/cn/tiger_broker.py +196 -0
  218. aria_code/brokers/cn/xtquant_broker.py +225 -0
  219. aria_code/brokers/config.py +414 -0
  220. aria_code/brokers/intl/__init__.py +5 -0
  221. aria_code/brokers/intl/alpaca_broker.py +183 -0
  222. aria_code/brokers/intl/ibkr_broker.py +215 -0
  223. aria_code/brokers/intl/trading212_broker.py +183 -0
  224. aria_code/brokers/intl/webull_broker.py +156 -0
  225. aria_code/brokers/paper_broker.py +266 -0
  226. aria_code/brokers/planning.py +296 -0
  227. aria_code/brokers/registry.py +213 -0
  228. aria_code/brokers/trading.py +267 -0
  229. aria_code/canva_client.py +4 -0
  230. aria_code/change_store.py +127 -0
  231. aria_code/clients/__init__.py +0 -0
  232. aria_code/clients/aliyun_data_client.py +660 -0
  233. aria_code/clients/aria_relay_client.py +182 -0
  234. aria_code/clients/canva_client.py +284 -0
  235. aria_code/clients/figma_client.py +100 -0
  236. aria_code/clients/football_data_client.py +1671 -0
  237. aria_code/clients/kling_video_client.py +182 -0
  238. aria_code/clients/market_data_client.py +1976 -0
  239. aria_code/clients/openai_image_client.py +242 -0
  240. aria_code/clients/runway_video_client.py +157 -0
  241. aria_code/clients/warehouse_erp_client.py +105 -0
  242. aria_code/cloud_memory.py +181 -0
  243. aria_code/command_safety.py +19 -0
  244. aria_code/computer_use_tools.py +4 -0
  245. aria_code/dashboard_generator.py +579 -0
  246. aria_code/data_analysis_tools.py +4 -0
  247. aria_code/data_cleaner.py +483 -0
  248. aria_code/data_service.py +513 -0
  249. aria_code/datasources/__init__.py +23 -0
  250. aria_code/datasources/base.py +166 -0
  251. aria_code/datasources/router.py +253 -0
  252. aria_code/datasources/sources/__init__.py +15 -0
  253. aria_code/datasources/sources/akshare_source.py +269 -0
  254. aria_code/datasources/sources/alpha_vantage_source.py +203 -0
  255. aria_code/datasources/sources/edgar_source.py +219 -0
  256. aria_code/datasources/sources/finnhub_source.py +198 -0
  257. aria_code/datasources/sources/fred_source.py +223 -0
  258. aria_code/datasources/sources/tushare_source.py +143 -0
  259. aria_code/datasources/sources/web_scraper_source.py +278 -0
  260. aria_code/datasources/sources/world_bank_source.py +206 -0
  261. aria_code/datasources/sources/yfinance_source.py +152 -0
  262. aria_code/demo_player.py +207 -0
  263. aria_code/doctor.py +813 -0
  264. aria_code/domain/__init__.py +0 -0
  265. aria_code/domain/backtest_engine.py +354 -0
  266. aria_code/domain/backtest_report.py +472 -0
  267. aria_code/domain/finance_formulas.py +389 -0
  268. aria_code/domain/portfolio_ledger.py +307 -0
  269. aria_code/domain/strategy_vault.py +421 -0
  270. aria_code/evals/__init__.py +37 -0
  271. aria_code/evals/harness.py +598 -0
  272. aria_code/evals/runner.py +238 -0
  273. aria_code/external_agent_runner.py +115 -0
  274. aria_code/figma_client.py +4 -0
  275. aria_code/file_analysis_tools.py +4 -0
  276. aria_code/finance_formulas.py +4 -0
  277. aria_code/football_data_client.py +4 -0
  278. aria_code/image_gen_tools.py +4 -0
  279. aria_code/intent_classifier.py +386 -0
  280. aria_code/kling_video_client.py +4 -0
  281. aria_code/licensing.py +151 -0
  282. aria_code/local_finance_tools.py +4 -0
  283. aria_code/local_image_provider.py +4 -0
  284. aria_code/local_llm_provider.py +4 -0
  285. aria_code/macro_tools.py +4 -0
  286. aria_code/markdown_pdf.py +289 -0
  287. aria_code/market_data_client.py +4 -0
  288. aria_code/mcp_client.py +639 -0
  289. aria_code/memory_manager.py +246 -0
  290. aria_code/model_capability.py +486 -0
  291. aria_code/notification_tools.py +4 -0
  292. aria_code/openai_image_client.py +4 -0
  293. aria_code/packages/__init__.py +23 -0
  294. aria_code/packages/adk_bridge/__init__.py +11 -0
  295. aria_code/packages/adk_bridge/code_review_tools.py +49 -0
  296. aria_code/packages/adk_bridge/market_tools.py +125 -0
  297. aria_code/packages/aria_agents/__init__.py +5 -0
  298. aria_code/packages/aria_agents/manifest.py +78 -0
  299. aria_code/packages/aria_core/__init__.py +34 -0
  300. aria_code/packages/aria_core/architecture.py +269 -0
  301. aria_code/packages/aria_core/export.py +147 -0
  302. aria_code/packages/aria_core/manifest.py +65 -0
  303. aria_code/packages/aria_core/paths.py +57 -0
  304. aria_code/packages/aria_core/secure_file.py +68 -0
  305. aria_code/packages/aria_infra/__init__.py +15 -0
  306. aria_code/packages/aria_infra/arthera.py +52 -0
  307. aria_code/packages/aria_infra/doctor.py +246 -0
  308. aria_code/packages/aria_infra/product.py +40 -0
  309. aria_code/packages/aria_mcp/__init__.py +25 -0
  310. aria_code/packages/aria_mcp/bridge.py +201 -0
  311. aria_code/packages/aria_mcp/circuit.py +82 -0
  312. aria_code/packages/aria_mcp/config.py +111 -0
  313. aria_code/packages/aria_mcp/installer.py +95 -0
  314. aria_code/packages/aria_mcp/server.py +1550 -0
  315. aria_code/packages/aria_mcp/tools.py +81 -0
  316. aria_code/packages/aria_sdk/__init__.py +19 -0
  317. aria_code/packages/aria_sdk/client.py +396 -0
  318. aria_code/packages/aria_sdk/providers.py +70 -0
  319. aria_code/packages/aria_sdk/streaming.py +79 -0
  320. aria_code/packages/aria_sdk/types.py +86 -0
  321. aria_code/packages/aria_services/__init__.py +92 -0
  322. aria_code/packages/aria_services/cache.py +60 -0
  323. aria_code/packages/aria_services/context.py +356 -0
  324. aria_code/packages/aria_services/context_checkpoints.py +157 -0
  325. aria_code/packages/aria_services/data.py +11 -0
  326. aria_code/packages/aria_services/provider_health.py +268 -0
  327. aria_code/packages/aria_services/references.py +247 -0
  328. aria_code/packages/aria_services/registry.py +249 -0
  329. aria_code/packages/aria_services/research_protocol.py +57 -0
  330. aria_code/packages/aria_services/research_quality.py +186 -0
  331. aria_code/packages/aria_services/settings.py +157 -0
  332. aria_code/packages/aria_services/usage.py +151 -0
  333. aria_code/packages/aria_skills/__init__.py +46 -0
  334. aria_code/packages/aria_skills/catalog.py +149 -0
  335. aria_code/packages/aria_skills/loader.py +455 -0
  336. aria_code/packages/aria_skills/registry.py +84 -0
  337. aria_code/packages/aria_tools/__init__.py +5 -0
  338. aria_code/packages/aria_tools/financial/__init__.py +8 -0
  339. aria_code/packages/aria_tools/financial/_paths.py +130 -0
  340. aria_code/packages/aria_tools/financial/compliance.py +31 -0
  341. aria_code/packages/aria_tools/financial/factors.py +33 -0
  342. aria_code/packages/aria_tools/financial/risk_tools.py +33 -0
  343. aria_code/packages/aria_tools/financial/strategy.py +31 -0
  344. aria_code/packages/aria_tools/registry.py +128 -0
  345. aria_code/packages/quant_engine/__init__.py +34 -0
  346. aria_code/packages/quant_engine/_namespace.py +62 -0
  347. aria_code/packages/quant_engine/backtest/__init__.py +14 -0
  348. aria_code/packages/quant_engine/backtest/core.py +53 -0
  349. aria_code/packages/quant_engine/backtest/engine.py +96 -0
  350. aria_code/packages/quant_engine/portfolio/__init__.py +13 -0
  351. aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
  352. aria_code/packages/quant_engine/sports/__init__.py +80 -0
  353. aria_code/packages/quant_engine/sports/calibrator.py +354 -0
  354. aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
  355. aria_code/packages/quant_engine/sports/elo.py +300 -0
  356. aria_code/packages/quant_engine/sports/form.py +188 -0
  357. aria_code/packages/quant_engine/sports/h2h.py +195 -0
  358. aria_code/packages/quant_engine/sports/ml_model.py +377 -0
  359. aria_code/packages/quant_engine/sports/predictor.py +312 -0
  360. aria_code/packages/quant_engine/sports/tracker.py +665 -0
  361. aria_code/packages/quant_engine/stochastic/__init__.py +35 -0
  362. aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
  363. aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
  364. aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
  365. aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
  366. aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
  367. aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
  368. aria_code/packs/__init__.py +85 -0
  369. aria_code/packs/base.py +168 -0
  370. aria_code/packs/finance/__init__.py +250 -0
  371. aria_code/packs/logistics/__init__.py +169 -0
  372. aria_code/packs/payments/__init__.py +139 -0
  373. aria_code/packs/realty/__init__.py +190 -0
  374. aria_code/packs/registry.py +202 -0
  375. aria_code/packs/rules.py +90 -0
  376. aria_code/plan_utils.py +194 -0
  377. aria_code/plugin_loader.py +328 -0
  378. aria_code/portfolio_ledger.py +4 -0
  379. aria_code/preview_server.py +449 -0
  380. aria_code/privacy/__init__.py +5 -0
  381. aria_code/privacy/feedback.py +123 -0
  382. aria_code/project_review.py +278 -0
  383. aria_code/project_review_api.py +235 -0
  384. aria_code/project_review_server.py +18 -0
  385. aria_code/project_tools.py +4 -0
  386. aria_code/providers/__init__.py +30 -0
  387. aria_code/providers/llm/__init__.py +19 -0
  388. aria_code/providers/llm/anthropic.py +184 -0
  389. aria_code/providers/llm/autoconfig.py +213 -0
  390. aria_code/providers/llm/base.py +139 -0
  391. aria_code/providers/llm/custom.py +158 -0
  392. aria_code/providers/llm/ollama.py +129 -0
  393. aria_code/providers/llm/openai_compat.py +313 -0
  394. aria_code/providers/llm/registry.py +444 -0
  395. aria_code/providers/local_image_provider.py +202 -0
  396. aria_code/providers/local_llm_provider.py +589 -0
  397. aria_code/realty_data_tools.py +4 -0
  398. aria_code/report_exporters.py +150 -0
  399. aria_code/report_generator.py +1764 -0
  400. aria_code/runtime/__init__.py +169 -0
  401. aria_code/runtime/acceptance.py +481 -0
  402. aria_code/runtime/agent_loop.py +1520 -0
  403. aria_code/runtime/approval.py +57 -0
  404. aria_code/runtime/budget.py +232 -0
  405. aria_code/runtime/checkpoints.py +432 -0
  406. aria_code/runtime/crash_report.py +174 -0
  407. aria_code/runtime/events.py +113 -0
  408. aria_code/runtime/gateway.py +150 -0
  409. aria_code/runtime/lsp.py +484 -0
  410. aria_code/runtime/orchestrator.py +55 -0
  411. aria_code/runtime/repo_map.py +700 -0
  412. aria_code/runtime/run_state.py +127 -0
  413. aria_code/runtime/run_store.py +450 -0
  414. aria_code/runtime/self_healing.py +422 -0
  415. aria_code/runtime/subagent.py +547 -0
  416. aria_code/runtime/task_ledger.py +86 -0
  417. aria_code/runtime/task_orchestrator.py +90 -0
  418. aria_code/runtime/tool_executor.py +217 -0
  419. aria_code/runtime/tool_policy.py +107 -0
  420. aria_code/runtime/worktrees.py +215 -0
  421. aria_code/runway_video_client.py +4 -0
  422. aria_code/safety/__init__.py +23 -0
  423. aria_code/safety/permissions.py +306 -0
  424. aria_code/safety/service.py +102 -0
  425. aria_code/setup_wizard.py +673 -0
  426. aria_code/spreadsheet_tools.py +4 -0
  427. aria_code/strategy_vault.py +4 -0
  428. aria_code/tools/__init__.py +0 -0
  429. aria_code/tools/artifact_tools.py +252 -0
  430. aria_code/tools/broker_tools.py +92 -0
  431. aria_code/tools/build_quant_engine.py +97 -0
  432. aria_code/tools/code_audit_tools.py +192 -0
  433. aria_code/tools/computer_use_tools.py +504 -0
  434. aria_code/tools/data_analysis_tools.py +809 -0
  435. aria_code/tools/enterprise_finance_tools.py +156 -0
  436. aria_code/tools/extended_tools.py +240 -0
  437. aria_code/tools/file_analysis_tools.py +885 -0
  438. aria_code/tools/image_gen_tools.py +114 -0
  439. aria_code/tools/local_finance_tools.py +3417 -0
  440. aria_code/tools/logistics_tools.py +135 -0
  441. aria_code/tools/macro_tools.py +369 -0
  442. aria_code/tools/notification_tools.py +249 -0
  443. aria_code/tools/project_tools.py +525 -0
  444. aria_code/tools/realty_data_tools.py +659 -0
  445. aria_code/tools/spreadsheet_tools.py +388 -0
  446. aria_code/tools/stripe_tools.py +115 -0
  447. aria_code/ui/__init__.py +105 -0
  448. aria_code/ui/banner.py +508 -0
  449. aria_code/ui/completer.py +501 -0
  450. aria_code/ui/console.py +281 -0
  451. aria_code/ui/image_render.py +243 -0
  452. aria_code/ui/input_box.py +488 -0
  453. aria_code/ui/picker.py +201 -0
  454. aria_code/ui/render/__init__.py +11 -0
  455. aria_code/ui/render/finance.py +1705 -0
  456. aria_code/ui/render/market.py +225 -0
  457. aria_code/ui/render/output.py +775 -0
  458. aria_code/ui/render/responsive.py +75 -0
  459. aria_code/ui/render/team.py +354 -0
  460. aria_code/ui/robot.py +235 -0
  461. aria_code/ui/startup_dashboard.py +109 -0
  462. aria_code/utils/vscode_uri.py +37 -0
  463. aria_code/video_analysis.py +147 -0
  464. aria_code/video_editor.py +271 -0
  465. aria_code/workspace/__init__.py +6 -0
  466. aria_code/workspace/files.py +193 -0
  467. aria_code/workspace/verify.py +113 -0
  468. aria_code/workspace_changes.py +199 -0
  469. aria_code/workspace_context.py +233 -0
  470. aria_code/workspace_service.py +196 -0
  471. aria_code/workspace_tools.py +150 -0
  472. aria_code-0.52.0.dist-info/METADATA +237 -0
  473. aria_code-0.52.0.dist-info/RECORD +478 -0
  474. aria_code-0.52.0.dist-info/WHEEL +5 -0
  475. aria_code-0.52.0.dist-info/entry_points.txt +3 -0
  476. aria_code-0.52.0.dist-info/licenses/LICENSE +201 -0
  477. aria_code-0.52.0.dist-info/licenses/NOTICE +49 -0
  478. aria_code-0.52.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2 @@
1
+ """Product entrypoints for Aria Code."""
2
+
@@ -0,0 +1,15 @@
1
+ # Channel Apps
2
+
3
+ Target role: adapters for non-terminal entrypoints.
4
+
5
+ Examples:
6
+
7
+ - relay server/client;
8
+ - Feishu bot;
9
+ - Telegram bot;
10
+ - webhooks;
11
+ - future desktop or browser UI.
12
+
13
+ Each channel should translate inbound messages into gateway requests and render
14
+ gateway responses back to the channel. It should not bypass safety, runtime, or
15
+ artifact policies.
@@ -0,0 +1,17 @@
1
+ """Aria channels — external entrypoints as structured-task producers."""
2
+
3
+ from .registry import (
4
+ CHANNEL_TASK_SCHEMA,
5
+ ChannelSpec,
6
+ channel_map,
7
+ default_channels,
8
+ enabled_channels,
9
+ )
10
+
11
+ __all__ = [
12
+ "CHANNEL_TASK_SCHEMA",
13
+ "ChannelSpec",
14
+ "channel_map",
15
+ "default_channels",
16
+ "enabled_channels",
17
+ ]
@@ -0,0 +1,92 @@
1
+ """Channel intake policy + gateway submission (the daemon-facing half).
2
+
3
+ Completes the channels contract loop: the daemon's webhook endpoint hands
4
+ verified channel tasks to ``runtime.run_turn`` instead of poking CLI
5
+ internals, and refuses unauthenticated ("open mode") intake from anywhere
6
+ but localhost.
7
+
8
+ Two pieces, both dependency-light so the daemon can import them without
9
+ dragging in aria_cli:
10
+
11
+ • should_refuse_open_intake() — pure policy: when neither an intake token
12
+ nor ARIA_WEBHOOK_SECRET is configured, only loopback clients may submit.
13
+ • analyze_alert_via_gateway() — submits a task prompt through the shared
14
+ runtime gateway with an EMPTY tool set: channel-triggered turns get
15
+ model analysis but can never execute tools from the daemon context.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ from typing import Any, Callable, Dict, Optional
21
+
22
+ _LOOPBACK_HOSTS = {"127.0.0.1", "::1", "localhost"}
23
+
24
+
25
+ def should_refuse_open_intake(
26
+ client_host: Optional[str],
27
+ *,
28
+ token_configured: bool,
29
+ secret_configured: bool,
30
+ ) -> bool:
31
+ """True when an unauthenticated intake must be rejected.
32
+
33
+ With any credential configured (endpoint token or webhook passphrase),
34
+ authentication handles trust and remote clients are fine. With neither
35
+ configured the endpoint is running "open", which is only acceptable from
36
+ the loopback interface — an open endpoint reachable off-host would let
37
+ anyone on the network inject buy/sell alerts.
38
+ """
39
+ if token_configured or secret_configured:
40
+ return False
41
+ host = str(client_host or "").strip().lower()
42
+ if host.startswith("[") and host.endswith("]"): # bracketed IPv6
43
+ host = host[1:-1]
44
+ return host not in _LOOPBACK_HOSTS
45
+
46
+
47
+ async def analyze_alert_via_gateway(
48
+ prompt: str,
49
+ config: Dict[str, Any],
50
+ *,
51
+ run_turn_fn: Optional[Callable] = None,
52
+ max_rounds: int = 4,
53
+ ) -> str:
54
+ """Run one tool-less analysis turn for a channel task; returns the text.
55
+
56
+ ``run_turn_fn`` is injectable for tests; the default builds the same
57
+ provider selection the CLI uses (chat_routing via runtime_bridge) and
58
+ drives ``runtime.gateway.run_turn``. Raises on failure — the caller
59
+ decides its own fallback (the daemon keeps its legacy quick summary).
60
+ """
61
+ if run_turn_fn is None:
62
+ # stream_ollama borrows 47 bare names from aria_cli's module globals
63
+ # (verified by AST audit) and only works after aria_cli's import-time
64
+ # rebinding. Until that module is untangled, any out-of-CLI consumer
65
+ # of the default Ollama path must import aria_cli first — a one-time
66
+ # ~1s cost the long-lived daemon amortizes.
67
+ import aria_cli # noqa: F401 (side effect: binds stream_ollama globals)
68
+ from apps.cli.providers.runtime_bridge import build_tool_executor, make_provider_fn
69
+ from runtime.gateway import run_turn as run_turn_fn_impl
70
+
71
+ provider_fn = make_provider_fn(
72
+ model=str(config.get("model", "qwen2.5:7b")),
73
+ config=config,
74
+ api_url=config.get("api_url"),
75
+ ollama_url=str(config.get("ollama_url", "http://localhost:11434")),
76
+ tool_schemas=[],
77
+ )
78
+ executor = build_tool_executor({}, config)
79
+
80
+ async def run_turn_fn(prompt_, history_, **kw):
81
+ return await run_turn_fn_impl(
82
+ prompt_, history_,
83
+ provider_fn=provider_fn, tool_executor=executor,
84
+ tool_schemas=[], max_rounds=max_rounds,
85
+ )
86
+
87
+ result = await run_turn_fn(prompt, [])
88
+ text = (getattr(result, "text", "") or "").strip()
89
+ error = getattr(result, "error", None)
90
+ if error or not text:
91
+ raise RuntimeError(f"gateway turn failed: {error or 'empty response'}")
92
+ return text
@@ -0,0 +1,95 @@
1
+ """Channel registry — the declared inventory of external entrypoints.
2
+
3
+ First slice of the channels layer (contract: "Channels submit structured
4
+ tasks to gateway/runtime and never call CLI internals directly"). The
5
+ registry is pure data + config resolution: it names each channel, its
6
+ direction, the config/env that enables it, and which capability it maps to,
7
+ so the daemon and doctor can reason about channels uniformly instead of each
8
+ integration hard-coding its own discovery.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from dataclasses import dataclass, field
14
+ from typing import Any, Dict, List, Mapping, Tuple
15
+
16
+ CHANNEL_TASK_SCHEMA = "aria.channel_task.v1"
17
+
18
+
19
+ @dataclass(frozen=True)
20
+ class ChannelSpec:
21
+ name: str
22
+ direction: str # "inbound" | "outbound" | "both"
23
+ description: str
24
+ capabilities: Tuple[str, ...] = ()
25
+ # Any of these config keys (or env vars) being truthy enables the channel.
26
+ config_keys: Tuple[str, ...] = ()
27
+ env_keys: Tuple[str, ...] = ()
28
+
29
+ def enabled(self, config: Mapping[str, Any], env: Mapping[str, str]) -> bool:
30
+ for key in self.config_keys:
31
+ if config.get(key):
32
+ return True
33
+ for key in self.env_keys:
34
+ if str(env.get(key, "") or "").strip():
35
+ return True
36
+ return False
37
+
38
+
39
+ def default_channels() -> List[ChannelSpec]:
40
+ return [
41
+ ChannelSpec(
42
+ name="tradingview",
43
+ direction="inbound",
44
+ description="TradingView alert webhooks → structured alert tasks",
45
+ capabilities=("alerts.ingest", "orders.preview"),
46
+ config_keys=("tradingview_webhook",),
47
+ env_keys=("ARIA_WEBHOOK_SECRET",),
48
+ ),
49
+ ChannelSpec(
50
+ name="webhook_jobs",
51
+ direction="inbound",
52
+ description="Generic daemon webhook job queue (/webhook/trigger)",
53
+ capabilities=("tasks.enqueue",),
54
+ env_keys=("WEBHOOK_TOKEN",),
55
+ ),
56
+ ChannelSpec(
57
+ name="telegram",
58
+ direction="both",
59
+ description="Telegram bot push + command intake via the daemon",
60
+ capabilities=("notify.push", "chat.intake"),
61
+ config_keys=("telegram_bot_token",),
62
+ env_keys=("TELEGRAM_BOT_TOKEN",),
63
+ ),
64
+ ChannelSpec(
65
+ name="feishu",
66
+ direction="outbound",
67
+ description="Feishu webhook card push",
68
+ capabilities=("notify.push",),
69
+ config_keys=("feishu_webhook",),
70
+ env_keys=("FEISHU_WEBHOOK_URL",),
71
+ ),
72
+ ChannelSpec(
73
+ name="macos_notify",
74
+ direction="outbound",
75
+ description="Local macOS notification center",
76
+ capabilities=("notify.push",),
77
+ config_keys=("macos_notifications",),
78
+ ),
79
+ ChannelSpec(
80
+ name="email",
81
+ direction="outbound",
82
+ description="SMTP email push",
83
+ capabilities=("notify.push",),
84
+ config_keys=("email_smtp_host",),
85
+ env_keys=("ARIA_SMTP_HOST",),
86
+ ),
87
+ ]
88
+
89
+
90
+ def channel_map() -> Dict[str, ChannelSpec]:
91
+ return {spec.name: spec for spec in default_channels()}
92
+
93
+
94
+ def enabled_channels(config: Mapping[str, Any], env: Mapping[str, str]) -> List[ChannelSpec]:
95
+ return [spec for spec in default_channels() if spec.enabled(config, env)]
@@ -0,0 +1,94 @@
1
+ """TradingView alert → structured channel task (aria.channel_task.v1).
2
+
3
+ The channels contract requires external entrypoints to submit *structured
4
+ tasks* to the gateway instead of poking CLI internals. This adapter turns a
5
+ raw TradingView webhook payload into that task shape, reusing the hardened
6
+ primitives that already live in apps/cli/tradingview_bridge.py (field-tolerant
7
+ parsing, passphrase + HMAC verification, dedup keys).
8
+
9
+ Verification posture mirrors the bridge's documented semantics: with
10
+ ARIA_WEBHOOK_SECRET unset verification is open (localhost-only assumption),
11
+ but the task carries explicit ``verified`` / ``open_mode`` flags so a
12
+ downstream gate (daemon, SafetyService) can refuse open-mode tasks in
13
+ non-local deployments.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import time
19
+ from typing import Any, Callable, Dict, Optional
20
+
21
+ from aria_code.apps.cli.tradingview_bridge import (
22
+ _alert_dedup_key as alert_dedup_key,
23
+ _expected_webhook_secret,
24
+ parse_tradingview_alert,
25
+ verify_webhook_hmac,
26
+ verify_webhook_secret,
27
+ )
28
+ from aria_code.apps.channels.registry import CHANNEL_TASK_SCHEMA
29
+
30
+
31
+ def alert_to_task(
32
+ payload: Dict[str, Any] | str,
33
+ *,
34
+ raw_body: Optional[bytes | str] = None,
35
+ signature: Optional[str] = None,
36
+ clock: Callable[[], float] = time.time,
37
+ ) -> Dict[str, Any]:
38
+ """Normalize + authenticate one webhook delivery.
39
+
40
+ Returns ``{"success": True, "task": {...}}`` or
41
+ ``{"success": False, "error": ...}`` (tool-result convention).
42
+ """
43
+ alert = parse_tradingview_alert(payload)
44
+ raw = alert.get("raw") or {}
45
+
46
+ secret_configured = bool(_expected_webhook_secret())
47
+ if signature is not None:
48
+ # A fronting signer supplied an HMAC — it must verify (never open).
49
+ if not verify_webhook_hmac(raw_body if raw_body is not None else "", signature):
50
+ return {"success": False, "error": "tradingview alert rejected: HMAC signature mismatch"}
51
+ verified = True
52
+ else:
53
+ if not verify_webhook_secret(raw):
54
+ return {"success": False, "error": "tradingview alert rejected: passphrase missing or wrong"}
55
+ verified = secret_configured # open mode when no secret is configured
56
+
57
+ if not alert.get("symbol"):
58
+ return {"success": False, "error": "tradingview alert rejected: no symbol in payload"}
59
+
60
+ task = {
61
+ "schema": CHANNEL_TASK_SCHEMA,
62
+ "channel": "tradingview",
63
+ "kind": "alert",
64
+ "received_at": clock(),
65
+ "verified": verified,
66
+ "open_mode": not secret_configured and signature is None,
67
+ "dedup_key": alert_dedup_key(alert),
68
+ "symbol": alert["symbol"],
69
+ "action": alert["action"],
70
+ "price": alert.get("price"),
71
+ "time": alert.get("time"),
72
+ "message": alert.get("message") or "",
73
+ "prompt": task_prompt(alert),
74
+ }
75
+ return {"success": True, "task": task}
76
+
77
+
78
+ def task_prompt(alert: Dict[str, Any]) -> str:
79
+ """Render the gateway-facing natural-language task for this alert.
80
+
81
+ The daemon submits this prompt to runtime's ``run_turn`` — the agent then
82
+ analyses the alert with its normal tools; nothing here places orders.
83
+ """
84
+ symbol = alert.get("symbol", "")
85
+ action = alert.get("action", "ALERT")
86
+ price = alert.get("price")
87
+ at = f" at {price}" if price not in (None, "") else ""
88
+ msg = str(alert.get("message") or "").strip()
89
+ tail = f' Alert message: "{msg}".' if msg else ""
90
+ return (
91
+ f"TradingView alert received: {action} signal for {symbol}{at}.{tail} "
92
+ f"Assess the signal against current market data and the portfolio, and "
93
+ f"summarize whether it warrants action. Do not place any orders."
94
+ )
@@ -0,0 +1,13 @@
1
+ # CLI App
2
+
3
+ Target role: terminal UI and command parsing only.
4
+
5
+ The CLI should depend on these services:
6
+
7
+ - `gateway`: session routing and task orchestration.
8
+ - `runtime`: agent loop and tool execution.
9
+ - `ui`: terminal rendering and input.
10
+ - `reports`: local artifact and report output.
11
+
12
+ Migration rule: new slash commands should call package services instead of
13
+ adding more business logic to `aria_cli.py`.
@@ -0,0 +1,2 @@
1
+ """Terminal client entrypoint and adapters for Aria Code."""
2
+
@@ -0,0 +1,120 @@
1
+ """Guarded imports for optional dependencies.
2
+
3
+ These try/except blocks sat in aria_cli.py, so five command mixins reached into
4
+ a 7000-line module to ask "is the market-data client available?". Nothing about
5
+ that question is session state — it is a fact about the install.
6
+
7
+ Import form matters here and is not incidental. market_data_client keeps a
8
+ module-level singleton, and the package is reachable under two roots whose
9
+ module objects are distinct — so importing it as aria_code.clients.
10
+ market_data_client would build a *second* MarketDataClient with its own
11
+ connections and caches. Every caller in the tree currently uses the bare
12
+ `market_data_client` shim, so there is one client today; this module uses the
13
+ same form deliberately to keep it that way. Converging the two roots is a
14
+ separate, repo-wide job (26 root modules use the same sys.modules shim trick).
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ __all__ = [
20
+ "MarketDataClient", "get_mdc", "HAS_MDC",
21
+ "HAS_BROKERS", "get_registry", "list_broker_configs", "get_broker_config",
22
+ "add_broker_config", "remove_broker_config", "set_default_broker",
23
+ "validate_broker_config", "supported_broker_types", "get_config_template",
24
+ "BROKERS_CONFIG_PATH",
25
+ "HAS_MODEL_CAP", "get_model_capability",
26
+ "HAS_MCP", "MCPToolRegistry", "MCP_CONFIG_PATH", "init_mcp",
27
+ ]
28
+
29
+ try:
30
+ from market_data_client import MarketDataClient, get_mdc # noqa: F401
31
+
32
+ HAS_MDC = True
33
+ except ImportError: # pragma: no cover - exercised only without the client installed
34
+ MarketDataClient = None # type: ignore[assignment]
35
+ get_mdc = None # type: ignore[assignment]
36
+ HAS_MDC = False
37
+
38
+
39
+ # ── Brokers ──────────────────────────────────────────────────────────────────
40
+ # Same reasoning as above, and the stakes are higher: brokers.registry keeps a
41
+ # module-level BrokerRegistry singleton holding *live broker connections*, and
42
+ # `brokers` / `aria_code.brokers` are distinct module objects with separate
43
+ # singletons. Connecting through one and querying the other would report "not
44
+ # connected" for a session that is. All 37 call sites in the tree use the bare
45
+ # form, so there is one registry today; this module uses the same form to keep
46
+ # it that way.
47
+ try:
48
+ from brokers import ( # noqa: F401
49
+ BROKERS_CONFIG_PATH,
50
+ add_broker_config,
51
+ get_broker_config,
52
+ get_config_template,
53
+ get_registry,
54
+ list_broker_configs,
55
+ remove_broker_config,
56
+ set_default_broker,
57
+ supported_broker_types,
58
+ validate_broker_config,
59
+ )
60
+
61
+ HAS_BROKERS = True
62
+ except ImportError: # pragma: no cover - exercised only without the broker stack
63
+ HAS_BROKERS = False
64
+ BROKERS_CONFIG_PATH = None # type: ignore[assignment]
65
+
66
+ # aria_cli's version of this block only supplied three of the ten fallbacks,
67
+ # so a build without the broker stack would raise NameError rather than
68
+ # degrade — on add/remove/validate/template, i.e. exactly the paths a user
69
+ # hits while trying to set a broker up. All ten are covered here.
70
+ def get_registry(): # type: ignore[misc]
71
+ return None
72
+
73
+ def list_broker_configs(): # type: ignore[misc]
74
+ return []
75
+
76
+ def get_broker_config(broker_id: str): # type: ignore[misc]
77
+ return None
78
+
79
+ def add_broker_config(cfg): # type: ignore[misc]
80
+ raise RuntimeError("Broker support is not installed")
81
+
82
+ def remove_broker_config(broker_id: str): # type: ignore[misc]
83
+ raise RuntimeError("Broker support is not installed")
84
+
85
+ def set_default_broker(broker_id: str): # type: ignore[misc]
86
+ raise RuntimeError("Broker support is not installed")
87
+
88
+ def validate_broker_config(cfg): # type: ignore[misc]
89
+ return ["Broker support is not installed"]
90
+
91
+ def supported_broker_types(): # type: ignore[misc]
92
+ return []
93
+
94
+ def get_config_template(broker_type: str): # type: ignore[misc]
95
+ return None
96
+
97
+
98
+ # ── Model capability registry ────────────────────────────────────────────────
99
+ # Another guarded import that happened to live in aria_cli. Used by the model
100
+ # and UI commands to describe a community Ollama model that is not in the
101
+ # MODELS table.
102
+ try:
103
+ from model_capability import get_model_capability # noqa: F401
104
+
105
+ HAS_MODEL_CAP = True
106
+ except ImportError: # pragma: no cover - exercised only without model_capability
107
+ get_model_capability = None # type: ignore[assignment]
108
+ HAS_MODEL_CAP = False
109
+
110
+
111
+ # ── MCP ──────────────────────────────────────────────────────────────────────
112
+ try:
113
+ from mcp_client import MCP_CONFIG_PATH, MCPToolRegistry, init_mcp # noqa: F401
114
+
115
+ HAS_MCP = True
116
+ except ImportError: # pragma: no cover - exercised only without mcp_client
117
+ MCPToolRegistry = None # type: ignore[assignment]
118
+ MCP_CONFIG_PATH = None # type: ignore[assignment]
119
+ init_mcp = None # type: ignore[assignment]
120
+ HAS_MCP = False
@@ -0,0 +1,145 @@
1
+ """CLI bootstrap utilities shared by legacy and packaged entrypoints."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import socket
7
+ import urllib.parse
8
+ from pathlib import Path
9
+
10
+ from aria_code.apps.cli.config_paths import resolve_paths
11
+
12
+
13
+ def load_aria_env(env_file: Path | None = None) -> None:
14
+ """Load persisted CLI environment values without overriding the process."""
15
+ target = env_file or (Path.home() / ".aria" / ".env")
16
+ if not target.exists():
17
+ return
18
+ try:
19
+ for line in target.read_text(encoding="utf-8").splitlines():
20
+ line = line.strip()
21
+ if not line or line.startswith("#") or "=" not in line:
22
+ continue
23
+ key, _, value = line.partition("=")
24
+ key = key.strip()
25
+ value = value.strip()
26
+ if key and value:
27
+ os.environ.setdefault(key, value)
28
+ except Exception:
29
+ return
30
+
31
+
32
+ def disable_broken_proxy(timeout: float = 1.5) -> None:
33
+ """Unset proxy variables when the configured proxy cannot be reached."""
34
+ proxy = (
35
+ os.environ.get("HTTPS_PROXY")
36
+ or os.environ.get("https_proxy")
37
+ or os.environ.get("HTTP_PROXY")
38
+ or os.environ.get("http_proxy")
39
+ )
40
+ if not proxy:
41
+ return
42
+ try:
43
+ parsed = urllib.parse.urlparse(proxy if "://" in proxy else f"http://{proxy}")
44
+ host = parsed.hostname
45
+ port = parsed.port or 80
46
+ if not host:
47
+ return
48
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
49
+ sock.settimeout(timeout)
50
+ alive = sock.connect_ex((host, port)) == 0
51
+ sock.close()
52
+ except Exception:
53
+ alive = False
54
+ if not alive:
55
+ for name in ("HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy", "ALL_PROXY", "all_proxy"):
56
+ os.environ.pop(name, None)
57
+
58
+
59
+ def use_system_trust_store() -> bool:
60
+ """Verify TLS against the OS trust store instead of certifi's bundle.
61
+
62
+ Corporate and local TLS-intercepting proxies present their own CA. That CA
63
+ is installed in the system keychain — which is why ``curl`` works on such a
64
+ machine — but Python verifies against certifi, which has never heard of it,
65
+ so every HTTPS call fails with CERTIFICATE_VERIFY_FAILED.
66
+
67
+ This was not hypothetical: on a machine behind an intercepting proxy,
68
+ ``oauth2.googleapis.com`` failed 5 times out of 5 from Python and returned
69
+ 404 from curl, so roughly a third of Vertex turns died fetching an OAuth
70
+ token. Trusting the OS store fixed it without disabling verification —
71
+ which is the tempting wrong fix, and would accept any certificate at all.
72
+
73
+ Returns whether the injection happened, and never raises: an environment
74
+ without ``truststore`` keeps certifi's behaviour exactly as before.
75
+ """
76
+ try:
77
+ import truststore
78
+
79
+ truststore.inject_into_ssl()
80
+ return True
81
+ except Exception:
82
+ return False
83
+
84
+
85
+ def initialize_cli_environment() -> None:
86
+ os.environ.setdefault("TQDM_DISABLE", "1")
87
+ load_aria_env()
88
+ disable_broken_proxy()
89
+ use_system_trust_store()
90
+
91
+
92
+ # The model used when nothing has been configured yet.
93
+ #
94
+ # This exists so there is ONE place that answers "which model by default".
95
+ # Call sites used to spell their own fallback — `config.get("model",
96
+ # "qwen2.5:7b")`, ten times over — which quietly made Ollama the answer
97
+ # whenever a config key was missing, no matter what the user had chosen.
98
+ # Provider configuration is the user's to make (that is what `/model` and
99
+ # `.ariarc` are for); the code's job is to have a sane default and then get
100
+ # out of the way.
101
+ DEFAULT_MODEL = os.getenv("ARIA_DEFAULT_MODEL", "google/gemini-2.5-pro")
102
+
103
+
104
+ def default_config() -> dict:
105
+ return {
106
+ "api_url": os.getenv(
107
+ "ARTHERA_API_URL",
108
+ "http://localhost:8000",
109
+ ),
110
+ "local_url": "http://localhost:8000",
111
+ "ollama_url": os.getenv("OLLAMA_URL", "http://localhost:11434"),
112
+ # Which backend serves a bare, unprefixed model name. Only consulted
113
+ # for names that do not name their own provider ("qwen2.5:7b"); a
114
+ # prefixed id like "google/gemini-2.5-pro" always wins.
115
+ "local_provider": os.getenv("ARIA_LLM_PROVIDER", "ollama"),
116
+ "provider_fallback": "configured",
117
+ "model": DEFAULT_MODEL,
118
+ "thinking_mode": "auto",
119
+ "watchlist": ["AAPL", "MSFT", "GOOGL", "TSLA", "NVDA"],
120
+ "auth_token": None,
121
+ "user_id": None,
122
+ "last_session_id": None,
123
+ "auto_save_sessions": True,
124
+ "auto_compact_context": True,
125
+ "auto_compact_threshold": 0.78,
126
+ "command_policy": "safe",
127
+ "permission_mode": "workspace-write",
128
+ "network_enabled": True,
129
+ "data_sharing": False,
130
+ "feedback_upload": False,
131
+ "write_policy": "desktop_only",
132
+ "lsp_autocheck": False,
133
+ "input_style": "panel",
134
+ "input_theme": "auto",
135
+ "response_footer": "compact",
136
+ "report_agent_timeout": 40.0,
137
+ "report_synthesis_timeout": 20.0,
138
+ "local_mode": False,
139
+ "conversation_history": [],
140
+ "ui_lang": "",
141
+ }
142
+
143
+
144
+ def runtime_paths():
145
+ return resolve_paths()