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,656 @@
1
+ """System-level tools: run_command, web_fetch, github.
2
+
3
+ All functions are pure (no module-level globals). Console output is
4
+ injected via keyword args so aria_cli.py thin wrappers supply the
5
+ Rich console and global state defaults.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ import os
11
+ import pathlib
12
+ import re
13
+ import shlex
14
+ import subprocess
15
+ import sys
16
+ from datetime import datetime
17
+ from pathlib import Path
18
+
19
+ _ROOT = Path(__file__).parent.parent.parent.parent # aria-code/
20
+ if str(_ROOT) not in sys.path:
21
+ sys.path.insert(0, str(_ROOT))
22
+
23
+ from aria_code.safety import evaluate_command_policy # noqa: E402
24
+
25
+
26
+ def _persist_command_output(command: str, stdout: str, stderr: str, returncode: int) -> dict:
27
+ """Persist full command output when it is too large for inline tool context."""
28
+ stdout_lines = stdout.splitlines()
29
+ stderr_lines = stderr.splitlines()
30
+ if (
31
+ len(stdout) <= 2500
32
+ and len(stderr) <= 1200
33
+ and len(stdout_lines) <= 18
34
+ and len(stderr_lines) <= 8
35
+ ):
36
+ return {}
37
+ try:
38
+ from aria_code.artifacts import create_artifact, write_artifact_metadata
39
+
40
+ record = create_artifact(
41
+ "command-output",
42
+ "shell",
43
+ "command_output",
44
+ ".txt",
45
+ timestamp=datetime.now(),
46
+ )
47
+ text = (
48
+ f"$ {command}\n"
49
+ f"exit_code={returncode}\n\n"
50
+ "===== STDOUT =====\n"
51
+ f"{stdout}"
52
+ "\n\n===== STDERR =====\n"
53
+ f"{stderr}"
54
+ )
55
+ record.path.write_text(text, encoding="utf-8", errors="replace")
56
+ write_artifact_metadata(record, {
57
+ "kind": "command_output",
58
+ "status": "complete" if returncode == 0 else "failed",
59
+ "created_at": datetime.now().isoformat(timespec="seconds"),
60
+ "command": command,
61
+ "exit_code": returncode,
62
+ "stdout_chars": len(stdout),
63
+ "stderr_chars": len(stderr),
64
+ "stdout_truncated_inline": len(stdout) > 5000,
65
+ "stderr_truncated_inline": len(stderr) > 2000,
66
+ })
67
+ return {"full_output_path": str(record.path)}
68
+ except Exception:
69
+ return {}
70
+
71
+
72
+ def _cprint(msg: str, *, console, has_rich: bool) -> None:
73
+ if has_rich and console is not None:
74
+ console.print(msg)
75
+ else:
76
+ plain = re.sub(r"\[/?[^\]]+\]", "", msg)
77
+ print(plain)
78
+
79
+
80
+ OUTPUT_PREVIEW_LINES = 5
81
+
82
+
83
+ def print_command_outcome(console, returncode: int, stdout: str, stderr: str, full_output_path: str = "") -> None:
84
+ """One step line and the last few lines of what the command printed.
85
+
86
+ This printed "Command completed (exit 0)", up to six stdout lines and
87
+ "full output saved" — and nothing at all for `python3 -m unittest -v`,
88
+ whose report goes to stderr, so the model pasted the test results into
89
+ its answer instead. Lines are plain text: program output such as
90
+ "[/dim]" is not Rich markup. As Codex does, the tail is kept — that is
91
+ where "OK" or the failure is — and the rest is counted.
92
+ """
93
+ from rich.text import Text
94
+
95
+ lines = stdout.rstrip().splitlines() + (stderr.rstrip().splitlines() if stderr.strip() else [])
96
+ ok = returncode == 0
97
+ head = Text(" ⎿ ", style="dim")
98
+ head.append(f"exit {returncode}", style="green" if ok else "red")
99
+ if lines:
100
+ head.append(f" · {len(lines)} line{'s' if len(lines) != 1 else ''}", style="dim")
101
+ console.print(head)
102
+ notes = []
103
+ if len(lines) > OUTPUT_PREVIEW_LINES:
104
+ notes.append(f"… +{len(lines) - OUTPUT_PREVIEW_LINES} lines")
105
+ if full_output_path:
106
+ from aria_code.ui.render.output import display_path
107
+
108
+ notes.append(f"full output saved: {display_path(full_output_path)}")
109
+ if notes:
110
+ console.print(Text(" " + " · ".join(notes), style="dim"))
111
+ for line in lines[-OUTPUT_PREVIEW_LINES:]:
112
+ console.print(Text(" " + line[:160], style="dim" if ok else "red"), overflow="ellipsis", no_wrap=True)
113
+
114
+
115
+ def tool_run_command(
116
+ params: dict,
117
+ *,
118
+ console=None,
119
+ has_rich: bool = True,
120
+ quiet: bool = False,
121
+ ) -> dict:
122
+ """Run a shell command and return output.
123
+
124
+ ``params`` should contain ``permission_mode`` and ``network_enabled``
125
+ (filled in by the aria_cli.py wrapper from the active globals).
126
+ ``quiet`` leaves the outcome to the caller: during a chat turn the
127
+ transcript's Ran cell shows the exit and the output tail itself.
128
+ """
129
+ command = params.get("command", "")
130
+ # LLMs sometimes send command as a list e.g. ['bash', '-lc', '...'] — normalize to string
131
+ if isinstance(command, list):
132
+ import shlex as _shlex
133
+ command = _shlex.join(str(c) for c in command)
134
+ params["command"] = command
135
+ if not command:
136
+ return {"success": False, "error": "Missing 'command' parameter"}
137
+
138
+ effective_policy = params.get("policy", "safe")
139
+ if params.get("user_approved") and effective_policy == "safe":
140
+ effective_policy = "balanced"
141
+
142
+ decision = evaluate_command_policy(
143
+ command,
144
+ effective_policy,
145
+ # "safe" is a *policy* name, not a mode — it never matched
146
+ # PermissionMode and silently resolved to workspace-write. Both
147
+ # executors supply a real mode, so this default is only reached
148
+ # by a caller that bypasses them; read-only is the right answer
149
+ # there.
150
+ mode=params.get("permission_mode", "read-only"),
151
+ network_enabled=bool(params.get("network_enabled", True)),
152
+ )
153
+ mode = str(params.get("permission_mode", "read-only"))
154
+ network = bool(params.get("network_enabled", True))
155
+ sandbox_hint = ""
156
+ command = decision.normalized_command
157
+
158
+ from aria_code.safety.permissions import writes_a_device
159
+ dangerous = ["rm -rf /", "mkfs", "dd if=", ":(){ :", "fork bomb"]
160
+ if any(d in command for d in dangerous) or writes_a_device(command):
161
+ return {"success": False, "error": f"Blocked dangerous command: {command}"}
162
+
163
+ # Prevent executing text/doc files as Python — they are analysis reports, not scripts
164
+ import re as _re_cmd
165
+ _py3_file = _re_cmd.search(r'\bpython3?\s+["\']?(\S+\.(?:txt|md|docx|csv|json|log))', command)
166
+ if _py3_file:
167
+ _bad_file = _py3_file.group(1)
168
+ return {
169
+ "success": False,
170
+ "error": (
171
+ f"拒绝执行: '{_bad_file}' 是文本/分析文件,不是 Python 脚本。\n"
172
+ "如需展示分析结果,请直接输出文字,或将分析结论写入 .py 文件后执行。"
173
+ ),
174
+ }
175
+
176
+ if params.get("dry_run"):
177
+ return {"success": True, "data": {
178
+ "command": command,
179
+ "risk": decision.risk,
180
+ "policy": decision.policy,
181
+ "requires_approval": getattr(decision, "requires_approval", False),
182
+ "network": getattr(decision, "network", False),
183
+ "dry_run": True,
184
+ }}
185
+ if not decision.allowed:
186
+ return {"success": False, "error": decision.reason}
187
+ try:
188
+ cwd = params.get("cwd", None)
189
+ timeout = min(params.get("timeout", 120), 300)
190
+ use_shell = True
191
+ argv = None
192
+ # POSIX shlex strips Windows path backslashes. Keep CMD's own parsing
193
+ # on Windows, after the same policy and permission checks above.
194
+ if decision.risk == "low" and os.name != "nt":
195
+ has_shell_meta = any(ch in command for ch in ["|", "&", ";", "<", ">", "$", "`", "\n"])
196
+ if not has_shell_meta:
197
+ try:
198
+ argv = shlex.split(command)
199
+ if argv:
200
+ use_shell = False
201
+ except ValueError:
202
+ use_shell = True
203
+ argv = None
204
+
205
+ sandbox = params.get("sandbox", False)
206
+ if params.get("background"):
207
+ return _start_background(params, command, argv, use_shell, cwd, mode, network,
208
+ docker=bool(sandbox), console=console, has_rich=has_rich)
209
+ if sandbox:
210
+ try:
211
+ from aria_code.apps.cli.sandbox import run_in_docker_sandbox
212
+ result = run_in_docker_sandbox(
213
+ command=command,
214
+ cwd=cwd,
215
+ timeout=timeout,
216
+ image="python:3.11-slim"
217
+ )
218
+ except Exception as e:
219
+ return {"success": False, "error": f"Sandbox execution failed: {e}"}
220
+ else:
221
+ from aria_code.safety import sandbox as _os_sandbox
222
+ confined = _os_sandbox.wrap(
223
+ argv if (argv and not use_shell) else command,
224
+ use_shell=use_shell, mode=mode, network=network, cwd=cwd,
225
+ setting=params.get("os_sandbox"),
226
+ workspace=params.get("_workspace"),
227
+ extra=params.get("_allowed_write_roots", ()),
228
+ )
229
+ # In a task worktree, the worktree's own source comes first on
230
+ # PYTHONPATH, so an editable install of the user's checkout does
231
+ # not answer imports meant for the task's edits.
232
+ from aria_code.runtime.task_worktree import worktree_command_env
233
+ result = subprocess.run(
234
+ confined or (argv if (argv and not use_shell) else command),
235
+ shell=use_shell and not confined,
236
+ capture_output=True,
237
+ text=True,
238
+ timeout=timeout,
239
+ cwd=cwd,
240
+ env=worktree_command_env(params.get("_workspace") or "", params.get("_workspace_origin") or ""),
241
+ )
242
+ if confined and "sandbox-exec: sandbox_apply" in (result.stderr or ""):
243
+ # Never fall back to running it unconfined.
244
+ return {"success": False, "error": "The command sandbox could not start: "
245
+ + result.stderr.strip()[:300]
246
+ + " — set os_sandbox=off in the config to run commands without it."}
247
+ if confined and result.returncode != 0:
248
+ sandbox_hint = _os_sandbox.denial_hint(result.stdout + "\n" + result.stderr,
249
+ mode=mode, network=network)
250
+ full_stdout = result.stdout
251
+ full_stderr = result.stderr
252
+ output = full_stdout[-5000:] if len(full_stdout) > 5000 else full_stdout
253
+ stderr = full_stderr[-2000:] if len(full_stderr) > 2000 else full_stderr
254
+ output_artifact = _persist_command_output(command, full_stdout, full_stderr, result.returncode)
255
+
256
+ # A failed command is reported, not repaired here. This used to edit
257
+ # the script (inserting imports, rewriting DataFrame.append) and run
258
+ # `pip3 install <the module named in the error>`, then re-run with
259
+ # shell=True: file writes with no approval and no checkpoint, so /undo
260
+ # could not reverse them, and a package install that ignored network
261
+ # off and the sandbox. The model gets the error and a hint, and makes
262
+ # the change through edit_file or an approved run_command.
263
+ hint = sandbox_hint or (_failure_hint(output + "\n" + stderr) if result.returncode != 0 else "")
264
+
265
+
266
+ if quiet:
267
+ pass
268
+ elif has_rich and console is not None:
269
+ print_command_outcome(console, result.returncode, output, stderr,
270
+ output_artifact.get("full_output_path", ""))
271
+ else:
272
+ print(f" Command exit: {result.returncode}")
273
+ data = {
274
+ "command": command, "exit_code": result.returncode,
275
+ "stdout": output, "stderr": stderr,
276
+ "stdout_truncated": len(full_stdout) > 5000,
277
+ "stderr_truncated": len(full_stderr) > 2000,
278
+ }
279
+ data.update(output_artifact)
280
+ if hint:
281
+ data["hint"] = hint
282
+ return {"success": True, "data": data}
283
+ except subprocess.TimeoutExpired:
284
+ return {"success": False, "error": f"Command timed out ({timeout}s)"}
285
+ except KeyboardInterrupt:
286
+ _cprint(" [dim]Command interrupted[/dim]", console=console, has_rich=has_rich)
287
+ return {"success": False, "error": "Command interrupted by user (Ctrl+C)"}
288
+ except Exception as e:
289
+ return {"success": False, "error": str(e)}
290
+
291
+
292
+ def _start_background(params, command, argv, use_shell, cwd, mode, network, *, docker,
293
+ console, has_rich) -> dict:
294
+ """Start a long-running command (server, watcher) and return its first output."""
295
+ if docker:
296
+ return {"success": False, "error": "background=true is not available with the Docker sandbox."}
297
+ from aria_code.runtime import processes
298
+ from aria_code.safety import sandbox as _os_sandbox
299
+
300
+ target = argv if (argv and not use_shell) else command
301
+ confined = _os_sandbox.wrap(target, use_shell=use_shell, mode=mode, network=network, cwd=cwd,
302
+ setting=params.get("os_sandbox"), workspace=params.get("_workspace"),
303
+ extra=params.get("_allowed_write_roots", ()))
304
+ result = processes.start(confined or target, shell=use_shell and not confined, cwd=cwd,
305
+ label=command, wait=min(float(params.get("wait_seconds", 3) or 0), 30.0),
306
+ until=params.get("until"))
307
+ if result.get("success"):
308
+ data = result["data"]
309
+ state = "running" if data["running"] else f"exited {data['exit_code']}"
310
+ _cprint(f" [dim]⎿ background {data['process_id']} · {state}[/dim]",
311
+ console=console, has_rich=has_rich)
312
+ if confined and not data["running"]:
313
+ hint = _os_sandbox.denial_hint(data.get("output", ""), mode=mode, network=network)
314
+ if hint:
315
+ data["hint"] = hint
316
+ return result
317
+
318
+
319
+ _PIP_NAMES = {
320
+ "sklearn": "scikit-learn", "cv2": "opencv-python", "bs4": "beautifulsoup4",
321
+ "PIL": "Pillow", "yaml": "PyYAML",
322
+ }
323
+
324
+
325
+ def _failure_hint(text: str) -> str:
326
+ """What to do about a common failure, for the model to act on with approval."""
327
+ missing = re.search(r"No module named ['\"]?([\w.]+)", text)
328
+ if missing:
329
+ module = missing.group(1).split(".")[0]
330
+ package = _PIP_NAMES.get(module, module)
331
+ return (f"Module '{module}' is not installed. If it is the right dependency, install it with "
332
+ f"run_command (e.g. `python3 -m pip install {package}`; check the package name first).")
333
+ name = re.search(r"NameError: name ['\"](\w+)['\"] is not defined", text)
334
+ if name:
335
+ return f"'{name.group(1)}' is not defined: add the missing import or definition with edit_file."
336
+ if "DataFrame' object has no attribute 'append'" in text:
337
+ return "DataFrame.append was removed in pandas 2: use pd.concat with edit_file."
338
+ return ""
339
+
340
+
341
+ def tool_web_fetch(params: dict) -> dict:
342
+ """Fetch the text content of any URL."""
343
+ url = params.get("url", "").strip()
344
+ if not url:
345
+ return {"success": False, "error": "Missing 'url' parameter"}
346
+ if not url.startswith(("http://", "https://")):
347
+ url = "https://" + url
348
+ max_chars = min(int(params.get("max_chars", 4000)), 12000)
349
+ timeout = min(int(params.get("timeout", 15)), 30)
350
+ try:
351
+ import urllib.request as _ur
352
+ import ssl as _ssl
353
+ _prx = _ur.getproxies()
354
+ # SEC EDGAR rejects browser-spoofed UAs from scripts (403) and requires
355
+ # a declarative UA with contact info — the root cause of "verify via
356
+ # 10-Q" tasks silently degrading to aggregator sites. Honor SEC's rule
357
+ # for sec.gov; keep a browser UA for sites that block obvious bots.
358
+ from urllib.parse import urlparse as _urlparse
359
+ _host = (_urlparse(url).hostname or "").lower()
360
+ if _host == "sec.gov" or _host.endswith(".sec.gov"):
361
+ _contact = os.environ.get("ARIA_SEC_CONTACT", "").strip() or "research@aria-code.local"
362
+ _ua = f"aria-code research client ({_contact})"
363
+ else:
364
+ _ua = (
365
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
366
+ "AppleWebKit/537.36 (KHTML, like Gecko) "
367
+ "Chrome/124.0 Safari/537.36"
368
+ )
369
+ headers = {
370
+ "User-Agent": _ua,
371
+ "Accept": "text/html,application/xhtml+xml,text/plain;q=0.9,*/*;q=0.8",
372
+ }
373
+ _gh_m = re.match(
374
+ r"https://github\.com/([^/]+/[^/]+)/blob/([^?#]+)", url
375
+ )
376
+ if _gh_m:
377
+ url = f"https://raw.githubusercontent.com/{_gh_m.group(1)}/{_gh_m.group(2)}"
378
+
379
+ import requests as _req
380
+ s = _req.Session()
381
+ s.proxies = _prx
382
+ # Certificate verification ON by default — research data fetched over
383
+ # an unverified channel is tamperable. ARIA_WEB_FETCH_INSECURE=1 is
384
+ # the explicit escape hatch for TLS-intercepting corporate proxies.
385
+ s.verify = os.environ.get("ARIA_WEB_FETCH_INSECURE", "") != "1"
386
+ r = s.get(url, headers=headers, timeout=timeout)
387
+ r.raise_for_status()
388
+ raw = r.text
389
+
390
+ ct = r.headers.get("content-type", "")
391
+ if "json" in ct or raw.lstrip().startswith(("{", "[")):
392
+ return {"success": True, "data": {
393
+ "url": url, "content_type": ct,
394
+ "text": raw[:max_chars], "length": len(raw),
395
+ }}
396
+
397
+ text = re.sub(r"<script[^>]*>.*?</script>", " ", raw, flags=re.DOTALL | re.I)
398
+ text = re.sub(r"<style[^>]*>.*?</style>", " ", text, flags=re.DOTALL | re.I)
399
+ text = re.sub(r"<[^>]+>", " ", text)
400
+ text = re.sub(r"&nbsp;", " ", text)
401
+ text = re.sub(r"&amp;", "&", text)
402
+ text = re.sub(r"&lt;", "<", text)
403
+ text = re.sub(r"&gt;", ">", text)
404
+ text = re.sub(r"&quot;", '"', text)
405
+ text = re.sub(r"\s{3,}", "\n", text)
406
+ text = text.strip()
407
+
408
+ return {"success": True, "data": {
409
+ "url": url, "content_type": ct,
410
+ "text": text[:max_chars], "length": len(text),
411
+ "truncated": len(text) > max_chars,
412
+ }}
413
+ except Exception as e:
414
+ return {"success": False, "error": f"web_fetch failed: {e}"}
415
+
416
+
417
+ def tool_github(
418
+ params: dict,
419
+ *,
420
+ console=None,
421
+ has_rich: bool = True,
422
+ ) -> dict:
423
+ """GitHub API / gh CLI integration.
424
+
425
+ actions: list_prs, list_issues, view_pr, view_issue, create_pr,
426
+ list_commits, read_file, search, pr_diff, pr_checks
427
+ """
428
+ action = params.get("action", "list_prs").lower().replace("-", "_")
429
+ cwd = params.get("cwd") or None
430
+ policy = "safe"
431
+
432
+ def _gh(cmd: str, timeout: int = 20) -> dict:
433
+ import shutil
434
+ if not shutil.which("gh"):
435
+ return {"success": False,
436
+ "error": "gh CLI not found. Install: brew install gh && gh auth login"}
437
+ return tool_run_command(
438
+ {"command": cmd, "cwd": cwd, "timeout": timeout, "policy": policy},
439
+ console=console,
440
+ has_rich=has_rich,
441
+ )
442
+
443
+ if action in ("list_prs", "prs", "pull_requests"):
444
+ state = params.get("state", "open")
445
+ limit = int(params.get("limit", 20))
446
+ return _gh(f"gh pr list --state {state} --limit {limit} "
447
+ "--json number,title,author,state,headRefName,url")
448
+
449
+ if action in ("list_issues", "issues"):
450
+ state = params.get("state", "open")
451
+ limit = int(params.get("limit", 20))
452
+ label = f' --label "{params["label"]}"' if params.get("label") else ""
453
+ return _gh(f"gh issue list --state {state} --limit {limit}{label} "
454
+ "--json number,title,author,state,labels,url")
455
+
456
+ if action in ("view_pr", "pr"):
457
+ number = params.get("number") or params.get("pr")
458
+ if not number:
459
+ return {"success": False, "error": "Missing 'number' parameter"}
460
+ return _gh(f"gh pr view {number} "
461
+ "--json number,title,body,state,headRefName,baseRefName,additions,deletions,files,url")
462
+
463
+ if action in ("view_issue", "issue"):
464
+ number = params.get("number") or params.get("issue")
465
+ if not number:
466
+ return {"success": False, "error": "Missing 'number' parameter"}
467
+ return _gh(f"gh issue view {number} "
468
+ "--json number,title,body,state,labels,comments,url")
469
+
470
+ if action == "create_pr":
471
+ title = params.get("title", "")
472
+ body = params.get("body", "")
473
+ branch = params.get("branch", "")
474
+ base = params.get("base", "main")
475
+ if not title:
476
+ return {"success": False, "error": "Missing 'title' for create_pr"}
477
+ b_flag = f"--head {shlex.quote(branch)}" if branch else ""
478
+ cmd = (
479
+ f"gh pr create --title {shlex.quote(title)} "
480
+ f"--body {shlex.quote(body)} "
481
+ f"--base {shlex.quote(base)} {b_flag}"
482
+ )
483
+ return _gh(cmd, timeout=30)
484
+
485
+ if action in ("list_commits", "commits", "log"):
486
+ limit = int(params.get("limit", 10))
487
+ return _gh(
488
+ f"gh api repos/{{owner}}/{{repo}}/commits?per_page={limit} "
489
+ "--jq '[.[] | {sha: .sha[:7], "
490
+ 'message: .commit.message | split("\\n")[0], '
491
+ "author: .commit.author.name, date: .commit.author.date}]'"
492
+ )
493
+
494
+ if action == "search":
495
+ q = params.get("q") or params.get("query", "")
496
+ kind = params.get("kind", "code")
497
+ if not q:
498
+ return {"success": False, "error": "Missing 'q' parameter"}
499
+ return _gh(f"gh search {kind} {shlex.quote(q)} --limit 10 "
500
+ "--json url,path,textMatches", timeout=15)
501
+
502
+ if action in ("read_file", "file"):
503
+ ref = params.get("ref", "")
504
+ file_path = params.get("path", "")
505
+ if ref:
506
+ m = re.match(r"([^@:]+)@([^:]+):(.+)", ref)
507
+ if m:
508
+ repo, branch, fp = m.groups()
509
+ url = f"https://raw.githubusercontent.com/{repo}/{branch}/{fp}"
510
+ return tool_web_fetch({"url": url, "max_chars": 20000})
511
+ if file_path:
512
+ return _gh(f"gh api repos/{{owner}}/{{repo}}/contents/{file_path} "
513
+ "--jq '.content' | base64 -d")
514
+ return {"success": False, "error": "Provide 'ref' (owner/repo@branch:path) or 'path'"}
515
+
516
+ if action in ("pr_diff", "diff"):
517
+ number = params.get("number") or params.get("pr")
518
+ if not number:
519
+ return {"success": False, "error": "Missing 'number' parameter"}
520
+ return _gh(f"gh pr diff {number}", timeout=30)
521
+
522
+ if action in ("pr_checks", "checks", "ci"):
523
+ number = params.get("number") or params.get("pr")
524
+ return _gh(f"gh pr checks {number or ''}")
525
+
526
+ if action in ("git_status", "status"):
527
+ return tool_run_command(
528
+ {"command": "git status --short && echo '---' && git log --oneline -5",
529
+ "cwd": cwd, "policy": policy},
530
+ console=console, has_rich=has_rich,
531
+ )
532
+
533
+ if action in ("commit_and_push", "commit", "push"):
534
+ message = params.get("message", "")
535
+ branch = params.get("branch", "")
536
+ add_files = params.get("files", [])
537
+ repo = params.get("repo", "") # e.g. "artheras/aria-code"
538
+ coauthor = params.get("coauthor", "")
539
+
540
+ if not message:
541
+ return {"success": False, "error": "Missing 'message' for commit_and_push"}
542
+
543
+ # ── Aria Code[bot] identity via GitHub App ─────────────────────────────
544
+ try:
545
+ from aria_code.apps.cli.github_app_auth import (
546
+ get_installation_token, get_aria_git_url,
547
+ aria_bot_env, ARIA_BOT_NAME, ARIA_BOT_EMAIL,
548
+ )
549
+ owner = (repo.split("/")[0] if repo else None) or "artheras"
550
+ token = get_installation_token(owner)
551
+ bot_env = aria_bot_env()
552
+ auth_available = True
553
+ except Exception as _auth_err:
554
+ # Fall back to local git credentials if App not configured
555
+ token = None
556
+ bot_env = {
557
+ "GIT_AUTHOR_NAME": "Aria Code",
558
+ "GIT_AUTHOR_EMAIL": "aria-code[bot]@artherahq.com",
559
+ "GIT_COMMITTER_NAME": "Aria Code",
560
+ "GIT_COMMITTER_EMAIL": "aria-code[bot]@artherahq.com",
561
+ }
562
+ auth_available = False
563
+ ARIA_BOT_NAME = "Aria Code"
564
+ ARIA_BOT_EMAIL = "aria-code[bot]@artherahq.com"
565
+
566
+ env_prefix = " ".join(f'{k}="{v}"' for k, v in bot_env.items()) + " "
567
+
568
+ # ── Build commit message with co-author attribution ────────────────────
569
+ body = message
570
+ if coauthor:
571
+ body += f"\n\nCo-Authored-By: {coauthor}"
572
+ # Always credit the Aria GitHub account so it appears in Contributors
573
+ if auth_available:
574
+ try:
575
+ from aria_code.apps.cli.github_app_auth import ARIA_GITHUB_LOGIN, ARIA_GITHUB_EMAIL
576
+ body += f"\n\nCo-Authored-By: {ARIA_GITHUB_LOGIN} <{ARIA_GITHUB_EMAIL}>"
577
+ except ImportError:
578
+ pass
579
+ user_name = tool_run_command({"command": "git config user.name", "policy": "safe", "cwd": cwd}).get("output", "").strip()
580
+ user_email = tool_run_command({"command": "git config user.email", "policy": "safe", "cwd": cwd}).get("output", "").strip()
581
+ if user_name and user_email and user_email != ARIA_BOT_EMAIL:
582
+ body += f"\n\nCo-Authored-By: {user_name} <{user_email}>"
583
+
584
+ # ── Stage ──────────────────────────────────────────────────────────────
585
+ stage_cmd = ("git add " + " ".join(shlex.quote(f) for f in add_files)) if add_files else "git add -A"
586
+ stage_result = tool_run_command(
587
+ {"command": stage_cmd, "cwd": cwd, "policy": policy},
588
+ console=console, has_rich=has_rich,
589
+ )
590
+ if not stage_result.get("success"):
591
+ return stage_result
592
+
593
+ # ── Commit ─────────────────────────────────────────────────────────────
594
+ safe_body = body.replace('"', '\\"').replace('$', '\\$')
595
+ commit_result = tool_run_command(
596
+ {"command": f'{env_prefix}git commit -m "{safe_body}"',
597
+ "cwd": cwd, "policy": policy},
598
+ console=console, has_rich=has_rich,
599
+ )
600
+ if not commit_result.get("success"):
601
+ return commit_result
602
+
603
+ # ── Push (use App token remote if available) ───────────────────────────
604
+ push_branch = branch or tool_run_command(
605
+ {"command": "git rev-parse --abbrev-ref HEAD", "policy": "safe", "cwd": cwd}
606
+ ).get("output", "").strip() or "main"
607
+
608
+ if auth_available and token and repo:
609
+ auth_url = get_aria_git_url(repo, token)
610
+ push_cmd = f"git push {shlex.quote(auth_url)} {shlex.quote(push_branch)}"
611
+ else:
612
+ push_cmd = f"git push origin {shlex.quote(push_branch)}"
613
+
614
+ push_result = tool_run_command(
615
+ {"command": push_cmd, "cwd": cwd, "policy": policy, "timeout": 60},
616
+ console=console, has_rich=has_rich,
617
+ )
618
+ return {
619
+ **push_result,
620
+ "committed_as": f"{ARIA_BOT_NAME} <{ARIA_BOT_EMAIL}>",
621
+ "branch": push_branch,
622
+ "app_auth": auth_available,
623
+ }
624
+
625
+ return {
626
+ "success": False,
627
+ "error": (
628
+ f"Unknown GitHub action: '{action}'. "
629
+ "Use: list_prs, list_issues, view_pr, view_issue, create_pr, "
630
+ "list_commits, search, read_file, pr_diff, pr_checks, "
631
+ "git_status, commit_and_push"
632
+ ),
633
+ }
634
+
635
+
636
+ def tool_ask_user(params: dict, *, console=None, has_rich: bool = True) -> dict:
637
+ """Pause execution and ask the user for clarification or a decision."""
638
+ question = params.get("question", "")
639
+ if not question:
640
+ return {"success": False, "error": "Missing 'question' parameter"}
641
+
642
+ if has_rich and console is not None:
643
+ from rich.prompt import Prompt
644
+ console.print(f"\n[bold magenta]🤔 Agent needs clarification:[/bold magenta] {question}")
645
+ try:
646
+ answer = Prompt.ask("[cyan]Your answer[/cyan]")
647
+ except (KeyboardInterrupt, EOFError):
648
+ return {"success": False, "error": "User cancelled the input."}
649
+ else:
650
+ print(f"\nAgent needs clarification: {question}")
651
+ try:
652
+ answer = input("Your answer: ")
653
+ except (KeyboardInterrupt, EOFError):
654
+ return {"success": False, "error": "User cancelled the input."}
655
+
656
+ return {"success": True, "data": {"user_answer": answer}}