aria-code 0.167.0__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (601) hide show
  1. aria_bots/__init__.py +7 -0
  2. aria_bots/channels/README.md +97 -0
  3. aria_bots/channels/__init__.py +1 -0
  4. aria_bots/channels/approvals.py +263 -0
  5. aria_bots/channels/conversation.py +280 -0
  6. aria_bots/channels/digest.py +186 -0
  7. aria_bots/channels/registry.py +95 -0
  8. aria_bots/engine.py +144 -0
  9. aria_bots/feishu_bot.py +1385 -0
  10. aria_bots/logistics/__init__.py +1 -0
  11. aria_bots/logistics/carriers.py +253 -0
  12. aria_bots/logistics/freight.py +154 -0
  13. aria_bots/logistics/inventory.py +242 -0
  14. aria_bots/logistics/mcp_server.py +156 -0
  15. aria_bots/logistics/records.py +119 -0
  16. aria_bots/logistics/tenancy.py +152 -0
  17. aria_bots/market.py +91 -0
  18. aria_bots/relay_client.py +326 -0
  19. aria_bots/telegram_bot.py +299 -0
  20. aria_code/__init__.py +111 -0
  21. aria_code/_bin/aria-native.exe +0 -0
  22. aria_code/_bin/aria-runtime.exe +0 -0
  23. aria_code/_version.py +20 -0
  24. aria_code/account_memory.py +296 -0
  25. aria_code/account_session.py +166 -0
  26. aria_code/adk_apps/__init__.py +1 -0
  27. aria_code/adk_apps/aria_code_review/__init__.py +1 -0
  28. aria_code/adk_apps/aria_code_review/agent.py +32 -0
  29. aria_code/adk_apps/aria_research/__init__.py +1 -0
  30. aria_code/adk_apps/aria_research/agent.py +31 -0
  31. aria_code/agents/__init__.py +49 -0
  32. aria_code/agents/base.py +329 -0
  33. aria_code/agents/code_review.py +200 -0
  34. aria_code/agents/deep/__init__.py +37 -0
  35. aria_code/agents/deep/calibration_loop.py +144 -0
  36. aria_code/agents/deep/critic.py +125 -0
  37. aria_code/agents/deep/deepen.py +193 -0
  38. aria_code/agents/deep/models.py +149 -0
  39. aria_code/agents/deep/pipeline.py +164 -0
  40. aria_code/agents/deep/quant_fusion.py +192 -0
  41. aria_code/agents/deep/themes.py +95 -0
  42. aria_code/agents/deep/tiers.py +106 -0
  43. aria_code/agents/engineering/__init__.py +14 -0
  44. aria_code/agents/engineering/coder.py +222 -0
  45. aria_code/agents/engineering/tester.py +145 -0
  46. aria_code/agents/financial/__init__.py +21 -0
  47. aria_code/agents/financial/cashflow_burn.py +119 -0
  48. aria_code/agents/financial/catalyst.py +279 -0
  49. aria_code/agents/financial/corporate_finance.py +175 -0
  50. aria_code/agents/financial/debate.py +224 -0
  51. aria_code/agents/financial/earnings.py +315 -0
  52. aria_code/agents/financial/fundamental.py +178 -0
  53. aria_code/agents/financial/macro.py +111 -0
  54. aria_code/agents/financial/news.py +231 -0
  55. aria_code/agents/financial/risk.py +146 -0
  56. aria_code/agents/financial/sector.py +279 -0
  57. aria_code/agents/financial/strategist.py +121 -0
  58. aria_code/agents/financial/stripe_revenue.py +127 -0
  59. aria_code/agents/financial/synthesis.py +274 -0
  60. aria_code/agents/financial/technical.py +277 -0
  61. aria_code/agents/orchestrator.py +44 -0
  62. aria_code/agents/portfolio_agent.py +392 -0
  63. aria_code/agents/realty/__init__.py +62 -0
  64. aria_code/agents/realty/asset_diagnosis.py +152 -0
  65. aria_code/agents/realty/business_match.py +166 -0
  66. aria_code/agents/realty/cashflow_verify.py +209 -0
  67. aria_code/agents/realty/contract_rules.py +210 -0
  68. aria_code/agents/realty/energy_anomaly.py +189 -0
  69. aria_code/agents/realty/exit_settlement.py +208 -0
  70. aria_code/agents/realty/fulfillment_risk.py +206 -0
  71. aria_code/agents/realty/ops_optimize.py +160 -0
  72. aria_code/agents/realty/revenue_share.py +215 -0
  73. aria_code/agents/registry.py +168 -0
  74. aria_code/agents/signal_scheme.py +111 -0
  75. aria_code/agents/sports/__init__.py +0 -0
  76. aria_code/agents/sports/football_agent.py +197 -0
  77. aria_code/agents/supervisor.py +113 -0
  78. aria_code/agents/team.py +500 -0
  79. aria_code/agents/video/__init__.py +16 -0
  80. aria_code/agents/video/director.py +376 -0
  81. aria_code/agents/video/qa_agent.py +143 -0
  82. aria_code/agents/video/script_doctor.py +112 -0
  83. aria_code/agents/warehouse/__init__.py +25 -0
  84. aria_code/agents/warehouse/contracts.py +26 -0
  85. aria_code/agents/warehouse/dashboard.py +155 -0
  86. aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
  87. aria_code/agents/warehouse/inbound_exceptions.py +25 -0
  88. aria_code/agents/warehouse/inventory_health.py +24 -0
  89. aria_code/agents/warehouse/local_run.py +71 -0
  90. aria_code/agents/warehouse/local_snapshot.py +132 -0
  91. aria_code/agents/warehouse/logistics_cost.py +84 -0
  92. aria_code/agents/warehouse/logistics_sync.py +21 -0
  93. aria_code/agents/warehouse/navigation.schema.json +110 -0
  94. aria_code/agents/warehouse/task_agent.py +172 -0
  95. aria_code/agents/warehouse/workflow.py +31 -0
  96. aria_code/aliyun_data_client.py +4 -0
  97. aria_code/apps/README.md +12 -0
  98. aria_code/apps/__init__.py +2 -0
  99. aria_code/apps/channels/README.md +9 -0
  100. aria_code/apps/channels/__init__.py +17 -0
  101. aria_code/apps/channels/approvals.py +11 -0
  102. aria_code/apps/channels/conversation.py +11 -0
  103. aria_code/apps/channels/digest.py +11 -0
  104. aria_code/apps/channels/intake.py +92 -0
  105. aria_code/apps/channels/registry.py +11 -0
  106. aria_code/apps/channels/tradingview.py +94 -0
  107. aria_code/apps/cli/README.md +13 -0
  108. aria_code/apps/cli/__init__.py +2 -0
  109. aria_code/apps/cli/_optional.py +120 -0
  110. aria_code/apps/cli/app_server.py +656 -0
  111. aria_code/apps/cli/auto_update.py +125 -0
  112. aria_code/apps/cli/bootstrap.py +206 -0
  113. aria_code/apps/cli/broker_render.py +206 -0
  114. aria_code/apps/cli/chat_turn.py +1327 -0
  115. aria_code/apps/cli/cloud_models.py +231 -0
  116. aria_code/apps/cli/codegen_paths.py +29 -0
  117. aria_code/apps/cli/commands/__init__.py +34 -0
  118. aria_code/apps/cli/commands/_business_render.py +78 -0
  119. aria_code/apps/cli/commands/_ui.py +71 -0
  120. aria_code/apps/cli/commands/analysis_cmds.py +378 -0
  121. aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
  122. aria_code/apps/cli/commands/auth_cmds.py +215 -0
  123. aria_code/apps/cli/commands/backtest_cmds.py +2518 -0
  124. aria_code/apps/cli/commands/broker_cmds.py +1236 -0
  125. aria_code/apps/cli/commands/business_workflow_cmds.py +379 -0
  126. aria_code/apps/cli/commands/canvas_cmds.py +77 -0
  127. aria_code/apps/cli/commands/catalog.py +189 -0
  128. aria_code/apps/cli/commands/core_cmds.py +2748 -0
  129. aria_code/apps/cli/commands/data_cmds.py +521 -0
  130. aria_code/apps/cli/commands/diagnostic_cmds.py +285 -0
  131. aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
  132. aria_code/apps/cli/commands/engineering_cmds.py +399 -0
  133. aria_code/apps/cli/commands/file_cmds.py +312 -0
  134. aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
  135. aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
  136. aria_code/apps/cli/commands/market.py +544 -0
  137. aria_code/apps/cli/commands/market_cmds.py +1419 -0
  138. aria_code/apps/cli/commands/market_context.py +432 -0
  139. aria_code/apps/cli/commands/market_render.py +7 -0
  140. aria_code/apps/cli/commands/model_cmds.py +2374 -0
  141. aria_code/apps/cli/commands/ops_cmds.py +721 -0
  142. aria_code/apps/cli/commands/orchestrator_cmds.py +181 -0
  143. aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
  144. aria_code/apps/cli/commands/portfolio_cmds.py +1316 -0
  145. aria_code/apps/cli/commands/report.py +476 -0
  146. aria_code/apps/cli/commands/scaffold_templates.py +617 -0
  147. aria_code/apps/cli/commands/session_cmds.py +236 -0
  148. aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
  149. aria_code/apps/cli/commands/team.py +723 -0
  150. aria_code/apps/cli/commands/team_render.py +8 -0
  151. aria_code/apps/cli/commands/ui_cmds.py +401 -0
  152. aria_code/apps/cli/commands/warehouse_cmds.py +297 -0
  153. aria_code/apps/cli/commands/workflow_cmds.py +629 -0
  154. aria_code/apps/cli/commands/workspace_cmds.py +1543 -0
  155. aria_code/apps/cli/config_paths.py +73 -0
  156. aria_code/apps/cli/config_store.py +158 -0
  157. aria_code/apps/cli/constants.py +88 -0
  158. aria_code/apps/cli/context.py +34 -0
  159. aria_code/apps/cli/conversation_policy.py +53 -0
  160. aria_code/apps/cli/deterministic.py +200 -0
  161. aria_code/apps/cli/direct.py +48 -0
  162. aria_code/apps/cli/earnings_view.py +172 -0
  163. aria_code/apps/cli/endpoint_migration.py +64 -0
  164. aria_code/apps/cli/exec_events.py +255 -0
  165. aria_code/apps/cli/file_references.py +155 -0
  166. aria_code/apps/cli/finance_service_catalog.py +111 -0
  167. aria_code/apps/cli/football_reports.py +231 -0
  168. aria_code/apps/cli/github_app_auth.py +135 -0
  169. aria_code/apps/cli/google_login.py +239 -0
  170. aria_code/apps/cli/handlers/__init__.py +11 -0
  171. aria_code/apps/cli/handlers/broker_handlers.py +122 -0
  172. aria_code/apps/cli/handlers/chart_handlers.py +1314 -0
  173. aria_code/apps/cli/handlers/market_handlers.py +2570 -0
  174. aria_code/apps/cli/handlers/realty_handlers.py +114 -0
  175. aria_code/apps/cli/handlers/sports_handlers.py +22 -0
  176. aria_code/apps/cli/handlers/strategy_advice.py +82 -0
  177. aria_code/apps/cli/headless.py +352 -0
  178. aria_code/apps/cli/helpers.py +326 -0
  179. aria_code/apps/cli/hooks.py +180 -0
  180. aria_code/apps/cli/i18n.py +310 -0
  181. aria_code/apps/cli/intent.py +136 -0
  182. aria_code/apps/cli/intent_router.py +305 -0
  183. aria_code/apps/cli/intent_shadow.py +72 -0
  184. aria_code/apps/cli/intent_signals.py +347 -0
  185. aria_code/apps/cli/lifecycle_hooks.py +48 -0
  186. aria_code/apps/cli/local_tool_schemas.py +550 -0
  187. aria_code/apps/cli/main.py +39 -0
  188. aria_code/apps/cli/market_hours.py +100 -0
  189. aria_code/apps/cli/market_metadata.py +135 -0
  190. aria_code/apps/cli/market_universe.py +487 -0
  191. aria_code/apps/cli/message_processing.py +310 -0
  192. aria_code/apps/cli/mixin_binding.py +32 -0
  193. aria_code/apps/cli/model_catalog.py +652 -0
  194. aria_code/apps/cli/model_probe.py +169 -0
  195. aria_code/apps/cli/model_retirement.py +65 -0
  196. aria_code/apps/cli/native_branding.py +12 -0
  197. aria_code/apps/cli/native_bridge.py +118 -0
  198. aria_code/apps/cli/native_entry.py +58 -0
  199. aria_code/apps/cli/pdf_report.py +977 -0
  200. aria_code/apps/cli/plan_mode.py +139 -0
  201. aria_code/apps/cli/plotly_html.py +15 -0
  202. aria_code/apps/cli/prediction_feedback.py +202 -0
  203. aria_code/apps/cli/preflight.py +502 -0
  204. aria_code/apps/cli/project_aria.py +60 -0
  205. aria_code/apps/cli/prompt_assembly.py +78 -0
  206. aria_code/apps/cli/prompts/__init__.py +0 -0
  207. aria_code/apps/cli/prompts/coding.py +71 -0
  208. aria_code/apps/cli/prompts/select.py +193 -0
  209. aria_code/apps/cli/prompts/system_prompts.py +562 -0
  210. aria_code/apps/cli/prompts/ui.py +436 -0
  211. aria_code/apps/cli/provider_endpoints.py +237 -0
  212. aria_code/apps/cli/provider_keys.py +73 -0
  213. aria_code/apps/cli/providers/__init__.py +1 -0
  214. aria_code/apps/cli/providers/base.py +775 -0
  215. aria_code/apps/cli/providers/chat_routing.py +139 -0
  216. aria_code/apps/cli/providers/collaboration.py +98 -0
  217. aria_code/apps/cli/providers/llm/__init__.py +1 -0
  218. aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
  219. aria_code/apps/cli/providers/llm/ollama_stream.py +1574 -0
  220. aria_code/apps/cli/providers/llm/response_cache.py +60 -0
  221. aria_code/apps/cli/providers/llm/sse_stream.py +298 -0
  222. aria_code/apps/cli/providers/runtime_bridge.py +586 -0
  223. aria_code/apps/cli/providers/vertexai_stream.py +592 -0
  224. aria_code/apps/cli/release_download.py +159 -0
  225. aria_code/apps/cli/review_runner.py +111 -0
  226. aria_code/apps/cli/runtime_consumer.py +769 -0
  227. aria_code/apps/cli/sandbox.py +32 -0
  228. aria_code/apps/cli/session_export.py +120 -0
  229. aria_code/apps/cli/session_jsonl.py +208 -0
  230. aria_code/apps/cli/session_refresh.py +123 -0
  231. aria_code/apps/cli/session_store.py +125 -0
  232. aria_code/apps/cli/skills_catalog.py +273 -0
  233. aria_code/apps/cli/task_isolation.py +211 -0
  234. aria_code/apps/cli/terminal_chrome.py +412 -0
  235. aria_code/apps/cli/todo_tracker.py +190 -0
  236. aria_code/apps/cli/tool_executor.py +932 -0
  237. aria_code/apps/cli/tool_registry.py +34 -0
  238. aria_code/apps/cli/tool_scope.py +113 -0
  239. aria_code/apps/cli/tools/__init__.py +40 -0
  240. aria_code/apps/cli/tools/context.py +46 -0
  241. aria_code/apps/cli/tools/file_tools.py +181 -0
  242. aria_code/apps/cli/tools/market_tools.py +626 -0
  243. aria_code/apps/cli/tools/notebook_tools.py +111 -0
  244. aria_code/apps/cli/tools/system_tools.py +656 -0
  245. aria_code/apps/cli/tools/write_tools.py +961 -0
  246. aria_code/apps/cli/tradingview_bridge.py +529 -0
  247. aria_code/apps/cli/transactions.py +269 -0
  248. aria_code/apps/cli/turn_planning.py +137 -0
  249. aria_code/apps/cli/update_check.py +257 -0
  250. aria_code/apps/cli/updater.py +373 -0
  251. aria_code/apps/cli/utils/__init__.py +0 -0
  252. aria_code/apps/cli/utils/market_detect.py +1663 -0
  253. aria_code/apps/cli/web_login.py +136 -0
  254. aria_code/apps/cli/workflow_runner.py +127 -0
  255. aria_code/apps/cli/workspace_route.py +121 -0
  256. aria_code/apps/daemon/README.md +14 -0
  257. aria_code/apps/vscode/README.md +115 -0
  258. aria_code/apps/vscode/package.json +70 -0
  259. aria_code/aria_cli.py +5244 -0
  260. aria_code/aria_daemon.py +1372 -0
  261. aria_code/aria_feishu_bot.py +16 -0
  262. aria_code/aria_mcp_server.py +61 -0
  263. aria_code/aria_relay_client.py +4 -0
  264. aria_code/aria_telegram_bot.py +11 -0
  265. aria_code/ariarc.py +385 -0
  266. aria_code/artifacts.py +581 -0
  267. aria_code/backtest_engine.py +4 -0
  268. aria_code/backtest_report.py +4 -0
  269. aria_code/brokers/__init__.py +78 -0
  270. aria_code/brokers/automation.py +193 -0
  271. aria_code/brokers/base.py +231 -0
  272. aria_code/brokers/capabilities.py +264 -0
  273. aria_code/brokers/cn/__init__.py +10 -0
  274. aria_code/brokers/cn/easytrader_broker.py +193 -0
  275. aria_code/brokers/cn/futu_broker.py +194 -0
  276. aria_code/brokers/cn/longbridge_broker.py +190 -0
  277. aria_code/brokers/cn/tiger_broker.py +196 -0
  278. aria_code/brokers/cn/xtquant_broker.py +225 -0
  279. aria_code/brokers/config.py +414 -0
  280. aria_code/brokers/intl/__init__.py +5 -0
  281. aria_code/brokers/intl/alpaca_broker.py +183 -0
  282. aria_code/brokers/intl/ibkr_broker.py +215 -0
  283. aria_code/brokers/intl/trading212_broker.py +183 -0
  284. aria_code/brokers/intl/webull_broker.py +156 -0
  285. aria_code/brokers/paper_broker.py +266 -0
  286. aria_code/brokers/planning.py +296 -0
  287. aria_code/brokers/registry.py +213 -0
  288. aria_code/brokers/trading.py +267 -0
  289. aria_code/canva_client.py +4 -0
  290. aria_code/change_store.py +127 -0
  291. aria_code/clients/__init__.py +0 -0
  292. aria_code/clients/aliyun_data_client.py +660 -0
  293. aria_code/clients/aria_relay_client.py +16 -0
  294. aria_code/clients/canva_client.py +284 -0
  295. aria_code/clients/figma_client.py +100 -0
  296. aria_code/clients/football_data_client.py +1671 -0
  297. aria_code/clients/kling_video_client.py +182 -0
  298. aria_code/clients/market_data_client.py +1985 -0
  299. aria_code/clients/openai_image_client.py +242 -0
  300. aria_code/clients/runway_video_client.py +157 -0
  301. aria_code/clients/warehouse_erp_client.py +105 -0
  302. aria_code/cloud_memory.py +190 -0
  303. aria_code/command_safety.py +19 -0
  304. aria_code/computer_use_server.py +276 -0
  305. aria_code/computer_use_tools.py +4 -0
  306. aria_code/dashboard_generator.py +579 -0
  307. aria_code/data_analysis_tools.py +4 -0
  308. aria_code/data_cleaner.py +483 -0
  309. aria_code/data_service.py +513 -0
  310. aria_code/datasources/__init__.py +23 -0
  311. aria_code/datasources/base.py +166 -0
  312. aria_code/datasources/router.py +253 -0
  313. aria_code/datasources/sec_statements.py +217 -0
  314. aria_code/datasources/sources/__init__.py +15 -0
  315. aria_code/datasources/sources/akshare_source.py +269 -0
  316. aria_code/datasources/sources/alpha_vantage_source.py +203 -0
  317. aria_code/datasources/sources/edgar_source.py +219 -0
  318. aria_code/datasources/sources/finnhub_source.py +198 -0
  319. aria_code/datasources/sources/fred_source.py +223 -0
  320. aria_code/datasources/sources/tushare_source.py +143 -0
  321. aria_code/datasources/sources/web_scraper_source.py +278 -0
  322. aria_code/datasources/sources/world_bank_source.py +206 -0
  323. aria_code/datasources/sources/yfinance_source.py +152 -0
  324. aria_code/doctor.py +860 -0
  325. aria_code/domain/__init__.py +0 -0
  326. aria_code/domain/_finance_core/__init__.py +5 -0
  327. aria_code/domain/_finance_core/backtest_engine.py +325 -0
  328. aria_code/domain/_finance_core/performance_stats.py +101 -0
  329. aria_code/domain/backtest_engine.py +75 -0
  330. aria_code/domain/backtest_report.py +488 -0
  331. aria_code/domain/finance_formulas.py +389 -0
  332. aria_code/domain/performance_stats.py +6 -0
  333. aria_code/domain/portfolio_ledger.py +307 -0
  334. aria_code/domain/strategy_vault.py +421 -0
  335. aria_code/evals/__init__.py +37 -0
  336. aria_code/evals/behavior.py +113 -0
  337. aria_code/evals/gap.py +93 -0
  338. aria_code/evals/harness.py +949 -0
  339. aria_code/evals/review_probe.py +132 -0
  340. aria_code/evals/runner.py +425 -0
  341. aria_code/evals/scorecard.py +322 -0
  342. aria_code/evals/summary.py +125 -0
  343. aria_code/external_agent_runner.py +115 -0
  344. aria_code/figma_client.py +4 -0
  345. aria_code/file_analysis_tools.py +4 -0
  346. aria_code/finance_formulas.py +4 -0
  347. aria_code/football_data_client.py +4 -0
  348. aria_code/image_gen_tools.py +4 -0
  349. aria_code/intent_classifier.py +459 -0
  350. aria_code/kling_video_client.py +4 -0
  351. aria_code/licensing.py +151 -0
  352. aria_code/local_finance_tools.py +4 -0
  353. aria_code/local_image_provider.py +4 -0
  354. aria_code/local_llm_provider.py +4 -0
  355. aria_code/macro_tools.py +4 -0
  356. aria_code/markdown_pdf.py +289 -0
  357. aria_code/market_data_client.py +4 -0
  358. aria_code/mcp_client.py +744 -0
  359. aria_code/memory_manager.py +273 -0
  360. aria_code/model_capability.py +512 -0
  361. aria_code/notification_tools.py +4 -0
  362. aria_code/openai_image_client.py +4 -0
  363. aria_code/packages/__init__.py +26 -0
  364. aria_code/packages/adk_bridge/__init__.py +11 -0
  365. aria_code/packages/adk_bridge/code_review_tools.py +49 -0
  366. aria_code/packages/adk_bridge/market_tools.py +125 -0
  367. aria_code/packages/aria_agents/__init__.py +5 -0
  368. aria_code/packages/aria_agents/manifest.py +78 -0
  369. aria_code/packages/aria_core/__init__.py +34 -0
  370. aria_code/packages/aria_core/architecture.py +269 -0
  371. aria_code/packages/aria_core/export.py +147 -0
  372. aria_code/packages/aria_core/manifest.py +65 -0
  373. aria_code/packages/aria_core/paths.py +57 -0
  374. aria_code/packages/aria_core/secure_file.py +68 -0
  375. aria_code/packages/aria_infra/__init__.py +15 -0
  376. aria_code/packages/aria_infra/arthera.py +58 -0
  377. aria_code/packages/aria_infra/doctor.py +246 -0
  378. aria_code/packages/aria_infra/product.py +40 -0
  379. aria_code/packages/aria_mcp/__init__.py +25 -0
  380. aria_code/packages/aria_mcp/bridge.py +232 -0
  381. aria_code/packages/aria_mcp/circuit.py +82 -0
  382. aria_code/packages/aria_mcp/config.py +162 -0
  383. aria_code/packages/aria_mcp/installer.py +95 -0
  384. aria_code/packages/aria_mcp/server.py +1705 -0
  385. aria_code/packages/aria_mcp/tools.py +81 -0
  386. aria_code/packages/aria_sdk/__init__.py +19 -0
  387. aria_code/packages/aria_sdk/client.py +393 -0
  388. aria_code/packages/aria_sdk/providers.py +70 -0
  389. aria_code/packages/aria_sdk/streaming.py +75 -0
  390. aria_code/packages/aria_sdk/types.py +86 -0
  391. aria_code/packages/aria_services/__init__.py +92 -0
  392. aria_code/packages/aria_services/cache.py +60 -0
  393. aria_code/packages/aria_services/context.py +356 -0
  394. aria_code/packages/aria_services/context_checkpoints.py +157 -0
  395. aria_code/packages/aria_services/data.py +11 -0
  396. aria_code/packages/aria_services/provider_health.py +304 -0
  397. aria_code/packages/aria_services/references.py +247 -0
  398. aria_code/packages/aria_services/registry.py +249 -0
  399. aria_code/packages/aria_services/research_protocol.py +137 -0
  400. aria_code/packages/aria_services/research_quality.py +186 -0
  401. aria_code/packages/aria_services/settings.py +160 -0
  402. aria_code/packages/aria_services/usage.py +151 -0
  403. aria_code/packages/aria_skills/__init__.py +46 -0
  404. aria_code/packages/aria_skills/catalog.py +149 -0
  405. aria_code/packages/aria_skills/loader.py +455 -0
  406. aria_code/packages/aria_skills/registry.py +84 -0
  407. aria_code/packages/aria_tools/__init__.py +5 -0
  408. aria_code/packages/aria_tools/financial/__init__.py +5 -0
  409. aria_code/packages/aria_tools/financial/_paths.py +92 -0
  410. aria_code/packages/aria_tools/registry.py +129 -0
  411. aria_code/packages/quant_engine/__init__.py +33 -0
  412. aria_code/packages/quant_engine/_namespace.py +24 -0
  413. aria_code/packages/quant_engine/backtest/__init__.py +10 -0
  414. aria_code/packages/quant_engine/backtest/core.py +53 -0
  415. aria_code/packages/quant_engine/backtest/engine.py +102 -0
  416. aria_code/packages/quant_engine/portfolio/__init__.py +9 -0
  417. aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
  418. aria_code/packages/quant_engine/sports/__init__.py +76 -0
  419. aria_code/packages/quant_engine/sports/calibrator.py +354 -0
  420. aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
  421. aria_code/packages/quant_engine/sports/elo.py +300 -0
  422. aria_code/packages/quant_engine/sports/form.py +188 -0
  423. aria_code/packages/quant_engine/sports/h2h.py +195 -0
  424. aria_code/packages/quant_engine/sports/predictor.py +312 -0
  425. aria_code/packages/quant_engine/sports/tracker.py +665 -0
  426. aria_code/packages/quant_engine/stochastic/__init__.py +31 -0
  427. aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
  428. aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
  429. aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
  430. aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
  431. aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
  432. aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
  433. aria_code/packs/__init__.py +85 -0
  434. aria_code/packs/base.py +168 -0
  435. aria_code/packs/finance/__init__.py +250 -0
  436. aria_code/packs/healthcare/__init__.py +40 -0
  437. aria_code/packs/logistics/__init__.py +171 -0
  438. aria_code/packs/payments/__init__.py +139 -0
  439. aria_code/packs/realty/__init__.py +190 -0
  440. aria_code/packs/registry.py +202 -0
  441. aria_code/packs/rules.py +90 -0
  442. aria_code/plan_utils.py +194 -0
  443. aria_code/plugin_loader.py +328 -0
  444. aria_code/portfolio_ledger.py +4 -0
  445. aria_code/preview_server.py +449 -0
  446. aria_code/privacy/__init__.py +5 -0
  447. aria_code/privacy/feedback.py +123 -0
  448. aria_code/project_review.py +278 -0
  449. aria_code/project_review_api.py +235 -0
  450. aria_code/project_review_server.py +18 -0
  451. aria_code/project_tools.py +4 -0
  452. aria_code/providers/__init__.py +30 -0
  453. aria_code/providers/google_video_provider.py +256 -0
  454. aria_code/providers/llm/__init__.py +19 -0
  455. aria_code/providers/llm/anthropic.py +184 -0
  456. aria_code/providers/llm/arthera_gateway.py +90 -0
  457. aria_code/providers/llm/autoconfig.py +213 -0
  458. aria_code/providers/llm/base.py +139 -0
  459. aria_code/providers/llm/custom.py +158 -0
  460. aria_code/providers/llm/ollama.py +137 -0
  461. aria_code/providers/llm/openai_compat.py +350 -0
  462. aria_code/providers/llm/registry.py +457 -0
  463. aria_code/providers/local_image_provider.py +202 -0
  464. aria_code/providers/local_llm_provider.py +549 -0
  465. aria_code/providers/ollama_models.py +79 -0
  466. aria_code/providers/openai_params.py +32 -0
  467. aria_code/providers/tool_messages.py +100 -0
  468. aria_code/realty_data_tools.py +4 -0
  469. aria_code/report_exporters.py +150 -0
  470. aria_code/report_generator.py +1764 -0
  471. aria_code/review_service.py +497 -0
  472. aria_code/runtime/__init__.py +176 -0
  473. aria_code/runtime/acceptance.py +632 -0
  474. aria_code/runtime/agent_loop.py +1851 -0
  475. aria_code/runtime/agent_profiles.py +75 -0
  476. aria_code/runtime/approval.py +71 -0
  477. aria_code/runtime/baseline.py +219 -0
  478. aria_code/runtime/budget.py +232 -0
  479. aria_code/runtime/checkpoints.py +481 -0
  480. aria_code/runtime/consult.py +65 -0
  481. aria_code/runtime/contract.py +282 -0
  482. aria_code/runtime/delivery.py +432 -0
  483. aria_code/runtime/events.py +113 -0
  484. aria_code/runtime/gateway.py +167 -0
  485. aria_code/runtime/lsp.py +484 -0
  486. aria_code/runtime/native_index.py +153 -0
  487. aria_code/runtime/orchestrator.py +55 -0
  488. aria_code/runtime/processes.py +343 -0
  489. aria_code/runtime/project_graph.py +614 -0
  490. aria_code/runtime/repo_map.py +712 -0
  491. aria_code/runtime/research_bundle.py +105 -0
  492. aria_code/runtime/review.py +269 -0
  493. aria_code/runtime/run_state.py +127 -0
  494. aria_code/runtime/run_store.py +522 -0
  495. aria_code/runtime/scoped_runs.py +113 -0
  496. aria_code/runtime/self_healing.py +422 -0
  497. aria_code/runtime/semantic_diff.py +171 -0
  498. aria_code/runtime/subagent.py +721 -0
  499. aria_code/runtime/symbol_edit.py +117 -0
  500. aria_code/runtime/task_brief.py +46 -0
  501. aria_code/runtime/task_context.py +145 -0
  502. aria_code/runtime/task_ledger.py +108 -0
  503. aria_code/runtime/task_orchestrator.py +90 -0
  504. aria_code/runtime/task_outcome.py +33 -0
  505. aria_code/runtime/task_verification.py +266 -0
  506. aria_code/runtime/task_worktree.py +448 -0
  507. aria_code/runtime/tool_executor.py +329 -0
  508. aria_code/runtime/tool_policy.py +107 -0
  509. aria_code/runtime/transactions.py +216 -0
  510. aria_code/runtime/windows_job.py +115 -0
  511. aria_code/runtime/workflows.py +222 -0
  512. aria_code/runtime/worktrees.py +215 -0
  513. aria_code/runway_video_client.py +4 -0
  514. aria_code/safety/__init__.py +27 -0
  515. aria_code/safety/client_isolation.py +178 -0
  516. aria_code/safety/permissions.py +339 -0
  517. aria_code/safety/risk.py +699 -0
  518. aria_code/safety/sandbox.py +148 -0
  519. aria_code/safety/service.py +102 -0
  520. aria_code/service_endpoints.py +14 -0
  521. aria_code/setup_wizard.py +684 -0
  522. aria_code/spreadsheet_tools.py +4 -0
  523. aria_code/strategy_vault.py +4 -0
  524. aria_code/tools/__init__.py +0 -0
  525. aria_code/tools/artifact_tools.py +252 -0
  526. aria_code/tools/broker_tools.py +92 -0
  527. aria_code/tools/build_quant_engine.py +97 -0
  528. aria_code/tools/code_audit_tools.py +192 -0
  529. aria_code/tools/computer_use_tools.py +509 -0
  530. aria_code/tools/data_analysis_tools.py +831 -0
  531. aria_code/tools/enterprise_finance_tools.py +202 -0
  532. aria_code/tools/extended_tools.py +240 -0
  533. aria_code/tools/file_analysis_tools.py +880 -0
  534. aria_code/tools/image_gen_tools.py +114 -0
  535. aria_code/tools/local_finance_tools.py +3488 -0
  536. aria_code/tools/logistics_carriers.py +11 -0
  537. aria_code/tools/logistics_inventory.py +11 -0
  538. aria_code/tools/logistics_io.py +11 -0
  539. aria_code/tools/logistics_tenancy.py +11 -0
  540. aria_code/tools/logistics_tools.py +11 -0
  541. aria_code/tools/macro_tools.py +412 -0
  542. aria_code/tools/notification_tools.py +249 -0
  543. aria_code/tools/project_tools.py +525 -0
  544. aria_code/tools/realty_data_tools.py +662 -0
  545. aria_code/tools/spreadsheet_tools.py +399 -0
  546. aria_code/tools/stripe_tools.py +115 -0
  547. aria_code/tools/video_tools.py +500 -0
  548. aria_code/training/__init__.py +1 -0
  549. aria_code/training/compare.py +117 -0
  550. aria_code/training/prelude_commands.py +111 -0
  551. aria_code/training/prelude_eval.py +390 -0
  552. aria_code/training/prelude_real.py +183 -0
  553. aria_code/training/prelude_train.py +248 -0
  554. aria_code/training/sft_dataset.py +230 -0
  555. aria_code/training/trajectory_dataset.py +263 -0
  556. aria_code/ui/__init__.py +105 -0
  557. aria_code/ui/banner.py +404 -0
  558. aria_code/ui/completer.py +571 -0
  559. aria_code/ui/console.py +285 -0
  560. aria_code/ui/input_box.py +505 -0
  561. aria_code/ui/mentions.py +206 -0
  562. aria_code/ui/picker.py +248 -0
  563. aria_code/ui/render/__init__.py +11 -0
  564. aria_code/ui/render/actions.py +297 -0
  565. aria_code/ui/render/finance.py +1732 -0
  566. aria_code/ui/render/market.py +253 -0
  567. aria_code/ui/render/output.py +954 -0
  568. aria_code/ui/render/responsive.py +75 -0
  569. aria_code/ui/render/team.py +367 -0
  570. aria_code/ui/robot.py +239 -0
  571. aria_code/ui/startup_dashboard.py +110 -0
  572. aria_code/video_analysis.py +147 -0
  573. aria_code/video_editor.py +518 -0
  574. aria_code/video_workflow/__init__.py +8 -0
  575. aria_code/video_workflow/__main__.py +61 -0
  576. aria_code/video_workflow/engines/__init__.py +18 -0
  577. aria_code/video_workflow/engines/base.py +69 -0
  578. aria_code/video_workflow/engines/custom_model.py +204 -0
  579. aria_code/video_workflow/engines/google_veo.py +94 -0
  580. aria_code/video_workflow/engines/local_engine.py +71 -0
  581. aria_code/video_workflow/engines/registry.py +98 -0
  582. aria_code/video_workflow/google_models.py +278 -0
  583. aria_code/video_workflow/music/__init__.py +5 -0
  584. aria_code/video_workflow/music/foley_service.py +132 -0
  585. aria_code/video_workflow/music/service.py +212 -0
  586. aria_code/video_workflow/pipeline.py +620 -0
  587. aria_code/video_workflow/plan.py +202 -0
  588. aria_code/video_workflow/session.py +297 -0
  589. aria_code/workspace/__init__.py +6 -0
  590. aria_code/workspace/files.py +219 -0
  591. aria_code/workspace/verify.py +167 -0
  592. aria_code/workspace_changes.py +199 -0
  593. aria_code/workspace_service.py +196 -0
  594. aria_code/workspace_tools.py +150 -0
  595. aria_code-0.167.0.dist-info/METADATA +330 -0
  596. aria_code-0.167.0.dist-info/RECORD +601 -0
  597. aria_code-0.167.0.dist-info/WHEEL +5 -0
  598. aria_code-0.167.0.dist-info/entry_points.txt +5 -0
  599. aria_code-0.167.0.dist-info/licenses/LICENSE +201 -0
  600. aria_code-0.167.0.dist-info/licenses/NOTICE +49 -0
  601. aria_code-0.167.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,497 @@
1
+ """Code review as a service: one target, one isolated reviewer, structured findings.
2
+
3
+ Shared by the interactive ``/review`` command and the headless
4
+ ``aria-code review`` used in CI. The design follows the review flow of
5
+ OpenAI's Codex CLI (Apache-2.0):
6
+
7
+ - **A named target.** Uncommitted changes (tracked *and* untracked), staged
8
+ changes, everything since the merge base with a branch, one commit, or one
9
+ file. The old ``/review`` saw ``git diff HEAD`` only, so new files were never
10
+ reviewed, and a branch could not be reviewed against ``main`` at all.
11
+ - **An isolated reviewer.** The model gets the rubric, the project's own rules
12
+ and the change — no conversation history and no tools — so a review cannot
13
+ run commands, edit files, or lean on earlier chat.
14
+ - **Structured output.** Every finding has a priority (P0–P3), a confidence and
15
+ a file + line range; the review ends with an overall verdict. Parsing
16
+ degrades in steps (JSON → the first ``{…}`` in the text → the text as the
17
+ explanation), so a model that drifts from the format still yields a review.
18
+ - **Nothing hidden.** A change too large for one review is cut at a file
19
+ boundary and the reviewer is told which files it did not see; the old
20
+ command truncated silently at 12,000 characters.
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ import json
26
+ import re
27
+ import subprocess
28
+ from dataclasses import asdict, dataclass, field
29
+ from pathlib import Path
30
+ from typing import Awaitable, Callable, Iterable
31
+
32
+ PRIORITIES = ("P0", "P1", "P2", "P3")
33
+ DEFAULT_MAX_CHARS = 60_000
34
+ MAX_UNTRACKED_FILES = 40
35
+ MAX_UNTRACKED_BYTES = 200_000
36
+ PROJECT_RULE_FILES = ("AGENTS.override.md", "AGENTS.md", "ARIA.md")
37
+ MAX_RULE_CHARS = 8_000
38
+
39
+
40
+ class ReviewError(RuntimeError):
41
+ """The review could not be prepared or run (not a git repo, unknown branch, model failure)."""
42
+
43
+
44
+ # ── Target and input ─────────────────────────────────────────────────────────
45
+
46
+ @dataclass(frozen=True)
47
+ class ReviewTarget:
48
+ kind: str # uncommitted | staged | base | commit | file
49
+ value: str = "" # branch, commit or path
50
+
51
+ def describe(self) -> str:
52
+ return {
53
+ "uncommitted": "uncommitted changes (staged, unstaged and untracked)",
54
+ "staged": "staged changes",
55
+ "base": f"changes against {self.value}",
56
+ "commit": f"commit {self.value}",
57
+ "file": f"file {self.value}",
58
+ }[self.kind]
59
+
60
+
61
+ @dataclass
62
+ class ReviewInput:
63
+ target: ReviewTarget
64
+ root: Path
65
+ diff: str
66
+ files: list[str]
67
+ omitted_files: list[str] = field(default_factory=list)
68
+ total_chars: int = 0
69
+ added: int = 0
70
+ removed: int = 0
71
+ base_sha: str = ""
72
+ commit_title: str = ""
73
+ # New-side line ranges each file's hunks cover, to tell a finding on the
74
+ # change from one elsewhere in the file.
75
+ hunks: dict[str, list[tuple[int, int]]] = field(default_factory=dict)
76
+
77
+ @property
78
+ def truncated(self) -> bool:
79
+ return bool(self.omitted_files)
80
+
81
+
82
+ def _git(root: Path, *args: str, check: bool = True) -> str:
83
+ result = subprocess.run(["git", *args], cwd=root, capture_output=True, text=True,
84
+ errors="replace", timeout=60)
85
+ if check and result.returncode != 0:
86
+ raise ReviewError(f"git {' '.join(args)} failed: {result.stderr.strip() or result.stdout.strip()}")
87
+ return result.stdout
88
+
89
+
90
+ def repo_root(cwd: Path) -> Path:
91
+ try:
92
+ return Path(_git(cwd, "rev-parse", "--show-toplevel").strip())
93
+ except (ReviewError, FileNotFoundError) as exc:
94
+ raise ReviewError(f"{cwd} is not inside a git repository") from exc
95
+
96
+
97
+ def _has_head(root: Path) -> bool:
98
+ return subprocess.run(["git", "rev-parse", "--verify", "-q", "HEAD"], cwd=root,
99
+ capture_output=True).returncode == 0
100
+
101
+
102
+ def _untracked_as_diff(root: Path) -> str:
103
+ names = [n for n in _git(root, "ls-files", "--others", "--exclude-standard", "-z").split("\0") if n]
104
+ parts = []
105
+ for name in names[:MAX_UNTRACKED_FILES]:
106
+ path = root / name
107
+ try:
108
+ data = path.read_bytes()
109
+ except OSError:
110
+ continue
111
+ if b"\0" in data[:8000] or len(data) > MAX_UNTRACKED_BYTES:
112
+ parts.append(f"diff --git a/{name} b/{name}\nnew file (binary or larger than "
113
+ f"{MAX_UNTRACKED_BYTES} bytes; not shown)\n")
114
+ continue
115
+ lines = data.decode("utf-8", "replace").splitlines()
116
+ body = "\n".join("+" + line for line in lines)
117
+ parts.append(f"diff --git a/{name} b/{name}\nnew file mode 100644\n--- /dev/null\n+++ b/{name}\n"
118
+ f"@@ -0,0 +1,{len(lines)} @@\n{body}\n")
119
+ if len(names) > MAX_UNTRACKED_FILES:
120
+ parts.append(f"# {len(names) - MAX_UNTRACKED_FILES} more untracked files not shown\n")
121
+ return "".join(parts)
122
+
123
+
124
+ _FILE_HEADER = re.compile(r"^diff --git a/(.+?) b/(.+)$", re.M)
125
+ _HUNK = re.compile(r"^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@", re.M)
126
+
127
+
128
+ def _split_files(diff: str) -> list[tuple[str, str]]:
129
+ starts = [(m.start(), m.group(2)) for m in _FILE_HEADER.finditer(diff)]
130
+ return [(name, diff[start:(starts[i + 1][0] if i + 1 < len(starts) else len(diff))])
131
+ for i, (start, name) in enumerate(starts)]
132
+
133
+
134
+ def _hunks(section: str) -> list[tuple[int, int]]:
135
+ ranges = []
136
+ for match in _HUNK.finditer(section):
137
+ start, count = int(match.group(1)), int(match.group(2) or 1)
138
+ if count:
139
+ ranges.append((start, start + count - 1))
140
+ return ranges
141
+
142
+
143
+ def _fit(target: ReviewTarget, root: Path, diff: str, max_chars: int, **extra) -> ReviewInput:
144
+ sections = _split_files(diff)
145
+ kept, omitted, size = [], [], 0
146
+ for name, section in sections:
147
+ if size + len(section) > max_chars and kept:
148
+ omitted.append(name)
149
+ continue
150
+ kept.append((name, section))
151
+ size += len(section)
152
+ text = "".join(section for _, section in kept)
153
+ added = sum(1 for line in text.splitlines() if line.startswith("+") and not line.startswith("+++"))
154
+ removed = sum(1 for line in text.splitlines() if line.startswith("-") and not line.startswith("---"))
155
+ return ReviewInput(target=target, root=root, diff=text, files=[n for n, _ in kept], omitted_files=omitted,
156
+ total_chars=len(diff), added=added, removed=removed,
157
+ hunks={n: _hunks(s) for n, s in kept}, **extra)
158
+
159
+
160
+ def collect(target: ReviewTarget, cwd: Path | str = ".", *, max_chars: int = DEFAULT_MAX_CHARS) -> ReviewInput:
161
+ """Gather exactly what the target names, as a unified diff."""
162
+ cwd = Path(cwd)
163
+ if target.kind == "file":
164
+ path = (cwd / target.value).resolve()
165
+ if not path.is_file():
166
+ raise ReviewError(f"file not found: {target.value}")
167
+ try:
168
+ root = repo_root(path.parent)
169
+ name = str(path.relative_to(root))
170
+ except ReviewError:
171
+ root, name = path.parent, path.name
172
+ lines = path.read_text(encoding="utf-8", errors="replace").splitlines()
173
+ diff = (f"diff --git a/{name} b/{name}\n--- a/{name}\n+++ b/{name}\n@@ -1,{len(lines)} +1,{len(lines)} @@\n"
174
+ + "".join(f" {line}\n" for line in lines))
175
+ return _fit(target, root, diff, max_chars)
176
+
177
+ root = repo_root(cwd)
178
+ if target.kind == "uncommitted":
179
+ tracked = _git(root, "diff", "HEAD") if _has_head(root) else _git(root, "diff", "--cached")
180
+ return _fit(target, root, tracked + _untracked_as_diff(root), max_chars)
181
+ if target.kind == "staged":
182
+ return _fit(target, root, _git(root, "diff", "--cached"), max_chars)
183
+ if target.kind == "base":
184
+ branch = target.value
185
+ if not branch:
186
+ raise ReviewError("--base needs a branch name")
187
+ upstream = _git(root, "rev-parse", "--abbrev-ref", f"{branch}@{{upstream}}", check=False).strip()
188
+ base_sha = ""
189
+ for candidate in (upstream, branch):
190
+ if candidate:
191
+ base_sha = _git(root, "merge-base", "HEAD", candidate, check=False).strip()
192
+ if base_sha:
193
+ break
194
+ if not base_sha:
195
+ raise ReviewError(f"no merge base between HEAD and {branch}")
196
+ return _fit(target, root, _git(root, "diff", base_sha), max_chars, base_sha=base_sha)
197
+ if target.kind == "commit":
198
+ sha = _git(root, "rev-parse", "--verify", f"{target.value}^{{commit}}").strip()
199
+ title = _git(root, "log", "-1", "--format=%s", sha).strip()
200
+ patch = _git(root, "show", "--format=", "--patch", sha)
201
+ return _fit(target, root, patch, max_chars, base_sha=sha, commit_title=title)
202
+ raise ReviewError(f"unknown review target {target.kind!r}")
203
+
204
+
205
+ def project_rules(root: Path) -> str:
206
+ """The project's own review guidance, most specific file first."""
207
+ for name in PROJECT_RULE_FILES:
208
+ path = root / name
209
+ if path.is_file():
210
+ text = path.read_text(encoding="utf-8", errors="replace").strip()
211
+ if text:
212
+ return f"{name}:\n{text[:MAX_RULE_CHARS]}"
213
+ return ""
214
+
215
+
216
+ # ── The reviewer ─────────────────────────────────────────────────────────────
217
+
218
+ RUBRIC = """You review one code change for the engineer who wrote it. Report only problems they would want to fix before merging.
219
+
220
+ What counts as a finding:
221
+ - It changes behaviour for the worse: a wrong result, a crash, lost or leaked data, a security hole, a serious slowdown, or code that will clearly be hard to maintain.
222
+ - It was introduced by this change. Problems that were already there are out of scope.
223
+ - It is specific: one problem, one place, one fix. Say which inputs, settings or environments trigger it; if it depends on them, say so in the first sentence.
224
+ - It is shown, not guessed. "This might affect X" is not a finding unless you can point to the code in X that breaks.
225
+ - It is not an obvious, deliberate choice by the author.
226
+
227
+ What does not: style, naming, formatting, typos and missing comments, unless a documented project rule requires them.
228
+
229
+ Priorities, at the start of each title:
230
+ [P0] blocks a release or breaks the main path for everyone, whatever the input.
231
+ [P1] urgent: fix in the next cycle.
232
+ [P2] normal: fix when convenient.
233
+ [P3] minor.
234
+
235
+ Each finding: a title of at most 80 characters that names the problem; a body of one short paragraph saying why it is wrong and when it happens; at most three lines of code, in backticks; the narrowest line range (new-side line numbers of the change, no more than about ten lines); and a confidence from 0 to 1. List every qualifying problem — and none when there are none. A short empty review is better than padding.
236
+
237
+ Then give an overall verdict: "patch is correct" when existing code and tests will keep working and nothing above P3 is wrong, otherwise "patch is incorrect", with a one-to-three sentence explanation and a confidence.
238
+
239
+ Respond with JSON only, no prose and no code fences, in exactly this shape:
240
+ {"findings": [{"title": "[P1] ...", "body": "...", "confidence_score": 0.8, "priority": 1,
241
+ "code_location": {"file_path": "path/relative/to/repo", "line_range": {"start": 10, "end": 12}}}],
242
+ "overall_correctness": "patch is correct" | "patch is incorrect",
243
+ "overall_explanation": "...",
244
+ "overall_confidence_score": 0.8}"""
245
+
246
+ LANGUAGE_NOTE = {
247
+ "en": "Write titles, bodies and the explanation in English.",
248
+ "zh": "标题、正文和总体说明用简体中文书写;JSON 字段名和优先级标签保持英文。",
249
+ }
250
+
251
+
252
+ def build_messages(inp: ReviewInput, *, lang: str = "en", automated_hints: str = "",
253
+ rules: str | None = None) -> list[dict]:
254
+ """The reviewer's whole world: rubric, project rules, the change. Nothing else."""
255
+ rules = project_rules(inp.root) if rules is None else rules
256
+ system = RUBRIC + "\n\n" + LANGUAGE_NOTE["zh" if lang.startswith("zh") else "en"]
257
+ if rules:
258
+ system += ("\n\nThis project's own guidance follows. It overrides the defaults above where they "
259
+ "conflict; when a finding rests on it, cite the file.\n\n" + rules)
260
+ parts = [f"Review target: {inp.target.describe()}."]
261
+ if inp.commit_title:
262
+ parts.append(f'Commit title: "{inp.commit_title}".')
263
+ if inp.base_sha and inp.target.kind == "base":
264
+ parts.append(f"Merge base: {inp.base_sha}.")
265
+ parts.append(f"Files: {', '.join(inp.files) or '(none)'} (+{inp.added} -{inp.removed}).")
266
+ if inp.truncated:
267
+ parts.append(f"The change was too large to show whole. These files were NOT shown and must not be "
268
+ f"reviewed or guessed about: {', '.join(inp.omitted_files)}.")
269
+ if automated_hints:
270
+ parts.append("Automated pattern checks flagged the lines below. Keep a hint only if the change really "
271
+ "has the problem; they are leads, not findings.\n" + automated_hints)
272
+ parts.append("The change:\n" + inp.diff)
273
+ return [{"role": "system", "content": system}, {"role": "user", "content": "\n\n".join(parts)}]
274
+
275
+
276
+ @dataclass
277
+ class ReviewFinding:
278
+ title: str
279
+ body: str
280
+ priority: int | None
281
+ confidence: float
282
+ file_path: str
283
+ start: int
284
+ end: int
285
+ in_change: bool = True
286
+
287
+ @property
288
+ def label(self) -> str:
289
+ return PRIORITIES[self.priority] if self.priority is not None else "P?"
290
+
291
+ @property
292
+ def location(self) -> str:
293
+ return f"{self.file_path}:{self.start}" + (f"-{self.end}" if self.end != self.start else "")
294
+
295
+
296
+ @dataclass
297
+ class ReviewResult:
298
+ findings: list[ReviewFinding]
299
+ correct: bool | None
300
+ explanation: str
301
+ confidence: float
302
+ structured: bool = True # False when the model's reply was not the JSON asked for
303
+ target: str = ""
304
+ files: list[str] = field(default_factory=list)
305
+ omitted_files: list[str] = field(default_factory=list)
306
+
307
+ def to_dict(self) -> dict:
308
+ return {
309
+ "target": self.target,
310
+ "files": self.files,
311
+ "omitted_files": self.omitted_files,
312
+ "overall_correctness": None if self.correct is None else
313
+ ("patch is correct" if self.correct else "patch is incorrect"),
314
+ "overall_explanation": self.explanation,
315
+ "overall_confidence_score": self.confidence,
316
+ "structured": self.structured,
317
+ "findings": [{**asdict(f), "priority_label": f.label} for f in self.findings],
318
+ }
319
+
320
+ def worst_priority(self) -> int | None:
321
+ levels = [f.priority for f in self.findings if f.priority is not None and f.in_change]
322
+ return min(levels) if levels else None
323
+
324
+
325
+ def _clamp(value, default: float = 0.5) -> float:
326
+ try:
327
+ return max(0.0, min(1.0, float(value)))
328
+ except (TypeError, ValueError):
329
+ return default
330
+
331
+
332
+ def _priority(raw: dict) -> int | None:
333
+ value = raw.get("priority")
334
+ if isinstance(value, (int, float)) and 0 <= int(value) <= 3:
335
+ return int(value)
336
+ match = re.match(r"\s*\[P([0-3])\]", str(raw.get("title", "")))
337
+ return int(match.group(1)) if match else None
338
+
339
+
340
+ def _load_json(text: str):
341
+ text = text.strip()
342
+ candidates = [text]
343
+ fenced = re.search(r"```(?:json)?\s*(\{.*\})\s*```", text, re.S)
344
+ if fenced:
345
+ candidates.append(fenced.group(1))
346
+ if "{" in text and "}" in text:
347
+ candidates.append(text[text.find("{"):text.rfind("}") + 1])
348
+ for candidate in candidates:
349
+ try:
350
+ data = json.loads(candidate)
351
+ except (json.JSONDecodeError, ValueError):
352
+ continue
353
+ if isinstance(data, dict):
354
+ return data
355
+ return None
356
+
357
+
358
+ def parse_review(text: str, inp: ReviewInput | None = None) -> ReviewResult:
359
+ data = _load_json(text or "")
360
+ if data is None:
361
+ return ReviewResult([], None, (text or "").strip() or "The reviewer returned nothing.", 0.0,
362
+ structured=False)
363
+ findings = []
364
+ for raw in data.get("findings") or []:
365
+ if not isinstance(raw, dict):
366
+ continue
367
+ location = raw.get("code_location") or {}
368
+ lines = location.get("line_range") or {}
369
+ path = str(location.get("file_path") or location.get("absolute_file_path") or "").strip()
370
+ if inp is not None and path:
371
+ try:
372
+ path = str(Path(path).resolve().relative_to(inp.root.resolve())) if Path(path).is_absolute() else path
373
+ except ValueError:
374
+ pass
375
+ try:
376
+ start = int(lines.get("start") or 0)
377
+ end = int(lines.get("end") or start)
378
+ except (TypeError, ValueError):
379
+ start = end = 0
380
+ start, end = min(start, end), max(start, end)
381
+ title = re.sub(r"^\s*\[P[0-3?]\]\s*", "", str(raw.get("title", "")).strip())
382
+ finding = ReviewFinding(title=title[:120], body=str(raw.get("body", "")).strip(), priority=_priority(raw),
383
+ confidence=_clamp(raw.get("confidence_score")), file_path=path, start=start, end=end)
384
+ if inp is not None:
385
+ ranges = inp.hunks.get(path)
386
+ finding.in_change = bool(ranges) and any(start <= b and end >= a for a, b in ranges)
387
+ findings.append(finding)
388
+ findings.sort(key=lambda f: (not f.in_change, 9 if f.priority is None else f.priority, -f.confidence))
389
+ verdict = str(data.get("overall_correctness", "")).strip().lower()
390
+ correct = True if verdict == "patch is correct" else False if verdict == "patch is incorrect" else None
391
+ result = ReviewResult(findings, correct, str(data.get("overall_explanation", "")).strip(),
392
+ _clamp(data.get("overall_confidence_score"), 0.0))
393
+ if inp is not None:
394
+ result.target, result.files, result.omitted_files = inp.target.describe(), inp.files, inp.omitted_files
395
+ return result
396
+
397
+
398
+ ModelCall = Callable[[list], Awaitable[str]]
399
+
400
+
401
+ def automated_hints(inp: ReviewInput) -> str:
402
+ """Aria's deterministic pattern checks over the added lines, as leads for the reviewer."""
403
+ try:
404
+ from aria_code.agents.code_review import CodeReviewAgent
405
+ except Exception:
406
+ return ""
407
+ rows = []
408
+ for name, section in _split_files(inp.diff):
409
+ for item in CodeReviewAgent.review_source(section, filename=name, is_diff=True):
410
+ if item.rule in ("empty-input", "input-truncated"):
411
+ continue
412
+ rows.append(f"- {name}: [{item.severity}] {item.rule}: {item.message} `{item.evidence[:80]}`")
413
+ return "\n".join(rows[:30])
414
+
415
+
416
+ async def run_review(inp: ReviewInput, call_model: ModelCall, *, lang: str = "en") -> ReviewResult:
417
+ if not inp.diff.strip():
418
+ result = ReviewResult([], True, "Nothing to review: the target has no changes.", 1.0)
419
+ result.target = inp.target.describe()
420
+ return result
421
+ reply = await call_model(build_messages(inp, lang=lang, automated_hints=automated_hints(inp)))
422
+ return parse_review(reply, inp)
423
+
424
+
425
+ # ── Presentation ─────────────────────────────────────────────────────────────
426
+
427
+ _TEXT = {
428
+ "en": {"title": "Review", "correct": "Looks correct", "incorrect": "Needs changes",
429
+ "unknown": "No verdict", "none": "No findings.", "outside": "Outside this change",
430
+ "omitted": "Not reviewed (too large to include)", "confidence": "confidence",
431
+ "unstructured": "The reviewer did not answer in the expected format; its reply:"},
432
+ "zh": {"title": "审查", "correct": "可以合并", "incorrect": "需要修改",
433
+ "unknown": "无结论", "none": "没有发现问题。", "outside": "不在本次改动范围内",
434
+ "omitted": "未审查(改动过大未纳入)", "confidence": "置信度",
435
+ "unstructured": "审查模型未按约定格式回答,原文如下:"},
436
+ }
437
+
438
+
439
+ def render_text(result: ReviewResult, *, lang: str = "en") -> str:
440
+ t = _TEXT["zh" if lang.startswith("zh") else "en"]
441
+ lines = [f"{t['title']} · {result.target}" if result.target else t["title"]]
442
+ if not result.structured:
443
+ return "\n".join(lines + [t["unstructured"], result.explanation])
444
+ verdict = t["unknown"] if result.correct is None else t["correct"] if result.correct else t["incorrect"]
445
+ lines.append(f"{verdict} · {t['confidence']} {result.confidence:.2f}")
446
+ if result.explanation:
447
+ lines.append(result.explanation)
448
+ if not result.findings:
449
+ lines.append(t["none"])
450
+ shown_outside = False
451
+ for number, f in enumerate(result.findings, 1):
452
+ if not f.in_change and not shown_outside:
453
+ lines.append(f"— {t['outside']} —")
454
+ shown_outside = True
455
+ lines.append("")
456
+ lines.append(f"{number}. [{f.label}] {f.title} {f.location} ({f.confidence:.2f})")
457
+ lines.extend(" " + line for line in f.body.splitlines() if line.strip())
458
+ if result.omitted_files:
459
+ lines.append("")
460
+ lines.append(f"{t['omitted']}: {', '.join(result.omitted_files)}")
461
+ return "\n".join(lines)
462
+
463
+
464
+ def history_note(result: ReviewResult) -> str:
465
+ """What the main conversation remembers, so "fix finding 2" means something."""
466
+ rows = [f"Code review of {result.target}: "
467
+ + ("no verdict" if result.correct is None else "patch is correct" if result.correct else "patch is incorrect")
468
+ + (f". {result.explanation}" if result.explanation else "")]
469
+ for number, f in enumerate(result.findings, 1):
470
+ rows.append(f"{number}. [{f.label}] {f.title} — {f.location}: {f.body}")
471
+ return "\n".join(rows)
472
+
473
+
474
+ def parse_priority(value: str) -> int:
475
+ value = value.strip().upper()
476
+ if value not in PRIORITIES:
477
+ raise ValueError(f"priority must be one of {', '.join(PRIORITIES)}")
478
+ return PRIORITIES.index(value)
479
+
480
+
481
+ def target_from_args(args: Iterable[str]) -> ReviewTarget:
482
+ """`--staged` | `--base BRANCH` | `--commit SHA` | `PATH` | nothing (uncommitted)."""
483
+ args = list(args)
484
+ if not args:
485
+ return ReviewTarget("uncommitted")
486
+ head = args[0]
487
+ if head in ("--staged", "--cached"):
488
+ return ReviewTarget("staged")
489
+ if head in ("--uncommitted",):
490
+ return ReviewTarget("uncommitted")
491
+ if head in ("--base", "--commit"):
492
+ if len(args) < 2:
493
+ raise ReviewError(f"{head} needs a value")
494
+ return ReviewTarget(head[2:], args[1])
495
+ if head.startswith("--"):
496
+ raise ReviewError(f"unknown option {head}")
497
+ return ReviewTarget("file", head)
@@ -0,0 +1,176 @@
1
+ """Runtime primitives for Aria Code agent execution."""
2
+
3
+ from .agent_loop import (
4
+ AgentErrorPresentation,
5
+ AgentEvent,
6
+ AgentEventCancelled,
7
+ AgentEventComplete,
8
+ AgentEventError,
9
+ AgentEventStatus,
10
+ AgentEventThinking,
11
+ AgentEventToken,
12
+ AgentEventToolCall,
13
+ AgentEventToolResult,
14
+ AgentOptions,
15
+ AgentTurnMetadata,
16
+ AgentTurnEnvelope,
17
+ AgentTurnResult,
18
+ AgentTurnState,
19
+ ToolBatchState,
20
+ ToolExecutionActivity,
21
+ ToolExecutionTurnResult,
22
+ ToolCallTask,
23
+ ToolTurnPlan,
24
+ build_next_turn_messages,
25
+ build_tool_followup,
26
+ collect_parallel_done,
27
+ detect_task_complete,
28
+ execute_tool_turn,
29
+ LoopGuard,
30
+ record_tool_result,
31
+ run_agent,
32
+ run_parallel_tools,
33
+ run_serial_tool,
34
+ split_tool_calls,
35
+ )
36
+ from .contract import ChangeContract, ContractError, ContractVerdict
37
+ from .review import ReviewGate, ReviewReport
38
+ from .acceptance import (
39
+ AcceptanceGate,
40
+ AcceptanceReport,
41
+ CheckResult,
42
+ DEFAULT_MUTATING_TOOLS,
43
+ extract_mutated_paths,
44
+ )
45
+ from .repo_map import (
46
+ REPO_MAP_SCHEMAS,
47
+ REPO_MAP_TOOLS,
48
+ RepoMap,
49
+ Symbol,
50
+ extract_symbols,
51
+ )
52
+ from .gateway import TurnResult, run_turn
53
+ from .approval import ApprovalDecision, apply_approval_decision
54
+ from .events import RuntimeEvent, RuntimeTrace, ToolCallRecord, TurnResultRecord
55
+ from .run_state import (
56
+ ACTIVE_RUN_STATUSES,
57
+ TERMINAL_RUN_STATUSES,
58
+ InvalidRunTransition,
59
+ RunStatus,
60
+ can_transition,
61
+ is_terminal,
62
+ require_transition,
63
+ )
64
+ from .run_store import RunEventRecord, RunNotFoundError, RunRecord, RunStore
65
+ from .checkpoints import (
66
+ CheckpointConflictError,
67
+ CheckpointFile,
68
+ CheckpointNotFoundError,
69
+ CheckpointRecord,
70
+ CheckpointStore,
71
+ RestoreResult,
72
+ )
73
+ from .worktrees import WorktreeApplyResult, WorktreeError, WorktreeManager, WorktreeSpec
74
+ from .tool_executor import ToolExecutor
75
+ from .tool_policy import check_tool_policy, add_to_policy, remove_from_policy, load_tool_policy
76
+ from .subagent import (
77
+ SUBAGENT_TOOLS,
78
+ SUBAGENT_SCHEMAS,
79
+ tool_spawn_task,
80
+ tool_task_status,
81
+ tool_task_result,
82
+ tool_task_list,
83
+ tool_task_cancel,
84
+ register_runner,
85
+ restore_tasks,
86
+ )
87
+
88
+ __all__ = [
89
+ "REPO_MAP_SCHEMAS",
90
+ "REPO_MAP_TOOLS",
91
+ "RepoMap",
92
+ "Symbol",
93
+ "extract_symbols",
94
+ "AcceptanceGate",
95
+ "ChangeContract",
96
+ "ReviewGate",
97
+ "ReviewReport",
98
+ "ContractError",
99
+ "ContractVerdict",
100
+ "AcceptanceReport",
101
+ "CheckResult",
102
+ "DEFAULT_MUTATING_TOOLS",
103
+ "extract_mutated_paths",
104
+ "AgentErrorPresentation",
105
+ "AgentEvent",
106
+ "AgentEventCancelled",
107
+ "AgentEventComplete",
108
+ "AgentEventError",
109
+ "AgentEventStatus",
110
+ "AgentEventThinking",
111
+ "AgentEventToken",
112
+ "AgentEventToolCall",
113
+ "AgentEventToolResult",
114
+ "AgentOptions",
115
+ "AgentTurnMetadata",
116
+ "AgentTurnEnvelope",
117
+ "AgentTurnResult",
118
+ "AgentTurnState",
119
+ "ApprovalDecision",
120
+ "RuntimeEvent",
121
+ "RuntimeTrace",
122
+ "RunEventRecord",
123
+ "RunNotFoundError",
124
+ "RunRecord",
125
+ "RunStatus",
126
+ "RunStore",
127
+ "InvalidRunTransition",
128
+ "CheckpointConflictError",
129
+ "CheckpointFile",
130
+ "CheckpointNotFoundError",
131
+ "CheckpointRecord",
132
+ "CheckpointStore",
133
+ "RestoreResult",
134
+ "WorktreeError",
135
+ "WorktreeApplyResult",
136
+ "WorktreeManager",
137
+ "WorktreeSpec",
138
+ "ACTIVE_RUN_STATUSES",
139
+ "TERMINAL_RUN_STATUSES",
140
+ "ToolCallRecord",
141
+ "TurnResultRecord",
142
+ "ToolBatchState",
143
+ "ToolExecutionActivity",
144
+ "ToolExecutionTurnResult",
145
+ "ToolCallTask",
146
+ "ToolExecutor",
147
+ "ToolTurnPlan",
148
+ "apply_approval_decision",
149
+ "build_next_turn_messages",
150
+ "build_tool_followup",
151
+ "collect_parallel_done",
152
+ "detect_task_complete",
153
+ "execute_tool_turn",
154
+ "LoopGuard",
155
+ "record_tool_result",
156
+ "run_agent",
157
+ "run_parallel_tools",
158
+ "run_serial_tool",
159
+ "split_tool_calls",
160
+ "can_transition",
161
+ "is_terminal",
162
+ "require_transition",
163
+ "check_tool_policy",
164
+ "add_to_policy",
165
+ "remove_from_policy",
166
+ "load_tool_policy",
167
+ "SUBAGENT_TOOLS",
168
+ "SUBAGENT_SCHEMAS",
169
+ "tool_spawn_task",
170
+ "tool_task_status",
171
+ "tool_task_result",
172
+ "tool_task_list",
173
+ "tool_task_cancel",
174
+ "register_runner",
175
+ "restore_tasks",
176
+ ]