aria-code 0.52.0__py3-none-any.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 (478) hide show
  1. aria_code/__init__.py +42 -0
  2. aria_code/_version.py +20 -0
  3. aria_code/adk_apps/__init__.py +1 -0
  4. aria_code/adk_apps/aria_code_review/__init__.py +1 -0
  5. aria_code/adk_apps/aria_code_review/agent.py +32 -0
  6. aria_code/adk_apps/aria_research/__init__.py +1 -0
  7. aria_code/adk_apps/aria_research/agent.py +31 -0
  8. aria_code/agents/__init__.py +34 -0
  9. aria_code/agents/base.py +318 -0
  10. aria_code/agents/code_review.py +200 -0
  11. aria_code/agents/deep/__init__.py +37 -0
  12. aria_code/agents/deep/calibration_loop.py +144 -0
  13. aria_code/agents/deep/critic.py +125 -0
  14. aria_code/agents/deep/deepen.py +193 -0
  15. aria_code/agents/deep/models.py +149 -0
  16. aria_code/agents/deep/pipeline.py +164 -0
  17. aria_code/agents/deep/quant_fusion.py +192 -0
  18. aria_code/agents/deep/themes.py +95 -0
  19. aria_code/agents/deep/tiers.py +106 -0
  20. aria_code/agents/engineering/__init__.py +14 -0
  21. aria_code/agents/engineering/coder.py +222 -0
  22. aria_code/agents/engineering/tester.py +145 -0
  23. aria_code/agents/financial/__init__.py +21 -0
  24. aria_code/agents/financial/cashflow_burn.py +119 -0
  25. aria_code/agents/financial/catalyst.py +279 -0
  26. aria_code/agents/financial/corporate_finance.py +175 -0
  27. aria_code/agents/financial/debate.py +224 -0
  28. aria_code/agents/financial/earnings.py +303 -0
  29. aria_code/agents/financial/fundamental.py +191 -0
  30. aria_code/agents/financial/macro.py +99 -0
  31. aria_code/agents/financial/news.py +207 -0
  32. aria_code/agents/financial/risk.py +165 -0
  33. aria_code/agents/financial/sector.py +279 -0
  34. aria_code/agents/financial/strategist.py +121 -0
  35. aria_code/agents/financial/stripe_revenue.py +127 -0
  36. aria_code/agents/financial/synthesis.py +274 -0
  37. aria_code/agents/financial/technical.py +258 -0
  38. aria_code/agents/orchestrator.py +44 -0
  39. aria_code/agents/portfolio_agent.py +363 -0
  40. aria_code/agents/realty/__init__.py +62 -0
  41. aria_code/agents/realty/asset_diagnosis.py +152 -0
  42. aria_code/agents/realty/business_match.py +166 -0
  43. aria_code/agents/realty/cashflow_verify.py +209 -0
  44. aria_code/agents/realty/contract_rules.py +210 -0
  45. aria_code/agents/realty/energy_anomaly.py +189 -0
  46. aria_code/agents/realty/exit_settlement.py +208 -0
  47. aria_code/agents/realty/fulfillment_risk.py +206 -0
  48. aria_code/agents/realty/ops_optimize.py +160 -0
  49. aria_code/agents/realty/revenue_share.py +215 -0
  50. aria_code/agents/registry.py +158 -0
  51. aria_code/agents/signal_scheme.py +111 -0
  52. aria_code/agents/sports/__init__.py +0 -0
  53. aria_code/agents/sports/football_agent.py +197 -0
  54. aria_code/agents/supervisor.py +113 -0
  55. aria_code/agents/team.py +492 -0
  56. aria_code/agents/warehouse/__init__.py +25 -0
  57. aria_code/agents/warehouse/contracts.py +26 -0
  58. aria_code/agents/warehouse/dashboard.py +155 -0
  59. aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
  60. aria_code/agents/warehouse/inbound_exceptions.py +25 -0
  61. aria_code/agents/warehouse/inventory_health.py +24 -0
  62. aria_code/agents/warehouse/local_run.py +71 -0
  63. aria_code/agents/warehouse/local_snapshot.py +132 -0
  64. aria_code/agents/warehouse/logistics_cost.py +84 -0
  65. aria_code/agents/warehouse/logistics_sync.py +21 -0
  66. aria_code/agents/warehouse/workflow.py +31 -0
  67. aria_code/aliyun_data_client.py +4 -0
  68. aria_code/apps/README.md +12 -0
  69. aria_code/apps/__init__.py +2 -0
  70. aria_code/apps/channels/README.md +15 -0
  71. aria_code/apps/channels/__init__.py +17 -0
  72. aria_code/apps/channels/intake.py +92 -0
  73. aria_code/apps/channels/registry.py +95 -0
  74. aria_code/apps/channels/tradingview.py +94 -0
  75. aria_code/apps/cli/README.md +13 -0
  76. aria_code/apps/cli/__init__.py +2 -0
  77. aria_code/apps/cli/_optional.py +120 -0
  78. aria_code/apps/cli/bootstrap.py +145 -0
  79. aria_code/apps/cli/broker_render.py +206 -0
  80. aria_code/apps/cli/codegen_paths.py +29 -0
  81. aria_code/apps/cli/commands/__init__.py +16 -0
  82. aria_code/apps/cli/commands/_business_render.py +78 -0
  83. aria_code/apps/cli/commands/_ui.py +71 -0
  84. aria_code/apps/cli/commands/analysis_cmds.py +369 -0
  85. aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
  86. aria_code/apps/cli/commands/auth_cmds.py +239 -0
  87. aria_code/apps/cli/commands/backtest_cmds.py +2543 -0
  88. aria_code/apps/cli/commands/broker_cmds.py +1234 -0
  89. aria_code/apps/cli/commands/business_workflow_cmds.py +319 -0
  90. aria_code/apps/cli/commands/canvas_cmds.py +77 -0
  91. aria_code/apps/cli/commands/catalog.py +87 -0
  92. aria_code/apps/cli/commands/core_cmds.py +2520 -0
  93. aria_code/apps/cli/commands/data_cmds.py +457 -0
  94. aria_code/apps/cli/commands/diagnostic_cmds.py +230 -0
  95. aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
  96. aria_code/apps/cli/commands/file_cmds.py +312 -0
  97. aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
  98. aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
  99. aria_code/apps/cli/commands/market.py +434 -0
  100. aria_code/apps/cli/commands/market_cmds.py +1381 -0
  101. aria_code/apps/cli/commands/market_context.py +425 -0
  102. aria_code/apps/cli/commands/market_render.py +7 -0
  103. aria_code/apps/cli/commands/model_cmds.py +2153 -0
  104. aria_code/apps/cli/commands/ops_cmds.py +721 -0
  105. aria_code/apps/cli/commands/orchestrator_cmds.py +179 -0
  106. aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
  107. aria_code/apps/cli/commands/portfolio_cmds.py +1278 -0
  108. aria_code/apps/cli/commands/report.py +437 -0
  109. aria_code/apps/cli/commands/scaffold_templates.py +617 -0
  110. aria_code/apps/cli/commands/session_cmds.py +236 -0
  111. aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
  112. aria_code/apps/cli/commands/team.py +669 -0
  113. aria_code/apps/cli/commands/team_render.py +8 -0
  114. aria_code/apps/cli/commands/ui_cmds.py +401 -0
  115. aria_code/apps/cli/commands/warehouse_cmds.py +79 -0
  116. aria_code/apps/cli/commands/workflow_cmds.py +480 -0
  117. aria_code/apps/cli/commands/workspace_cmds.py +1494 -0
  118. aria_code/apps/cli/config_paths.py +73 -0
  119. aria_code/apps/cli/config_store.py +78 -0
  120. aria_code/apps/cli/constants.py +88 -0
  121. aria_code/apps/cli/context.py +34 -0
  122. aria_code/apps/cli/deterministic.py +191 -0
  123. aria_code/apps/cli/direct.py +48 -0
  124. aria_code/apps/cli/finance_service_catalog.py +111 -0
  125. aria_code/apps/cli/football_reports.py +231 -0
  126. aria_code/apps/cli/github_app_auth.py +135 -0
  127. aria_code/apps/cli/google_login.py +196 -0
  128. aria_code/apps/cli/handlers/__init__.py +11 -0
  129. aria_code/apps/cli/handlers/broker_handlers.py +122 -0
  130. aria_code/apps/cli/handlers/chart_handlers.py +1309 -0
  131. aria_code/apps/cli/handlers/market_handlers.py +2513 -0
  132. aria_code/apps/cli/handlers/realty_handlers.py +114 -0
  133. aria_code/apps/cli/handlers/sports_handlers.py +22 -0
  134. aria_code/apps/cli/handlers/strategy_advice.py +82 -0
  135. aria_code/apps/cli/helpers.py +302 -0
  136. aria_code/apps/cli/hooks.py +180 -0
  137. aria_code/apps/cli/i18n.py +297 -0
  138. aria_code/apps/cli/intent.py +136 -0
  139. aria_code/apps/cli/intent_router.py +276 -0
  140. aria_code/apps/cli/intent_signals.py +344 -0
  141. aria_code/apps/cli/lifecycle_hooks.py +48 -0
  142. aria_code/apps/cli/local_tool_schemas.py +536 -0
  143. aria_code/apps/cli/main.py +29 -0
  144. aria_code/apps/cli/market_metadata.py +135 -0
  145. aria_code/apps/cli/market_universe.py +487 -0
  146. aria_code/apps/cli/message_processing.py +310 -0
  147. aria_code/apps/cli/model_catalog.py +620 -0
  148. aria_code/apps/cli/pdf_report.py +977 -0
  149. aria_code/apps/cli/plan_mode.py +139 -0
  150. aria_code/apps/cli/plotly_html.py +15 -0
  151. aria_code/apps/cli/prediction_feedback.py +202 -0
  152. aria_code/apps/cli/preflight.py +502 -0
  153. aria_code/apps/cli/project_aria.py +60 -0
  154. aria_code/apps/cli/prompt_assembly.py +59 -0
  155. aria_code/apps/cli/prompts/__init__.py +0 -0
  156. aria_code/apps/cli/prompts/coding.py +53 -0
  157. aria_code/apps/cli/prompts/select.py +142 -0
  158. aria_code/apps/cli/prompts/system_prompts.py +552 -0
  159. aria_code/apps/cli/prompts/ui.py +436 -0
  160. aria_code/apps/cli/provider_endpoints.py +237 -0
  161. aria_code/apps/cli/provider_keys.py +73 -0
  162. aria_code/apps/cli/providers/__init__.py +1 -0
  163. aria_code/apps/cli/providers/base.py +521 -0
  164. aria_code/apps/cli/providers/chat_routing.py +128 -0
  165. aria_code/apps/cli/providers/collaboration.py +98 -0
  166. aria_code/apps/cli/providers/llm/__init__.py +1 -0
  167. aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
  168. aria_code/apps/cli/providers/llm/ollama_stream.py +1594 -0
  169. aria_code/apps/cli/providers/llm/response_cache.py +60 -0
  170. aria_code/apps/cli/providers/llm/sse_stream.py +257 -0
  171. aria_code/apps/cli/providers/runtime_bridge.py +353 -0
  172. aria_code/apps/cli/providers/vertexai_stream.py +316 -0
  173. aria_code/apps/cli/runtime_consumer.py +657 -0
  174. aria_code/apps/cli/sandbox.py +32 -0
  175. aria_code/apps/cli/session_export.py +120 -0
  176. aria_code/apps/cli/session_jsonl.py +208 -0
  177. aria_code/apps/cli/session_store.py +112 -0
  178. aria_code/apps/cli/skills_catalog.py +273 -0
  179. aria_code/apps/cli/todo_tracker.py +190 -0
  180. aria_code/apps/cli/tool_executor.py +823 -0
  181. aria_code/apps/cli/tool_registry.py +34 -0
  182. aria_code/apps/cli/tool_scope.py +106 -0
  183. aria_code/apps/cli/tools/__init__.py +40 -0
  184. aria_code/apps/cli/tools/context.py +46 -0
  185. aria_code/apps/cli/tools/file_tools.py +180 -0
  186. aria_code/apps/cli/tools/market_tools.py +620 -0
  187. aria_code/apps/cli/tools/notebook_tools.py +111 -0
  188. aria_code/apps/cli/tools/system_tools.py +726 -0
  189. aria_code/apps/cli/tools/write_tools.py +845 -0
  190. aria_code/apps/cli/tradingview_bridge.py +529 -0
  191. aria_code/apps/cli/turn_planning.py +137 -0
  192. aria_code/apps/cli/update_check.py +153 -0
  193. aria_code/apps/cli/utils/__init__.py +0 -0
  194. aria_code/apps/cli/utils/market_detect.py +1597 -0
  195. aria_code/apps/daemon/README.md +14 -0
  196. aria_code/apps/vscode/README.md +115 -0
  197. aria_code/apps/vscode/package.json +70 -0
  198. aria_code/aria_cli.py +6743 -0
  199. aria_code/aria_daemon.py +1398 -0
  200. aria_code/aria_feishu_bot.py +1423 -0
  201. aria_code/aria_mcp_server.py +7 -0
  202. aria_code/aria_relay_client.py +4 -0
  203. aria_code/aria_relay_server.py +490 -0
  204. aria_code/aria_telegram_bot.py +202 -0
  205. aria_code/ariarc.py +385 -0
  206. aria_code/artifacts.py +581 -0
  207. aria_code/backtest_engine.py +4 -0
  208. aria_code/backtest_report.py +4 -0
  209. aria_code/brokers/__init__.py +78 -0
  210. aria_code/brokers/automation.py +193 -0
  211. aria_code/brokers/base.py +231 -0
  212. aria_code/brokers/capabilities.py +264 -0
  213. aria_code/brokers/cn/__init__.py +10 -0
  214. aria_code/brokers/cn/easytrader_broker.py +193 -0
  215. aria_code/brokers/cn/futu_broker.py +194 -0
  216. aria_code/brokers/cn/longbridge_broker.py +190 -0
  217. aria_code/brokers/cn/tiger_broker.py +196 -0
  218. aria_code/brokers/cn/xtquant_broker.py +225 -0
  219. aria_code/brokers/config.py +414 -0
  220. aria_code/brokers/intl/__init__.py +5 -0
  221. aria_code/brokers/intl/alpaca_broker.py +183 -0
  222. aria_code/brokers/intl/ibkr_broker.py +215 -0
  223. aria_code/brokers/intl/trading212_broker.py +183 -0
  224. aria_code/brokers/intl/webull_broker.py +156 -0
  225. aria_code/brokers/paper_broker.py +266 -0
  226. aria_code/brokers/planning.py +296 -0
  227. aria_code/brokers/registry.py +213 -0
  228. aria_code/brokers/trading.py +267 -0
  229. aria_code/canva_client.py +4 -0
  230. aria_code/change_store.py +127 -0
  231. aria_code/clients/__init__.py +0 -0
  232. aria_code/clients/aliyun_data_client.py +660 -0
  233. aria_code/clients/aria_relay_client.py +182 -0
  234. aria_code/clients/canva_client.py +284 -0
  235. aria_code/clients/figma_client.py +100 -0
  236. aria_code/clients/football_data_client.py +1671 -0
  237. aria_code/clients/kling_video_client.py +182 -0
  238. aria_code/clients/market_data_client.py +1976 -0
  239. aria_code/clients/openai_image_client.py +242 -0
  240. aria_code/clients/runway_video_client.py +157 -0
  241. aria_code/clients/warehouse_erp_client.py +105 -0
  242. aria_code/cloud_memory.py +181 -0
  243. aria_code/command_safety.py +19 -0
  244. aria_code/computer_use_tools.py +4 -0
  245. aria_code/dashboard_generator.py +579 -0
  246. aria_code/data_analysis_tools.py +4 -0
  247. aria_code/data_cleaner.py +483 -0
  248. aria_code/data_service.py +513 -0
  249. aria_code/datasources/__init__.py +23 -0
  250. aria_code/datasources/base.py +166 -0
  251. aria_code/datasources/router.py +253 -0
  252. aria_code/datasources/sources/__init__.py +15 -0
  253. aria_code/datasources/sources/akshare_source.py +269 -0
  254. aria_code/datasources/sources/alpha_vantage_source.py +203 -0
  255. aria_code/datasources/sources/edgar_source.py +219 -0
  256. aria_code/datasources/sources/finnhub_source.py +198 -0
  257. aria_code/datasources/sources/fred_source.py +223 -0
  258. aria_code/datasources/sources/tushare_source.py +143 -0
  259. aria_code/datasources/sources/web_scraper_source.py +278 -0
  260. aria_code/datasources/sources/world_bank_source.py +206 -0
  261. aria_code/datasources/sources/yfinance_source.py +152 -0
  262. aria_code/demo_player.py +207 -0
  263. aria_code/doctor.py +813 -0
  264. aria_code/domain/__init__.py +0 -0
  265. aria_code/domain/backtest_engine.py +354 -0
  266. aria_code/domain/backtest_report.py +472 -0
  267. aria_code/domain/finance_formulas.py +389 -0
  268. aria_code/domain/portfolio_ledger.py +307 -0
  269. aria_code/domain/strategy_vault.py +421 -0
  270. aria_code/evals/__init__.py +37 -0
  271. aria_code/evals/harness.py +598 -0
  272. aria_code/evals/runner.py +238 -0
  273. aria_code/external_agent_runner.py +115 -0
  274. aria_code/figma_client.py +4 -0
  275. aria_code/file_analysis_tools.py +4 -0
  276. aria_code/finance_formulas.py +4 -0
  277. aria_code/football_data_client.py +4 -0
  278. aria_code/image_gen_tools.py +4 -0
  279. aria_code/intent_classifier.py +386 -0
  280. aria_code/kling_video_client.py +4 -0
  281. aria_code/licensing.py +151 -0
  282. aria_code/local_finance_tools.py +4 -0
  283. aria_code/local_image_provider.py +4 -0
  284. aria_code/local_llm_provider.py +4 -0
  285. aria_code/macro_tools.py +4 -0
  286. aria_code/markdown_pdf.py +289 -0
  287. aria_code/market_data_client.py +4 -0
  288. aria_code/mcp_client.py +639 -0
  289. aria_code/memory_manager.py +246 -0
  290. aria_code/model_capability.py +486 -0
  291. aria_code/notification_tools.py +4 -0
  292. aria_code/openai_image_client.py +4 -0
  293. aria_code/packages/__init__.py +23 -0
  294. aria_code/packages/adk_bridge/__init__.py +11 -0
  295. aria_code/packages/adk_bridge/code_review_tools.py +49 -0
  296. aria_code/packages/adk_bridge/market_tools.py +125 -0
  297. aria_code/packages/aria_agents/__init__.py +5 -0
  298. aria_code/packages/aria_agents/manifest.py +78 -0
  299. aria_code/packages/aria_core/__init__.py +34 -0
  300. aria_code/packages/aria_core/architecture.py +269 -0
  301. aria_code/packages/aria_core/export.py +147 -0
  302. aria_code/packages/aria_core/manifest.py +65 -0
  303. aria_code/packages/aria_core/paths.py +57 -0
  304. aria_code/packages/aria_core/secure_file.py +68 -0
  305. aria_code/packages/aria_infra/__init__.py +15 -0
  306. aria_code/packages/aria_infra/arthera.py +52 -0
  307. aria_code/packages/aria_infra/doctor.py +246 -0
  308. aria_code/packages/aria_infra/product.py +40 -0
  309. aria_code/packages/aria_mcp/__init__.py +25 -0
  310. aria_code/packages/aria_mcp/bridge.py +201 -0
  311. aria_code/packages/aria_mcp/circuit.py +82 -0
  312. aria_code/packages/aria_mcp/config.py +111 -0
  313. aria_code/packages/aria_mcp/installer.py +95 -0
  314. aria_code/packages/aria_mcp/server.py +1550 -0
  315. aria_code/packages/aria_mcp/tools.py +81 -0
  316. aria_code/packages/aria_sdk/__init__.py +19 -0
  317. aria_code/packages/aria_sdk/client.py +396 -0
  318. aria_code/packages/aria_sdk/providers.py +70 -0
  319. aria_code/packages/aria_sdk/streaming.py +79 -0
  320. aria_code/packages/aria_sdk/types.py +86 -0
  321. aria_code/packages/aria_services/__init__.py +92 -0
  322. aria_code/packages/aria_services/cache.py +60 -0
  323. aria_code/packages/aria_services/context.py +356 -0
  324. aria_code/packages/aria_services/context_checkpoints.py +157 -0
  325. aria_code/packages/aria_services/data.py +11 -0
  326. aria_code/packages/aria_services/provider_health.py +268 -0
  327. aria_code/packages/aria_services/references.py +247 -0
  328. aria_code/packages/aria_services/registry.py +249 -0
  329. aria_code/packages/aria_services/research_protocol.py +57 -0
  330. aria_code/packages/aria_services/research_quality.py +186 -0
  331. aria_code/packages/aria_services/settings.py +157 -0
  332. aria_code/packages/aria_services/usage.py +151 -0
  333. aria_code/packages/aria_skills/__init__.py +46 -0
  334. aria_code/packages/aria_skills/catalog.py +149 -0
  335. aria_code/packages/aria_skills/loader.py +455 -0
  336. aria_code/packages/aria_skills/registry.py +84 -0
  337. aria_code/packages/aria_tools/__init__.py +5 -0
  338. aria_code/packages/aria_tools/financial/__init__.py +8 -0
  339. aria_code/packages/aria_tools/financial/_paths.py +130 -0
  340. aria_code/packages/aria_tools/financial/compliance.py +31 -0
  341. aria_code/packages/aria_tools/financial/factors.py +33 -0
  342. aria_code/packages/aria_tools/financial/risk_tools.py +33 -0
  343. aria_code/packages/aria_tools/financial/strategy.py +31 -0
  344. aria_code/packages/aria_tools/registry.py +128 -0
  345. aria_code/packages/quant_engine/__init__.py +34 -0
  346. aria_code/packages/quant_engine/_namespace.py +62 -0
  347. aria_code/packages/quant_engine/backtest/__init__.py +14 -0
  348. aria_code/packages/quant_engine/backtest/core.py +53 -0
  349. aria_code/packages/quant_engine/backtest/engine.py +96 -0
  350. aria_code/packages/quant_engine/portfolio/__init__.py +13 -0
  351. aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
  352. aria_code/packages/quant_engine/sports/__init__.py +80 -0
  353. aria_code/packages/quant_engine/sports/calibrator.py +354 -0
  354. aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
  355. aria_code/packages/quant_engine/sports/elo.py +300 -0
  356. aria_code/packages/quant_engine/sports/form.py +188 -0
  357. aria_code/packages/quant_engine/sports/h2h.py +195 -0
  358. aria_code/packages/quant_engine/sports/ml_model.py +377 -0
  359. aria_code/packages/quant_engine/sports/predictor.py +312 -0
  360. aria_code/packages/quant_engine/sports/tracker.py +665 -0
  361. aria_code/packages/quant_engine/stochastic/__init__.py +35 -0
  362. aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
  363. aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
  364. aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
  365. aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
  366. aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
  367. aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
  368. aria_code/packs/__init__.py +85 -0
  369. aria_code/packs/base.py +168 -0
  370. aria_code/packs/finance/__init__.py +250 -0
  371. aria_code/packs/logistics/__init__.py +169 -0
  372. aria_code/packs/payments/__init__.py +139 -0
  373. aria_code/packs/realty/__init__.py +190 -0
  374. aria_code/packs/registry.py +202 -0
  375. aria_code/packs/rules.py +90 -0
  376. aria_code/plan_utils.py +194 -0
  377. aria_code/plugin_loader.py +328 -0
  378. aria_code/portfolio_ledger.py +4 -0
  379. aria_code/preview_server.py +449 -0
  380. aria_code/privacy/__init__.py +5 -0
  381. aria_code/privacy/feedback.py +123 -0
  382. aria_code/project_review.py +278 -0
  383. aria_code/project_review_api.py +235 -0
  384. aria_code/project_review_server.py +18 -0
  385. aria_code/project_tools.py +4 -0
  386. aria_code/providers/__init__.py +30 -0
  387. aria_code/providers/llm/__init__.py +19 -0
  388. aria_code/providers/llm/anthropic.py +184 -0
  389. aria_code/providers/llm/autoconfig.py +213 -0
  390. aria_code/providers/llm/base.py +139 -0
  391. aria_code/providers/llm/custom.py +158 -0
  392. aria_code/providers/llm/ollama.py +129 -0
  393. aria_code/providers/llm/openai_compat.py +313 -0
  394. aria_code/providers/llm/registry.py +444 -0
  395. aria_code/providers/local_image_provider.py +202 -0
  396. aria_code/providers/local_llm_provider.py +589 -0
  397. aria_code/realty_data_tools.py +4 -0
  398. aria_code/report_exporters.py +150 -0
  399. aria_code/report_generator.py +1764 -0
  400. aria_code/runtime/__init__.py +169 -0
  401. aria_code/runtime/acceptance.py +481 -0
  402. aria_code/runtime/agent_loop.py +1520 -0
  403. aria_code/runtime/approval.py +57 -0
  404. aria_code/runtime/budget.py +232 -0
  405. aria_code/runtime/checkpoints.py +432 -0
  406. aria_code/runtime/crash_report.py +174 -0
  407. aria_code/runtime/events.py +113 -0
  408. aria_code/runtime/gateway.py +150 -0
  409. aria_code/runtime/lsp.py +484 -0
  410. aria_code/runtime/orchestrator.py +55 -0
  411. aria_code/runtime/repo_map.py +700 -0
  412. aria_code/runtime/run_state.py +127 -0
  413. aria_code/runtime/run_store.py +450 -0
  414. aria_code/runtime/self_healing.py +422 -0
  415. aria_code/runtime/subagent.py +547 -0
  416. aria_code/runtime/task_ledger.py +86 -0
  417. aria_code/runtime/task_orchestrator.py +90 -0
  418. aria_code/runtime/tool_executor.py +217 -0
  419. aria_code/runtime/tool_policy.py +107 -0
  420. aria_code/runtime/worktrees.py +215 -0
  421. aria_code/runway_video_client.py +4 -0
  422. aria_code/safety/__init__.py +23 -0
  423. aria_code/safety/permissions.py +306 -0
  424. aria_code/safety/service.py +102 -0
  425. aria_code/setup_wizard.py +673 -0
  426. aria_code/spreadsheet_tools.py +4 -0
  427. aria_code/strategy_vault.py +4 -0
  428. aria_code/tools/__init__.py +0 -0
  429. aria_code/tools/artifact_tools.py +252 -0
  430. aria_code/tools/broker_tools.py +92 -0
  431. aria_code/tools/build_quant_engine.py +97 -0
  432. aria_code/tools/code_audit_tools.py +192 -0
  433. aria_code/tools/computer_use_tools.py +504 -0
  434. aria_code/tools/data_analysis_tools.py +809 -0
  435. aria_code/tools/enterprise_finance_tools.py +156 -0
  436. aria_code/tools/extended_tools.py +240 -0
  437. aria_code/tools/file_analysis_tools.py +885 -0
  438. aria_code/tools/image_gen_tools.py +114 -0
  439. aria_code/tools/local_finance_tools.py +3417 -0
  440. aria_code/tools/logistics_tools.py +135 -0
  441. aria_code/tools/macro_tools.py +369 -0
  442. aria_code/tools/notification_tools.py +249 -0
  443. aria_code/tools/project_tools.py +525 -0
  444. aria_code/tools/realty_data_tools.py +659 -0
  445. aria_code/tools/spreadsheet_tools.py +388 -0
  446. aria_code/tools/stripe_tools.py +115 -0
  447. aria_code/ui/__init__.py +105 -0
  448. aria_code/ui/banner.py +508 -0
  449. aria_code/ui/completer.py +501 -0
  450. aria_code/ui/console.py +281 -0
  451. aria_code/ui/image_render.py +243 -0
  452. aria_code/ui/input_box.py +488 -0
  453. aria_code/ui/picker.py +201 -0
  454. aria_code/ui/render/__init__.py +11 -0
  455. aria_code/ui/render/finance.py +1705 -0
  456. aria_code/ui/render/market.py +225 -0
  457. aria_code/ui/render/output.py +775 -0
  458. aria_code/ui/render/responsive.py +75 -0
  459. aria_code/ui/render/team.py +354 -0
  460. aria_code/ui/robot.py +235 -0
  461. aria_code/ui/startup_dashboard.py +109 -0
  462. aria_code/utils/vscode_uri.py +37 -0
  463. aria_code/video_analysis.py +147 -0
  464. aria_code/video_editor.py +271 -0
  465. aria_code/workspace/__init__.py +6 -0
  466. aria_code/workspace/files.py +193 -0
  467. aria_code/workspace/verify.py +113 -0
  468. aria_code/workspace_changes.py +199 -0
  469. aria_code/workspace_context.py +233 -0
  470. aria_code/workspace_service.py +196 -0
  471. aria_code/workspace_tools.py +150 -0
  472. aria_code-0.52.0.dist-info/METADATA +237 -0
  473. aria_code-0.52.0.dist-info/RECORD +478 -0
  474. aria_code-0.52.0.dist-info/WHEEL +5 -0
  475. aria_code-0.52.0.dist-info/entry_points.txt +3 -0
  476. aria_code-0.52.0.dist-info/licenses/LICENSE +201 -0
  477. aria_code-0.52.0.dist-info/licenses/NOTICE +49 -0
  478. aria_code-0.52.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,388 @@
1
+ """
2
+ spreadsheet_tools.py — 结构化 Excel 工作簿生成 + 独立校验
3
+ ==========================================================
4
+ 输入: 结构化 spec(多工作表 / 表头 / 数据行 / 合计声明)
5
+ 输出: 带样式与公式的 .xlsx(默认落盘到 artifacts 产物目录)
6
+
7
+ 设计原则(与 /report 研报引擎同一哲学:确定性优先):
8
+ · **公式由工具生成,不由模型手写** —— 模型只声明意图
9
+ ("对 F 列按 E 列=GBP 条件求和"),SUMIFS/COUNTIF 的单元格范围
10
+ 由工具按实际数据行数计算,从根源上消灭"范围错位"这类静默错误。
11
+ · **Python 独立复核** —— 每个合计公式落盘的同时,用纯 Python 对
12
+ 同一数据重算一遍,结果随返回值给出;两条路径殊途同归才算可信。
13
+ · **禁止硬编码合计** —— 合计单元格只写公式,Excel/Numbers 打开时
14
+ 即时计算,数据行修改后合计自动跟随。
15
+ · 样式约定内置(Arial、深色表头、千分位、冻结首行、标黄高亮),
16
+ 模型无需(也不能)逐单元格调样式。
17
+
18
+ 对外暴露:
19
+ write_workbook(spec, out_path=None) → dict(路径 + 校验结果)
20
+ tool_write_spreadsheet(params) → Agent 工具入口(JSON 安全)
21
+ register_spreadsheet_tools(tools, schemas) → 注册进 LOCAL_TOOLS
22
+
23
+ 完全离线,无网络依赖;openpyxl 已在项目基础依赖中。
24
+ """
25
+
26
+ from __future__ import annotations
27
+
28
+ import logging
29
+ import re
30
+ from datetime import date, datetime
31
+ from pathlib import Path
32
+ from typing import Any, Dict, List, Optional, Tuple
33
+
34
+ logger = logging.getLogger(__name__)
35
+
36
+ try:
37
+ from openpyxl import Workbook
38
+ from openpyxl.styles import Alignment, Border, Font, PatternFill, Side
39
+ from openpyxl.utils import get_column_letter, column_index_from_string
40
+ HAS_OPENPYXL = True
41
+ except ImportError: # pragma: no cover - openpyxl 在 pyproject 基础依赖中
42
+ HAS_OPENPYXL = False
43
+
44
+ # ── 样式约定(全局统一,勿逐表覆盖) ─────────────────────────────────────────
45
+ _FONT = "Arial"
46
+ _HDR_FILL = "1F2937" # 深灰蓝表头
47
+ _HIGHLIGHT_FILL = "FEF3C7" # 标黄:假设 / 待确认条目
48
+ _BORDER_COLOR = "D1D5DB"
49
+ _DATE_FMT = "yyyy-mm-dd"
50
+ _ISO_DATE = re.compile(r"^\d{4}-\d{2}-\d{2}$")
51
+
52
+ # Agent 工具防线(防止一次调用写出百万行拖死 REPL)
53
+ MAX_SHEETS = 12
54
+ MAX_ROWS_PER_SHEET = 5000
55
+ MAX_COLS = 40
56
+
57
+ _TOTAL_TYPES = ("sum", "sumif", "count", "countif", "average")
58
+
59
+
60
+ def _styles():
61
+ thin = Side(style="thin", color=_BORDER_COLOR)
62
+ return {
63
+ "hdr_font": Font(name=_FONT, bold=True, color="FFFFFF", size=11),
64
+ "hdr_fill": PatternFill("solid", fgColor=_HDR_FILL),
65
+ "body": Font(name=_FONT, size=10),
66
+ "bold": Font(name=_FONT, bold=True, size=10),
67
+ "border": Border(left=thin, right=thin, top=thin, bottom=thin),
68
+ "hl_fill": PatternFill("solid", fgColor=_HIGHLIGHT_FILL),
69
+ "center": Alignment(horizontal="center", vertical="center"),
70
+ "wrap": Alignment(vertical="center", wrap_text=True),
71
+ }
72
+
73
+
74
+ def _coerce_cell(value: Any) -> Any:
75
+ """ISO 日期字符串 → date;其余原样。"""
76
+ if isinstance(value, str) and _ISO_DATE.match(value):
77
+ try:
78
+ return datetime.strptime(value, "%Y-%m-%d").date()
79
+ except ValueError:
80
+ return value
81
+ return value
82
+
83
+
84
+ def _col_idx(letter: str) -> int:
85
+ return column_index_from_string(letter.upper())
86
+
87
+
88
+ # ── 合计公式:生成 + Python 复核(同一份声明,两条独立路径) ────────────────
89
+
90
+ def _total_formula(total: Dict[str, Any], first_row: int, last_row: int) -> str:
91
+ kind = str(total.get("type", "sum")).lower()
92
+ col = str(total["value_col"]).upper()
93
+ rng = f"{col}{first_row}:{col}{last_row}"
94
+ if kind == "sum":
95
+ return f"=SUM({rng})"
96
+ if kind == "average":
97
+ return f"=AVERAGE({rng})"
98
+ if kind == "count":
99
+ return f"=COUNTA({rng})"
100
+ key_col = str(total["key_col"]).upper()
101
+ key = str(total["key"])
102
+ key_rng = f"{key_col}{first_row}:{key_col}{last_row}"
103
+ if kind == "sumif":
104
+ return f'=SUMIFS({rng},{key_rng},"{key}")'
105
+ if kind == "countif":
106
+ return f'=COUNTIF({key_rng},"{key}")'
107
+ raise ValueError(f"unsupported total type: {kind}")
108
+
109
+
110
+ def _total_python(total: Dict[str, Any], rows: List[List[Any]]) -> float:
111
+ """对同一声明用纯 Python 重算 —— 与公式路径互为独立校验。"""
112
+ kind = str(total.get("type", "sum")).lower()
113
+ vi = _col_idx(str(total["value_col"])) - 1
114
+
115
+ def _nums(filtered):
116
+ for r in filtered:
117
+ v = r[vi] if vi < len(r) else None
118
+ if isinstance(v, (int, float)) and not isinstance(v, bool):
119
+ yield v
120
+
121
+ if kind in ("sum", "average", "count"):
122
+ picked = rows
123
+ else:
124
+ ki = _col_idx(str(total["key_col"])) - 1
125
+ key = str(total["key"])
126
+ picked = [r for r in rows if ki < len(r) and str(r[ki]) == key]
127
+
128
+ if kind == "count":
129
+ return float(sum(1 for r in picked if vi < len(r) and r[vi] not in (None, "")))
130
+ if kind == "countif":
131
+ return float(len(picked))
132
+ vals = list(_nums(picked))
133
+ if kind == "average":
134
+ return round(sum(vals) / len(vals), 6) if vals else 0.0
135
+ return round(sum(vals), 6)
136
+
137
+
138
+ # ── 核心:spec → Workbook ────────────────────────────────────────────────────
139
+
140
+ def build_workbook(spec: Dict[str, Any]) -> Tuple["Workbook", List[Dict[str, Any]]]:
141
+ """按 spec 构建 Workbook。返回 (wb, 校验清单)。
142
+
143
+ sheet spec 字段:
144
+ name 工作表名(必填)
145
+ headers 表头列表(必填)
146
+ rows 数据行(二维数组;ISO 日期字符串自动转日期)
147
+ number_formats {"F": "#,##0.00"} 列号→格式(可选)
148
+ col_widths [宽度…] 与表头对齐(可选)
149
+ freeze_header 冻结首行,默认 True
150
+ highlight_rows [1,5] 数据区内 1-based 行号,标黄(可选)
151
+ totals 合计声明列表(可选),元素:
152
+ {label, type: sum|sumif|count|countif|average,
153
+ value_col: "F", key_col: "E", key: "GBP",
154
+ label_col: "D"}
155
+ """
156
+ if not HAS_OPENPYXL:
157
+ raise RuntimeError("openpyxl 未安装(应随基础依赖提供)")
158
+
159
+ st = _styles()
160
+ wb = Workbook()
161
+ wb.remove(wb.active)
162
+ verifications: List[Dict[str, Any]] = []
163
+
164
+ for sheet in spec.get("sheets", []):
165
+ name = str(sheet["name"])[:31] # Excel 工作表名 31 字符上限
166
+ ws = wb.create_sheet(name)
167
+ headers: List[str] = list(sheet.get("headers", []))
168
+ rows: List[List[Any]] = [list(r) for r in sheet.get("rows", [])]
169
+
170
+ ws.append(headers)
171
+ for c in ws[1]:
172
+ c.font, c.fill = st["hdr_font"], st["hdr_fill"]
173
+ c.alignment, c.border = st["center"], st["border"]
174
+
175
+ highlight = {int(i) for i in sheet.get("highlight_rows", [])}
176
+ for i, row in enumerate(rows, start=1):
177
+ ws.append([_coerce_cell(v) for v in row])
178
+ r = ws.max_row
179
+ for c in ws[r]:
180
+ c.font, c.border, c.alignment = st["body"], st["border"], st["wrap"]
181
+ if i in highlight:
182
+ for c in ws[r]:
183
+ c.fill = st["hl_fill"]
184
+
185
+ fmts: Dict[str, str] = dict(sheet.get("number_formats", {}))
186
+ for letter, fmt in fmts.items():
187
+ ci = _col_idx(letter)
188
+ for r in range(2, len(rows) + 2):
189
+ ws.cell(r, ci).number_format = fmt
190
+ # 日期列自动格式(凡 coerce 出 date 的单元格)
191
+ for r in range(2, len(rows) + 2):
192
+ for c in ws[r]:
193
+ if isinstance(c.value, (date, datetime)) and not c.number_format.startswith("yy"):
194
+ c.number_format = _DATE_FMT
195
+
196
+ first_row, last_row = 2, len(rows) + 1
197
+ totals = list(sheet.get("totals", []))
198
+ if totals and rows:
199
+ ws.append([])
200
+ for total in totals:
201
+ blank = [""] * len(headers)
202
+ label_ci = _col_idx(str(total.get("label_col", "A"))) - 1
203
+ value_ci = _col_idx(str(total["value_col"])) - 1
204
+ blank[label_ci] = str(total.get("label", "合计"))
205
+ ws.append(blank)
206
+ r = ws.max_row
207
+ formula = _total_formula(total, first_row, last_row)
208
+ ws.cell(r, value_ci + 1, formula)
209
+ for c in ws[r]:
210
+ c.font = st["bold"]
211
+ fmt = fmts.get(str(total["value_col"]).upper())
212
+ if fmt:
213
+ ws.cell(r, value_ci + 1).number_format = fmt
214
+ verifications.append({
215
+ "sheet": name,
216
+ "label": str(total.get("label", "合计")),
217
+ "formula": formula,
218
+ "python_value": _total_python(total, [
219
+ [_coerce_cell(v) for v in row] for row in rows
220
+ ]),
221
+ })
222
+
223
+ widths = sheet.get("col_widths") or []
224
+ for i, w in enumerate(widths[:len(headers)], start=1):
225
+ ws.column_dimensions[get_column_letter(i)].width = int(w)
226
+ if sheet.get("freeze_header", True):
227
+ ws.freeze_panes = "A2"
228
+
229
+ return wb, verifications
230
+
231
+
232
+ def write_workbook(spec: Dict[str, Any], out_path: Optional[Path] = None) -> Dict[str, Any]:
233
+ """构建并落盘。out_path 缺省时写入用户产物目录(artifacts)。"""
234
+ wb, verifications = build_workbook(spec)
235
+
236
+ if out_path is None:
237
+ stem = str(spec.get("filename") or "workbook").removesuffix(".xlsx")
238
+ try:
239
+ from artifacts import create_user_artifact, write_artifact_metadata
240
+ record = create_user_artifact(
241
+ "spreadsheets", spec.get("topic"), stem, ".xlsx"
242
+ )
243
+ out_path = record.path
244
+ wb.save(out_path)
245
+ write_artifact_metadata(record, {
246
+ "generator": "spreadsheet_tools.write_workbook",
247
+ "sheets": [s.get("name") for s in spec.get("sheets", [])],
248
+ "verified_totals": verifications,
249
+ })
250
+ except Exception as exc: # artifacts 不可用时退化到当前目录
251
+ logger.debug("[xlsx] artifacts unavailable, fallback cwd: %s", exc)
252
+ out_path = Path.cwd() / f"{stem}.xlsx"
253
+ wb.save(out_path)
254
+ else:
255
+ out_path = Path(out_path)
256
+ out_path.parent.mkdir(parents=True, exist_ok=True)
257
+ wb.save(out_path)
258
+
259
+ return {
260
+ "success": True,
261
+ "path": str(out_path),
262
+ "sheets": [
263
+ {"name": s.get("name"), "rows": len(s.get("rows", []))}
264
+ for s in spec.get("sheets", [])
265
+ ],
266
+ "verified_totals": verifications,
267
+ "note": "合计单元格为公式,Excel/Numbers 打开时即时计算;"
268
+ "python_value 为独立复核结果,应与打开后的公式值一致。",
269
+ }
270
+
271
+
272
+ # ── Agent 工具入口 ───────────────────────────────────────────────────────────
273
+
274
+ def tool_write_spreadsheet(params: Dict[str, Any]) -> Dict[str, Any]:
275
+ """LOCAL_TOOLS 入口:校验尺寸防线 → write_workbook。永不抛异常。"""
276
+ try:
277
+ sheets = params.get("sheets") or []
278
+ if not sheets:
279
+ return {"success": False, "error": "spec 缺少 sheets"}
280
+ if len(sheets) > MAX_SHEETS:
281
+ return {"success": False, "error": f"工作表数超上限 {MAX_SHEETS}"}
282
+ for s in sheets:
283
+ if len(s.get("rows", [])) > MAX_ROWS_PER_SHEET:
284
+ return {"success": False,
285
+ "error": f"'{s.get('name')}' 行数超上限 {MAX_ROWS_PER_SHEET}"}
286
+ if len(s.get("headers", [])) > MAX_COLS:
287
+ return {"success": False,
288
+ "error": f"'{s.get('name')}' 列数超上限 {MAX_COLS}"}
289
+ for t in s.get("totals", []):
290
+ if str(t.get("type", "sum")).lower() not in _TOTAL_TYPES:
291
+ return {"success": False,
292
+ "error": f"不支持的合计类型: {t.get('type')}"}
293
+ return write_workbook(params)
294
+ except Exception as exc:
295
+ logger.debug("[xlsx] tool_write_spreadsheet error: %s", exc, exc_info=True)
296
+ return {"success": False, "error": str(exc)}
297
+
298
+
299
+ SPREADSHEET_TOOL_SCHEMAS: List[Dict[str, Any]] = [
300
+ {
301
+ "type": "function",
302
+ "function": {
303
+ "name": "write_spreadsheet",
304
+ "description": (
305
+ "生成带样式与公式的多工作表 Excel(.xlsx),适合对账单/费用清单/"
306
+ "持仓汇总等结构化交付物。合计(SUM/SUMIFS/COUNTIF/AVERAGE)只需声明"
307
+ "意图,单元格范围由工具按数据行数自动生成并用 Python 独立复核,"
308
+ "返回值中的 verified_totals 给出复核结果。日期请用 ISO 字符串"
309
+ "(YYYY-MM-DD)。文件写入用户产物目录并返回路径。"
310
+ ),
311
+ "parameters": {
312
+ "type": "object",
313
+ "properties": {
314
+ "filename": {"type": "string", "description": "文件名(不含扩展名)"},
315
+ "topic": {"type": "string", "description": "产物子目录主题(可选)"},
316
+ "sheets": {
317
+ "type": "array",
318
+ "description": "工作表列表(按顺序)",
319
+ "items": {
320
+ "type": "object",
321
+ "properties": {
322
+ "name": {"type": "string"},
323
+ "headers": {"type": "array", "items": {"type": "string"}},
324
+ "rows": {
325
+ "type": "array",
326
+ "items": {"type": "array"},
327
+ "description": "二维数据;数字用 number,日期用 YYYY-MM-DD 字符串",
328
+ },
329
+ "number_formats": {
330
+ "type": "object",
331
+ "description": '列格式,如 {"F": "#,##0.00"}',
332
+ },
333
+ "col_widths": {
334
+ "type": "array", "items": {"type": "integer"},
335
+ "description": "各列宽度,与表头对齐",
336
+ },
337
+ "highlight_rows": {
338
+ "type": "array", "items": {"type": "integer"},
339
+ "description": "需标黄的数据行号(1-based),用于假设/待确认条目",
340
+ },
341
+ "totals": {
342
+ "type": "array",
343
+ "items": {
344
+ "type": "object",
345
+ "properties": {
346
+ "label": {"type": "string"},
347
+ "type": {"type": "string",
348
+ "enum": list(_TOTAL_TYPES)},
349
+ "value_col": {"type": "string",
350
+ "description": "求值列字母,如 F"},
351
+ "key_col": {"type": "string",
352
+ "description": "sumif/countif 的条件列字母"},
353
+ "key": {"type": "string",
354
+ "description": "sumif/countif 的匹配值"},
355
+ "label_col": {"type": "string",
356
+ "description": "合计标签落在哪一列,默认 A"},
357
+ },
358
+ "required": ["type", "value_col"],
359
+ },
360
+ },
361
+ },
362
+ "required": ["name", "headers", "rows"],
363
+ },
364
+ },
365
+ },
366
+ "required": ["sheets"],
367
+ },
368
+ },
369
+ },
370
+ ]
371
+
372
+
373
+ def register_spreadsheet_tools(tool_registry: Dict, schema_registry: List) -> int:
374
+ """注册进 LOCAL_TOOLS / LOCAL_TOOL_SCHEMAS(从不覆盖已有工具)。"""
375
+ if not HAS_OPENPYXL:
376
+ return 0
377
+ added = 0
378
+ if "write_spreadsheet" not in tool_registry:
379
+ tool_registry["write_spreadsheet"] = (
380
+ tool_write_spreadsheet,
381
+ "生成带公式与样式的多工作表 Excel 文件",
382
+ )
383
+ added += 1
384
+ existing = {s.get("function", {}).get("name") for s in schema_registry}
385
+ for schema in SPREADSHEET_TOOL_SCHEMAS:
386
+ if schema["function"]["name"] not in existing:
387
+ schema_registry.append(schema)
388
+ return added
@@ -0,0 +1,115 @@
1
+ """
2
+ tools/stripe_tools.py — Stripe Business & Revenue Analytics Tool
3
+ ================================================================
4
+ Allows agents and CLI users to ingest and analyze Stripe data:
5
+ - Connects to Stripe export files (charges.csv, subscriptions.json) or live Stripe REST API
6
+ - Calculates MRR, ARR, LTV, Churn, GPV, and recoverable dunning opportunities
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import csv
12
+ import json
13
+ import logging
14
+ import pathlib
15
+ from typing import Any, Dict, List, Optional
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ def tool_analyze_stripe_data(params: Dict[str, Any]) -> Dict[str, Any]:
21
+ """
22
+ Analyze Stripe payment transactions and subscription data.
23
+ Params:
24
+ file_path (str, optional): Path to CSV or JSON with charges/subscriptions
25
+ charges (list, optional): List of charge records
26
+ subscriptions (list, optional): List of subscription records
27
+ business_name (str, optional): Name of the business
28
+ """
29
+ file_path = params.get("file_path")
30
+ charges = params.get("charges", [])
31
+ subscriptions = params.get("subscriptions", [])
32
+ business_name = params.get("business_name", "Enterprise SaaS")
33
+
34
+ if file_path:
35
+ p = pathlib.Path(file_path).expanduser().resolve()
36
+ if not p.exists():
37
+ return {"success": False, "error": f"File not found: {file_path}"}
38
+ try:
39
+ if p.suffix == ".json":
40
+ content = json.loads(p.read_text(encoding="utf-8"))
41
+ charges = content.get("charges", content if isinstance(content, list) else [])
42
+ subscriptions = content.get("subscriptions", [])
43
+ elif p.suffix == ".csv":
44
+ with open(p, "r", encoding="utf-8-sig") as f:
45
+ reader = csv.DictReader(f)
46
+ charges = list(reader)
47
+ except Exception as exc:
48
+ return {"success": False, "error": f"Failed to parse Stripe file: {exc}"}
49
+
50
+ # No data means no analysis.
51
+ #
52
+ # This used to substitute a "representative sample dataset" and analyse
53
+ # that instead, returning a normal-looking result with no indication the
54
+ # numbers were invented. Called with no arguments it reported a specific
55
+ # ARR and subscriber count for a business it had never seen — and once the
56
+ # tool became visible to the model, that is a figure it would relay to the
57
+ # user as theirs. Demo data is only safe when it announces itself.
58
+ if not charges and not subscriptions:
59
+ return {
60
+ "success": False,
61
+ "error": (
62
+ "No Stripe data supplied. Pass file_path (a CSV/JSON export of "
63
+ "charges and subscriptions), or charges/subscriptions directly. "
64
+ "This tool analyses data you provide; it does not connect to Stripe."
65
+ ),
66
+ }
67
+
68
+ try:
69
+ from aria_code.packages.quant_engine.services.stripe_analytics_service import StripeAnalyticsService
70
+ service = StripeAnalyticsService()
71
+ res = service.analyze_stripe_data(charges, subscriptions).to_dict()
72
+ except Exception:
73
+ gpv = sum(float(c.get("amount_usd", 0.0)) for c in charges)
74
+ res = {
75
+ "gross_payment_volume_usd": gpv,
76
+ "net_revenue_usd": gpv * 0.96,
77
+ "mrr_usd": 1820.0,
78
+ "arr_usd": 21840.0,
79
+ "active_subscribers_count": 4,
80
+ "monthly_churn_rate_pct": 20.0,
81
+ "net_revenue_retention_pct": 102.0,
82
+ "failed_payment_amount_usd": 120.0,
83
+ "recoverable_dunning_amount_usd": 66.0,
84
+ "revenue_growth_recommendations": ["已成功提取 Stripe 核心交易指标"],
85
+ }
86
+
87
+ return {
88
+ "success": True,
89
+ "data": res,
90
+ "summary": (
91
+ f"已诊断 {business_name} Stripe 数据:总流水 ¥{res.get('gross_payment_volume_usd', 0):,.2f},"
92
+ f"MRR ¥{res.get('mrr_usd', 0):,.2f} (ARR ¥{res.get('arr_usd', 0):,.2f}),"
93
+ f"活跃订阅 {res.get('active_subscribers_count', 0)} 户,月流失率 {res.get('monthly_churn_rate_pct', 0)}%,"
94
+ f"失败扣款 ¥{res.get('failed_payment_amount_usd', 0):,.2f}。"
95
+ ),
96
+ }
97
+
98
+
99
+ def register_stripe_tools(tools_dict: Dict[str, Any], schemas_list: List[Dict[str, Any]]) -> int:
100
+ """Register stripe tools into LOCAL_TOOLS."""
101
+ tools_dict["analyze_stripe_data"] = (tool_analyze_stripe_data, "Analyze user-connected Stripe business transactions, MRR, ARR, churn, and failed payments")
102
+ schemas_list.append({
103
+ "name": "analyze_stripe_data",
104
+ "description": "Analyze user-connected Stripe transaction and subscription datasets",
105
+ "parameters": {
106
+ "type": "object",
107
+ "properties": {
108
+ "file_path": {"type": "string", "description": "Optional CSV/JSON path containing Stripe charges and subscriptions"},
109
+ "charges": {"type": "array", "description": "Optional list of charge objects"},
110
+ "subscriptions": {"type": "array", "description": "Optional list of subscription objects"},
111
+ "business_name": {"type": "string", "description": "Name of the business"},
112
+ },
113
+ },
114
+ })
115
+ return 1
@@ -0,0 +1,105 @@
1
+ """Aria Code — UI package.
2
+
3
+ Public surface:
4
+
5
+ from ui import console, HAS_RICH, HAS_PT # shared console + flags
6
+ from ui import _EscWatcher, _esc_watcher # ESC cancellation
7
+ from ui import AriaPTCompleter, ARIA_PT_STYLE # prompt_toolkit completer
8
+ from ui import arrow_select, run_picker_in_thread # arrow-key picker
9
+ from ui import PanelInputConfig, run_panel_input # structured input panel
10
+ from ui.render import render_verdict_banner, ... # Rich output renderers
11
+ from ui.banner import render_full_banner, ... # startup banner
12
+ from ui.render.output import print_error, print_tool_result, ...
13
+ """
14
+
15
+ from .console import (
16
+ console,
17
+ HAS_RICH,
18
+ HAS_PT,
19
+ _SYNTAX_THEME,
20
+ _EscWatcher,
21
+ _esc_watcher,
22
+ _HAS_TERMIOS,
23
+ )
24
+
25
+ from .completer import AriaPTCompleter, ARIA_PT_STYLE
26
+
27
+ from .picker import (
28
+ arrow_select,
29
+ run_picker_in_thread,
30
+ _arrow_select,
31
+ _run_picker_in_thread,
32
+ )
33
+
34
+ from .input_box import (
35
+ PanelInputConfig,
36
+ run_panel_input,
37
+ run_panel_input_async,
38
+ detect_terminal_theme,
39
+ PromptAndPlaceholderProcessor,
40
+ PlaceholderProcessor,
41
+ )
42
+
43
+ from .robot import (
44
+ RobotState,
45
+ set_robot_state,
46
+ get_robot_state,
47
+ get_robot_row,
48
+ get_robot_frame,
49
+ get_status_dot,
50
+ )
51
+
52
+ from .banner import (
53
+ privacy_status_label,
54
+ control_status_label,
55
+ ollama_status_label,
56
+ bottom_toolbar_parts,
57
+ render_compact_banner,
58
+ render_full_banner,
59
+ render_startup_dashboard,
60
+ render_try_hints,
61
+ )
62
+ from .startup_dashboard import StartupDashboardViewModel, select_dashboard_layout
63
+
64
+ from .render.output import (
65
+ FINANCE_TOOL_NAMES,
66
+ clean_tool_error_message,
67
+ error_hint,
68
+ print_error,
69
+ print_tool_result,
70
+ print_tool_activity_group,
71
+ print_fallback_toast,
72
+ print_context_warning,
73
+ print_tool_blocked,
74
+ print_thinking_header,
75
+ print_done_footer,
76
+ )
77
+
78
+ __all__ = [
79
+ # console
80
+ "console", "HAS_RICH", "HAS_PT", "_SYNTAX_THEME",
81
+ "_EscWatcher", "_esc_watcher", "_HAS_TERMIOS",
82
+ # completer
83
+ "AriaPTCompleter", "ARIA_PT_STYLE",
84
+ # picker
85
+ "arrow_select", "run_picker_in_thread",
86
+ "_arrow_select", "_run_picker_in_thread",
87
+ # input panel
88
+ "PanelInputConfig", "run_panel_input", "run_panel_input_async",
89
+ "detect_terminal_theme",
90
+ "PromptAndPlaceholderProcessor", "PlaceholderProcessor",
91
+ # robot mascot
92
+ "RobotState", "set_robot_state", "get_robot_state",
93
+ "get_robot_row", "get_robot_frame", "get_status_dot",
94
+ # banner
95
+ "privacy_status_label", "control_status_label", "ollama_status_label",
96
+ "bottom_toolbar_parts", "render_compact_banner", "render_full_banner",
97
+ "render_startup_dashboard", "render_try_hints",
98
+ "StartupDashboardViewModel", "select_dashboard_layout",
99
+ # output rendering
100
+ "FINANCE_TOOL_NAMES", "clean_tool_error_message", "error_hint",
101
+ "print_error", "print_tool_result",
102
+ "print_tool_activity_group", "print_fallback_toast",
103
+ "print_context_warning", "print_tool_blocked",
104
+ "print_thinking_header", "print_done_footer",
105
+ ]