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,278 @@
1
+ """Google Cloud (Vertex AI) models used by the video workflow.
2
+
3
+ Every model call in the workflow goes through here, so the pipeline has one
4
+ place that knows endpoints, credentials and response shapes:
5
+
6
+ - Gemini (native :generateContent) — reads images and scripts, writes the
7
+ edit plan with a JSON response schema.
8
+ - Gemini TTS (gemini-2.5-flash-tts) — narration. Returns bare 24 kHz / 16-bit
9
+ mono PCM, wrapped here in a WAV header. The same request shape is already in
10
+ production in Arthera's voice routes.
11
+ - Veo — generated shots. Paid per second, so it is only reachable through
12
+ `generate_shot(..., confirmed=True)`; see pipeline.render_video.
13
+
14
+ Credentials: Application Default Credentials plus VERTEX_PROJECT (or
15
+ GOOGLE_CLOUD_PROJECT). No API keys are read here.
16
+ """
17
+ from __future__ import annotations
18
+
19
+ import base64
20
+ import json
21
+ import os
22
+ import shutil
23
+ import struct
24
+ import subprocess
25
+ import tempfile
26
+ import time
27
+ from pathlib import Path
28
+ from typing import Any, Dict, List, Optional
29
+
30
+ DEFAULT_PLANNER_MODEL = "gemini-3.8-flash"
31
+ DEFAULT_TTS_MODEL = "gemini-2.5-flash-tts"
32
+ DEFAULT_TTS_VOICE = "Aoede"
33
+ # Listed in the Vertex publisher catalog (checked 2026-09-14). Generation itself
34
+ # has not been exercised from this workflow yet: it costs money per second.
35
+ # veo-3.0-* is not reachable from our production project (404, checked 2026-09-15); Veo 3.1 is.
36
+ DEFAULT_VEO_MODEL = "veo-3.1-fast-generate-001"
37
+
38
+ MAX_INLINE_IMAGE_BYTES = 4 * 1024 * 1024
39
+ IMAGE_SUFFIX_MIME = {".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png", ".webp": "image/webp"}
40
+
41
+
42
+ class GoogleModelError(RuntimeError):
43
+ """A Google Cloud model call failed; the message says which and why."""
44
+
45
+
46
+ def _adc_config_project() -> str:
47
+ """The project named on disk by `gcloud auth application-default login`.
48
+
49
+ `google.auth.default()` finds the project for a user credential by running
50
+ `gcloud`, so it returns nothing whenever gcloud is not on PATH — which is
51
+ every run launched from a desktop app rather than a shell. Both files it
52
+ would consult are plain text, so they are read directly instead.
53
+ """
54
+ config = Path(os.getenv("CLOUDSDK_CONFIG") or Path.home() / ".config" / "gcloud")
55
+ try:
56
+ adc = json.loads((config / "application_default_credentials.json").read_text())
57
+ if adc.get("quota_project_id"):
58
+ return str(adc["quota_project_id"])
59
+ except Exception: # noqa: BLE001
60
+ pass
61
+ try:
62
+ for line in (config / "configurations" / "config_default").read_text().splitlines():
63
+ name, _, value = line.partition("=")
64
+ if name.strip() == "project" and value.strip():
65
+ return value.strip()
66
+ except Exception: # noqa: BLE001
67
+ pass
68
+ return ""
69
+
70
+
71
+ def vertex_project() -> str:
72
+ """The Google Cloud project: VERTEX_PROJECT, GOOGLE_CLOUD_PROJECT, then what ADC names.
73
+
74
+ A desktop app launches this workflow without the shell's environment, so
75
+ the project configured with `gcloud` is the useful last resort.
76
+ """
77
+ configured = os.getenv("VERTEX_PROJECT") or os.getenv("GOOGLE_CLOUD_PROJECT", "")
78
+ if configured:
79
+ return configured
80
+ try:
81
+ import google.auth
82
+
83
+ _, project = google.auth.default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
84
+ if project:
85
+ return str(project)
86
+ except Exception: # noqa: BLE001
87
+ pass
88
+ return _adc_config_project()
89
+
90
+
91
+ def _access_token() -> str:
92
+ try:
93
+ import google.auth
94
+ from google.auth.transport.requests import Request as GoogleAuthRequest
95
+
96
+ creds, _ = google.auth.default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
97
+ creds.refresh(GoogleAuthRequest())
98
+ except Exception as exc: # noqa: BLE001
99
+ raise GoogleModelError(f"Google Cloud credentials unavailable (run `gcloud auth application-default login`): {exc}") from exc
100
+ if not creds.token:
101
+ raise GoogleModelError("Google Cloud credentials returned no access token")
102
+ return creds.token
103
+
104
+
105
+ # Vertex's shared endpoints shed load: 429 and 503 mean "busy now", not
106
+ # "wrong request", and a plan that took a minute to set up should not be
107
+ # thrown away because of one of them.
108
+ _BUSY_STATUSES = frozenset({429, 503})
109
+ _BUSY_ATTEMPTS = 4
110
+ _BUSY_BACKOFF = (2.0, 6.0, 15.0)
111
+
112
+
113
+ def _explain(status: int, model: str, body: str) -> str:
114
+ """Say what a refusal means, when Vertex says it in its own vocabulary.
115
+
116
+ A project whose billing is suspended is refused with "Lightning dunning
117
+ decision is deny for project: projects/<number>" — internal wording that
118
+ reads like a fault in the request, and sends you looking through code and
119
+ credentials for something that is not there. It is the billing account.
120
+ """
121
+ if status == 403 and "dunning" in body.lower():
122
+ return (
123
+ "Google Cloud is refusing this project because of its billing account "
124
+ "(check for an unpaid balance or a suspended billing account in the "
125
+ "Cloud console). Nothing is wrong with the request or the credentials."
126
+ )
127
+ if status == 403:
128
+ return f"Google Cloud refused the call to {model}: {body[:300]}"
129
+ if status == 404:
130
+ return f"{model} is not available to this project (HTTP 404)"
131
+ return f"HTTP {status} from {model}: {body[:300]}"
132
+
133
+
134
+ def _post(url: str, body: Dict[str, Any], timeout: float) -> Dict[str, Any]:
135
+ import requests
136
+
137
+ project = vertex_project()
138
+ if not project:
139
+ raise GoogleModelError(
140
+ "No Google Cloud project: run `gcloud auth application-default login` "
141
+ "or set VERTEX_PROJECT"
142
+ )
143
+ model = url.rsplit("/", 1)[-1]
144
+ for attempt in range(_BUSY_ATTEMPTS):
145
+ response = requests.post(
146
+ url,
147
+ headers={"Authorization": f"Bearer {_access_token()}", "Content-Type": "application/json", "x-goog-user-project": project},
148
+ json=body,
149
+ timeout=timeout,
150
+ )
151
+ if response.status_code == 200:
152
+ return response.json()
153
+ if response.status_code in _BUSY_STATUSES and attempt < _BUSY_ATTEMPTS - 1:
154
+ time.sleep(_BUSY_BACKOFF[attempt])
155
+ continue
156
+ if response.status_code in _BUSY_STATUSES:
157
+ raise GoogleModelError(f"{model} is busy right now (HTTP {response.status_code}); try again in a minute")
158
+ raise GoogleModelError(_explain(response.status_code, model, response.text))
159
+ raise GoogleModelError(f"{model} is busy right now; try again in a minute")
160
+
161
+
162
+ def _generate_content_url(model: str) -> str:
163
+ return (
164
+ f"https://aiplatform.googleapis.com/v1/projects/{vertex_project()}"
165
+ f"/locations/global/publishers/google/models/{model}:generateContent"
166
+ )
167
+
168
+
169
+ def image_part(path: str) -> Dict[str, Any]:
170
+ """An inline image part. Large images are downscaled with ffmpeg first."""
171
+ source = Path(path)
172
+ mime = IMAGE_SUFFIX_MIME.get(source.suffix.lower())
173
+ data = source.read_bytes()
174
+ if mime is None or len(data) > MAX_INLINE_IMAGE_BYTES:
175
+ if shutil.which("ffmpeg") is None:
176
+ raise GoogleModelError(f"{source.name}: unsupported or too large, and ffmpeg is not available to convert it")
177
+ with tempfile.TemporaryDirectory() as tmp:
178
+ out = Path(tmp) / "image.jpg"
179
+ result = subprocess.run(
180
+ ["ffmpeg", "-y", "-loglevel", "error", "-i", str(source), "-vf", "scale='min(1600,iw)':-2", "-q:v", "3", str(out)],
181
+ capture_output=True, text=True, timeout=60,
182
+ )
183
+ if result.returncode != 0 or not out.exists():
184
+ raise GoogleModelError(f"{source.name}: could not convert image: {result.stderr[-200:]}")
185
+ data, mime = out.read_bytes(), "image/jpeg"
186
+ return {"inlineData": {"mimeType": mime, "data": base64.b64encode(data).decode("ascii")}}
187
+
188
+
189
+ def generate_json(
190
+ parts: List[Dict[str, Any]],
191
+ response_schema: Dict[str, Any],
192
+ *,
193
+ system: str = "",
194
+ model: Optional[str] = None,
195
+ timeout: float = 120.0,
196
+ ) -> Dict[str, Any]:
197
+ """Ask Gemini for a JSON object matching `response_schema` (OpenAPI subset)."""
198
+ body: Dict[str, Any] = {
199
+ "contents": [{"role": "user", "parts": parts}],
200
+ "generationConfig": {
201
+ "responseMimeType": "application/json",
202
+ "responseSchema": response_schema,
203
+ "temperature": 0.4,
204
+ },
205
+ }
206
+ if system:
207
+ body["systemInstruction"] = {"parts": [{"text": system}]}
208
+ model_id = model or os.getenv("ARIA_VIDEO_PLANNER_MODEL", DEFAULT_PLANNER_MODEL)
209
+ payload = _post(_generate_content_url(model_id), body, timeout)
210
+ try:
211
+ text = "".join(part.get("text", "") for part in payload["candidates"][0]["content"]["parts"])
212
+ return json.loads(text)
213
+ except (KeyError, IndexError, json.JSONDecodeError) as exc:
214
+ raise GoogleModelError(f"{model_id} returned no usable JSON: {str(payload)[:300]}") from exc
215
+
216
+
217
+ def _wav_from_pcm(pcm: bytes, sample_rate: int = 24000, channels: int = 1, bits: int = 16) -> bytes:
218
+ byte_rate = sample_rate * channels * bits // 8
219
+ block_align = channels * bits // 8
220
+ header = (
221
+ b"RIFF" + struct.pack("<I", 36 + len(pcm)) + b"WAVE"
222
+ + b"fmt " + struct.pack("<IHHIIHH", 16, 1, channels, sample_rate, byte_rate, block_align, bits)
223
+ + b"data" + struct.pack("<I", len(pcm))
224
+ )
225
+ return header + pcm
226
+
227
+
228
+ def synthesize_speech(text: str, output_path: str, *, voice: Optional[str] = None, model: Optional[str] = None) -> str:
229
+ """Narrate `text` with Gemini TTS into a WAV file; returns the path."""
230
+ text = (text or "").strip()
231
+ if not text:
232
+ raise GoogleModelError("Nothing to narrate")
233
+ model_id = model or os.getenv("ARIA_VIDEO_TTS_MODEL", DEFAULT_TTS_MODEL)
234
+ body = {
235
+ "contents": [{"role": "user", "parts": [{"text": text}]}],
236
+ "generationConfig": {
237
+ "responseModalities": ["AUDIO"],
238
+ "speechConfig": {"voiceConfig": {"prebuiltVoiceConfig": {"voiceName": voice or DEFAULT_TTS_VOICE}}},
239
+ },
240
+ }
241
+ payload = _post(_generate_content_url(model_id), body, timeout=90.0)
242
+ try:
243
+ inline = payload["candidates"][0]["content"]["parts"][0]["inlineData"]
244
+ pcm = base64.b64decode(inline["data"])
245
+ except (KeyError, IndexError) as exc:
246
+ raise GoogleModelError(f"{model_id} returned no audio: {str(payload)[:300]}") from exc
247
+ out = Path(output_path)
248
+ out.parent.mkdir(parents=True, exist_ok=True)
249
+ out.write_bytes(_wav_from_pcm(pcm))
250
+ return str(out)
251
+
252
+
253
+ def generate_shot(
254
+ prompt: str,
255
+ output_path: str,
256
+ *,
257
+ duration_seconds: int,
258
+ aspect_ratio: str,
259
+ image_path: Optional[str] = None,
260
+ model: Optional[str] = None,
261
+ confirmed: bool = False,
262
+ ) -> str:
263
+ """Generate one shot with Veo. Refuses unless `confirmed` — it is billed per second."""
264
+ if not confirmed:
265
+ raise GoogleModelError("Veo generation is paid per second; it needs explicit confirmation")
266
+ from aria_code.providers.google_video_provider import generate_video_google
267
+
268
+ model_id = model or os.getenv("ARIA_VIDEO_VEO_MODEL", DEFAULT_VEO_MODEL)
269
+ result = generate_video_google(
270
+ prompt, image_path=image_path, model=model_id, aspect_ratio=aspect_ratio, duration_seconds=duration_seconds,
271
+ max_wait_seconds=600.0,
272
+ )
273
+ if not result.get("success") or not result.get("path"):
274
+ raise GoogleModelError(f"Veo ({model_id}) failed: {result.get('error') or result}")
275
+ out = Path(output_path)
276
+ out.parent.mkdir(parents=True, exist_ok=True)
277
+ shutil.move(result["path"], out)
278
+ return str(out)
@@ -0,0 +1,5 @@
1
+ """music package — 视频音乐与音频资产管理服务。"""
2
+
3
+ from .service import MusicLibraryService, MusicTrackMetadata
4
+
5
+ __all__ = ["MusicLibraryService", "MusicTrackMetadata"]
@@ -0,0 +1,132 @@
1
+ """foley_service.py — 影视级拟音声效 (Foley SFX) 与转场音效服务。
2
+
3
+ 为视频自动识别并在精确毫秒时间码插入音效:
4
+ - whoosh: 镜头快速推拉或转场切换时的空气扫风声;
5
+ - glint: 金属墨镜反光、高光扫掠或极光破晓时的清脆晶莹音效;
6
+ - impact: 标题出字或产品霸气定格时的低音共振冲击 (Sub-bass impact);
7
+ - click: 极简机械按键或聚光灯开启声。
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import logging
13
+ import math
14
+ import struct
15
+ import wave
16
+ from dataclasses import dataclass, field
17
+ from pathlib import Path
18
+ from typing import Any, Dict, List, Optional
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ @dataclass
24
+ class FoleyCue:
25
+ sound_type: str # "whoosh" | "glint" | "impact" | "click"
26
+ timestamp_seconds: float
27
+ volume: float = 0.5
28
+ duration: float = 0.8
29
+ description: str = ""
30
+
31
+
32
+ class FoleySoundService:
33
+ """拟音声效编排与程序化生成服务。"""
34
+
35
+ @classmethod
36
+ def generate_cues_for_storyboard(cls, shots: List[Dict[str, Any]]) -> List[FoleyCue]:
37
+ """依据分镜时序与动作特征自动打点生成音效提示清单。"""
38
+ cues: List[FoleyCue] = []
39
+ cursor = 0.0
40
+
41
+ for idx, shot in enumerate(shots):
42
+ dur = float(shot.get("duration", 4.0))
43
+ prompt = str(shot.get("prompt", "")).lower()
44
+
45
+ # 镜头转场处(除首镜头外)插入转场扫风
46
+ if idx > 0:
47
+ cues.append(FoleyCue(
48
+ sound_type="whoosh",
49
+ timestamp_seconds=round(max(0.0, cursor - 0.15), 2),
50
+ volume=0.35,
51
+ description="Shot transition whoosh",
52
+ ))
53
+
54
+ # 包含光线反光或高光的镜头插入 Glint
55
+ if any(k in prompt for k in ["sunglasses", "reflection", "flare", "shimmer", "glint", "反光", "高光"]):
56
+ cues.append(FoleyCue(
57
+ sound_type="glint",
58
+ timestamp_seconds=round(cursor + dur * 0.4, 2),
59
+ volume=0.4,
60
+ description="Specular highlight glint shimmer",
61
+ ))
62
+
63
+ # 压轴定格或 Hook 开头插入 Sub-impact
64
+ if idx == 0 or idx == len(shots) - 1:
65
+ cues.append(FoleyCue(
66
+ sound_type="impact",
67
+ timestamp_seconds=round(cursor + 0.2, 2),
68
+ volume=0.45,
69
+ description="Cinematic low-end keynote presence",
70
+ ))
71
+
72
+ cursor += dur
73
+
74
+ return cues
75
+
76
+ @classmethod
77
+ def synthesize_cue_track(
78
+ cls,
79
+ cues: List[FoleyCue],
80
+ total_duration: float,
81
+ output_path: str,
82
+ sample_rate: int = 44100,
83
+ ) -> str:
84
+ """程序化合成包含所有 Foley 打点音效的独立音轨。"""
85
+ out_path = Path(output_path)
86
+ out_path.parent.mkdir(parents=True, exist_ok=True)
87
+
88
+ total_samples = int(total_duration * sample_rate)
89
+ samples = [0.0] * total_samples
90
+
91
+ for cue in cues:
92
+ start_sample = int(cue.timestamp_seconds * sample_rate)
93
+ if start_sample >= total_samples:
94
+ continue
95
+
96
+ cue_samples = int(cue.duration * sample_rate)
97
+ for s in range(cue_samples):
98
+ idx = start_sample + s
99
+ if idx >= total_samples:
100
+ break
101
+
102
+ t = s / sample_rate
103
+ # 根据不同音效类型生成对应的正弦频移波形
104
+ if cue.sound_type == "whoosh":
105
+ # 扫频白噪过滤带通效果
106
+ freq = 200.0 + 600.0 * math.sin(math.pi * (t / cue.duration))
107
+ val = 0.5 * math.sin(2 * math.pi * freq * t) * math.sin(math.pi * (t / cue.duration))
108
+ elif cue.sound_type == "glint":
109
+ # 高频清脆钟音 2400Hz 快速衰减
110
+ val = math.sin(2 * math.pi * 2400 * t) * math.exp(-6.0 * t)
111
+ elif cue.sound_type == "impact":
112
+ # 低频 60Hz -> 30Hz 重低音下潜
113
+ freq = 65.0 * math.exp(-2.5 * t)
114
+ val = math.sin(2 * math.pi * freq * t) * math.exp(-3.0 * t)
115
+ else:
116
+ val = 0.0
117
+
118
+ samples[idx] += val * cue.volume
119
+
120
+ # 封包为 16-bit 双声道 PCM WAV
121
+ frames = bytearray()
122
+ for sample in samples:
123
+ clamped = int(max(-32767, min(32767, sample * 16000)))
124
+ frames.extend(struct.pack("<hh", clamped, clamped))
125
+
126
+ with wave.open(str(out_path), "wb") as wf:
127
+ wf.setnchannels(2)
128
+ wf.setsampwidth(2)
129
+ wf.setframerate(sample_rate)
130
+ wf.writeframes(frames)
131
+
132
+ return str(out_path)
@@ -0,0 +1,212 @@
1
+ """service.py — 视频背景音乐 (BGM) 与音效智能管理服务。
2
+
3
+ 核心功能:
4
+ 1. 情绪与风格智能选曲:根据剧本文案与视觉风格(Keynote发布会、科技极简、萌宠轻快、史诗电影等)
5
+ 自动分析匹配最契合的背景音乐风格。
6
+ 2. 免版税与本地音乐库索引:统一管理本地存储 (~/.aria-code/music 或 assets/music) 的免版税音频资产。
7
+ 3. 程序化高保真氛围音轨合成 (Procedural Ambient Synth):零依赖、零外链,可在本地瞬时合成指定时长的
8
+ 苹果发布会质感 44.1kHz 立体声环境背景音轨。
9
+ 4. AI 生成式配乐 (MusicGen / Suno) 提示词编排:为后续接入云端生成式音乐大模型提供专业的 Prompt 生成器。
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import json
15
+ import logging
16
+ import math
17
+ import os
18
+ import struct
19
+ import wave
20
+ from dataclasses import dataclass, field
21
+ from pathlib import Path
22
+ from typing import Any, Dict, List, Optional
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ @dataclass
28
+ class MusicTrackMetadata:
29
+ id: str
30
+ title: str
31
+ genre: str # ambient, electronic, acoustic, orchestral, lofi
32
+ mood: str # professional, futuristic, cute, epic, chill
33
+ bpm: int = 90
34
+ duration_seconds: float = 30.0
35
+ file_path: Optional[str] = None
36
+ tags: List[str] = field(default_factory=list)
37
+ license: str = "Royalty-Free / CC0"
38
+
39
+
40
+ class MusicLibraryService:
41
+ """背景音乐与音频资产管理服务单例。"""
42
+
43
+ _instance: Optional[MusicLibraryService] = None
44
+
45
+ STYLE_MOOD_MAP = {
46
+ "apple_keynote": {"genre": "ambient", "mood": "professional", "bpm": 80, "desc": "Apple keynote ambient synthesizer, C major 7th chords, minimalist, spacious, inspiring"},
47
+ "tech": {"genre": "electronic", "mood": "futuristic", "bpm": 110, "desc": "Modern tech, crisp digital synth plucks, clean bassline, innovation narrative"},
48
+ "cute": {"genre": "acoustic", "mood": "cute", "bpm": 105, "desc": "Playful acoustic, wooden marimba, ukulele, cheerful, warm, bouncy pet style"},
49
+ "cinematic": {"genre": "orchestral", "mood": "epic", "bpm": 75, "desc": "Cinematic orchestral swelling, deep cello, expansive cinematic atmosphere"},
50
+ "chill": {"genre": "lofi", "mood": "chill", "bpm": 85, "desc": "Warm lo-fi chill hip-hop, vinyl crackle, gentle Rhodes piano, relaxing vibe"},
51
+ }
52
+
53
+ def __init__(self, custom_library_dir: Optional[str] = None):
54
+ self.library_dir = Path(custom_library_dir or os.path.expanduser("~/.aria-code/music"))
55
+ self.library_dir.mkdir(parents=True, exist_ok=True)
56
+ self._tracks: Dict[str, MusicTrackMetadata] = {}
57
+ self._load_local_library()
58
+
59
+ @classmethod
60
+ def get_instance(cls) -> MusicLibraryService:
61
+ if cls._instance is None:
62
+ cls._instance = cls()
63
+ return cls._instance
64
+
65
+ def _load_local_library(self) -> None:
66
+ """扫描本地音乐库目录下的音频文件与元数据。"""
67
+ meta_file = self.library_dir / "catalog.json"
68
+ if meta_file.exists():
69
+ try:
70
+ data = json.loads(meta_file.read_text(encoding="utf-8"))
71
+ for item in data.get("tracks", []):
72
+ self._tracks[item["id"]] = MusicTrackMetadata(**item)
73
+ except Exception as exc:
74
+ logger.warning(f"[MusicLibraryService] Failed to parse {meta_file}: {exc}")
75
+
76
+ # 扫描目录下的 mp3 / wav 文件
77
+ for ext in ("*.mp3", "*.wav", "*.m4a"):
78
+ for audio_file in self.library_dir.glob(ext):
79
+ tid = audio_file.stem
80
+ if tid not in self._tracks:
81
+ self._tracks[tid] = MusicTrackMetadata(
82
+ id=tid,
83
+ title=tid.replace("_", " ").title(),
84
+ genre="general",
85
+ mood="ambient",
86
+ file_path=str(audio_file),
87
+ )
88
+
89
+ def analyze_script_mood(self, script: str, style: str = "apple_keynote") -> Dict[str, Any]:
90
+ """根据脚本词汇与视频风格推断配乐情绪与匹配标准。"""
91
+ script_lower = script.lower()
92
+ matched_style = style.lower()
93
+
94
+ # 关键字启发式推导
95
+ if any(w in script_lower for w in ["发布会", "keynote", "apple", "旗舰", "pro", "极简", "优雅"]):
96
+ matched_style = "apple_keynote"
97
+ elif any(w in script_lower for w in ["猫", "狗", "萌", "可爱", "taco", "cute", "pet", "bunny", "兔"]):
98
+ matched_style = "cute"
99
+ elif any(w in script_lower for w in ["芯片", "算法", "ai", "算力", "科技", "智能", "未来"]):
100
+ matched_style = "tech"
101
+ elif any(w in script_lower for w in ["震撼", "史诗", "宇宙", "宏大", "征程", "突破"]):
102
+ matched_style = "cinematic"
103
+
104
+ spec = self.STYLE_MOOD_MAP.get(matched_style, self.STYLE_MOOD_MAP["apple_keynote"])
105
+ return {
106
+ "style": matched_style,
107
+ "genre": spec["genre"],
108
+ "mood": spec["mood"],
109
+ "target_bpm": spec["bpm"],
110
+ "ai_prompt": spec["desc"],
111
+ }
112
+
113
+ def match_or_synthesize_bgm(
114
+ self,
115
+ script: str,
116
+ style: str = "apple_keynote",
117
+ duration_seconds: float = 20.0,
118
+ output_dir: Optional[str] = None,
119
+ ) -> str:
120
+ """获取或合成与脚本最匹配的背景音乐,返回音频文件绝对路径。"""
121
+ mood_spec = self.analyze_script_mood(script, style)
122
+ matched_genre = mood_spec["genre"]
123
+
124
+ # 1. 如果本地库有匹配的音频文件,优先使用
125
+ for track in self._tracks.values():
126
+ if track.genre == matched_genre and track.file_path and os.path.exists(track.file_path):
127
+ logger.info(f"[MusicLibraryService] Using matched local library track: {track.title}")
128
+ return track.file_path
129
+
130
+ # 2. 如果没有本地预录文件,运行程序化高保真合成 (零依赖快速产出)
131
+ target_dir = Path(output_dir) if output_dir else self.library_dir
132
+ target_dir.mkdir(parents=True, exist_ok=True)
133
+ filename = f"bgm_{mood_spec['style']}_{int(duration_seconds)}s.wav"
134
+ out_path = target_dir / filename
135
+
136
+ if not out_path.exists():
137
+ logger.info(f"[MusicLibraryService] Synthesizing procedural ambient keynote track ({duration_seconds}s)...")
138
+ self.synthesize_ambient_synth_bgm(str(out_path), duration_seconds=duration_seconds)
139
+
140
+ return str(out_path)
141
+
142
+ @classmethod
143
+ def synthesize_ambient_synth_bgm(
144
+ cls,
145
+ output_path: str,
146
+ duration_seconds: float = 25.0,
147
+ sample_rate: int = 44100,
148
+ ) -> str:
149
+ """纯 Python 程序化合成 44.1kHz 立体声苹果发布会风格环境氛围音轨 (Cmaj7 -> Am9)。"""
150
+ out_path = Path(output_path)
151
+ out_path.parent.mkdir(parents=True, exist_ok=True)
152
+
153
+ total_samples = int(duration_seconds * sample_rate)
154
+ # 苹果发布会经典和弦走带: Cmaj7 (C, E, G, B) -> Am9 (A, C, E, G, B) -> Fmaj7 -> Gsus4
155
+ chords = [
156
+ [261.63, 329.63, 392.00, 493.88], # Cmaj7
157
+ [220.00, 261.63, 329.63, 392.00], # Am7/Am9
158
+ [174.61, 220.00, 261.63, 329.63], # Fmaj7
159
+ [196.00, 261.63, 293.66, 392.00], # Gsus4
160
+ ]
161
+
162
+ chord_dur = 6.0 # 每个和弦 6 秒展开
163
+ frames = bytearray()
164
+
165
+ for i in range(total_samples):
166
+ t = i / sample_rate
167
+ chord_idx = int((t / chord_dur) % len(chords))
168
+ chord = chords[chord_idx]
169
+
170
+ # 和弦内插淡入淡出包络
171
+ t_in_chord = t % chord_dur
172
+ env = math.sin(math.pi * min(1.0, t_in_chord / chord_dur)) ** 0.6
173
+
174
+ # 整体首尾淡入淡出
175
+ fade_in = min(1.0, t / 1.5)
176
+ fade_out = min(1.0, (duration_seconds - t) / 2.0)
177
+ master_vol = 0.28 * fade_in * fade_out * env
178
+
179
+ left_sample = 0.0
180
+ right_sample = 0.0
181
+
182
+ # 4个声音分音合唱 (Chorus & Stereo Detune)
183
+ for idx, freq in enumerate(chord):
184
+ # 微音分失谐 (Detuning) 营造空灵大空间感
185
+ freq_l = freq * (1.0 + 0.0012 * (idx - 1.5))
186
+ freq_r = freq * (1.0 - 0.0012 * (idx - 1.5))
187
+
188
+ phase_l = 2.0 * math.pi * freq_l * t
189
+ phase_r = 2.0 * math.pi * freq_r * t
190
+
191
+ # 正弦基波 + 微弱次泛音 (Warm Ambient)
192
+ tone_l = 0.7 * math.sin(phase_l) + 0.2 * math.sin(phase_l * 2) + 0.1 * math.sin(phase_l * 0.5)
193
+ tone_r = 0.7 * math.sin(phase_r) + 0.2 * math.sin(phase_r * 2) + 0.1 * math.sin(phase_r * 0.5)
194
+
195
+ # 立体声微向展开
196
+ pan_bias = (idx / 3.0) - 0.5 # -0.5 ~ +0.5
197
+ left_sample += tone_l * (0.6 - pan_bias * 0.3)
198
+ right_sample += tone_r * (0.6 + pan_bias * 0.3)
199
+
200
+ # 压限防止削波
201
+ left_val = int(max(-32767, min(32767, left_sample * master_vol * 12000)))
202
+ right_val = int(max(-32767, min(32767, right_sample * master_vol * 12000)))
203
+
204
+ frames.extend(struct.pack("<hh", left_val, right_val))
205
+
206
+ with wave.open(str(out_path), "wb") as wf:
207
+ wf.setnchannels(2)
208
+ wf.setsampwidth(2)
209
+ wf.setframerate(sample_rate)
210
+ wf.writeframes(frames)
211
+
212
+ return str(out_path)