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,436 @@
1
+ """
2
+ ui.py — Aria UI Skill System Prompt
3
+ Bloomberg-quality HTML generation for financial dashboards, reports, and data views.
4
+ """
5
+
6
+ UI_SYSTEM_PROMPT = """\
7
+ You are Aria UI, a specialist in generating professional, production-grade HTML interfaces for any product domain.
8
+ Choose the visual language that fits the product, target users, information hierarchy, and existing brand. Use
9
+ finance-terminal patterns only for explicitly financial products; do not impose them on consumer, SaaS, developer,
10
+ commerce, education, health, or other interfaces.
11
+
12
+ ## CORE PHILOSOPHY
13
+ Information density over aesthetics. Every pixel earns its place.
14
+ The user reads data, not art. Clarity beats beauty.
15
+
16
+ ## ABSOLUTE OUTPUT RULES
17
+ 1. Output ONLY a single complete HTML file. No explanation, no markdown fences.
18
+ 2. ALL data must be real — fetched via Python (yfinance / akshare) and embedded as JavaScript variables.
19
+ NEVER hardcode placeholder prices like "150.00" or "N/A" for fields you could compute.
20
+ 3. The HTML must be fully self-contained: no external fetch calls at runtime, no CDN dependencies.
21
+ Google Fonts (@import) is the ONLY allowed external resource.
22
+ 4. Always save to os.path.expanduser('~/Documents/Aria Code/generated/<descriptive_name>.html').
23
+ 5. After write_file, open in browser: run_command: open ~/Documents/Aria Code/generated/<name>.html (macOS) or start <name>.html (Windows).
24
+
25
+ ## DESIGN SYSTEM — BLOOMBERG STYLE
26
+
27
+ ### Typography
28
+ - Body / labels: 'IBM Plex Sans', system-ui, sans-serif
29
+ - Numbers / prices / codes: 'IBM Plex Mono', 'Courier New', monospace
30
+ - Load via: @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&family=IBM+Plex+Sans:wght@400;600;700&display=swap');
31
+ - All prices, percentages, and quantities: font-family: var(--font-mono); font-variant-numeric: tabular-nums;
32
+ - Section headers: font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.12em;
33
+ - NO emojis anywhere — use text indicators instead:
34
+ - Up trend: [+] or ▲ or colored text
35
+ - Down trend: [-] or ▼ or colored text
36
+ - Active: [ON] Inactive: [OFF]
37
+ - Warning: [!] OK: [OK]
38
+
39
+ ### Color System — CSS Variables (MUST use these exact names)
40
+ ```css
41
+ :root {
42
+ /* Dark mode (default) */
43
+ --bg-primary: #000000;
44
+ --bg-secondary: #111111;
45
+ --bg-tertiary: #1A1A1A;
46
+ --bg-hover: #222222;
47
+ --border: #2A2A2A;
48
+ --border-strong: #444444;
49
+ --text-primary: #E8E9EA;
50
+ --text-secondary:#A0A0A0;
51
+ --text-muted: #606060;
52
+ --accent: #F5A623; /* Bloomberg orange */
53
+ --accent-dim: #7A5010;
54
+ --positive: #00CC66;
55
+ --positive-dim: #004422;
56
+ --negative: #FF3B3B;
57
+ --negative-dim: #440000;
58
+ --neutral: #4A9EFF;
59
+ --warning: #FFB800;
60
+ }
61
+ @media (prefers-color-scheme: light) {
62
+ :root {
63
+ --bg-primary: #FFFFFF;
64
+ --bg-secondary: #F4F4F4;
65
+ --bg-tertiary: #EAEAEA;
66
+ --bg-hover: #E0E0E0;
67
+ --border: #CCCCCC;
68
+ --border-strong: #999999;
69
+ --text-primary: #111111;
70
+ --text-secondary:#444444;
71
+ --text-muted: #888888;
72
+ --accent: #B8520A;
73
+ --accent-dim: #FAE0C8;
74
+ --positive: #006B2E;
75
+ --positive-dim: #D4F0E0;
76
+ --negative: #B30000;
77
+ --negative-dim: #FFE0E0;
78
+ --neutral: #0057B7;
79
+ --warning: #8B6000;
80
+ }
81
+ }
82
+ ```
83
+
84
+ ### Layout Rules
85
+ - border-radius: 0 everywhere — flat, terminal aesthetic
86
+ - Base spacing unit: 4px. Use 4, 8, 12, 16, 20, 24, 32px — never odd values
87
+ - Max content width: 1440px, centered
88
+ - Grid: use CSS Grid with explicit columns, never flexbox for multi-column layouts
89
+ - Body padding: 16px on sides, 12px top
90
+ - Section gap: 20px
91
+ - Card padding: 12px
92
+ - Table row height: 28px (compact), 36px (comfortable)
93
+
94
+ ### Component Patterns
95
+
96
+ **Section Header:**
97
+ ```html
98
+ <div class="section-header">SECTION TITLE</div>
99
+ ```
100
+ ```css
101
+ .section-header {
102
+ font-size: 10px; font-weight: 700; text-transform: uppercase;
103
+ letter-spacing: 0.12em; color: var(--text-muted);
104
+ border-bottom: 1px solid var(--border);
105
+ padding-bottom: 6px; margin-bottom: 10px;
106
+ }
107
+ ```
108
+
109
+ **Quote Tile (compact, for index grids):**
110
+ ```html
111
+ <div class="qt">
112
+ <div class="qt-sym">SPX</div>
113
+ <div class="qt-name">S&P 500</div>
114
+ <div class="qt-price">5,847.23</div>
115
+ <div class="qt-change up">+0.84%</div>
116
+ </div>
117
+ ```
118
+ ```css
119
+ .qt { background: var(--bg-secondary); border: 1px solid var(--border); padding: 10px 12px; display: flex; flex-direction: column; gap: 2px; }
120
+ .qt-sym { font-family: var(--font-mono); font-size: 11px; color: var(--accent); font-weight: 600; }
121
+ .qt-name { font-size: 10px; color: var(--text-muted); }
122
+ .qt-price { font-family: var(--font-mono); font-size: 20px; font-weight: 600; color: var(--text-primary); letter-spacing: -0.01em; }
123
+ .qt-change { font-family: var(--font-mono); font-size: 12px; font-weight: 600; }
124
+ .up { color: var(--positive); }
125
+ .down { color: var(--negative); }
126
+ .flat { color: var(--text-muted); }
127
+ ```
128
+
129
+ **Data Table (dense, financial):**
130
+ ```html
131
+ <table class="data-table">
132
+ <thead><tr><th>SYMBOL</th><th class="r">PRICE</th><th class="r">CHG%</th></tr></thead>
133
+ <tbody>
134
+ <tr><td class="sym">AAPL</td><td class="num">185.42</td><td class="num up">+1.23%</td></tr>
135
+ </tbody>
136
+ </table>
137
+ ```
138
+ ```css
139
+ .data-table { width: 100%; border-collapse: collapse; font-size: 12px; }
140
+ .data-table th { background: var(--bg-tertiary); color: var(--text-muted); font-size: 10px;
141
+ font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em;
142
+ padding: 6px 10px; text-align: left; border-bottom: 1px solid var(--border-strong);
143
+ white-space: nowrap; }
144
+ .data-table th.r, .data-table td.r { text-align: right; }
145
+ .data-table td { padding: 5px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
146
+ .data-table tr:hover td { background: var(--bg-hover); }
147
+ .data-table tr:last-child td { border-bottom: none; }
148
+ .sym { font-family: var(--font-mono); font-weight: 600; color: var(--accent); font-size: 12px; }
149
+ .num { font-family: var(--font-mono); text-align: right; }
150
+ ```
151
+
152
+ **Metric Card (KPI summary):**
153
+ ```html
154
+ <div class="metric">
155
+ <div class="metric-label">TOTAL PNL</div>
156
+ <div class="metric-val up">+¥12,480</div>
157
+ <div class="metric-sub">unrealized</div>
158
+ </div>
159
+ ```
160
+ ```css
161
+ .metric { background: var(--bg-secondary); border: 1px solid var(--border); padding: 14px 16px; }
162
+ .metric-label { font-size: 10px; font-weight: 700; text-transform: uppercase;
163
+ letter-spacing: 0.1em; color: var(--text-muted); margin-bottom: 6px; }
164
+ .metric-val { font-family: var(--font-mono); font-size: 24px; font-weight: 600;
165
+ color: var(--text-primary); letter-spacing: -0.02em; }
166
+ .metric-sub { font-size: 10px; color: var(--text-muted); margin-top: 4px; }
167
+ ```
168
+
169
+ **Status Badge (no emoji):**
170
+ ```html
171
+ <span class="badge badge-on">ACTIVE</span>
172
+ <span class="badge badge-off">STOPPED</span>
173
+ <span class="badge badge-warn">WARNING</span>
174
+ ```
175
+ ```css
176
+ .badge { font-family: var(--font-mono); font-size: 9px; font-weight: 700;
177
+ padding: 2px 6px; letter-spacing: 0.08em; border: 1px solid; }
178
+ .badge-on { color: var(--positive); border-color: var(--positive); background: var(--positive-dim); }
179
+ .badge-off { color: var(--text-muted); border-color: var(--border); background: transparent; }
180
+ .badge-warn { color: var(--warning); border-color: var(--warning); background: transparent; }
181
+ ```
182
+
183
+ **Top Bar / Header:**
184
+ ```html
185
+ <header class="topbar">
186
+ <div class="topbar-brand">ARIA <span>TERMINAL</span></div>
187
+ <div class="topbar-meta">Generated 2026-06-17 10:45 · Data: yfinance + Local DB</div>
188
+ </header>
189
+ ```
190
+ ```css
191
+ .topbar { display: flex; align-items: baseline; justify-content: space-between;
192
+ border-bottom: 2px solid var(--accent); padding: 10px 0 8px; margin-bottom: 20px; }
193
+ .topbar-brand { font-family: var(--font-mono); font-size: 18px; font-weight: 700;
194
+ color: var(--accent); letter-spacing: 0.04em; }
195
+ .topbar-brand span { color: var(--text-secondary); font-weight: 400; margin-left: 4px; }
196
+ .topbar-meta { font-size: 10px; color: var(--text-muted); letter-spacing: 0.04em; }
197
+ ```
198
+
199
+ **Change Indicator with direction marker:**
200
+ ```html
201
+ <span class="chg up">+1.84%</span>
202
+ <span class="chg down">-2.31%</span>
203
+ ```
204
+ Always prepend sign: positive gets "+", negative already has "-", zero shows "0.00%".
205
+
206
+ ### FORBIDDEN patterns
207
+ - NO emojis (no , no , no , no — anywhere)
208
+ - NO rounded corners (border-radius: 0 always)
209
+ - NO gradient backgrounds
210
+ - NO box shadows
211
+ - NO animations except: cursor blink on live data indicators (optional)
212
+ - NO external JS libraries (no Chart.js, no D3, no jQuery)
213
+ - NO placeholder data that you did not fetch
214
+ - NO inline styles for colors — use CSS variables only
215
+
216
+ ## WORKFLOW
217
+
218
+ When user requests a UI artifact (dashboard, report, heatmap, etc.):
219
+
220
+ 1. **Plan data requirements**: what symbols / metrics are needed
221
+ 2. **write_file**: write complete Python script to ~/Documents/Aria Code/generated/aria_ui_<name>_generator.py
222
+ - Script fetches ALL data, embeds as JS constants, renders full HTML
223
+ - Script saves to ~/Documents/Aria Code/generated/aria_<name>_<YYYYMMDD>.html
224
+ 3. **run_command**: python3 ~/Documents/Aria Code/generated/aria_ui_<name>_generator.py
225
+ 4. **run_command**: open ~/Documents/Aria Code/generated/aria_<name>_<date>.html
226
+
227
+ The generator script structure:
228
+ ```python
229
+ import os, json
230
+ from datetime import datetime
231
+ import yfinance as yf # or akshare for A-share
232
+
233
+ # --- Fetch data ---
234
+ # ... fetch all required data ...
235
+
236
+ # --- Render HTML ---
237
+ now = datetime.now().strftime("%Y-%m-%d %H:%M")
238
+ data_json = json.dumps(data, ensure_ascii=False)
239
+
240
+ html = f\\'\\'\\'<!DOCTYPE html>
241
+ <html lang="zh"><head>
242
+ <meta charset="UTF-8">
243
+ <meta name="viewport" content="width=device-width,initial-scale=1.0">
244
+ <title>ARIA TERMINAL — {title}</title>
245
+ <style>
246
+ @import url(\\'https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&family=IBM+Plex+Sans:wght@400;600;700&display=swap\\');
247
+ /* ... full Bloomberg design system CSS ... */
248
+ </style>
249
+ </head><body>
250
+ <!-- Bloomberg-style layout with all data embedded -->
251
+ </body></html>\\'\\'\\'
252
+
253
+ out = os.path.expanduser(f\\'~/Documents/Aria Code/generated/aria_{name}_{datetime.now().strftime("%Y%m%d")}.html\\')
254
+ with open(out, \\'w\\', encoding=\\'utf-8\\') as f: f.write(html)
255
+ print(f\\'Saved: {out}\\')
256
+ ```
257
+
258
+ ## WHAT TO GENERATE FOR COMMON REQUESTS
259
+
260
+ - "行情看板 / market dashboard" → quote tiles grid (4x4), top movers table, volume leaders, sector heatmap (text-based color cells)
261
+ - "持仓报告 / portfolio report" → positions table, P&L summary metrics, allocation bar (ASCII-style), trade history
262
+ - "策略回测报告 / backtest report" → equity curve (SVG path), drawdown chart (SVG), trade log table, metrics card grid
263
+ - "因子分析 / factor analysis" → factor table, z-score heatmap (color cells), quintile return bar chart (SVG bars)
264
+ - "晨报 / morning brief" → compact layout, indices strip, overnight changes, key events calendar table
265
+ - "股票分析 / stock analysis" → header with key metrics, price + volume SVG chart, technical indicators table, company fundamentals
266
+
267
+ For SVG charts: generate them inline, no external SVG libraries.
268
+ Use <path> for line charts, <rect> for bar charts, <text> for labels.
269
+ Scale data to viewport coordinates mathematically (min-max normalization).
270
+ """
271
+
272
+ UI_STYLE_GUIDE = {
273
+ "fonts": {
274
+ "sans": "'IBM Plex Sans', system-ui, sans-serif",
275
+ "mono": "'IBM Plex Mono', 'Courier New', monospace",
276
+ },
277
+ "colors": {
278
+ "dark": {
279
+ "bg_primary": "#000000",
280
+ "bg_secondary": "#111111",
281
+ "bg_tertiary": "#1A1A1A",
282
+ "accent": "#F5A623",
283
+ "positive": "#00CC66",
284
+ "negative": "#FF3B3B",
285
+ "text": "#E8E9EA",
286
+ "muted": "#606060",
287
+ "border": "#2A2A2A",
288
+ },
289
+ "light": {
290
+ "bg_primary": "#FFFFFF",
291
+ "bg_secondary": "#F4F4F4",
292
+ "bg_tertiary": "#EAEAEA",
293
+ "accent": "#B8520A",
294
+ "positive": "#006B2E",
295
+ "negative": "#B30000",
296
+ "text": "#111111",
297
+ "muted": "#888888",
298
+ "border": "#CCCCCC",
299
+ },
300
+ },
301
+ "principles": [
302
+ "No emojis — use [+]/[-]/[!]/[ON]/[OFF] text indicators",
303
+ "No border-radius — flat terminal aesthetic",
304
+ "No gradients or shadows",
305
+ "IBM Plex Mono for all numbers and prices",
306
+ "Tabular-nums for all numeric columns",
307
+ "prefers-color-scheme for auto dark/light",
308
+ "All data embedded at generation time — zero runtime API calls",
309
+ ],
310
+ }
311
+
312
+
313
+ def get_ui_css_base() -> str:
314
+ """Return the complete Bloomberg-style CSS base as a string for embedding in generated HTML."""
315
+ return """
316
+ @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&family=IBM+Plex+Sans:wght@400;600;700&display=swap');
317
+
318
+ :root {
319
+ --bg-primary: #000000;
320
+ --bg-secondary: #111111;
321
+ --bg-tertiary: #1A1A1A;
322
+ --bg-hover: #222222;
323
+ --border: #2A2A2A;
324
+ --border-strong: #444444;
325
+ --text-primary: #E8E9EA;
326
+ --text-secondary:#A0A0A0;
327
+ --text-muted: #606060;
328
+ --accent: #F5A623;
329
+ --accent-dim: #7A5010;
330
+ --positive: #00CC66;
331
+ --positive-dim: #003318;
332
+ --negative: #FF3B3B;
333
+ --negative-dim: #3D0000;
334
+ --neutral: #4A9EFF;
335
+ --warning: #FFB800;
336
+ --font-sans: 'IBM Plex Sans', system-ui, sans-serif;
337
+ --font-mono: 'IBM Plex Mono', 'Courier New', monospace;
338
+ }
339
+ @media (prefers-color-scheme: light) {
340
+ :root {
341
+ --bg-primary: #FFFFFF;
342
+ --bg-secondary: #F4F4F4;
343
+ --bg-tertiary: #EAEAEA;
344
+ --bg-hover: #E0E0E0;
345
+ --border: #CCCCCC;
346
+ --border-strong: #999999;
347
+ --text-primary: #111111;
348
+ --text-secondary:#444444;
349
+ --text-muted: #888888;
350
+ --accent: #B8520A;
351
+ --accent-dim: #FAE0C8;
352
+ --positive: #006B2E;
353
+ --positive-dim: #D4F0E0;
354
+ --negative: #B30000;
355
+ --negative-dim: #FFE0E0;
356
+ --neutral: #0057B7;
357
+ --warning: #8B6000;
358
+ }
359
+ }
360
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
361
+ html { font-size: 13px; }
362
+ body {
363
+ font-family: var(--font-sans);
364
+ background: var(--bg-primary);
365
+ color: var(--text-primary);
366
+ padding: 12px 16px 32px;
367
+ max-width: 1440px;
368
+ margin: 0 auto;
369
+ line-height: 1.4;
370
+ }
371
+ /* ── Top bar ── */
372
+ .topbar { display: flex; align-items: baseline; justify-content: space-between;
373
+ border-bottom: 2px solid var(--accent); padding-bottom: 8px; margin-bottom: 20px; }
374
+ .topbar-brand { font-family: var(--font-mono); font-size: 16px; font-weight: 700;
375
+ color: var(--accent); letter-spacing: 0.06em; }
376
+ .topbar-brand span { color: var(--text-secondary); font-weight: 400; }
377
+ .topbar-meta { font-size: 10px; color: var(--text-muted); letter-spacing: 0.04em; font-family: var(--font-mono); }
378
+ /* ── Section header ── */
379
+ .sh { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.12em;
380
+ color: var(--text-muted); border-bottom: 1px solid var(--border);
381
+ padding-bottom: 5px; margin-bottom: 10px; }
382
+ /* ── Layout ── */
383
+ .section { margin-bottom: 20px; }
384
+ .grid { display: grid; gap: 1px; background: var(--border); border: 1px solid var(--border); }
385
+ .g2 { grid-template-columns: 1fr 1fr; }
386
+ .g3 { grid-template-columns: repeat(3, 1fr); }
387
+ .g4 { grid-template-columns: repeat(4, 1fr); }
388
+ .g5 { grid-template-columns: repeat(5, 1fr); }
389
+ .g6 { grid-template-columns: repeat(6, 1fr); }
390
+ .gcol2 { grid-template-columns: 2fr 1fr; }
391
+ .gcol3 { grid-template-columns: 3fr 1fr; }
392
+ /* ── Quote tile ── */
393
+ .qt { background: var(--bg-secondary); padding: 10px 12px;
394
+ display: flex; flex-direction: column; gap: 2px; }
395
+ .qt-sym { font-family: var(--font-mono); font-size: 11px; color: var(--accent); font-weight: 600; }
396
+ .qt-name { font-size: 10px; color: var(--text-muted); }
397
+ .qt-price { font-family: var(--font-mono); font-size: 20px; font-weight: 600;
398
+ color: var(--text-primary); letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
399
+ .qt-chg { font-family: var(--font-mono); font-size: 12px; font-weight: 600; }
400
+ .up { color: var(--positive); }
401
+ .down { color: var(--negative); }
402
+ .flat { color: var(--text-muted); }
403
+ /* ── Metric card ── */
404
+ .metric { background: var(--bg-secondary); padding: 14px 16px; }
405
+ .metric-label { font-size: 10px; font-weight: 700; text-transform: uppercase;
406
+ letter-spacing: 0.1em; color: var(--text-muted); margin-bottom: 6px; }
407
+ .metric-val { font-family: var(--font-mono); font-size: 22px; font-weight: 600;
408
+ color: var(--text-primary); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
409
+ .metric-sub { font-size: 10px; color: var(--text-muted); margin-top: 3px; font-family: var(--font-mono); }
410
+ /* ── Data table ── */
411
+ .data-table { width: 100%; border-collapse: collapse; font-size: 12px; }
412
+ .data-table th { background: var(--bg-tertiary); color: var(--text-muted); font-size: 10px;
413
+ font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em;
414
+ padding: 6px 10px; text-align: left; border-bottom: 1px solid var(--border-strong);
415
+ white-space: nowrap; font-family: var(--font-sans); }
416
+ .data-table td { padding: 5px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
417
+ .data-table tr:hover td { background: var(--bg-hover); }
418
+ .data-table tr:last-child td { border-bottom: none; }
419
+ .r { text-align: right; }
420
+ .sym { font-family: var(--font-mono); font-weight: 600; color: var(--accent); font-size: 12px; }
421
+ .num { font-family: var(--font-mono); text-align: right; font-variant-numeric: tabular-nums; }
422
+ .dim { color: var(--text-muted); font-size: 11px; }
423
+ /* ── Badge ── */
424
+ .badge { font-family: var(--font-mono); font-size: 9px; font-weight: 700;
425
+ padding: 1px 5px; letter-spacing: 0.06em; border: 1px solid; }
426
+ .badge-on { color: var(--positive); border-color: var(--positive); background: var(--positive-dim); }
427
+ .badge-off { color: var(--text-muted); border-color: var(--border); background: transparent; }
428
+ .badge-warn { color: var(--warning); border-color: var(--warning); background: transparent; }
429
+ /* ── Card ── */
430
+ .card { background: var(--bg-secondary); border: 1px solid var(--border); padding: 14px; }
431
+ /* ── Divider ── */
432
+ hr { border: none; border-top: 1px solid var(--border); margin: 16px 0; }
433
+ /* ── Responsive ── */
434
+ @media (max-width: 960px) { .g4,.g5,.g6 { grid-template-columns: repeat(2, 1fr); } }
435
+ @media (max-width: 600px) { .g2,.g3,.g4 { grid-template-columns: 1fr; } }
436
+ """
@@ -0,0 +1,237 @@
1
+ """Provider 端点表与 API key 连通性测试 —— 从 aria_cli.py 抽出。
2
+
3
+ 这两块(_PROVIDER_BASE_URLS 的 28 个端点 + _test_api_key 的 178 行分支)跟
4
+ aria_cli 的会话状态完全无关:一个是纯数据,一个是纯函数(给定 provider 与
5
+ key,发一次 HTTP 请求判断是否有效)。放在 7278 行的主文件里只是历史原因。
6
+
7
+ ⚠️ 调用约束(跟 apps/cli/football_reports.py 同一套):
8
+ apps/cli/commands/model_cmds.py 是 mixin,它用**裸名**调用 _test_api_key,
9
+ 靠 aria_cli 的 _rebind_mixin_globals() 把方法 __globals__ 指向 aria_cli 命名
10
+ 空间才能解析。所以本模块不能只是被 import,必须由 aria_cli 用
11
+ _rebind_module_function_globals() 绑回它自己的 globals。
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from typing import Dict, Tuple
17
+
18
+ __all__ = ["PROVIDER_BASE_URLS", "_PROVIDER_BASE_URLS", "_test_api_key"]
19
+
20
+
21
+ _PROVIDER_BASE_URLS: Dict[str, str] = {
22
+ # ── 国际主流 ──────────────────────────────────────────────────────
23
+ "deepseek": "https://api.deepseek.com",
24
+ "openai": "https://api.openai.com",
25
+ "anthropic": "https://api.anthropic.com",
26
+ "claude": "https://api.anthropic.com",
27
+ "groq": "https://api.groq.com/openai",
28
+ "together": "https://api.together.xyz",
29
+ "google": "https://generativelanguage.googleapis.com/v1beta/openai",
30
+ "gemini": "https://generativelanguage.googleapis.com/v1beta/openai",
31
+ "xai": "https://api.x.ai/v1",
32
+ "grok": "https://api.x.ai/v1",
33
+ "mistral": "https://api.mistral.ai/v1",
34
+ "cohere": "https://api.cohere.ai/compatibility/v1",
35
+ "perplexity": "https://api.perplexity.ai",
36
+ # ── 国内主流 ──────────────────────────────────────────────────────
37
+ "dashscope": "https://dashscope.aliyuncs.com/compatible-mode",
38
+ "aliyun": "https://dashscope.aliyuncs.com/compatible-mode",
39
+ "siliconflow": "https://api.siliconflow.cn",
40
+ "moonshot": "https://api.moonshot.cn/v1",
41
+ "zhipu": "https://open.bigmodel.cn/api/paas/v4",
42
+ "glm": "https://open.bigmodel.cn/api/paas/v4",
43
+ "baidu": "https://qianfan.baidubce.com/v2",
44
+ "ernie": "https://qianfan.baidubce.com/v2",
45
+ "qianfan": "https://qianfan.baidubce.com/v2",
46
+ "bytedance": "https://ark.cn-beijing.volces.com/api/v3",
47
+ "doubao": "https://ark.cn-beijing.volces.com/api/v3",
48
+ "ark": "https://ark.cn-beijing.volces.com/api/v3",
49
+ "minimax": "https://api.minimax.chat/v1",
50
+ "stepfun": "https://api.stepfun.com/v1",
51
+ "01ai": "https://api.lingyiwanwu.com/v1",
52
+ "yi": "https://api.lingyiwanwu.com/v1",
53
+ }
54
+
55
+
56
+ def _test_api_key(provider: str, key: str) -> tuple:
57
+ """Test if an API key is valid. Returns (ok: bool, message: str)."""
58
+ import urllib.request as _ur
59
+ import urllib.error as _ue
60
+ import json as _json
61
+
62
+ provider = provider.lower()
63
+
64
+ try:
65
+ # ── Anthropic (different auth scheme) ────────────────────────────────
66
+ if provider in ("anthropic", "claude"):
67
+ req = _ur.Request(
68
+ "https://api.anthropic.com/v1/models",
69
+ headers={
70
+ "x-api-key": key,
71
+ "anthropic-version": "2023-06-01",
72
+ },
73
+ )
74
+ with _ur.urlopen(req, timeout=8) as r:
75
+ return True, f"✅ Anthropic HTTP {r.status} key 有效"
76
+
77
+ # ── ZhiPu (JWT-based, just try /v1/models) ───────────────────────────
78
+ if provider == "zhipu":
79
+ base = _PROVIDER_BASE_URLS.get("zhipu", "https://open.bigmodel.cn/api/paas/v4")
80
+ req = _ur.Request(
81
+ base.rstrip("/") + "/models",
82
+ headers={"Authorization": f"Bearer {key}"},
83
+ )
84
+ try:
85
+ with _ur.urlopen(req, timeout=8) as r:
86
+ return True, f"✅ 智谱 GLM HTTP {r.status} key 有效"
87
+ except _ue.HTTPError as e:
88
+ if e.code in (401, 403):
89
+ return False, f"❌ 智谱 GLM HTTP {e.code} key 无效"
90
+ return True, f"✅ 智谱 GLM HTTP {e.code} 可连接"
91
+
92
+ # ── Standard OpenAI-compat LLM providers ─────────────────────────────
93
+ if provider in _PROVIDER_BASE_URLS:
94
+ base = _PROVIDER_BASE_URLS[provider].rstrip("/")
95
+ # Avoid double /v1 when base already ends with /v1 or /v2 etc.
96
+ if base.endswith(("/v1", "/v2", "/v3", "/v4", "/openai")):
97
+ url = base + "/models"
98
+ else:
99
+ url = base + "/v1/models"
100
+ req = _ur.Request(url, headers={"Authorization": f"Bearer {key}"})
101
+ try:
102
+ with _ur.urlopen(req, timeout=8) as r:
103
+ return True, f"✅ {provider.capitalize()} HTTP {r.status} key 有效"
104
+ except _ue.HTTPError as e:
105
+ if e.code in (401, 403):
106
+ return False, f"❌ {provider.capitalize()} HTTP {e.code} key 无效或已过期"
107
+ return True, f"✅ {provider.capitalize()} HTTP {e.code} 可连接"
108
+
109
+ # ── Data services ─────────────────────────────────────────────────────
110
+ if provider == "finnhub":
111
+ url = f"https://finnhub.io/api/v1/quote?symbol=AAPL&token={key}"
112
+ req = _ur.Request(url, headers={"User-Agent": "aria-code/1.0"})
113
+ with _ur.urlopen(req, timeout=8) as r:
114
+ body = _json.loads(r.read())
115
+ if body.get("error"):
116
+ return False, f"❌ Finnhub error: {body['error']}"
117
+ price = body.get("c", "?")
118
+ return True, f"✅ Finnhub AAPL现价 ${price} key 有效"
119
+
120
+ if provider == "alphavantage":
121
+ url = f"https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=AAPL&apikey={key}"
122
+ req = _ur.Request(url, headers={"User-Agent": "aria-code/1.0"})
123
+ with _ur.urlopen(req, timeout=10) as r:
124
+ body = _json.loads(r.read())
125
+ if "Information" in body:
126
+ return False, f"❌ Alpha Vantage 超出频率限制或 key 无效"
127
+ if "Global Quote" in body and body["Global Quote"]:
128
+ price = body["Global Quote"].get("05. price", "?")
129
+ return True, f"✅ Alpha Vantage AAPL=${price} key 有效"
130
+ return False, f"❌ Alpha Vantage 返回异常: {str(body)[:80]}"
131
+
132
+ if provider == "polygon":
133
+ url = f"https://api.polygon.io/v2/aggs/ticker/AAPL/range/1/day/2024-01-09/2024-01-09?adjusted=true&sort=asc&limit=1&apiKey={key}"
134
+ req = _ur.Request(url, headers={"User-Agent": "aria-code/1.0"})
135
+ try:
136
+ with _ur.urlopen(req, timeout=8) as r:
137
+ body = _json.loads(r.read())
138
+ if body.get("status") == "OK":
139
+ return True, f"✅ Polygon {body.get('resultsCount', 0)} 条数据 key 有效"
140
+ return False, f"❌ Polygon {body.get('status', 'unknown')}: {body.get('error', '')}"
141
+ except _ue.HTTPError as e:
142
+ if e.code == 403:
143
+ return False, f"❌ Polygon HTTP 403 key 无效"
144
+ return True, f"✅ Polygon HTTP {e.code} 可连接"
145
+
146
+ if provider == "fmp":
147
+ url = f"https://financialmodelingprep.com/api/v3/quote/AAPL?apikey={key}"
148
+ req = _ur.Request(url, headers={"User-Agent": "aria-code/1.0"})
149
+ with _ur.urlopen(req, timeout=8) as r:
150
+ body = _json.loads(r.read())
151
+ if isinstance(body, list) and body:
152
+ price = body[0].get("price", "?")
153
+ return True, f"✅ FMP AAPL=${price} key 有效"
154
+ if isinstance(body, dict) and "Error Message" in body:
155
+ return False, f"❌ FMP {body['Error Message']}"
156
+ return False, f"❌ FMP 返回异常: {str(body)[:80]}"
157
+
158
+ if provider == "twelvedata":
159
+ url = f"https://api.twelvedata.com/api_usage?apikey={key}"
160
+ req = _ur.Request(url, headers={"User-Agent": "aria-code/1.0"})
161
+ with _ur.urlopen(req, timeout=8) as r:
162
+ body = _json.loads(r.read())
163
+ if body.get("status") == "error":
164
+ return False, f"❌ TwelveData {body.get('message', 'key 无效')}"
165
+ used = body.get("current_usage", {}).get("daily", {}).get("used", "?")
166
+ limit = body.get("current_usage", {}).get("daily", {}).get("limit", "?")
167
+ return True, f"✅ TwelveData 今日已用 {used}/{limit} key 有效"
168
+
169
+ if provider == "newsapi":
170
+ url = f"https://newsapi.org/v2/top-headlines?country=us&pageSize=1&apiKey={key}"
171
+ req = _ur.Request(url, headers={"User-Agent": "aria-code/1.0"})
172
+ try:
173
+ with _ur.urlopen(req, timeout=8) as r:
174
+ body = _json.loads(r.read())
175
+ if body.get("status") == "ok":
176
+ return True, f"✅ NewsAPI {body.get('totalResults', 0)} 条新闻 key 有效"
177
+ return False, f"❌ NewsAPI {body.get('message', 'key 无效')}"
178
+ except _ue.HTTPError as e:
179
+ err_body = _json.loads(e.read().decode()) if e.read else {}
180
+ return False, f"❌ NewsAPI HTTP {e.code} {err_body.get('message', '')}"
181
+
182
+ if provider == "coingecko":
183
+ url = "https://pro-api.coingecko.com/api/v3/ping"
184
+ req = _ur.Request(url, headers={"x-cg-pro-api-key": key, "User-Agent": "aria-code/1.0"})
185
+ try:
186
+ with _ur.urlopen(req, timeout=8) as r:
187
+ return True, f"✅ CoinGecko Pro key 有效"
188
+ except _ue.HTTPError as e:
189
+ if e.code == 401:
190
+ url2 = f"https://api.coingecko.com/api/v3/ping?x_cg_demo_api_key={key}"
191
+ req2 = _ur.Request(url2, headers={"User-Agent": "aria-code/1.0"})
192
+ try:
193
+ with _ur.urlopen(req2, timeout=8) as r2:
194
+ return True, f"✅ CoinGecko Demo key 有效"
195
+ except Exception:
196
+ pass
197
+ return False, f"❌ CoinGecko HTTP {e.code} key 无效"
198
+
199
+ if provider == "tavily":
200
+ import urllib.parse as _up
201
+ data = _json.dumps({"api_key": key, "query": "test", "max_results": 1}).encode()
202
+ req = _ur.Request(
203
+ "https://api.tavily.com/search",
204
+ data=data,
205
+ headers={"Content-Type": "application/json", "User-Agent": "aria-code/1.0"},
206
+ )
207
+ try:
208
+ with _ur.urlopen(req, timeout=10) as r:
209
+ return True, f"✅ Tavily HTTP {r.status} key 有效"
210
+ except _ue.HTTPError as e:
211
+ if e.code == 401:
212
+ return False, f"❌ Tavily HTTP 401 key 无效"
213
+ return True, f"✅ Tavily HTTP {e.code} 可连接"
214
+
215
+ if provider == "brave":
216
+ req = _ur.Request(
217
+ "https://api.search.brave.com/res/v1/web/search?q=AAPL&count=1",
218
+ headers={"X-Subscription-Token": key, "User-Agent": "aria-code/1.0"},
219
+ )
220
+ try:
221
+ with _ur.urlopen(req, timeout=8) as r:
222
+ return True, f"✅ Brave Search HTTP {r.status} key 有效"
223
+ except _ue.HTTPError as e:
224
+ if e.code == 401:
225
+ return False, f"❌ Brave Search HTTP 401 key 无效"
226
+ return True, f"✅ Brave Search HTTP {e.code} 可连接"
227
+
228
+ return False, f"⚠ 未知 provider '{provider}',无法测试"
229
+
230
+ except _ue.URLError as e:
231
+ return False, f"❌ 网络错误: {e.reason}"
232
+ except Exception as e:
233
+ return False, f"❌ 测试失败: {e}"
234
+
235
+
236
+ # 对外的规范名;_PROVIDER_BASE_URLS 保留给既有裸名调用方。
237
+ PROVIDER_BASE_URLS = _PROVIDER_BASE_URLS