aria-code 0.167.0__py3-none-macosx_13_0_arm64.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 +0 -0
  22. aria_code/_bin/aria-runtime +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,186 @@
1
+ """The daily shipper digest: what needs attention, pushed to the shipper's group.
2
+
3
+ A bot that only answers questions waits to be asked about the SKU that ran out
4
+ yesterday. This sends each shipper's group, unprompted, what the 3PL would
5
+ otherwise find out too late: what to reorder, what history is too thin to
6
+ plan from, what stock has stopped moving, which waybills to query with the
7
+ carrier, and where a cheaper carrier is at least as reliable.
8
+
9
+ Platform-neutral like the rest of apps/channels: it walks the conversations
10
+ bound to a shipper (ConversationStore) and hands each digest to that
11
+ channel's sender. Feishu is the first sender; another channel registers one.
12
+
13
+ Where the data comes from is the operator's decision, not the chat's:
14
+ ARIA_SHIPPER_FEEDS names a JSON file mapping each shipper to its exports —
15
+
16
+ {"ACME": {"inventory": "/data/acme/skus.csv", "waybills": "/data/acme/waybills.csv"},
17
+ "*": {"inventory": "/data/wms/all_skus.csv"}}
18
+
19
+ "*" is the fallback for shippers without their own entry, typically one
20
+ multi-shipper export. Letting a chat command set a path would let anyone in
21
+ the group read any CSV on the host.
22
+
23
+ Every number comes from plan_inventory_policy and score_carriers, run with
24
+ ARIA_OWNER_SCOPE set to the shipper — the same tool-level confinement a bound
25
+ conversation gets — so a shared multi-shipper export yields only that
26
+ shipper's lines, and a file without owner_id is refused rather than guessed.
27
+ Digests are built one at a time: the scope is process environment, and the
28
+ tools are synchronous, so nothing else runs while it is set.
29
+ """
30
+
31
+ from __future__ import annotations
32
+
33
+ import json
34
+ import logging
35
+ import os
36
+ from contextlib import contextmanager
37
+ from dataclasses import dataclass, field
38
+ from pathlib import Path
39
+ from typing import Awaitable, Callable, Dict, Iterator, List, Optional
40
+
41
+ from aria_bots.channels.conversation import ConversationStore
42
+ from aria_bots.logistics.tenancy import OWNER_SCOPE_ENV
43
+
44
+ logger = logging.getLogger(__name__)
45
+
46
+ FEEDS_ENV = "ARIA_SHIPPER_FEEDS"
47
+ MAX_LINES = 8 # per section; a digest is a prompt to look, not the report
48
+
49
+ # (conversation_id, title, body) -> delivered?
50
+ Sender = Callable[[str, str, str], Awaitable[bool]]
51
+
52
+
53
+ @dataclass
54
+ class Digest:
55
+ owner_id: str
56
+ title: str
57
+ body: str = ""
58
+ items: int = 0
59
+ problems: List[str] = field(default_factory=list)
60
+
61
+ @property
62
+ def worth_sending(self) -> bool:
63
+ return self.items > 0
64
+
65
+
66
+ def load_feeds(path: Optional[str] = None) -> Dict[str, Dict[str, str]]:
67
+ """The operator's shipper → export files map; {} when not configured."""
68
+ source = path or os.environ.get(FEEDS_ENV, "").strip()
69
+ if not source:
70
+ return {}
71
+ data = json.loads(Path(source).expanduser().read_text(encoding="utf-8"))
72
+ if not isinstance(data, dict):
73
+ raise ValueError(f"{FEEDS_ENV} must be a JSON object of shipper -> feeds")
74
+ return {str(k): {kind: str(v) for kind, v in (feeds or {}).items()} for k, feeds in data.items()}
75
+
76
+
77
+ def feeds_for(owner_id: str, feeds: Dict[str, Dict[str, str]]) -> Dict[str, str]:
78
+ return feeds.get(owner_id) or feeds.get("*") or {}
79
+
80
+
81
+ @contextmanager
82
+ def _confined_to(owner_id: str) -> Iterator[None]:
83
+ previous = os.environ.get(OWNER_SCOPE_ENV)
84
+ os.environ[OWNER_SCOPE_ENV] = owner_id
85
+ try:
86
+ yield
87
+ finally:
88
+ if previous is None:
89
+ os.environ.pop(OWNER_SCOPE_ENV, None)
90
+ else:
91
+ os.environ[OWNER_SCOPE_ENV] = previous
92
+
93
+
94
+ def _section(title: str, lines: List[str]) -> str:
95
+ shown = lines[:MAX_LINES]
96
+ more = f"\n- …另有 {len(lines) - MAX_LINES} 项" if len(lines) > MAX_LINES else ""
97
+ return f"**{title}({len(lines)})**\n" + "\n".join(f"- {line}" for line in shown) + more
98
+
99
+
100
+ def build_digest(owner_id: str, feeds: Dict[str, Dict[str, str]]) -> Digest:
101
+ from aria_bots.logistics.carriers import tool_score_carriers
102
+ from aria_bots.logistics.inventory import tool_plan_inventory_policy
103
+
104
+ digest = Digest(owner_id=owner_id, title=f"📦 {owner_id} 今日库存与运费提醒")
105
+ sources = feeds_for(owner_id, feeds)
106
+ sections: List[str] = []
107
+
108
+ with _confined_to(owner_id):
109
+ if sources.get("inventory"):
110
+ result = tool_plan_inventory_policy({"file_path": sources["inventory"]})
111
+ if result.get("success"):
112
+ items = result["data"]["items"]
113
+ reorder = [i for i in items if i.get("action") == "reorder"]
114
+ thin = [i for i in items if i.get("action") == "insufficient_history"]
115
+ dead = [i for i in items if i.get("movement") == "dead"]
116
+ if reorder:
117
+ sections.append(_section("建议补货", [
118
+ f"{i['sku']}:订 {i['suggested_order_qty']}(现有可用 {i['inventory_position']:g},"
119
+ f"补货点 {i['reorder_point']},约可撑 {i['days_of_cover']} 天)" for i in reorder])
120
+ + "\n在群里 @Aria 发送 /补货,可发起采购单草稿审批。")
121
+ if thin:
122
+ sections.append(_section("历史不足、未给建议", [
123
+ f"{i['sku']}:仅 {i['history_days']} 天出库记录" for i in thin]))
124
+ if dead:
125
+ sections.append(_section("呆滞库存", [
126
+ f"{i['sku']}:在库 {i['on_hand']:g}" for i in dead]))
127
+ digest.items += len(reorder) + len(thin) + len(dead)
128
+ else:
129
+ digest.problems.append(f"inventory: {result.get('error')}")
130
+
131
+ if sources.get("waybills"):
132
+ result = tool_score_carriers({"file_path": sources["waybills"]})
133
+ if result.get("success"):
134
+ data = result["data"]
135
+ anomalies, savings = data.get("anomalies") or [], data.get("savings") or []
136
+ if anomalies:
137
+ sections.append(_section("运费待核对", [
138
+ f"{a['waybill_no']}({a['carrier']} {a['lane']}):{a['detail']}" for a in anomalies]))
139
+ if savings:
140
+ sections.append(_section("可节省的线路", [
141
+ f"{s['lane']}:{s['from_carrier']} → {s['to_carrier']},"
142
+ f"按近期运量约省 {s['estimated_saving']:g}(准时率不低于现承运商)" for s in savings]))
143
+ digest.items += len(anomalies) + len(savings)
144
+ else:
145
+ digest.problems.append(f"waybills: {result.get('error')}")
146
+
147
+ if not sources:
148
+ digest.problems.append(f"no feeds configured for {owner_id}")
149
+ digest.body = "\n\n".join(sections) + (
150
+ "\n\n建议数量未计入起订量、箱规和供应商条款;运费异常请先与承运商核对再下结论。" if sections else "")
151
+ return digest
152
+
153
+
154
+ async def run_digests(store: ConversationStore, senders: Dict[str, Sender],
155
+ feeds: Optional[Dict[str, Dict[str, str]]] = None) -> List[Dict[str, str]]:
156
+ """Send today's digest to every bound conversation that has something to say.
157
+
158
+ Returns one record per conversation for the log. Problems — a missing
159
+ feed, a file the tenancy check refused — go to the log only: a client's
160
+ group is not where a 3PL's configuration errors belong.
161
+ """
162
+ feeds = load_feeds() if feeds is None else feeds
163
+ report: List[Dict[str, str]] = []
164
+ built: Dict[str, Digest] = {}
165
+ for conversation, owner_id in store.bindings():
166
+ channel, _, conversation_id = conversation.partition(":")
167
+ send = senders.get(channel)
168
+ if send is None:
169
+ report.append({"conversation": conversation, "status": "no_sender"})
170
+ continue
171
+ if owner_id not in built:
172
+ try:
173
+ built[owner_id] = build_digest(owner_id, feeds)
174
+ except Exception as exc: # one bad feed must not stop the others
175
+ logger.warning("digest for %s failed: %s", owner_id, exc)
176
+ report.append({"conversation": conversation, "status": "error"})
177
+ continue
178
+ digest = built[owner_id]
179
+ for problem in digest.problems:
180
+ logger.warning("digest %s: %s", owner_id, problem)
181
+ if not digest.worth_sending:
182
+ report.append({"conversation": conversation, "status": "nothing_to_report"})
183
+ continue
184
+ delivered = await send(conversation_id, digest.title, digest.body)
185
+ report.append({"conversation": conversation, "status": "sent" if delivered else "send_failed"})
186
+ return report
@@ -0,0 +1,95 @@
1
+ """Channel registry — the declared inventory of external entrypoints.
2
+
3
+ First slice of the channels layer (contract: "Channels submit structured
4
+ tasks to gateway/runtime and never call CLI internals directly"). The
5
+ registry is pure data + config resolution: it names each channel, its
6
+ direction, the config/env that enables it, and which capability it maps to,
7
+ so the daemon and doctor can reason about channels uniformly instead of each
8
+ integration hard-coding its own discovery.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from dataclasses import dataclass, field
14
+ from typing import Any, Dict, List, Mapping, Tuple
15
+
16
+ CHANNEL_TASK_SCHEMA = "aria.channel_task.v1"
17
+
18
+
19
+ @dataclass(frozen=True)
20
+ class ChannelSpec:
21
+ name: str
22
+ direction: str # "inbound" | "outbound" | "both"
23
+ description: str
24
+ capabilities: Tuple[str, ...] = ()
25
+ # Any of these config keys (or env vars) being truthy enables the channel.
26
+ config_keys: Tuple[str, ...] = ()
27
+ env_keys: Tuple[str, ...] = ()
28
+
29
+ def enabled(self, config: Mapping[str, Any], env: Mapping[str, str]) -> bool:
30
+ for key in self.config_keys:
31
+ if config.get(key):
32
+ return True
33
+ for key in self.env_keys:
34
+ if str(env.get(key, "") or "").strip():
35
+ return True
36
+ return False
37
+
38
+
39
+ def default_channels() -> List[ChannelSpec]:
40
+ return [
41
+ ChannelSpec(
42
+ name="tradingview",
43
+ direction="inbound",
44
+ description="TradingView alert webhooks → structured alert tasks",
45
+ capabilities=("alerts.ingest", "orders.preview"),
46
+ config_keys=("tradingview_webhook",),
47
+ env_keys=("ARIA_WEBHOOK_SECRET",),
48
+ ),
49
+ ChannelSpec(
50
+ name="webhook_jobs",
51
+ direction="inbound",
52
+ description="Generic daemon webhook job queue (/webhook/trigger)",
53
+ capabilities=("tasks.enqueue",),
54
+ env_keys=("WEBHOOK_TOKEN",),
55
+ ),
56
+ ChannelSpec(
57
+ name="telegram",
58
+ direction="both",
59
+ description="Telegram bot push + command intake via the daemon",
60
+ capabilities=("notify.push", "chat.intake"),
61
+ config_keys=("telegram_bot_token",),
62
+ env_keys=("TELEGRAM_BOT_TOKEN",),
63
+ ),
64
+ ChannelSpec(
65
+ name="feishu",
66
+ direction="outbound",
67
+ description="Feishu webhook card push",
68
+ capabilities=("notify.push",),
69
+ config_keys=("feishu_webhook",),
70
+ env_keys=("FEISHU_WEBHOOK_URL",),
71
+ ),
72
+ ChannelSpec(
73
+ name="macos_notify",
74
+ direction="outbound",
75
+ description="Local macOS notification center",
76
+ capabilities=("notify.push",),
77
+ config_keys=("macos_notifications",),
78
+ ),
79
+ ChannelSpec(
80
+ name="email",
81
+ direction="outbound",
82
+ description="SMTP email push",
83
+ capabilities=("notify.push",),
84
+ config_keys=("email_smtp_host",),
85
+ env_keys=("ARIA_SMTP_HOST",),
86
+ ),
87
+ ]
88
+
89
+
90
+ def channel_map() -> Dict[str, ChannelSpec]:
91
+ return {spec.name: spec for spec in default_channels()}
92
+
93
+
94
+ def enabled_channels(config: Mapping[str, Any], env: Mapping[str, str]) -> List[ChannelSpec]:
95
+ return [spec for spec in default_channels() if spec.enabled(config, env)]
aria_bots/engine.py ADDED
@@ -0,0 +1,144 @@
1
+ """Run one chat turn on the Go engine (`aria-runtime stream`).
2
+
3
+ The bots used to shell out to aria_cli.py. Now a turn is
4
+
5
+ aria-runtime stream --format=jsonl --quiet --no-banner --prompt=...
6
+
7
+ in a workspace of its own, read as JSONL until `turn.completed`. The engine
8
+ runs headless: a tool that needs approval is refused, because nobody in the
9
+ chat can answer the prompt. An operator grants named tools with
10
+ ARIA_BOT_ALLOW_TOOLS.
11
+
12
+ The logistics tools reach the engine as an MCP server the bots register
13
+ through ARIA_MCP_EXTRA_CONFIG, so the user's own mcp_servers.json is left
14
+ alone. A conversation bound to a shipper passes ARIA_OWNER_SCOPE down; the
15
+ engine hands its environment to the MCP server, where logistics.tenancy
16
+ enforces it.
17
+ """
18
+ from __future__ import annotations
19
+
20
+ import asyncio
21
+ import json
22
+ import os
23
+ import shutil
24
+ import sys
25
+ from pathlib import Path
26
+ from typing import Iterable, Optional
27
+
28
+ from .logistics.tenancy import OWNER_SCOPE_ENV
29
+
30
+ ENGINE_ENV = "ARIA_RUNTIME"
31
+ MAX_PROMPT = 65536
32
+ LOGISTICS_SERVER = "aria-logistics"
33
+
34
+
35
+ def state_dir() -> Path:
36
+ base = os.environ.get("ARIA_BOTS_HOME", "").strip()
37
+ return Path(base).expanduser() if base else Path.home() / ".aria" / "bots"
38
+
39
+
40
+ def find_engine() -> Optional[str]:
41
+ """ARIA_RUNTIME when it names an aria-runtime, else aria-runtime on PATH."""
42
+ configured = os.environ.get(ENGINE_ENV, "").strip()
43
+ if configured:
44
+ path = Path(configured).expanduser()
45
+ if path.name.removesuffix(".exe").startswith("aria-runtime") and path.is_file() and os.access(path, os.X_OK):
46
+ return str(path)
47
+ return shutil.which("aria-runtime")
48
+
49
+
50
+ def mcp_config() -> Path:
51
+ """The servers the bots add to every engine turn (rewritten each time)."""
52
+ folder = state_dir()
53
+ folder.mkdir(parents=True, exist_ok=True)
54
+ server = {
55
+ "name": LOGISTICS_SERVER,
56
+ "command": sys.executable,
57
+ "args": ["-m", "aria_bots.logistics.mcp_server"],
58
+ "description": "Freight analysis, carrier scoring and inventory policy, scoped per shipper",
59
+ }
60
+ path = folder / "mcp_servers.json"
61
+ path.write_text(json.dumps({"servers": [server]}, indent=2), encoding="utf-8")
62
+ return path
63
+
64
+
65
+ def allowed_tools() -> list[str]:
66
+ return [t.strip() for t in os.environ.get("ARIA_BOT_ALLOW_TOOLS", "").split(",") if t.strip()]
67
+
68
+
69
+ def with_history(prompt: str, history: Optional[Iterable[dict]]) -> str:
70
+ """The engine takes one prompt; earlier messages go in front of it."""
71
+ lines = []
72
+ for item in history or []:
73
+ role = "Assistant" if item.get("role") == "assistant" else "User"
74
+ content = str(item.get("content", "")).strip()
75
+ if content:
76
+ lines.append(f"{role}: {content}")
77
+ if not lines:
78
+ return prompt
79
+ return "Earlier in this conversation:\n" + "\n".join(lines) + "\n\nNow answer:\n" + prompt
80
+
81
+
82
+ def command(engine: str, prompt: str) -> list[str]:
83
+ argv = [engine, "stream", "--format=jsonl", "--quiet", "--no-banner", f"--prompt={prompt}"]
84
+ tools = allowed_tools()
85
+ if tools:
86
+ argv += ["--allow-tools", ",".join(tools)]
87
+ return argv
88
+
89
+
90
+ def environment(owner: Optional[str]) -> dict[str, str]:
91
+ env = {**os.environ, "ARIA_BOT_MODE": "1", "ARIA_MCP_EXTRA_CONFIG": str(mcp_config())}
92
+ env.pop(OWNER_SCOPE_ENV, None)
93
+ if owner:
94
+ env[OWNER_SCOPE_ENV] = owner
95
+ return env
96
+
97
+
98
+ def read_answer(stdout: bytes) -> tuple[bool, str]:
99
+ """(success, answer) from the engine's JSONL; deltas when no final text."""
100
+ deltas: list[str] = []
101
+ for raw in stdout.splitlines():
102
+ try:
103
+ event = json.loads(raw)
104
+ except ValueError:
105
+ continue
106
+ if not isinstance(event, dict):
107
+ continue
108
+ kind = event.get("type")
109
+ if kind == "answer.delta":
110
+ deltas.append(str(event.get("text") or event.get("delta") or ""))
111
+ elif kind == "turn.completed":
112
+ answer = str(event.get("response") or "".join(deltas)).strip()
113
+ return bool(event.get("success")), answer or str(event.get("error") or "")
114
+ return False, "".join(deltas).strip()
115
+
116
+
117
+ async def run_turn(prompt: str, *, engine: str, owner: Optional[str] = None,
118
+ history: Optional[Iterable[dict]] = None, timeout: float = 120) -> str:
119
+ """The answer text, or a message starting with ❌ / ⏱️ when there is none."""
120
+ prompt = with_history(prompt, history)
121
+ if len(prompt.encode("utf-8")) > MAX_PROMPT:
122
+ return "❌ 消息太长,请缩短后重试。"
123
+ workspace = state_dir() / "workspace"
124
+ workspace.mkdir(parents=True, exist_ok=True)
125
+ proc = await asyncio.create_subprocess_exec(
126
+ *command(engine, prompt),
127
+ stdin=asyncio.subprocess.PIPE,
128
+ stdout=asyncio.subprocess.PIPE,
129
+ stderr=asyncio.subprocess.PIPE,
130
+ cwd=str(workspace),
131
+ env=environment(owner),
132
+ )
133
+ try:
134
+ # One newline acknowledges the host; EOF after it, so nothing can wait on input.
135
+ stdout, stderr = await asyncio.wait_for(proc.communicate(b"\n"), timeout=timeout)
136
+ except asyncio.TimeoutError:
137
+ proc.kill()
138
+ await proc.wait()
139
+ return f"⏱️ 查询超时(>{int(timeout)}s),请简化问题后重试。"
140
+ ok, answer = read_answer(stdout)
141
+ if answer and (ok or proc.returncode == 0):
142
+ return answer[:3000]
143
+ detail = answer or stderr.decode("utf-8", errors="replace").strip()[-500:] or f"exit {proc.returncode}"
144
+ return f"❌ Aria 引擎未能完成:{detail}"