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,171 @@
1
+ """Logistics — waybills, containers, carriers.
2
+
3
+ What makes this pack safe to have switched on is that every identifier it
4
+ recognises is *verifiable*, not merely shaped right. A bare run of twelve
5
+ digits appears in invoices, timestamps, phone numbers and order IDs; a
6
+ container number carries a check digit that can be recomputed, and a UPS or SF
7
+ tracking number carries a prefix that nothing else uses.
8
+
9
+ So the resolver reports both kinds and scores them differently: verified
10
+ identifiers activate the pack, shape-only matches are reported below the
11
+ activation threshold so the CLI can offer "did you mean this waybill?" without
12
+ answering a code question with a shipment lookup on its own initiative. That
13
+ asymmetry is the contract's rule applied to a domain whose identifiers are
14
+ almost all digits.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import re
20
+ from typing import Sequence
21
+
22
+ from aria_code.packs.base import BaseDomainPack, EntityMatch, PackActivation
23
+
24
+ PACK_NAME = "logistics"
25
+
26
+ LOGISTICS_TOOLS = (
27
+ "analyze_logistics_data",
28
+ "plan_inventory_policy",
29
+ "score_carriers",
30
+ )
31
+
32
+ _VERIFIED = 0.95
33
+ _SHAPE_ONLY = 0.3
34
+
35
+ # Carrier prefixes that no other identifier uses.
36
+ _CARRIER_PATTERNS: tuple[tuple[str, re.Pattern], ...] = (
37
+ # UPS: 1Z + 6-char shipper + 2-char service + 8-digit sequence.
38
+ ("ups", re.compile(r"\b(1Z[0-9A-Z]{16})\b", re.I)),
39
+ # SF Express domestic waybill.
40
+ ("sf", re.compile(r"\b(SF\d{12,15})\b", re.I)),
41
+ # DHL express, 'JD' + 20 digits (also used on some waybill labels).
42
+ ("dhl", re.compile(r"\b(JD\d{18,20})\b")),
43
+ )
44
+
45
+ # ISO 6346 container: 4 letters (owner + category) + 6 digits + check digit.
46
+ _CONTAINER = re.compile(r"\b([A-Z]{4}\d{7})\b")
47
+
48
+ # Bare numeric runs — the shape most domestic waybills take, and also the shape
49
+ # of an order id, an invoice number and a unix timestamp in milliseconds.
50
+ _BARE_DIGITS = re.compile(r"(?<!\d)(\d{10,15})(?!\d)")
51
+
52
+ # ISO 6346 letter values: A=10, then ascending, skipping every multiple of 11.
53
+ def _iso6346_letter_values() -> dict[str, int]:
54
+ values: dict[str, int] = {}
55
+ value = 10
56
+ for index in range(26):
57
+ while value % 11 == 0:
58
+ value += 1
59
+ values[chr(ord("A") + index)] = value
60
+ value += 1
61
+ return values
62
+
63
+
64
+ _LETTER_VALUES = _iso6346_letter_values()
65
+
66
+
67
+ def is_valid_container(code: str) -> bool:
68
+ """True when *code* satisfies the ISO 6346 check digit.
69
+
70
+ This is what separates a container number from four capitals followed by
71
+ seven digits, which is also the shape of plenty of part numbers and
72
+ internal SKUs. Recomputing the check digit turns a guess into a
73
+ resolution — the distinction the pack contract is built on.
74
+ """
75
+ text = (code or "").strip().upper()
76
+ if len(text) != 11 or not text[:4].isalpha() or not text[4:].isdigit():
77
+ return False
78
+ total = 0
79
+ for position, char in enumerate(text[:10]):
80
+ value = _LETTER_VALUES[char] if char.isalpha() else int(char)
81
+ total += value * (2 ** position)
82
+ return (total % 11) % 10 == int(text[10])
83
+
84
+
85
+ class LogisticsPack(BaseDomainPack):
86
+ """Recognises shipment identifiers and owns the freight workflows."""
87
+
88
+ name = PACK_NAME
89
+
90
+ def resolve_entities(self, message: str) -> Sequence[EntityMatch]:
91
+ text = message or ""
92
+ if not text.strip():
93
+ return ()
94
+
95
+ seen: set[str] = set()
96
+ claimed: list[tuple[int, int]] = []
97
+ entities: list[EntityMatch] = []
98
+
99
+ def _add(value: str, kind: str, surface: str, span: tuple[int, int], confidence: float) -> None:
100
+ if value in seen:
101
+ return
102
+ seen.add(value)
103
+ claimed.append(span)
104
+ entities.append(EntityMatch(
105
+ pack=PACK_NAME, kind=kind, value=value,
106
+ surface=surface, position=span[0], confidence=confidence,
107
+ ))
108
+
109
+ for carrier, pattern in _CARRIER_PATTERNS:
110
+ for match in pattern.finditer(text):
111
+ _add(match.group(1).upper(), f"waybill:{carrier}",
112
+ match.group(1), match.span(1), _VERIFIED)
113
+
114
+ for match in _CONTAINER.finditer(text):
115
+ code = match.group(1)
116
+ _add(code, "container", code, match.span(1),
117
+ _VERIFIED if is_valid_container(code) else _SHAPE_ONLY)
118
+
119
+ # Bare digit runs last, and only outside what a verified identifier
120
+ # already claimed: the digits inside `1Z999AA10123456784` are not a
121
+ # second, weaker waybill, and reporting them as one would let the UI
122
+ # offer a "did you mean" for a number the user never wrote.
123
+ for match in _BARE_DIGITS.finditer(text):
124
+ start, end = match.span(1)
125
+ if any(start >= c_start and end <= c_end for c_start, c_end in claimed):
126
+ continue
127
+ _add(match.group(1), "waybill", match.group(1), match.span(1), _SHAPE_ONLY)
128
+
129
+ return tuple(entities)
130
+
131
+ def tool_names(self) -> Sequence[str]:
132
+ return LOGISTICS_TOOLS
133
+
134
+ def prompt_fragment(self, activation: PackActivation) -> str:
135
+ kinds = sorted({e.kind for e in activation.entities})
136
+ ids = ", ".join(sorted({e.value for e in activation.entities}))
137
+ return (
138
+ f"物流标识已识别({', '.join(kinds)}):{ids}。\n"
139
+ "用工具取回的运单/箱单数据回答,不要凭记忆编造承运商、时效或费率;"
140
+ "标注数据来源与时间戳。金额与账期以对账结果为准。"
141
+ )
142
+
143
+ def acceptance_commands(self, activation: PackActivation) -> Sequence[str]:
144
+ # Looked up through the module rather than a name bound at import, so
145
+ # what this workspace declares is read when the turn runs — a .ariarc
146
+ # edited mid-session takes effect on the next message, not the next
147
+ # process.
148
+ from aria_code.packs import rules
149
+
150
+ return rules.acceptance_commands_for(PACK_NAME)
151
+
152
+
153
+ LOGISTICS_PACK = LogisticsPack()
154
+
155
+
156
+ def register() -> LogisticsPack:
157
+ """Register the logistics pack. Idempotent."""
158
+ from aria_code.packs.registry import register_pack
159
+
160
+ register_pack(LOGISTICS_PACK)
161
+ return LOGISTICS_PACK
162
+
163
+
164
+ __all__ = [
165
+ "LOGISTICS_PACK",
166
+ "LOGISTICS_TOOLS",
167
+ "PACK_NAME",
168
+ "LogisticsPack",
169
+ "is_valid_container",
170
+ "register",
171
+ ]
@@ -0,0 +1,139 @@
1
+ """Payments — Stripe objects.
2
+
3
+ The cleanest case the pack contract has. Stripe object ids carry a typed
4
+ prefix (``ch_`` charge, ``pi_`` payment intent, ``cus_`` customer, ``sub_``
5
+ subscription…) followed by a long opaque suffix, so recognising one is a
6
+ resolution rather than a guess: nothing else in an English or Chinese sentence
7
+ looks like ``pi_3PqR8s2eZvKYlo2C0aBcDeFg``.
8
+
9
+ That precision is what lets this pack stay registered permanently at no cost.
10
+ It cannot fire on domain vocabulary — the words "payment", "refund" and
11
+ "订阅" never activate it — so a payments deployment adds nothing to the latency
12
+ or the failure surface of a session about anything else.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import re
18
+ from typing import Sequence
19
+
20
+ from aria_code.packs.base import BaseDomainPack, EntityMatch, PackActivation
21
+
22
+ PACK_NAME = "payments"
23
+
24
+ PAYMENT_TOOLS = (
25
+ "analyze_stripe_data",
26
+ )
27
+
28
+ _RESOLVED = 0.95
29
+
30
+ # prefix → what the object is. Kept explicit rather than matching a generic
31
+ # `\w+_[A-Za-z0-9]{14,}` because an unknown prefix is far more likely to be
32
+ # someone's own snake_case identifier than a Stripe object.
33
+ _OBJECT_PREFIXES: dict[str, str] = {
34
+ "ch": "charge",
35
+ "pi": "payment_intent",
36
+ "cus": "customer",
37
+ "sub": "subscription",
38
+ "in": "invoice",
39
+ "il": "invoice_item",
40
+ "price": "price",
41
+ "prod": "product",
42
+ "acct": "account",
43
+ "evt": "event",
44
+ "re": "refund",
45
+ "txn": "balance_transaction",
46
+ "po": "payout",
47
+ "seti": "setup_intent",
48
+ "pm": "payment_method",
49
+ "cs": "checkout_session",
50
+ "dp": "dispute",
51
+ "sk": "secret_key",
52
+ "rk": "restricted_key",
53
+ }
54
+
55
+ # Stripe ids are prefix + '_' + at least 14 base62 characters, optionally with
56
+ # a `test_` segment in live-vs-test form (`sk_test_…`, `ch_test_…`).
57
+ _OBJECT_ID = re.compile(
58
+ r"\b(" + "|".join(sorted(_OBJECT_PREFIXES, key=len, reverse=True)) + r")_"
59
+ r"(?:test_|live_)?([A-Za-z0-9]{14,})\b"
60
+ )
61
+
62
+
63
+ class PaymentsPack(BaseDomainPack):
64
+ """Recognises Stripe object ids and owns the payments workflows."""
65
+
66
+ name = PACK_NAME
67
+
68
+ def resolve_entities(self, message: str) -> Sequence[EntityMatch]:
69
+ text = message or ""
70
+ if "_" not in text:
71
+ # Every id this pack knows contains an underscore, so this one
72
+ # check skips the regex entirely for the overwhelming majority of
73
+ # messages — the resolver runs on every message, for every pack.
74
+ return ()
75
+
76
+ seen: set[str] = set()
77
+ entities: list[EntityMatch] = []
78
+ for match in _OBJECT_ID.finditer(text):
79
+ value = match.group(0)
80
+ if value in seen:
81
+ continue
82
+ seen.add(value)
83
+ entities.append(EntityMatch(
84
+ pack=PACK_NAME,
85
+ kind=_OBJECT_PREFIXES[match.group(1)],
86
+ value=value,
87
+ surface=value,
88
+ position=match.start(),
89
+ confidence=_RESOLVED,
90
+ ))
91
+ return tuple(entities)
92
+
93
+ def tool_names(self) -> Sequence[str]:
94
+ return PAYMENT_TOOLS
95
+
96
+ def prompt_fragment(self, activation: PackActivation) -> str:
97
+ kinds = ", ".join(sorted({e.kind for e in activation.entities}))
98
+ has_key = any(e.kind.endswith("_key") for e in activation.entities)
99
+ text = (
100
+ f"Stripe 对象已识别({kinds})。\n"
101
+ "用工具取回的账务数据回答,不要凭记忆推断金额、状态或结算周期;"
102
+ "涉及退款、扣款、订阅变更等写操作时,先说明将要发生什么并等待确认。"
103
+ )
104
+ if has_key:
105
+ # The one case where the right move is to stop rather than help.
106
+ text += (
107
+ "\n⚠ 消息中疑似包含 Stripe 密钥。不要复述它、不要写入文件、"
108
+ "不要用它发起请求;提醒用户立即在 Stripe 后台轮换该密钥。"
109
+ )
110
+ return text
111
+
112
+ def acceptance_commands(self, activation: PackActivation) -> Sequence[str]:
113
+ # Looked up through the module rather than a name bound at import, so
114
+ # what this workspace declares is read when the turn runs — a .ariarc
115
+ # edited mid-session takes effect on the next message, not the next
116
+ # process.
117
+ from aria_code.packs import rules
118
+
119
+ return rules.acceptance_commands_for(PACK_NAME)
120
+
121
+
122
+ PAYMENTS_PACK = PaymentsPack()
123
+
124
+
125
+ def register() -> PaymentsPack:
126
+ """Register the payments pack. Idempotent."""
127
+ from aria_code.packs.registry import register_pack
128
+
129
+ register_pack(PAYMENTS_PACK)
130
+ return PAYMENTS_PACK
131
+
132
+
133
+ __all__ = [
134
+ "PACK_NAME",
135
+ "PAYMENTS_PACK",
136
+ "PAYMENT_TOOLS",
137
+ "PaymentsPack",
138
+ "register",
139
+ ]
@@ -0,0 +1,190 @@
1
+ """Real estate — a city's housing market.
2
+
3
+ This pack is the contract's hard case, and worth reading as one. Its domain
4
+ has no ``AAPL`` and no ``ch_3Pq…``: the thing a housing question is *about* is
5
+ a city, and a city name on its own is a perfectly ordinary word. "北京" appears
6
+ in travel plans, in address parsing, in a comment about a datacenter region.
7
+
8
+ So the entity this pack resolves is not the city. It is **this city's housing
9
+ market**, which takes two parts to name: a city from a real table, and a
10
+ housing term in the same message. A city alone resolves at a confidence below
11
+ the activation threshold — reported, so the UI can ask, but never enough to
12
+ answer a code question with a house-price index on its own initiative.
13
+
14
+ That is the same rule finance applies to a bare uppercase run, arrived at from
15
+ the opposite direction: finance has to *demote* a shape that looks like an
16
+ identifier, and realty has to *combine* two things neither of which is one.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ from typing import Sequence
22
+
23
+ from aria_code.packs.base import BaseDomainPack, EntityMatch, PackActivation
24
+
25
+ PACK_NAME = "realty"
26
+
27
+ # Empty on purpose. get_house_price_index/get_re_investment exist as functions
28
+ # in realty_data_tools but have no register_* wrapper, so they are not in
29
+ # LOCAL_TOOLS. Naming them here told the model about a capability it does not
30
+ # have, which costs a wasted round and a confusing "unknown tool" error.
31
+ # The pack still contributes its handler and its prompt guidance.
32
+ REALTY_TOOLS: tuple[str, ...] = ()
33
+
34
+ _RESOLVED = 0.95
35
+ _CITY_ONLY = 0.3
36
+
37
+ # Terms that name a housing market by themselves, with no city attached.
38
+ # "全国房价走势" is a real question about a real market, and refusing it would
39
+ # lose behaviour the ungated chain used to provide.
40
+ #
41
+ # The line drawn here is narrower than the handler's keyword list on purpose.
42
+ # "房价" and "楼市" name a market; "房产", "地产" and "物业" name a *topic*, and
43
+ # they appear in the source of any property-management codebase — which is
44
+ # exactly the kind of message that must not come back as a price index.
45
+ _NATIONAL_MARKET_TERMS = (
46
+ "房价", "楼市", "楼价", "二手房", "新房",
47
+ "house price", "home price", "housing market", "property price",
48
+ )
49
+
50
+
51
+ def _tables() -> tuple[tuple[str, ...], tuple[str, ...], tuple[str, ...]]:
52
+ """City and keyword tables, borrowed rather than duplicated.
53
+
54
+ They live in ``market_detect`` because the legacy chain used them; a copy
55
+ here would drift, and the failure that drift produces (a city Aria stopped
56
+ recognising after someone edited one list) is silent.
57
+ """
58
+ try:
59
+ from aria_code.apps.cli.utils.market_detect import (
60
+ _CN_CITIES,
61
+ _INTL_CITIES,
62
+ _REALTY_QUERY_KEYWORDS,
63
+ )
64
+ except Exception:
65
+ return (), (), ()
66
+ return tuple(_CN_CITIES), tuple(_INTL_CITIES), tuple(_REALTY_QUERY_KEYWORDS)
67
+
68
+
69
+ class RealtyPack(BaseDomainPack):
70
+ """Recognises a named city's housing market."""
71
+
72
+ name = PACK_NAME
73
+
74
+ def resolve_entities(self, message: str) -> Sequence[EntityMatch]:
75
+ text = message or ""
76
+ if not text.strip():
77
+ return ()
78
+
79
+ cn_cities, intl_cities, keywords = _tables()
80
+ if not cn_cities and not intl_cities:
81
+ return ()
82
+
83
+ lowered = text.lower()
84
+ has_housing_term = any(keyword in lowered for keyword in keywords)
85
+
86
+ found: list[tuple[str, int]] = []
87
+ for city in cn_cities:
88
+ position = text.find(city)
89
+ if position >= 0:
90
+ found.append((city, position))
91
+ for city in intl_cities:
92
+ position = lowered.find(city)
93
+ if position >= 0:
94
+ found.append((city, position))
95
+
96
+ if not found:
97
+ # No city named, but the message may still name the national
98
+ # market outright.
99
+ for term in _NATIONAL_MARKET_TERMS:
100
+ position = lowered.find(term)
101
+ if position >= 0:
102
+ return (EntityMatch(
103
+ pack=PACK_NAME, kind="housing_market", value="全国",
104
+ surface=term, position=position, confidence=_RESOLVED,
105
+ ),)
106
+ return ()
107
+
108
+ # Earliest mention first, and cap it: a message listing fifteen cities
109
+ # is a table, not a question about a housing market.
110
+ found.sort(key=lambda item: item[1])
111
+ confidence = _RESOLVED if has_housing_term else _CITY_ONLY
112
+
113
+ seen: set[str] = set()
114
+ entities: list[EntityMatch] = []
115
+ for city, position in found[:6]:
116
+ if city in seen:
117
+ continue
118
+ seen.add(city)
119
+ entities.append(EntityMatch(
120
+ pack=PACK_NAME, kind="housing_market", value=city,
121
+ surface=city, position=position, confidence=confidence,
122
+ ))
123
+ return tuple(entities)
124
+
125
+ def handlers(self) -> Sequence[object]:
126
+ """The realty handler, now reachable only when a market is named."""
127
+ try:
128
+ from aria_code.apps.cli.handlers.realty_handlers import handle_realty_query
129
+ from aria_code.apps.cli.utils.market_detect import (
130
+ _CN_CITIES,
131
+ _INTL_CITIES,
132
+ _is_realty_query,
133
+ )
134
+ except Exception:
135
+ return ()
136
+
137
+ def _handle(message: str) -> dict:
138
+ return handle_realty_query(
139
+ message,
140
+ is_realty_query=_is_realty_query,
141
+ cn_cities=_CN_CITIES,
142
+ intl_cities=_INTL_CITIES,
143
+ )
144
+
145
+ return (_handle,)
146
+
147
+ def tool_names(self) -> Sequence[str]:
148
+ return REALTY_TOOLS
149
+
150
+ def prompt_fragment(self, activation: PackActivation) -> str:
151
+ cities = ", ".join(sorted({e.value for e in activation.entities}))
152
+ # No tool instruction here: this pack exposes none. The price index is
153
+ # fetched by the deterministic handler above, so if the model is the one
154
+ # answering, it has no data source and must say so rather than produce
155
+ # a plausible number.
156
+ return (
157
+ f"房地产市场已识别:{cities}。\n"
158
+ "你没有房价数据工具。除非上文已给出取回的数据,否则不要给出具体房价、"
159
+ "涨跌幅或指数值——说明数据不可得,并建议用 /realty 命令获取;"
160
+ "标注统计口径(新房/二手房、环比/同比)与数据时间;输出不构成投资建议。"
161
+ )
162
+
163
+ def acceptance_commands(self, activation: PackActivation) -> Sequence[str]:
164
+ # Looked up through the module rather than a name bound at import, so
165
+ # what this workspace declares is read when the turn runs — a .ariarc
166
+ # edited mid-session takes effect on the next message, not the next
167
+ # process.
168
+ from aria_code.packs import rules
169
+
170
+ return rules.acceptance_commands_for(PACK_NAME)
171
+
172
+
173
+ REALTY_PACK = RealtyPack()
174
+
175
+
176
+ def register() -> RealtyPack:
177
+ """Register the realty pack. Idempotent."""
178
+ from aria_code.packs.registry import register_pack
179
+
180
+ register_pack(REALTY_PACK)
181
+ return REALTY_PACK
182
+
183
+
184
+ __all__ = [
185
+ "PACK_NAME",
186
+ "REALTY_PACK",
187
+ "REALTY_TOOLS",
188
+ "RealtyPack",
189
+ "register",
190
+ ]
@@ -0,0 +1,202 @@
1
+ """Domain pack registration and entity-gated activation.
2
+
3
+ Activation is the whole point of this module. A pack is switched on for a
4
+ message only when it resolves a concrete entity *from that message*, at or
5
+ above a confidence threshold. Three consequences follow, each of which fixes a
6
+ failure this codebase actually shipped:
7
+
8
+ - **Domain vocabulary cannot activate a pack.** "根据以上分析和建议开始完善"
9
+ contains 分析 but names nothing; no pack claims it, so no market handler,
10
+ no quote, no ticker.
11
+ - **Conversation history cannot activate a pack.** Only the user's current
12
+ message is offered to resolvers. An assistant reply that mentioned
13
+ "Cassandra/MongoDB" can no longer donate the ticker MDB to the next turn.
14
+ - **An inactive pack costs nothing.** It contributes no handlers, no tools
15
+ and no prompt text, so adding a clinical or logistics pack does not slow
16
+ down or perturb a finance user, and vice versa.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import logging
22
+ from typing import Iterable, Sequence
23
+
24
+ from aria_code.packs.base import (
25
+ DEFAULT_ACTIVATION_THRESHOLD,
26
+ DomainPack,
27
+ EntityMatch,
28
+ PackActivation,
29
+ )
30
+
31
+ logger = logging.getLogger(__name__)
32
+
33
+ _REGISTRY: dict[str, DomainPack] = {}
34
+
35
+
36
+ def register_pack(pack: DomainPack) -> None:
37
+ """Register *pack* under its name, replacing any earlier registration."""
38
+ name = getattr(pack, "name", "")
39
+ if not name:
40
+ raise ValueError("a domain pack must declare a non-empty name")
41
+ if not hasattr(pack, "resolve_entities"):
42
+ raise TypeError(f"pack {name!r} does not implement resolve_entities()")
43
+ _REGISTRY[name] = pack
44
+
45
+
46
+ def unregister_pack(name: str) -> None:
47
+ _REGISTRY.pop(name, None)
48
+
49
+
50
+ def registered_packs() -> tuple[DomainPack, ...]:
51
+ return tuple(_REGISTRY.values())
52
+
53
+
54
+ def get_pack(name: str) -> DomainPack | None:
55
+ return _REGISTRY.get(name)
56
+
57
+
58
+ def clear_registry() -> None:
59
+ """Drop every registration (tests)."""
60
+ _REGISTRY.clear()
61
+
62
+
63
+ def _entities_from(pack: DomainPack, message: str) -> list[EntityMatch]:
64
+ """Ask one pack what it recognises, never letting it break the request.
65
+
66
+ A resolver runs on every message; a pack that raises, or that returns
67
+ something malformed, must degrade to "recognises nothing" rather than take
68
+ the CLI down with it.
69
+ """
70
+ try:
71
+ found = pack.resolve_entities(message) or ()
72
+ except Exception:
73
+ logger.debug("pack %r failed to resolve entities", getattr(pack, "name", "?"),
74
+ exc_info=True)
75
+ return []
76
+ out: list[EntityMatch] = []
77
+ for entity in found:
78
+ if isinstance(entity, EntityMatch):
79
+ out.append(entity)
80
+ return out
81
+
82
+
83
+ def activate_packs(
84
+ message: str,
85
+ *,
86
+ packs: Iterable[DomainPack] | None = None,
87
+ threshold: float = DEFAULT_ACTIVATION_THRESHOLD,
88
+ ) -> tuple[PackActivation, ...]:
89
+ """Return the packs that claim *message*, most confident first.
90
+
91
+ Only the current user message is considered. Callers must not pass
92
+ conversation history here: inheriting an entity across turns is what
93
+ produced a stock quote in reply to "根据以上分析和建议开始完善".
94
+ """
95
+ if not (message or "").strip():
96
+ return ()
97
+
98
+ candidates = tuple(packs) if packs is not None else registered_packs()
99
+ activations: list[PackActivation] = []
100
+ for pack in candidates:
101
+ entities = [
102
+ e for e in _entities_from(pack, message) if e.confidence >= threshold
103
+ ]
104
+ if entities:
105
+ activations.append(
106
+ PackActivation(
107
+ pack=getattr(pack, "name", ""),
108
+ entities=tuple(entities),
109
+ )
110
+ )
111
+ activations.sort(key=lambda a: -a.confidence)
112
+ return tuple(activations)
113
+
114
+
115
+ def active_handlers(activations: Sequence[PackActivation]) -> tuple[object, ...]:
116
+ """Deterministic handlers contributed by the active packs, in order."""
117
+ handlers: list[object] = []
118
+ for activation in activations:
119
+ pack = get_pack(activation.pack)
120
+ if pack is None:
121
+ continue
122
+ try:
123
+ handlers.extend(pack.handlers() or ())
124
+ except Exception:
125
+ logger.debug("pack %r failed to provide handlers", activation.pack,
126
+ exc_info=True)
127
+ return tuple(handlers)
128
+
129
+
130
+ def active_tool_names(activations: Sequence[PackActivation]) -> tuple[str, ...]:
131
+ """Tool names to expose to the model for this message."""
132
+ names: list[str] = []
133
+ for activation in activations:
134
+ pack = get_pack(activation.pack)
135
+ if pack is None:
136
+ continue
137
+ try:
138
+ for name in pack.tool_names() or ():
139
+ if name and name not in names:
140
+ names.append(str(name))
141
+ except Exception:
142
+ logger.debug("pack %r failed to provide tool names", activation.pack,
143
+ exc_info=True)
144
+ return tuple(names)
145
+
146
+
147
+ def active_prompt_fragments(activations: Sequence[PackActivation]) -> tuple[str, ...]:
148
+ """Domain guidance to append to the system prompt for this message."""
149
+ fragments: list[str] = []
150
+ for activation in activations:
151
+ pack = get_pack(activation.pack)
152
+ if pack is None:
153
+ continue
154
+ try:
155
+ fragment = pack.prompt_fragment(activation) or ""
156
+ except Exception:
157
+ logger.debug("pack %r failed to provide a prompt fragment", activation.pack,
158
+ exc_info=True)
159
+ continue
160
+ if fragment.strip():
161
+ fragments.append(fragment.strip())
162
+ return tuple(fragments)
163
+
164
+
165
+ def active_acceptance_commands(activations: Sequence[PackActivation]) -> tuple[str, ...]:
166
+ """Verification commands contributed by the active packs, deduplicated.
167
+
168
+ Order follows activation confidence, so the pack that most clearly owns
169
+ the message gets its check run first — and the acceptance gate stops at
170
+ the first red, which makes that ordering the difference between a useful
171
+ failure and a confusing one.
172
+ """
173
+ commands: list[str] = []
174
+ for activation in activations:
175
+ pack = get_pack(activation.pack)
176
+ if pack is None:
177
+ continue
178
+ try:
179
+ found = pack.acceptance_commands(activation) or ()
180
+ except Exception:
181
+ logger.debug("pack %r failed to provide acceptance commands", activation.pack,
182
+ exc_info=True)
183
+ continue
184
+ for command in found:
185
+ text = str(command or "").strip()
186
+ if text and text not in commands:
187
+ commands.append(text)
188
+ return tuple(commands)
189
+
190
+
191
+ __all__ = [
192
+ "activate_packs",
193
+ "active_acceptance_commands",
194
+ "active_handlers",
195
+ "active_prompt_fragments",
196
+ "active_tool_names",
197
+ "clear_registry",
198
+ "get_pack",
199
+ "register_pack",
200
+ "registered_packs",
201
+ "unregister_pack",
202
+ ]