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/artifacts.py ADDED
@@ -0,0 +1,581 @@
1
+ """Local artifact paths for reports, charts, projects, and strategy output."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ import re
8
+ from dataclasses import dataclass
9
+ from datetime import datetime
10
+ from pathlib import Path
11
+ from typing import Any, Dict, Optional
12
+
13
+
14
+ def slugify_topic(topic: Optional[str], fallback: str = "general") -> str:
15
+ raw = str(topic or "").strip()
16
+ if not raw:
17
+ raw = fallback
18
+ raw = re.sub(r"[^A-Za-z0-9._\-\u4e00-\u9fff]+", "-", raw)
19
+ raw = raw.strip("-._")
20
+ return raw[:80] or fallback
21
+
22
+
23
+ @dataclass(frozen=True)
24
+ class ArtifactRecord:
25
+ """Resolved paths for one generated artifact bundle."""
26
+
27
+ category: str
28
+ topic: str
29
+ directory: Path
30
+ path: Path
31
+ metadata_path: Path
32
+ raw_data_path: Path
33
+
34
+
35
+ @dataclass(frozen=True)
36
+ class ArtifactEntry:
37
+ """Parsed artifact metadata with resolved paths and file state."""
38
+
39
+ metadata_path: Path
40
+ path: Path
41
+ raw_data_path: Path
42
+ kind: str
43
+ status: str
44
+ topic: str
45
+ created_at: str
46
+ mtime: float
47
+ size_bytes: int
48
+
49
+
50
+ def _safe_stat(path: Path) -> Optional[os.stat_result]:
51
+ try:
52
+ return path.stat()
53
+ except Exception:
54
+ return None
55
+
56
+
57
+ def _artifact_entry_from_metadata(path: Path) -> Optional[ArtifactEntry]:
58
+ try:
59
+ data = json.loads(path.read_text(encoding="utf-8"))
60
+ artifact = data.get("artifact") or {}
61
+ output_path = Path(str(artifact.get("path") or ""))
62
+ metadata_path = Path(str(artifact.get("metadata_path") or path))
63
+ raw_path = Path(str(artifact.get("raw_data_path") or path.with_suffix(".raw_data.json")))
64
+ output_stat = _safe_stat(output_path)
65
+ meta_stat = _safe_stat(metadata_path)
66
+ raw_stat = _safe_stat(raw_path)
67
+ mtime = 0.0
68
+ for stat in (output_stat, meta_stat, raw_stat):
69
+ if stat is not None:
70
+ mtime = max(mtime, float(stat.st_mtime))
71
+ size_bytes = 0
72
+ for stat in (output_stat, meta_stat, raw_stat):
73
+ if stat is not None:
74
+ size_bytes += int(stat.st_size)
75
+ return ArtifactEntry(
76
+ metadata_path=metadata_path,
77
+ path=output_path,
78
+ raw_data_path=raw_path,
79
+ kind=str(data.get("kind") or artifact.get("category") or "artifact"),
80
+ status=str(data.get("status") or "unknown"),
81
+ topic=str(artifact.get("topic") or data.get("symbol") or ""),
82
+ created_at=str(data.get("created_at") or ""),
83
+ mtime=mtime or float(meta_stat.st_mtime if meta_stat else 0),
84
+ size_bytes=size_bytes,
85
+ )
86
+ except Exception:
87
+ return None
88
+
89
+
90
+ def _cleanup_empty_dirs(start: Path, stop: Path) -> None:
91
+ current = start
92
+ try:
93
+ stop = stop.resolve()
94
+ except Exception:
95
+ return
96
+ while True:
97
+ try:
98
+ current = current.resolve()
99
+ except Exception:
100
+ break
101
+ if current == stop or stop not in current.parents:
102
+ break
103
+ try:
104
+ current.rmdir()
105
+ except Exception:
106
+ break
107
+ current = current.parent
108
+
109
+
110
+ def _project_artifact_root() -> Optional[Path]:
111
+ """Return project-level artifact root from .ariarc when configured."""
112
+ try:
113
+ from aria_code.ariarc import AriaRC
114
+
115
+ rc = AriaRC.load()
116
+ source = rc.source_path
117
+ if not source:
118
+ return None
119
+ data = getattr(rc, "_data", None)
120
+ if not isinstance(data, dict):
121
+ text = source.read_text(encoding="utf-8")
122
+ import json as _json
123
+ import re as _re
124
+ text = _re.sub(r"/\*.*?\*/", "", text, flags=_re.DOTALL)
125
+ text = _re.sub(r'(?<!:)(?<!https)//[^\n]*', "", text)
126
+ data = _json.loads(text)
127
+ configured = data.get("artifact_root") or data.get("output_dir")
128
+ if configured:
129
+ path = Path(str(configured)).expanduser()
130
+ if not path.is_absolute():
131
+ path = source.parent / path
132
+ return path
133
+ return source.parent / "aria-output"
134
+ except Exception:
135
+ return None
136
+ return None
137
+
138
+
139
+ def artifact_root() -> Path:
140
+ """Return the per-user local artifact root.
141
+
142
+ Override with ARIA_ARTIFACT_ROOT when a user wants reports/projects under a
143
+ specific workspace. Defaults to a product-owned folder under that user's
144
+ Documents directory, not the developer's Arthera repo.
145
+ """
146
+ configured = os.getenv("ARIA_ARTIFACT_ROOT")
147
+ if configured:
148
+ return Path(configured).expanduser()
149
+ project_root = _project_artifact_root()
150
+ if project_root:
151
+ return project_root
152
+ return Path.home() / "Documents" / "Aria Code"
153
+
154
+
155
+ def user_output_root() -> Path:
156
+ """Return a user-owned output root that never falls back to project cwd.
157
+
158
+ Use this for generated code, strategies, and project scaffolds. Reports and
159
+ charts may still honor project `.ariarc` via `artifact_root()`, but user
160
+ code should not silently land in the Aria source checkout.
161
+ """
162
+ configured = os.getenv("ARIA_USER_OUTPUT_ROOT")
163
+ if configured:
164
+ return Path(configured).expanduser()
165
+ return Path.home() / "Documents" / "Aria Code"
166
+
167
+
168
+ def user_projects_dir(create: bool = True) -> Path:
169
+ path = user_output_root() / "projects"
170
+ if create:
171
+ path.mkdir(parents=True, exist_ok=True)
172
+ return path
173
+
174
+
175
+ def user_generated_dir(create: bool = True) -> Path:
176
+ path = user_output_root() / "generated"
177
+ if create:
178
+ path.mkdir(parents=True, exist_ok=True)
179
+ return path
180
+
181
+
182
+ def artifact_roots(*, include_user_generated: bool = True) -> list[Path]:
183
+ """Return unique artifact roots that should be visible to users."""
184
+ roots: list[Path] = []
185
+ for root in (artifact_root(), user_generated_dir(create=False) if include_user_generated else None):
186
+ if root is None:
187
+ continue
188
+ try:
189
+ resolved = root.expanduser().resolve()
190
+ except Exception:
191
+ resolved = root.expanduser()
192
+ if not any(existing == resolved for existing in roots):
193
+ roots.append(resolved)
194
+ return roots
195
+
196
+
197
+ def artifact_dir(category: str, topic: Optional[str] = None, create: bool = True) -> Path:
198
+ parts = [slugify_topic(part) for part in str(category or "artifacts").split("/") if part]
199
+ base = artifact_root().joinpath(*parts)
200
+ if topic:
201
+ base = base / slugify_topic(topic)
202
+ if create:
203
+ base.mkdir(parents=True, exist_ok=True)
204
+ return base
205
+
206
+
207
+ def create_artifact(
208
+ category: str,
209
+ topic: Optional[str],
210
+ stem: str,
211
+ suffix: str,
212
+ *,
213
+ timestamp: Optional[datetime] = None,
214
+ create: bool = True,
215
+ ) -> ArtifactRecord:
216
+ """Create a dated artifact bundle path and its sidecar metadata paths.
217
+
218
+ Output layout:
219
+
220
+ <root>/<category>/<topic>/YYYY-MM-DD/<HHMMSS>_<stem><suffix>
221
+ <root>/<category>/<topic>/YYYY-MM-DD/<HHMMSS>_<stem>.metadata.json
222
+ <root>/<category>/<topic>/YYYY-MM-DD/<HHMMSS>_<stem>.raw_data.json
223
+ """
224
+
225
+ ts = timestamp or datetime.now()
226
+ topic_slug = slugify_topic(topic)
227
+ stem_slug = slugify_topic(stem, fallback="artifact")
228
+ suffix = suffix if suffix.startswith(".") else f".{suffix}"
229
+ directory = artifact_dir(category, topic_slug, create=False) / ts.strftime("%Y-%m-%d")
230
+ prefix = ts.strftime("%H%M%S")
231
+ base_name = f"{prefix}_{stem_slug}"
232
+ if create:
233
+ directory.mkdir(parents=True, exist_ok=True)
234
+ return ArtifactRecord(
235
+ category=category,
236
+ topic=topic_slug,
237
+ directory=directory,
238
+ path=directory / f"{base_name}{suffix}",
239
+ metadata_path=directory / f"{base_name}.metadata.json",
240
+ raw_data_path=directory / f"{base_name}.raw_data.json",
241
+ )
242
+
243
+
244
+ def create_user_artifact(
245
+ category: str,
246
+ topic: Optional[str],
247
+ stem: str,
248
+ suffix: str,
249
+ *,
250
+ timestamp: Optional[datetime] = None,
251
+ create: bool = True,
252
+ ) -> ArtifactRecord:
253
+ """Create an artifact under the user-owned output root.
254
+
255
+ Unlike `create_artifact`, this intentionally ignores project `.ariarc`
256
+ output settings. Use it for charts, scripts, and generated assets the user
257
+ expects to find in their local Aria output folder rather than the source
258
+ checkout.
259
+ """
260
+ ts = timestamp or datetime.now()
261
+ parts = [slugify_topic(part) for part in str(category or "generated").split("/") if part]
262
+ topic_slug = slugify_topic(topic)
263
+ stem_slug = slugify_topic(stem, fallback="artifact")
264
+ suffix = suffix if suffix.startswith(".") else f".{suffix}"
265
+ directory = user_generated_dir(create=False).joinpath(*parts, topic_slug, ts.strftime("%Y-%m-%d"))
266
+ prefix = ts.strftime("%H%M%S")
267
+ base_name = f"{prefix}_{stem_slug}"
268
+ if create:
269
+ directory.mkdir(parents=True, exist_ok=True)
270
+ return ArtifactRecord(
271
+ category=f"generated/{'/'.join(parts)}" if parts else "generated",
272
+ topic=topic_slug,
273
+ directory=directory,
274
+ path=directory / f"{base_name}{suffix}",
275
+ metadata_path=directory / f"{base_name}.metadata.json",
276
+ raw_data_path=directory / f"{base_name}.raw_data.json",
277
+ )
278
+
279
+
280
+ def write_artifact_metadata(record: ArtifactRecord, metadata: Dict[str, Any]) -> Path:
281
+ payload = {
282
+ "artifact": {
283
+ "category": record.category,
284
+ "topic": record.topic,
285
+ "path": str(record.path),
286
+ "metadata_path": str(record.metadata_path),
287
+ "raw_data_path": str(record.raw_data_path),
288
+ },
289
+ **metadata,
290
+ }
291
+ record.metadata_path.write_text(
292
+ json.dumps(payload, ensure_ascii=False, indent=2, default=str),
293
+ encoding="utf-8",
294
+ )
295
+ _notify_preview_session(record)
296
+ return record.metadata_path
297
+
298
+
299
+ def _notify_preview_session(record: ArtifactRecord) -> None:
300
+ """Best-effort notification to a running /canvas preview session, if
301
+ any (see preview_server.py). A true no-op in the overwhelmingly common
302
+ case — no session running, e.g. every headless MCP tool call — must
303
+ never let a preview-notification failure break artifact writing, hence
304
+ the blanket except."""
305
+ try:
306
+ import asyncio
307
+
308
+ # Bare root: tests/test_preview_server.py patches `preview_server`,
309
+ # and the packaged root is a different module object — importing it
310
+ # here notified a session nothing was watching.
311
+ from preview_server import get_active_session, thread_id_for
312
+
313
+ session = get_active_session()
314
+ if session is None:
315
+ return
316
+ loop = asyncio.get_running_loop()
317
+ loop.create_task(session.notify_new_version(thread_id_for(record), record))
318
+ except Exception:
319
+ pass
320
+
321
+
322
+ def write_artifact_raw_data(record: ArtifactRecord, data: Any) -> Path:
323
+ record.raw_data_path.write_text(
324
+ json.dumps(data, ensure_ascii=False, indent=2, default=str),
325
+ encoding="utf-8",
326
+ )
327
+ return record.raw_data_path
328
+
329
+
330
+ _ARTIFACT_KINDS_BY_SUFFIX = {
331
+ ".md": "markdown_document",
332
+ ".markdown": "markdown_document",
333
+ ".html": "html_document",
334
+ ".htm": "html_document",
335
+ ".pdf": "pdf_document",
336
+ ".docx": "word_document",
337
+ ".xlsx": "spreadsheet",
338
+ ".xls": "spreadsheet",
339
+ ".csv": "data_file",
340
+ ".json": "data_file",
341
+ ".py": "code_file",
342
+ ".ipynb": "notebook",
343
+ ".png": "image",
344
+ ".jpg": "image",
345
+ ".jpeg": "image",
346
+ ".svg": "image",
347
+ }
348
+
349
+
350
+ def register_existing_artifact(
351
+ path: Path | str,
352
+ *,
353
+ kind: str = "",
354
+ topic: str = "",
355
+ status: str = "complete",
356
+ metadata: Optional[Dict[str, Any]] = None,
357
+ ) -> Optional[ArtifactRecord]:
358
+ """Register a generated file so it appears in the unified artifact list.
359
+
360
+ Only files under :func:`user_generated_dir` are registered. This keeps
361
+ ordinary source-code edits out of the user's generated-output inventory.
362
+ Registration is best-effort and never changes the generated file itself.
363
+ """
364
+ try:
365
+ output_path = Path(path).expanduser().resolve()
366
+ generated_root = user_generated_dir(create=False).expanduser().resolve()
367
+ output_path.relative_to(generated_root)
368
+ except (OSError, RuntimeError, ValueError):
369
+ return None
370
+
371
+ lowered_name = output_path.name.lower()
372
+ if lowered_name.endswith((".metadata.json", ".raw_data.json")):
373
+ return None
374
+
375
+ record = ArtifactRecord(
376
+ category="generated/files",
377
+ topic=slugify_topic(topic or output_path.stem),
378
+ directory=output_path.parent,
379
+ path=output_path,
380
+ # Keep the output extension in sidecar names so report.md and
381
+ # report.html can coexist without overwriting each other's metadata.
382
+ metadata_path=output_path.with_name(f"{output_path.name}.metadata.json"),
383
+ raw_data_path=output_path.with_name(f"{output_path.name}.raw_data.json"),
384
+ )
385
+ payload: Dict[str, Any] = {
386
+ "kind": kind or _ARTIFACT_KINDS_BY_SUFFIX.get(output_path.suffix.lower(), "generated_file"),
387
+ "status": status,
388
+ "created_at": datetime.now().astimezone().isoformat(timespec="seconds"),
389
+ }
390
+ if metadata:
391
+ payload.update(metadata)
392
+ write_artifact_metadata(record, payload)
393
+ return record
394
+
395
+
396
+ def recent_artifacts(limit: int = 20, root: Optional[Path] = None) -> list[Dict[str, Any]]:
397
+ """Return recent artifact metadata records, newest first."""
398
+ base = root or artifact_root()
399
+ if not base.exists():
400
+ return []
401
+ items: list[Dict[str, Any]] = []
402
+ for path in base.rglob("*.metadata.json"):
403
+ entry = _artifact_entry_from_metadata(path)
404
+ if entry is None:
405
+ continue
406
+ items.append({
407
+ "kind": entry.kind,
408
+ "status": entry.status,
409
+ "topic": entry.topic,
410
+ "path": str(entry.path) if str(entry.path) else "",
411
+ "metadata_path": str(entry.metadata_path),
412
+ "raw_data_path": str(entry.raw_data_path),
413
+ "created_at": entry.created_at,
414
+ "mtime": entry.mtime,
415
+ "size_bytes": entry.size_bytes,
416
+ })
417
+ items.sort(key=lambda item: item.get("mtime") or 0, reverse=True)
418
+ return items[: max(0, int(limit))]
419
+
420
+
421
+ def recent_artifacts_all(limit: int = 20) -> list[Dict[str, Any]]:
422
+ """Return recent artifacts across project and user-generated roots."""
423
+ items: list[Dict[str, Any]] = []
424
+ seen: set[str] = set()
425
+ for root in artifact_roots(include_user_generated=True):
426
+ for item in recent_artifacts(limit=max(limit, 20), root=root):
427
+ marker = str(item.get("metadata_path") or item.get("path") or "")
428
+ if marker and marker in seen:
429
+ continue
430
+ if marker:
431
+ seen.add(marker)
432
+ item = dict(item)
433
+ item["root"] = str(root)
434
+ items.append(item)
435
+ items.sort(key=lambda item: item.get("mtime") or 0, reverse=True)
436
+ return items[: max(0, int(limit))]
437
+
438
+
439
+ def artifact_summary(root: Optional[Path] = None) -> Dict[str, Any]:
440
+ """Return a lightweight inventory of artifacts under root."""
441
+ base = root or artifact_root()
442
+ if not base.exists():
443
+ return {
444
+ "root": str(base),
445
+ "total": 0,
446
+ "total_size_bytes": 0,
447
+ "by_kind": {},
448
+ "newest_mtime": 0.0,
449
+ "oldest_mtime": 0.0,
450
+ }
451
+ entries: list[ArtifactEntry] = []
452
+ for path in base.rglob("*.metadata.json"):
453
+ entry = _artifact_entry_from_metadata(path)
454
+ if entry is not None:
455
+ entries.append(entry)
456
+ by_kind: Dict[str, int] = {}
457
+ newest = 0.0
458
+ oldest = 0.0
459
+ total_size = 0
460
+ for entry in entries:
461
+ by_kind[entry.kind] = by_kind.get(entry.kind, 0) + 1
462
+ total_size += entry.size_bytes
463
+ if entry.mtime:
464
+ newest = max(newest, entry.mtime)
465
+ oldest = entry.mtime if not oldest else min(oldest, entry.mtime)
466
+ return {
467
+ "root": str(base),
468
+ "total": len(entries),
469
+ "total_size_bytes": total_size,
470
+ "by_kind": dict(sorted(by_kind.items(), key=lambda item: (-item[1], item[0]))),
471
+ "newest_mtime": newest,
472
+ "oldest_mtime": oldest,
473
+ }
474
+
475
+
476
+ def artifact_summary_all() -> Dict[str, Any]:
477
+ """Return artifact inventory across project and user-generated roots."""
478
+ roots = artifact_roots(include_user_generated=True)
479
+ summaries = [artifact_summary(root) for root in roots]
480
+ by_kind: Dict[str, int] = {}
481
+ total = 0
482
+ total_size = 0
483
+ newest = 0.0
484
+ oldest = 0.0
485
+ for summary in summaries:
486
+ total += int(summary.get("total") or 0)
487
+ total_size += int(summary.get("total_size_bytes") or 0)
488
+ newest = max(newest, float(summary.get("newest_mtime") or 0))
489
+ old = float(summary.get("oldest_mtime") or 0)
490
+ if old:
491
+ oldest = old if not oldest else min(oldest, old)
492
+ for kind, count in (summary.get("by_kind") or {}).items():
493
+ by_kind[str(kind)] = by_kind.get(str(kind), 0) + int(count)
494
+ return {
495
+ "roots": [str(root) for root in roots],
496
+ "total": total,
497
+ "total_size_bytes": total_size,
498
+ "by_kind": dict(sorted(by_kind.items(), key=lambda item: (-item[1], item[0]))),
499
+ "newest_mtime": newest,
500
+ "oldest_mtime": oldest,
501
+ "summaries": summaries,
502
+ }
503
+
504
+
505
+ def prune_artifacts(keep: int = 20, root: Optional[Path] = None, dry_run: bool = False) -> Dict[str, Any]:
506
+ """Delete artifact bundles older than the newest `keep` entries."""
507
+ base = root or artifact_root()
508
+ keep = max(0, int(keep))
509
+ if not base.exists():
510
+ return {
511
+ "root": str(base),
512
+ "keep": keep,
513
+ "scanned": 0,
514
+ "removed": 0,
515
+ "dry_run": dry_run,
516
+ "deleted": [],
517
+ }
518
+ entries: list[ArtifactEntry] = []
519
+ for path in base.rglob("*.metadata.json"):
520
+ entry = _artifact_entry_from_metadata(path)
521
+ if entry is not None:
522
+ entries.append(entry)
523
+ entries.sort(key=lambda entry: entry.mtime, reverse=True)
524
+ to_remove = entries[keep:]
525
+ deleted: list[Dict[str, Any]] = []
526
+ for entry in to_remove:
527
+ targets = [entry.path, entry.metadata_path, entry.raw_data_path]
528
+ removed_files: list[str] = []
529
+ if not dry_run:
530
+ for target in targets:
531
+ try:
532
+ if target.exists():
533
+ target.unlink()
534
+ removed_files.append(str(target))
535
+ except Exception:
536
+ continue
537
+ for target in targets:
538
+ if target.exists():
539
+ continue
540
+ _cleanup_empty_dirs(target.parent, base)
541
+ else:
542
+ removed_files = [str(target) for target in targets if target.exists()]
543
+ deleted.append(
544
+ {
545
+ "kind": entry.kind,
546
+ "status": entry.status,
547
+ "topic": entry.topic,
548
+ "metadata_path": str(entry.metadata_path),
549
+ "path": str(entry.path) if str(entry.path) else "",
550
+ "removed_files": removed_files,
551
+ }
552
+ )
553
+ return {
554
+ "root": str(base),
555
+ "keep": keep,
556
+ "scanned": len(entries),
557
+ "removed": len(deleted),
558
+ "dry_run": dry_run,
559
+ "deleted": deleted,
560
+ }
561
+
562
+
563
+ def prune_artifacts_all(keep: int = 20, dry_run: bool = False) -> Dict[str, Any]:
564
+ """Prune artifact bundles in every visible artifact root."""
565
+ results = [prune_artifacts(keep=keep, root=root, dry_run=dry_run) for root in artifact_roots(include_user_generated=True)]
566
+ deleted: list[Dict[str, Any]] = []
567
+ for result in results:
568
+ root = result.get("root") or ""
569
+ for item in result.get("deleted") or []:
570
+ item = dict(item)
571
+ item["root"] = root
572
+ deleted.append(item)
573
+ return {
574
+ "roots": [result.get("root") for result in results],
575
+ "keep": max(0, int(keep)),
576
+ "scanned": sum(int(result.get("scanned") or 0) for result in results),
577
+ "removed": sum(int(result.get("removed") or 0) for result in results),
578
+ "dry_run": dry_run,
579
+ "deleted": deleted,
580
+ "results": results,
581
+ }
@@ -0,0 +1,4 @@
1
+ """Compatibility import for :mod:`domain.backtest_engine`."""
2
+ from importlib import import_module as _import_module
3
+ import sys as _sys
4
+ _sys.modules[__name__] = _import_module("domain.backtest_engine")
@@ -0,0 +1,4 @@
1
+ """Compatibility import for :mod:`domain.backtest_report`."""
2
+ from importlib import import_module as _import_module
3
+ import sys as _sys
4
+ _sys.modules[__name__] = _import_module("domain.backtest_report")
@@ -0,0 +1,78 @@
1
+ """
2
+ brokers/ — Aria Code 券商接入层
3
+ ================================
4
+ 统一接口连接中国和国际主流券商,支持账户查询、持仓管理和下单。
5
+
6
+ 快速使用::
7
+
8
+ from brokers.registry import get_registry
9
+
10
+ reg = get_registry()
11
+ broker = reg.connect("xt_main") # 从 ~/.arthera/brokers.json 读取
12
+ acct = broker.account_info()
13
+ pos = broker.positions()
14
+
15
+ 支持券商
16
+ --------
17
+ 中国:
18
+ xtquant 迅投 XTQuant(中信/华鑫/浙商等QMT平台)
19
+ easytrader EasyTrader(同花顺/通达信/华泰/国君 等客户端)
20
+ futu 富途牛牛 OpenAPI(港/美/A股)
21
+ tiger 老虎证券 OpenAPI(美/港/A股)
22
+ longbridge 长桥证券 OpenAPI(港/美/A股)
23
+
24
+ 国际:
25
+ ibkr Interactive Brokers TWS/Gateway
26
+ alpaca Alpaca Markets(美股 + 模拟盘)
27
+ webull Webull(美股,只读模式)
28
+
29
+ 配置文件:~/.arthera/brokers.json
30
+ """
31
+
32
+ from .base import BrokerBase, AccountInfo, Position, Order, OrderResult, PortfolioSummary
33
+ from .config import (
34
+ load_config, list_broker_configs, get_broker_config,
35
+ add_broker_config, remove_broker_config, set_default_broker,
36
+ validate_broker_config, supported_broker_types, get_config_template,
37
+ BROKERS_CONFIG_PATH,
38
+ )
39
+ from .registry import BrokerRegistry, get_registry
40
+ from .planning import (
41
+ PortfolioSnapshot, StrategyIntent, RiskRuleSet, PlannedOrder, OrderPlan,
42
+ snapshot_from_broker, infer_intent_from_backtest, plan_order,
43
+ evaluate_risk, plans_from_strategy_results,
44
+ )
45
+ from .capabilities import (
46
+ BrokerCapability, broker_connection_plan, broker_dependency_state,
47
+ broker_service_playbook, filter_capabilities, get_broker_capability,
48
+ list_broker_capabilities,
49
+ )
50
+ from .paper_broker import PaperBroker, reset_paper_account
51
+ from .trading import (
52
+ OrderIntent, TradingPolicy, build_order_preview, execute_order_preview,
53
+ list_order_previews, load_order_preview, policy_from_config, resolve_trading_mode,
54
+ global_dry_run,
55
+ )
56
+ from .automation import (
57
+ AutoExecutePolicy, AutoExecuteDecision, evaluate_auto_execute, run_auto_execute,
58
+ )
59
+
60
+ __all__ = [
61
+ "BrokerBase", "AccountInfo", "Position", "Order", "OrderResult", "PortfolioSummary",
62
+ "load_config", "list_broker_configs", "get_broker_config",
63
+ "add_broker_config", "remove_broker_config", "set_default_broker",
64
+ "validate_broker_config", "supported_broker_types", "get_config_template",
65
+ "BROKERS_CONFIG_PATH",
66
+ "BrokerRegistry", "get_registry",
67
+ "PortfolioSnapshot", "StrategyIntent", "RiskRuleSet", "PlannedOrder", "OrderPlan",
68
+ "snapshot_from_broker", "infer_intent_from_backtest", "plan_order",
69
+ "evaluate_risk", "plans_from_strategy_results",
70
+ "BrokerCapability", "broker_connection_plan", "broker_dependency_state",
71
+ "broker_service_playbook", "filter_capabilities", "get_broker_capability",
72
+ "list_broker_capabilities",
73
+ "PaperBroker", "reset_paper_account",
74
+ "OrderIntent", "TradingPolicy", "build_order_preview", "execute_order_preview",
75
+ "list_order_previews", "load_order_preview", "policy_from_config", "resolve_trading_mode",
76
+ "global_dry_run",
77
+ "AutoExecutePolicy", "AutoExecuteDecision", "evaluate_auto_execute", "run_auto_execute",
78
+ ]