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
aria_code/__init__.py ADDED
@@ -0,0 +1,111 @@
1
+ """Aria Code.
2
+
3
+ This package is importable under two roots by design, and has been since the
4
+ src/ restructure: ``aria_code.X`` and a bare ``X``. The tree uses both — 399
5
+ modules import each other bare (``from market_data_client import get_mdc``)
6
+ while others use the package path, and the tests patch whichever root the code
7
+ under test actually uses. tests/test_single_import_root.py exists to keep a
8
+ single *file* from mixing the two.
9
+
10
+ In development both roots resolve because pyproject's
11
+ ``pythonpath = [".", "src", "src/aria_code"]`` and tests/conftest.py put them
12
+ there. An installed wheel has neither, so only ``aria_code`` resolved and the
13
+ console script died immediately:
14
+
15
+ $ aria-code --version
16
+ ModuleNotFoundError: No module named 'aria_cli'
17
+
18
+ 4.4.1 did not hit this because its wheel predates the restructure — it shipped
19
+ ``aria_cli.py`` and 56 other modules at top level, so the bare root *was* the
20
+ package. After the move, nothing put the inner directory on the path.
21
+
22
+ Adding it here rather than shipping a .pth file keeps it inside the package, so
23
+ it applies to `pip install`, `pip install -e .`, a zipapp and a PyInstaller
24
+ bundle alike, and it is visible to anyone reading the package rather than hidden
25
+ in site-packages.
26
+
27
+ Both roots now give the same module object (``_OneModulePerFile`` below), so
28
+ a bare import is an alias rather than a second copy.
29
+
30
+ This is a bridge, not the destination. One root is the goal — v4.4.2 converted
31
+ the tree to ``aria_code.*`` throughout — but converting it means moving every
32
+ test's patch target with it, and doing that silently under a release is how the
33
+ bare-root bugs in this history were introduced.
34
+ """
35
+
36
+ import importlib as _importlib
37
+ import importlib.abc as _importlib_abc
38
+ import importlib.machinery as _machinery
39
+ import os as _os
40
+ import sys as _sys
41
+
42
+ _HERE = _os.path.dirname(_os.path.abspath(__file__))
43
+ if _HERE not in _sys.path:
44
+ # Appended, not inserted: a module that legitimately shadows one of these
45
+ # names in the user's own project must keep winning.
46
+ _sys.path.append(_HERE)
47
+
48
+
49
+ class _OneModulePerFile(_importlib_abc.MetaPathFinder, _importlib_abc.Loader):
50
+ """A bare import of a module in this package returns the ``aria_code.*`` object.
51
+
52
+ Two roots used to mean two module objects per file, each with its own
53
+ globals, and nothing ever errored: a patch, a registry, a cache or an
54
+ exception class applied to one copy simply missed code using the other.
55
+ In one week that was a task list cleared in the copy nobody wrote to, a
56
+ rewind whose conflict error was a different class from the one caught,
57
+ and a test fixture isolating a ledger nobody used while the real one
58
+ filled with pending tasks. Here ``import runtime.checkpoints`` and
59
+ ``import aria_code.runtime.checkpoints`` give the same object.
60
+
61
+ Only when the bare name would load a file from this package: a user's
62
+ own ``tools`` or ``utils`` earlier on ``sys.path`` is found first and
63
+ left alone, as before.
64
+ """
65
+
66
+ def __init__(self, root: str) -> None:
67
+ self._own: dict = {}
68
+ self.root = _os.path.normcase(root) + _os.sep
69
+ if not getattr(_sys, "frozen", False) and _os.path.isdir(root):
70
+ self.names = {
71
+ entry[:-3] if entry.endswith(".py") else entry
72
+ for entry in _os.listdir(root)
73
+ if entry != "__init__.py" and not entry.startswith(("_", "."))
74
+ and (entry.endswith(".py") or _os.path.isfile(_os.path.join(root, entry, "__init__.py")))
75
+ }
76
+ else:
77
+ # Frozen Python modules live in PYZ, not a physical source tree.
78
+ # PyInstaller's pkgutil hook enumerates that archive even when the
79
+ # package directory is absent, or contains only bundled data files.
80
+ from pkgutil import iter_modules
81
+ self.names = {module.name for module in iter_modules([root])
82
+ if not module.name.startswith(("_", "."))}
83
+
84
+ def find_spec(self, fullname, path=None, target=None):
85
+ if fullname.partition(".")[0] not in self.names:
86
+ return None
87
+ spec = _machinery.PathFinder.find_spec(fullname, path)
88
+ origin = getattr(spec, "origin", None) or ""
89
+ locations = list(getattr(spec, "submodule_search_locations", None) or ())
90
+ mine = [loc for loc in [origin, *locations] if loc and _os.path.normcase(loc).startswith(self.root)]
91
+ if spec is None or not mine:
92
+ return None
93
+ return _machinery.ModuleSpec(fullname, self, is_package=bool(locations))
94
+
95
+ def create_module(self, spec):
96
+ module = _importlib.import_module("aria_code." + spec.name)
97
+ # Keyed by name: importing the real module can alias others first.
98
+ self._own[spec.name] = (module.__spec__, getattr(module, "__loader__", None))
99
+ return module
100
+
101
+ def exec_module(self, module):
102
+ # Already executed under its aria_code.* name. The import system has
103
+ # just stamped this alias's spec on it; put the real one back, or
104
+ # importlib.reload() would re-run this no-op instead of the module.
105
+ module.__spec__, module.__loader__ = self._own.pop(module.__spec__.name)
106
+
107
+
108
+ if not any(isinstance(finder, _OneModulePerFile) for finder in _sys.meta_path):
109
+ _sys.meta_path.insert(0, _OneModulePerFile(_HERE))
110
+
111
+ del _HERE, _importlib_abc # the finder still uses _os, _importlib and _machinery
Binary file
Binary file
aria_code/_version.py ADDED
@@ -0,0 +1,20 @@
1
+ """Single source of truth for the package version.
2
+
3
+ __version__ used to live in aria_cli.py, which meant anything wanting the
4
+ version string had to import the whole interactive CLI — prompt_toolkit,
5
+ bootstrap hooks, the tool registry, all of it. The three consumers each worked
6
+ around that differently: a crash reporter (since removed) and a diagnostics accessor imported
7
+ aria_cli anyway, and the MCP server went to importlib.metadata instead, with a
8
+ comment explaining that pulling in aria_cli was too heavy for a binary whose
9
+ job is speaking JSON-RPC over stdio.
10
+
11
+ Keeping it here costs nothing to import and gives all three the same answer.
12
+ Note that importlib.metadata reports what was *installed*, which is not the
13
+ same thing when running from a source checkout.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ __all__ = ["__version__"]
19
+
20
+ __version__ = "0.167.0"
@@ -0,0 +1,296 @@
1
+ """Account-scoped durable memory: a cloud snapshot plus a retryable outbox.
2
+
3
+ Only newly captured account facts are queued. Legacy files and repository
4
+ instructions are never uploaded. A failed request never becomes a success.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import uuid
10
+ import os
11
+ from contextlib import contextmanager
12
+ import json
13
+ import threading
14
+ import time
15
+ from typing import Callable
16
+
17
+ from aria_code.account_session import account_id, account_root, get_account_token, read_config
18
+ from aria_code.cloud_memory import CloudMemoryClient
19
+ from aria_code.packages.aria_core.secure_file import write_secret_json
20
+
21
+ _LOCKS: dict[str, threading.RLock] = {}
22
+ _SYNC_LOCKS: dict[str, threading.Lock] = {}
23
+ _LOCK = threading.Lock()
24
+
25
+
26
+ def _lock_for(table, key, factory):
27
+ with _LOCK:
28
+ return table.setdefault(str(key), factory())
29
+
30
+
31
+ @contextmanager
32
+ def _state_lock(path):
33
+ """Protect read-modify-write across CLI windows as well as threads."""
34
+ with _lock_for(_LOCKS, path, threading.RLock):
35
+ path.parent.mkdir(parents=True, exist_ok=True)
36
+ descriptor = os.open(str(path) + ".lock", os.O_CREAT | os.O_RDWR, 0o600)
37
+ with os.fdopen(descriptor, "r+b") as handle:
38
+ if os.name == "nt":
39
+ import msvcrt
40
+
41
+ handle.seek(0, 2)
42
+ if handle.tell() == 0:
43
+ handle.write(b"0")
44
+ handle.flush()
45
+ handle.seek(0)
46
+ msvcrt.locking(handle.fileno(), msvcrt.LK_LOCK, 1)
47
+ try:
48
+ yield
49
+ finally:
50
+ handle.seek(0)
51
+ msvcrt.locking(handle.fileno(), msvcrt.LK_UNLCK, 1)
52
+ else:
53
+ import fcntl
54
+
55
+ fcntl.flock(handle, fcntl.LOCK_EX)
56
+ try:
57
+ yield
58
+ finally:
59
+ fcntl.flock(handle, fcntl.LOCK_UN)
60
+
61
+
62
+ def _write_state(path, data):
63
+ temporary = path.with_name(f".{path.name}.{os.getpid()}.{threading.get_ident()}.tmp")
64
+ try:
65
+ write_secret_json(temporary, data)
66
+ os.replace(temporary, path)
67
+ finally:
68
+ temporary.unlink(missing_ok=True)
69
+
70
+
71
+ class AccountMemory:
72
+ def __init__(self, config: dict | Callable[[], dict] | None = None, save=None):
73
+ self._config = config if config is not None else read_config
74
+ self.save = save
75
+
76
+ def config(self):
77
+ return self._config() if callable(self._config) else self._config
78
+
79
+ def _owner(self):
80
+ config = self.config()
81
+ uid = account_id(config)
82
+ return config, uid, account_root(config) / "cloud-memory.json"
83
+
84
+ @staticmethod
85
+ def _read(path):
86
+ try:
87
+ data = json.loads(path.read_text(encoding="utf-8"))
88
+ return data if isinstance(data, dict) else {}
89
+ except (OSError, ValueError):
90
+ return {}
91
+
92
+ def status(self):
93
+ config, uid, path = self._owner()
94
+ with _state_lock(path):
95
+ data = self._read(path)
96
+ return {
97
+ "account_id": uid,
98
+ "email": config.get("email") or "",
99
+ "enabled": data.get("preferences", {}).get("enabled", True),
100
+ "pending": len(data.get("outbox", [])),
101
+ "last_synced": data.get("last_synced"),
102
+ "error": data.get("error"),
103
+ }
104
+
105
+ def facts(self, *, include_disabled=False):
106
+ _, uid, path = self._owner()
107
+ if not uid:
108
+ return []
109
+ with _state_lock(path):
110
+ data = self._read(path)
111
+ if not include_disabled and data.get("preferences", {}).get("enabled") is False:
112
+ return []
113
+ outbox = data.get("outbox", [])
114
+ hidden = {op["id"] for op in outbox if op.get("op") == "delete"}
115
+ cancelled = set(data.get("cancelled_adds", []))
116
+ facts = [
117
+ f
118
+ for f in data.get("facts", [])
119
+ if f.get("id") not in hidden and (f.get("metadata") or {}).get("client_id") not in cancelled
120
+ ]
121
+ seen = {f.get("content") for f in facts}
122
+ for op in outbox:
123
+ if op.get("op") == "add" and op.get("content") not in seen:
124
+ facts.append({"id": op["id"], "content": op["content"], "pending": True})
125
+ seen.add(op["content"])
126
+ return facts
127
+
128
+ def context(self, max_chars=800):
129
+ _, uid, path = self._owner()
130
+ if not uid:
131
+ return ""
132
+ with _state_lock(path):
133
+ preferences = self._read(path).get("preferences", {})
134
+ if preferences.get("enabled") is False:
135
+ return ""
136
+ lines = [str(preferences[key]).strip() for key in ("nickname", "occupation", "about") if preferences.get(key)]
137
+ lines.extend(str(f.get("content", "")) for f in self.facts())
138
+ text = "\n".join(dict.fromkeys(lines))[:max_chars]
139
+ return f"## Account Memory\n{text}\n" if text else ""
140
+
141
+ def add(self, content: str):
142
+ config, uid, path = self._owner()
143
+ content = content.strip()[:4000]
144
+ if not uid or not content:
145
+ return False
146
+ # Stable per queued operation, so a retry is idempotent but an explicit
147
+ # re-add after deletion can create a new fact.
148
+ item_id = uuid.uuid4().hex
149
+ with _state_lock(path):
150
+ data = self._read(path)
151
+ if data.get("preferences", {}).get("enabled") is False or account_id(self.config()) != uid:
152
+ return False
153
+ if any(f.get("content") == content for f in data.get("facts", [])):
154
+ return True
155
+ outbox = data.setdefault("outbox", [])
156
+ if not any(op.get("op") == "add" and op.get("content") == content for op in outbox):
157
+ outbox.append({"op": "add", "id": item_id, "content": content})
158
+ _write_state(path, data)
159
+ return True
160
+
161
+ def forget(self, item_id):
162
+ _, uid, path = self._owner()
163
+ if not uid:
164
+ return False
165
+ with _state_lock(path):
166
+ data = self._read(path)
167
+ pending = data.setdefault("outbox", [])
168
+ local = any(op.get("id") == item_id and op.get("op") == "add" for op in pending)
169
+ if local:
170
+ data["cancelled_adds"] = list(set(data.get("cancelled_adds", [])) | {item_id})
171
+ data["outbox"] = [op for op in pending if op.get("id") != item_id]
172
+ if not local and any(f.get("id") == item_id for f in data.get("facts", [])):
173
+ data["outbox"].append({"op": "delete", "id": item_id})
174
+ _write_state(path, data)
175
+ return True
176
+
177
+ def sync(self, *, force=False):
178
+ config, uid, path = self._owner()
179
+ if not uid:
180
+ return {"ok": False, "reason": "sign-in-required"}
181
+ lock = _lock_for(_SYNC_LOCKS, path, threading.Lock)
182
+ if not lock.acquire(blocking=False):
183
+ return {"ok": False, "reason": "in-progress"}
184
+ state_lock = lambda: _state_lock(path)
185
+ original = config.get("auth_token")
186
+
187
+ def current():
188
+ now = self.config()
189
+ return account_id(now) == uid and now.get("auth_token") == original
190
+
191
+ def update(**fields):
192
+ if not current():
193
+ return
194
+ with state_lock():
195
+ data = self._read(path)
196
+ data.update(fields)
197
+ _write_state(path, data)
198
+
199
+ try:
200
+ with state_lock():
201
+ data = self._read(path)
202
+ if not force and time.time() - data.get("last_attempt", 0) < 60:
203
+ return {"ok": not data.get("error"), "cached": True}
204
+ update(last_attempt=time.time())
205
+ token = get_account_token(config, self.save)
206
+ if token:
207
+ original = token
208
+ if not token or not current():
209
+ update(error="sign-in-required")
210
+ return {"ok": False, "reason": "sign-in-required"}
211
+ from aria_code.apps.cli.endpoint_migration import PRODUCTION_API_URL
212
+
213
+ client = CloudMemoryClient(str(config.get("api_url") or PRODUCTION_API_URL), token)
214
+ preferences = client.get_preferences()
215
+ if not preferences or not current():
216
+ reason = "sign-in-required" if client.last_status == 401 else "service-unavailable"
217
+ update(error=reason)
218
+ return {"ok": False, "reason": reason}
219
+ # A newly disabled switch takes effect even if the next read fails.
220
+ update(preferences=preferences)
221
+ summary = client._request("GET", "/api/v2/memory/summary")
222
+ if summary is None:
223
+ update(error="service-unavailable")
224
+ return {"ok": False, "reason": "service-unavailable"}
225
+ if not current():
226
+ return {"ok": False, "reason": "account-changed"}
227
+ facts = summary.get("facts", [])
228
+ facts = [f for f in facts if isinstance(f, dict) and f.get("id") and isinstance(f.get("content"), str)]
229
+ update(preferences=preferences, facts=facts)
230
+ enabled = preferences.get("enabled") is not False
231
+ with state_lock():
232
+ latest = self._read(path)
233
+ cancelled = set(latest.get("cancelled_adds", []))
234
+ outbox = latest.setdefault("outbox", [])
235
+ for fact in facts:
236
+ if (fact.get("metadata") or {}).get("client_id") in cancelled:
237
+ deletion = {"op": "delete", "id": fact["id"]}
238
+ if deletion not in outbox:
239
+ outbox.append(deletion)
240
+ _write_state(path, latest)
241
+ pending = list(outbox)
242
+ failed = False
243
+ for op in pending[:10]:
244
+ if not enabled and op["op"] == "add":
245
+ continue
246
+ if not current():
247
+ return {"ok": False, "reason": "account-changed"}
248
+ if op["op"] == "add":
249
+ existing = next(
250
+ (
251
+ f
252
+ for f in facts
253
+ if (f.get("metadata") or {}).get("client_id") == op["id"]
254
+ or f.get("content") == op["content"]
255
+ ),
256
+ None,
257
+ )
258
+ item = existing or client._request(
259
+ "POST",
260
+ "/api/v2/memory/items",
261
+ body={
262
+ "content": op["content"],
263
+ "client_id": op["id"],
264
+ "scope": "user",
265
+ "kind": "durable",
266
+ "metadata": {"source": "aria-code", "client_id": op["id"]},
267
+ },
268
+ )
269
+ success = isinstance(item, dict) and bool(item.get("id"))
270
+ if success and not existing and not item.get("deleted_at"):
271
+ facts.append(item)
272
+ else:
273
+ success = client.delete_item(op["id"])
274
+ if success:
275
+ facts = [f for f in facts if f.get("id") != op["id"]]
276
+ if not current():
277
+ return {"ok": False, "reason": "account-changed"}
278
+ if not success:
279
+ failed = True
280
+ break
281
+ with state_lock():
282
+ latest = self._read(path)
283
+ latest["outbox"] = [item for item in latest.get("outbox", []) if item != op]
284
+ if op["op"] == "add" and op["id"] in latest.get("cancelled_adds", []) and item.get("id"):
285
+ deletion = {"op": "delete", "id": item["id"]}
286
+ if deletion not in latest["outbox"]:
287
+ latest["outbox"].append(deletion)
288
+ latest["facts"] = facts
289
+ _write_state(path, latest)
290
+ update(last_synced=time.time(), error="pending-retry" if failed else None)
291
+ return {"ok": not failed, "pending": self.status()["pending"], "enabled": enabled}
292
+ except Exception:
293
+ update(error="service-unavailable")
294
+ return {"ok": False, "reason": "service-unavailable"}
295
+ finally:
296
+ lock.release()
@@ -0,0 +1,166 @@
1
+ """Firebase account identity and refresh shared by the CLI and memory client.
2
+
3
+ JWT claims here are a local consistency check, never authorization: the API
4
+ still verifies Firebase's signature/project on every request.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import base64
10
+ import hashlib
11
+ import json
12
+ import time
13
+ import urllib.parse
14
+ import urllib.request
15
+ from pathlib import Path
16
+ from typing import Callable
17
+
18
+ from aria_code.packages.aria_core.paths import aria_home
19
+ from aria_code.packages.aria_core.secure_file import write_secret_json
20
+
21
+ PROJECT_ID = "arthera-66e5b"
22
+
23
+
24
+ def read_config() -> dict:
25
+ try:
26
+ value = json.loads((aria_home() / "config.json").read_text(encoding="utf-8"))
27
+ return value if isinstance(value, dict) else {}
28
+ except (OSError, ValueError):
29
+ return {}
30
+
31
+
32
+ def claims_for(token: str) -> dict:
33
+ try:
34
+ encoded = token.split(".")[1]
35
+ claims = json.loads(base64.urlsafe_b64decode(encoded + "=" * (-len(encoded) % 4)))
36
+ if claims.get("aud") != PROJECT_ID or claims.get("iss") != f"https://securetoken.google.com/{PROJECT_ID}":
37
+ return {}
38
+ return claims if isinstance(claims.get("sub"), str) and claims["sub"] else {}
39
+ except (ValueError, IndexError, TypeError, AttributeError):
40
+ return {}
41
+
42
+
43
+ def account_id(config: dict) -> str | None:
44
+ if not config.get("auth_token"):
45
+ return None
46
+ uid = str(config.get("user_id") or "")
47
+ claims = claims_for(str(config["auth_token"]))
48
+ # Never infer identity from email or reuse a different account's token.
49
+ return uid if uid and claims.get("sub") == uid else None
50
+
51
+
52
+ def account_root(config: dict | None = None) -> Path:
53
+ config = read_config() if config is None else config
54
+ uid = account_id(config)
55
+ bucket = hashlib.sha256(uid.encode()).hexdigest() if uid else "anonymous"
56
+ return aria_home() / "accounts" / bucket
57
+
58
+
59
+ def profile_path(config: dict | None = None) -> Path:
60
+ return account_root(config) / "ARIA.md"
61
+
62
+
63
+ def persist_if_current(config: dict, original: tuple, updates: dict, save: Callable | None = None) -> bool:
64
+ if (config.get("user_id"), config.get("auth_token"), config.get("refresh_token")) != original:
65
+ return False
66
+ config.update(updates)
67
+ if save:
68
+ save(config)
69
+ else:
70
+ disk = read_config()
71
+ if (disk.get("user_id"), disk.get("auth_token"), disk.get("refresh_token")) != original:
72
+ return False
73
+ disk.update(updates)
74
+ write_secret_json(aria_home() / "config.json", disk)
75
+ return True
76
+
77
+
78
+ def get_account_token(config: dict, save: Callable | None = None, *, force=False) -> str | None:
79
+ uid = account_id(config)
80
+ if not uid:
81
+ return None
82
+ token = str(config["auth_token"])
83
+ claims = claims_for(token)
84
+ try:
85
+ expires = float(claims.get("exp", 0))
86
+ except (ValueError, TypeError):
87
+ return None
88
+ if not force and expires > time.time() + 120:
89
+ return token
90
+ refresh = config.get("refresh_token")
91
+ if not refresh:
92
+ return token if expires > time.time() else None
93
+ original = (uid, token, refresh)
94
+ from aria_code.apps.cli.google_login import FIREBASE_WEB_API_KEY
95
+
96
+ request = urllib.request.Request(
97
+ f"https://securetoken.googleapis.com/v1/token?key={FIREBASE_WEB_API_KEY}",
98
+ data=urllib.parse.urlencode({"grant_type": "refresh_token", "refresh_token": refresh}).encode(),
99
+ headers={"Content-Type": "application/x-www-form-urlencoded"},
100
+ method="POST",
101
+ )
102
+ try:
103
+ with urllib.request.urlopen(request, timeout=8) as response:
104
+ result = json.loads(response.read())
105
+ fresh = result.get("id_token", "")
106
+ fresh_claims = claims_for(fresh)
107
+ if (
108
+ result.get("user_id") != uid
109
+ or fresh_claims.get("sub") != uid
110
+ or float(fresh_claims.get("exp", 0)) <= time.time()
111
+ ):
112
+ return None
113
+ updates = {"auth_token": fresh, "refresh_token": result.get("refresh_token") or refresh}
114
+ if isinstance(fresh_claims.get("email"), str):
115
+ updates["email"] = fresh_claims["email"].strip().lower()
116
+ from datetime import datetime, timezone
117
+
118
+ updates["token_expires_at"] = datetime.fromtimestamp(float(fresh_claims["exp"]), timezone.utc).isoformat()
119
+ if not persist_if_current(config, original, updates, save):
120
+ return None
121
+ return fresh
122
+ except Exception:
123
+ # Do not expose tokens, refresh tokens, HTTP bodies or URLs in errors.
124
+ return token if not force and expires > time.time() else None
125
+
126
+
127
+ def password_session(email: str, password: str) -> dict:
128
+ """Browserless fallback, using the exact same Firebase account provider."""
129
+ from aria_code.apps.cli.google_login import FIREBASE_WEB_API_KEY
130
+
131
+ request = urllib.request.Request(
132
+ f"https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key={FIREBASE_WEB_API_KEY}",
133
+ data=json.dumps({"email": email, "password": password, "returnSecureToken": True}).encode(),
134
+ headers={"Content-Type": "application/json"},
135
+ method="POST",
136
+ )
137
+ with urllib.request.urlopen(request, timeout=15) as response:
138
+ result = json.loads(response.read())
139
+ token, uid = result.get("idToken"), result.get("localId")
140
+ if not token or claims_for(token).get("sub") != uid:
141
+ raise ValueError("Missing Firebase identity")
142
+ return {
143
+ "auth_token": token,
144
+ "user_id": uid,
145
+ "refresh_token": result.get("refreshToken"),
146
+ "email": result.get("email"),
147
+ "display_name": result.get("displayName"),
148
+ "provider": "password",
149
+ }
150
+
151
+
152
+ async def prepare_account(config: dict, save=None) -> str | None:
153
+ """Refresh credentials, and give memory two seconds before using its cache.
154
+
155
+ The fenced sync may finish in the background; a slow memory service must
156
+ not hold up sending a chat turn. Its status/outbox remains inspectable.
157
+ """
158
+ import asyncio
159
+ from aria_code.account_memory import AccountMemory
160
+
161
+ token = await asyncio.to_thread(get_account_token, config, save)
162
+ try:
163
+ await asyncio.wait_for(asyncio.shield(asyncio.to_thread(AccountMemory(config, save=save).sync)), timeout=2)
164
+ except asyncio.TimeoutError:
165
+ pass
166
+ return token
@@ -0,0 +1 @@
1
+ """ADK application packages shipped as optional Aria Code integrations."""
@@ -0,0 +1 @@
1
+ """Google ADK entrypoint package for Aria's read-only code reviewer."""
@@ -0,0 +1,32 @@
1
+ """Google ADK entrypoint: a bounded reviewer for pasted code."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+
7
+ from google.adk.agents.llm_agent import Agent
8
+
9
+ from aria_code.packages.adk_bridge import CodeReviewTools
10
+
11
+
12
+ _tools = CodeReviewTools()
13
+
14
+ root_agent = Agent(
15
+ model=os.getenv("ARIA_ADK_MODEL", "gemini-3.8-flash"),
16
+ name="aria_code_review",
17
+ description="A read-only code reviewer for user-submitted source text.",
18
+ instruction="""You are Aria Code Review, a careful software reviewer.
19
+
20
+ Ask the user to paste the relevant source code when it has not been supplied.
21
+ Use review_code for deterministic findings and preserve its severity, line,
22
+ rule, and limitations. Never claim to have opened a local path, accessed a
23
+ repository, run a command, changed a file, or executed tests: this ADK agent
24
+ has none of those capabilities.
25
+
26
+ Explain only findings supported by the submitted code. Separate deterministic
27
+ findings from suggestions, and recommend a test or validation step where
28
+ appropriate. Do not expose credentials appearing in source; tell the user to
29
+ revoke and rotate any exposed credential instead.
30
+ """,
31
+ tools=[_tools.review_code],
32
+ )
@@ -0,0 +1 @@
1
+ """Read-only Aria market-research agent for Google ADK."""
@@ -0,0 +1,31 @@
1
+ """Google ADK entrypoint: ``adk web adk_apps`` discovers ``aria_research``."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+
7
+ from google.adk.agents.llm_agent import Agent
8
+
9
+ from aria_code.packages.adk_bridge import MarketResearchTools
10
+
11
+
12
+ _tools = MarketResearchTools()
13
+
14
+ root_agent = Agent(
15
+ model=os.getenv("ARIA_ADK_MODEL", "gemini-3.8-flash"),
16
+ name="aria_research",
17
+ description="A read-only market-research assistant for Aria Code and Arthera.",
18
+ instruction="""You are Aria Research, a careful financial-research assistant.
19
+
20
+ Use get_market_snapshot for live market facts and explicitly identify its data
21
+ quality, timestamp, warnings, and source limitations. Use get_market_data_health
22
+ when a data result is missing, stale, or conflicting. Do not invent prices,
23
+ returns, news, citations, positions, or tool output.
24
+
25
+ This agent is research-only. Never claim to execute, recommend, place, modify,
26
+ or schedule trades. Do not request credentials. State clearly that your output
27
+ is research assistance, not investment advice. For quantitative conclusions,
28
+ separate observed facts from hypotheses and mention material uncertainty.
29
+ """,
30
+ tools=[_tools.get_market_snapshot, _tools.get_market_data_health],
31
+ )