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,149 @@
1
+ """Safe installation helpers for GitHub-hosted portable skill catalogs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ import os
7
+ from pathlib import Path
8
+ import re
9
+ import shutil
10
+ import subprocess
11
+ from typing import Callable, Sequence
12
+
13
+ from .loader import LoadedSkill, discover_external_skills
14
+ from aria_code.packages.aria_core.paths import aria_home
15
+
16
+
17
+ _REPOSITORY_RE = re.compile(r"^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$")
18
+ _REF_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._/-]{0,127}$")
19
+
20
+
21
+ @dataclass(frozen=True)
22
+ class CatalogSource:
23
+ owner: str
24
+ repository: str
25
+
26
+ @property
27
+ def full_name(self) -> str:
28
+ return f"{self.owner}/{self.repository}"
29
+
30
+ @property
31
+ def clone_url(self) -> str:
32
+ return f"https://github.com/{self.full_name}.git"
33
+
34
+
35
+ @dataclass(frozen=True)
36
+ class CatalogInstallResult:
37
+ source: CatalogSource
38
+ destination: Path
39
+ revision: str
40
+ skills: tuple[LoadedSkill, ...]
41
+
42
+
43
+ def parse_catalog_source(value: str) -> CatalogSource:
44
+ text = str(value or "").strip()
45
+ for prefix in ("https://github.com/", "http://github.com/"):
46
+ if text.startswith(prefix):
47
+ text = text[len(prefix) :]
48
+ break
49
+ text = text.removesuffix(".git").strip("/")
50
+ if not _REPOSITORY_RE.fullmatch(text):
51
+ raise ValueError("catalog must be a GitHub owner/repository path")
52
+ owner, repository = text.split("/", 1)
53
+ if owner in {".", ".."} or repository in {".", ".."}:
54
+ raise ValueError("catalog path traversal is not allowed")
55
+ return CatalogSource(owner=owner, repository=repository)
56
+
57
+
58
+ def default_catalog_home() -> Path:
59
+ configured = os.getenv("ARIA_SKILL_CATALOG_HOME", "")
60
+ if configured:
61
+ return Path(configured).expanduser().resolve()
62
+ return (aria_home() / "skill-catalogs").resolve()
63
+
64
+
65
+ def catalog_clone_command(
66
+ source: CatalogSource,
67
+ destination: Path,
68
+ ref: str = "",
69
+ ) -> list[str]:
70
+ if ref and not _REF_RE.fullmatch(ref):
71
+ raise ValueError("invalid catalog ref")
72
+ command = ["git", "clone", "--depth", "1", "--filter=blob:none"]
73
+ command.extend([source.clone_url, str(destination)])
74
+ return command
75
+
76
+
77
+ def install_catalog(
78
+ source_value: str,
79
+ *,
80
+ ref: str = "",
81
+ catalog_home: Path | None = None,
82
+ runner: Callable[..., subprocess.CompletedProcess] = subprocess.run,
83
+ ) -> CatalogInstallResult:
84
+ source = parse_catalog_source(source_value)
85
+ home = (catalog_home or default_catalog_home()).expanduser().resolve()
86
+ destination = home / source.owner / source.repository
87
+ if destination.exists():
88
+ raise FileExistsError(
89
+ f"catalog already installed at {destination}; remove or update it explicitly"
90
+ )
91
+ destination.parent.mkdir(parents=True, exist_ok=True)
92
+ command = catalog_clone_command(source, destination, ref)
93
+ try:
94
+ runner(
95
+ command,
96
+ check=True,
97
+ capture_output=True,
98
+ text=True,
99
+ timeout=120,
100
+ )
101
+ if ref:
102
+ runner(
103
+ ["git", "fetch", "--depth", "1", "origin", ref],
104
+ cwd=destination,
105
+ check=True,
106
+ capture_output=True,
107
+ text=True,
108
+ timeout=120,
109
+ )
110
+ runner(
111
+ ["git", "checkout", "--detach", "FETCH_HEAD"],
112
+ cwd=destination,
113
+ check=True,
114
+ capture_output=True,
115
+ text=True,
116
+ timeout=30,
117
+ )
118
+ skills_root = destination / "skills"
119
+ skills = discover_external_skills([skills_root])
120
+ if not skills:
121
+ raise ValueError("catalog contains no discoverable SKILL.md entries")
122
+ invalid = [
123
+ skill.qualified_name for skill in skills
124
+ if skill.integrity != "verified"
125
+ ]
126
+ if invalid:
127
+ raise ValueError(
128
+ "catalog integrity verification failed for: " + ", ".join(invalid)
129
+ )
130
+ revision_result = runner(
131
+ ["git", "rev-parse", "HEAD"],
132
+ cwd=destination,
133
+ check=True,
134
+ capture_output=True,
135
+ text=True,
136
+ timeout=15,
137
+ )
138
+ except Exception:
139
+ # The destination did not exist before this call, so it is safe to
140
+ # remove a partial clone or a catalog that failed verification.
141
+ if destination.exists():
142
+ shutil.rmtree(destination)
143
+ raise
144
+ return CatalogInstallResult(
145
+ source=source,
146
+ destination=destination,
147
+ revision=str(revision_result.stdout or "").strip(),
148
+ skills=tuple(skills),
149
+ )
@@ -0,0 +1,455 @@
1
+ """Discover, verify, match, and activate portable SKILL.md workflows."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections import deque
6
+ from dataclasses import dataclass, field
7
+ from datetime import datetime, timezone
8
+ import hashlib
9
+ import json
10
+ import os
11
+ from pathlib import Path
12
+ import re
13
+ from typing import Iterable, Sequence
14
+ from aria_code.packages.aria_core.paths import aria_home
15
+
16
+
17
+ #: Basic file I/O and deliverable-export tools that stay available no matter
18
+ #: which skill is active or what its `allowed_tools` policy declares.
19
+ #:
20
+ #: Why: a skill's allowed_tools is a *domain* policy (which market-data/
21
+ #: research tools may run), not a statement about whether the model may read
22
+ #: or write files. Observed failure: the "equity-research-report" skill's
23
+ #: policy listed only research tools; matched on the CJK term "报告" against
24
+ #: a user request to convert an *existing* file to PDF; once activated it
25
+ #: silently stripped read_file/write_file from the tool schema, and the model
26
+ #: could only reply "please paste the file contents" — it had no idea the
27
+ #: tool had been taken away. Keeping these core tools exempt means a
28
+ #: mismatched skill activation degrades to "runs extra irrelevant workflow
29
+ #: steps" instead of "loses the ability to read a file the user pointed to".
30
+ CORE_FILE_TOOLS: frozenset[str] = frozenset({
31
+ "read_file", "analyze_file", "write_file", "edit_file", "multi_edit",
32
+ "write_spreadsheet", "export_markdown_pdf",
33
+ })
34
+
35
+ _NAME_RE = re.compile(r"^[a-z0-9][a-z0-9-]{0,63}$")
36
+ _QUALIFIED_NAME_RE = re.compile(
37
+ r"^[a-z0-9][a-z0-9-]{0,63}:[a-z0-9][a-z0-9-]{0,63}$"
38
+ )
39
+ _MAX_SKILL_CHARS = 20_000
40
+ _ACTIVATION_HISTORY: deque["SkillActivationTrace"] = deque(maxlen=100)
41
+ _LATIN_STOP_WORDS = {
42
+ "about", "after", "also", "and", "any", "create", "does", "for", "from",
43
+ "into", "only", "report", "request", "skill", "that", "the", "this", "use",
44
+ "user", "when", "with",
45
+ }
46
+ # CJK equivalents of the above. Without these, a Chinese request scores almost
47
+ # entirely on function words: "帮我设计一个牙科诊所的网站" once ranked
48
+ # `strategy-generation` (a trading-strategy skill) above `ui-asset-sourcing` on
49
+ # the strength of 一个/帮我/设计 alone, because Chinese has no spaces and the
50
+ # n-gram tokenizer below emits every 2-4 char window — so polite framing like
51
+ # 帮我 also produces 帮我设, 帮我设计, 我设, 我设计, multiplying a single
52
+ # meaningless phrase into several "matches".
53
+ _CJK_STOP_WORDS = {
54
+ "一个", "一下", "一些", "个", "什么", "可以", "如何", "帮我", "帮我做", "帮我设",
55
+ "帮忙", "我们", "我的", "我想", "我要", "我设", "我需要", "怎么", "怎样",
56
+ "应该", "开始", "我", "然后", "现在", "生成", "用我", "的", "目前", "看看",
57
+ "给我", "请求", "需要", "麻烦", "这个", "那个", "项目", "使用", "进行",
58
+ }
59
+ _IGNORED_TREE_NAMES = {".DS_Store", ".pytest_cache", "__pycache__"}
60
+
61
+
62
+ @dataclass(frozen=True)
63
+ class SkillPolicy:
64
+ allowed_tools: tuple[str, ...] = ()
65
+ permissions: tuple[str, ...] = ()
66
+ # Specialist agents this skill expects to orchestrate, by registry name.
67
+ # Mirrors SkillSpec.agents in ..registry, which has carried the same
68
+ # skill→agent relationship for the built-in specs all along; this makes the
69
+ # portable SKILL.md catalog able to express it too. Advisory only — the
70
+ # loader never imports the agent registry, because it must keep working in
71
+ # runtimes that have no agents at all.
72
+ agents: tuple[str, ...] = ()
73
+ script_execution: str = "approval"
74
+ script_network: bool = False
75
+ script_workspace_write: bool = False
76
+
77
+
78
+ @dataclass(frozen=True)
79
+ class LoadedSkill:
80
+ name: str
81
+ description: str
82
+ instructions: str
83
+ path: Path
84
+ plugin_name: str = "local"
85
+ plugin_version: str = ""
86
+ repository: str = ""
87
+ content_sha256: str = ""
88
+ integrity: str = "unlocked"
89
+ policy: SkillPolicy = field(default_factory=SkillPolicy)
90
+
91
+ @property
92
+ def qualified_name(self) -> str:
93
+ return f"{self.plugin_name}:{self.name}"
94
+
95
+
96
+ @dataclass(frozen=True)
97
+ class SkillActivationTrace:
98
+ qualified_name: str
99
+ activated: bool
100
+ reason: str
101
+ score: float
102
+ integrity: str
103
+ source: str
104
+ timestamp: str = field(
105
+ default_factory=lambda: datetime.now(timezone.utc).isoformat(timespec="seconds")
106
+ )
107
+
108
+ def to_dict(self) -> dict[str, object]:
109
+ return {
110
+ "qualified_name": self.qualified_name,
111
+ "activated": self.activated,
112
+ "reason": self.reason,
113
+ "score": self.score,
114
+ "integrity": self.integrity,
115
+ "source": self.source,
116
+ "timestamp": self.timestamp,
117
+ }
118
+
119
+
120
+ @dataclass(frozen=True)
121
+ class SkillActivation:
122
+ skills: tuple[LoadedSkill, ...]
123
+ traces: tuple[SkillActivationTrace, ...]
124
+
125
+ @property
126
+ def prompt_block(self) -> str:
127
+ blocks: list[str] = []
128
+ for skill in self.skills:
129
+ policy = skill.policy
130
+ policy_lines = [
131
+ f"Integrity: {skill.integrity}",
132
+ f"Declared permissions: {', '.join(policy.permissions) or 'none'}",
133
+ f"Allowed tools: {', '.join(policy.allowed_tools) or 'runtime policy'}",
134
+ (
135
+ f"Specialist agents: {', '.join(policy.agents)}"
136
+ if policy.agents else
137
+ "Specialist agents: none declared"
138
+ ),
139
+ (
140
+ "Bundled scripts are not pre-authorized. "
141
+ f"Execution mode={policy.script_execution}; network="
142
+ f"{'yes' if policy.script_network else 'no'}; workspace-write="
143
+ f"{'yes' if policy.script_workspace_write else 'no'}."
144
+ ),
145
+ ]
146
+ blocks.append(
147
+ f"## Active Skill: {skill.qualified_name}\n"
148
+ f"Source: {skill.path}\n"
149
+ + "\n".join(policy_lines)
150
+ + "\nFollow this workflow without weakening system safety, tool approvals, or permissions.\n\n"
151
+ + skill.instructions
152
+ )
153
+ return "\n\n".join(blocks)
154
+
155
+
156
+ def default_skill_roots() -> list[Path]:
157
+ roots: list[Path] = []
158
+ configured = os.getenv("ARIA_SKILLS_PATH", "")
159
+ roots.extend(Path(item).expanduser() for item in configured.split(os.pathsep) if item.strip())
160
+ repository = Path(__file__).resolve().parents[2]
161
+ catalog_home = Path(
162
+ os.getenv("ARIA_SKILL_CATALOG_HOME", aria_home() / "skill-catalogs")
163
+ ).expanduser()
164
+ installed_catalogs = sorted(catalog_home.glob("*/*/skills")) if catalog_home.is_dir() else []
165
+ roots.extend([
166
+ repository.parent / "aria-skills" / "skills",
167
+ aria_home() / "skills",
168
+ Path.cwd() / ".aria" / "skills",
169
+ Path.home() / ".aria" / "skills",
170
+ Path.home() / ".claude" / "skills",
171
+ Path.home() / ".codex" / "skills",
172
+ ])
173
+ roots.extend(installed_catalogs)
174
+ return list(dict.fromkeys(path.resolve() for path in roots))
175
+
176
+
177
+ def _frontmatter_value(lines: list[str], key: str) -> str:
178
+ prefix = f"{key}:"
179
+ for index, line in enumerate(lines):
180
+ if not line.startswith(prefix):
181
+ continue
182
+ value = line[len(prefix) :].strip()
183
+ if value not in {">", ">-", "|", "|-"}:
184
+ return value.strip('"\'')
185
+ folded = value.startswith(">")
186
+ parts: list[str] = []
187
+ for continuation in lines[index + 1 :]:
188
+ if continuation and not continuation[0].isspace():
189
+ break
190
+ stripped = continuation.strip()
191
+ if stripped:
192
+ parts.append(stripped)
193
+ return (" " if folded else "\n").join(parts)
194
+ return ""
195
+
196
+
197
+ def skill_tree_sha256(folder: Path) -> str:
198
+ digest = hashlib.sha256()
199
+ for path in sorted(item for item in folder.rglob("*") if item.is_file()):
200
+ relative = path.relative_to(folder)
201
+ if any(part in _IGNORED_TREE_NAMES for part in relative.parts) or path.suffix == ".pyc":
202
+ continue
203
+ digest.update(relative.as_posix().encode("utf-8"))
204
+ digest.update(b"\0")
205
+ digest.update(path.read_bytes())
206
+ digest.update(b"\0")
207
+ return digest.hexdigest()
208
+
209
+
210
+ def _catalog_metadata(root: Path) -> tuple[dict[Path, dict[str, str]], dict[str, str]]:
211
+ catalog = root.parent if root.name == "skills" else root
212
+ manifest_path = catalog / ".claude-plugin" / "marketplace.json"
213
+ lock_path = catalog / ".claude-plugin" / "skills.lock.json"
214
+ mapping: dict[Path, dict[str, str]] = {}
215
+ locks: dict[str, str] = {}
216
+ try:
217
+ manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
218
+ catalog_version = str((manifest.get("metadata") or {}).get("version") or "")
219
+ catalog_repository = str(
220
+ (manifest.get("metadata") or {}).get("repository")
221
+ or (manifest.get("owner") or {}).get("url")
222
+ or ""
223
+ )
224
+ for plugin in manifest.get("plugins") or []:
225
+ plugin_name = str(plugin.get("name") or "local")
226
+ plugin_version = str(plugin.get("version") or catalog_version)
227
+ repository = str(plugin.get("repository") or plugin.get("homepage") or catalog_repository)
228
+ for skill_path in plugin.get("skills") or []:
229
+ resolved = (catalog / str(skill_path)).resolve()
230
+ mapping[resolved] = {
231
+ "plugin_name": plugin_name,
232
+ "plugin_version": plugin_version,
233
+ "repository": repository,
234
+ }
235
+ except (OSError, json.JSONDecodeError, TypeError):
236
+ pass
237
+ try:
238
+ lock = json.loads(lock_path.read_text(encoding="utf-8"))
239
+ for qualified_name, entry in (lock.get("skills") or {}).items():
240
+ if isinstance(entry, dict) and entry.get("sha256"):
241
+ locks[str(qualified_name)] = str(entry["sha256"])
242
+ except (OSError, json.JSONDecodeError, TypeError):
243
+ pass
244
+ return mapping, locks
245
+
246
+
247
+ def _load_policy(folder: Path) -> SkillPolicy:
248
+ try:
249
+ payload = json.loads((folder / "skill-policy.json").read_text(encoding="utf-8"))
250
+ except (OSError, json.JSONDecodeError, TypeError):
251
+ return SkillPolicy()
252
+ scripts = payload.get("scripts") or {}
253
+ return SkillPolicy(
254
+ allowed_tools=tuple(str(item) for item in payload.get("allowed_tools") or []),
255
+ permissions=tuple(str(item) for item in payload.get("permissions") or []),
256
+ agents=tuple(str(item) for item in payload.get("agents") or []),
257
+ script_execution=str(scripts.get("execution") or "approval"),
258
+ script_network=bool(scripts.get("network", False)),
259
+ script_workspace_write=bool(scripts.get("workspace_write", False)),
260
+ )
261
+
262
+
263
+ def _parse_skill(
264
+ path: Path,
265
+ metadata: dict[str, str] | None = None,
266
+ locks: dict[str, str] | None = None,
267
+ ) -> LoadedSkill | None:
268
+ try:
269
+ text = path.read_text(encoding="utf-8")
270
+ except OSError:
271
+ return None
272
+ if len(text) > _MAX_SKILL_CHARS or not text.startswith("---\n"):
273
+ return None
274
+ end = text.find("\n---\n", 4)
275
+ if end < 0:
276
+ return None
277
+ frontmatter = text[4:end].splitlines()
278
+ name = _frontmatter_value(frontmatter, "name")
279
+ description = _frontmatter_value(frontmatter, "description")
280
+ if not _NAME_RE.fullmatch(name) or not description:
281
+ return None
282
+ instructions = text[end + 5 :].strip()
283
+ if not instructions:
284
+ return None
285
+ metadata = metadata or {}
286
+ plugin_name = metadata.get("plugin_name") or "local"
287
+ if not _NAME_RE.fullmatch(plugin_name):
288
+ plugin_name = "local"
289
+ qualified_name = f"{plugin_name}:{name}"
290
+ content_sha256 = skill_tree_sha256(path.parent)
291
+ expected = (locks or {}).get(qualified_name)
292
+ integrity = "verified" if expected == content_sha256 else "mismatch" if expected else "unlocked"
293
+ return LoadedSkill(
294
+ name=name,
295
+ description=description,
296
+ instructions=instructions,
297
+ path=path,
298
+ plugin_name=plugin_name,
299
+ plugin_version=metadata.get("plugin_version", ""),
300
+ repository=metadata.get("repository", ""),
301
+ content_sha256=content_sha256,
302
+ integrity=integrity,
303
+ policy=_load_policy(path.parent),
304
+ )
305
+
306
+
307
+ def discover_external_skills(roots: Sequence[Path] | None = None) -> list[LoadedSkill]:
308
+ found: dict[str, LoadedSkill] = {}
309
+ for raw_root in roots or default_skill_roots():
310
+ root = Path(raw_root).expanduser().resolve()
311
+ if not root.is_dir():
312
+ continue
313
+ mapping, locks = _catalog_metadata(root)
314
+ for candidate in sorted(root.glob("*/SKILL.md")):
315
+ loaded = _parse_skill(candidate, mapping.get(candidate.parent.resolve()), locks)
316
+ if loaded and loaded.qualified_name not in found:
317
+ found[loaded.qualified_name] = loaded
318
+ return list(found.values())
319
+
320
+
321
+ def _requested_skill_names(message: str) -> set[str]:
322
+ return set(
323
+ re.findall(
324
+ r"\$([a-z0-9][a-z0-9-]{0,63}(?::[a-z0-9][a-z0-9-]{0,63})?)\b",
325
+ message.lower(),
326
+ )
327
+ )
328
+
329
+
330
+ def _quoted_phrases(description: str) -> list[str]:
331
+ return [
332
+ next(group for group in match.groups() if group is not None).strip().lower()
333
+ for match in re.finditer(r'"([^"]+)"|“([^”]+)”|\'([^\']+)\'', description)
334
+ ]
335
+
336
+
337
+ def _terms(text: str) -> set[str]:
338
+ low = text.lower()
339
+ latin = {
340
+ token for token in re.findall(r"[a-z0-9][a-z0-9_-]{2,}", low)
341
+ if token not in _LATIN_STOP_WORDS
342
+ }
343
+ cjk: set[str] = set()
344
+ for chunk in re.findall(r"[\u3400-\u9fff]{2,}", low):
345
+ if len(chunk) <= 8:
346
+ cjk.add(chunk)
347
+ for size in (2, 3, 4):
348
+ cjk.update(chunk[index : index + size] for index in range(len(chunk) - size + 1))
349
+ cjk -= _CJK_STOP_WORDS
350
+ # An n-gram that merely *contains* a stop word is usually noise too:
351
+ # "\u5e2e\u6211\u8bbe\u8ba1" is \u5e2e\u6211 + \u8bbe\u8ba1 with no extra signal, yet it scores as its own
352
+ # distinct match. Drop windows that are a stop word plus at most one
353
+ # character, which is where that inflation comes from.
354
+ cjk = {
355
+ gram for gram in cjk
356
+ if not any(
357
+ stop in gram and len(gram) - len(stop) <= 1
358
+ for stop in _CJK_STOP_WORDS
359
+ )
360
+ }
361
+ return latin | cjk
362
+
363
+
364
+ def _match_score(message: str, skill: LoadedSkill) -> tuple[float, str]:
365
+ low = message.lower()
366
+ for phrase in _quoted_phrases(skill.description):
367
+ if len(phrase) >= 2 and phrase in low:
368
+ return 20.0 + min(len(phrase), 20) / 10, f'description phrase "{phrase}"'
369
+ overlap = _terms(message) & _terms(skill.description)
370
+ if not overlap:
371
+ return 0.0, "no metadata overlap"
372
+ score = float(len(overlap))
373
+ if len(overlap) >= 2:
374
+ score += 2.0
375
+ return score, f"metadata overlap: {', '.join(sorted(overlap)[:6])}"
376
+
377
+
378
+ def activate_external_skills(
379
+ message: str,
380
+ skills: Iterable[LoadedSkill] | None = None,
381
+ max_skills: int = 2,
382
+ record: bool = True,
383
+ ) -> SkillActivation:
384
+ available = list(skills if skills is not None else discover_external_skills())
385
+ requested = _requested_skill_names(message)
386
+ by_short_name: dict[str, list[LoadedSkill]] = {}
387
+ for skill in available:
388
+ by_short_name.setdefault(skill.name, []).append(skill)
389
+
390
+ candidates: list[tuple[float, str, LoadedSkill]] = []
391
+ traces: list[SkillActivationTrace] = []
392
+ for skill in available:
393
+ explicit_qualified = skill.qualified_name in requested
394
+ explicit_short = skill.name in requested and len(by_short_name[skill.name]) == 1
395
+ if explicit_qualified or explicit_short:
396
+ score, reason = 100.0, "explicit invocation"
397
+ else:
398
+ score, reason = _match_score(message, skill)
399
+ if score < 4.0:
400
+ continue
401
+ if skill.integrity == "mismatch":
402
+ traces.append(SkillActivationTrace(
403
+ qualified_name=skill.qualified_name,
404
+ activated=False,
405
+ reason="integrity mismatch",
406
+ score=score,
407
+ integrity=skill.integrity,
408
+ source=str(skill.path),
409
+ ))
410
+ continue
411
+ if skill.integrity == "unlocked" and not (explicit_qualified or explicit_short):
412
+ traces.append(SkillActivationTrace(
413
+ qualified_name=skill.qualified_name,
414
+ activated=False,
415
+ reason="automatic activation requires an integrity lock",
416
+ score=score,
417
+ integrity=skill.integrity,
418
+ source=str(skill.path),
419
+ ))
420
+ continue
421
+ candidates.append((score, reason, skill))
422
+
423
+ candidates.sort(key=lambda item: (-item[0], item[2].qualified_name))
424
+ selected = candidates[: max(1, max_skills)]
425
+ for score, reason, skill in selected:
426
+ traces.append(SkillActivationTrace(
427
+ qualified_name=skill.qualified_name,
428
+ activated=True,
429
+ reason=reason,
430
+ score=round(score, 2),
431
+ integrity=skill.integrity,
432
+ source=str(skill.path),
433
+ ))
434
+ if record:
435
+ _ACTIVATION_HISTORY.extend(traces)
436
+ return SkillActivation(
437
+ skills=tuple(item[2] for item in selected),
438
+ traces=tuple(traces),
439
+ )
440
+
441
+
442
+ def select_external_skills(
443
+ message: str,
444
+ skills: Iterable[LoadedSkill] | None = None,
445
+ ) -> list[LoadedSkill]:
446
+ return list(activate_external_skills(message, skills).skills)
447
+
448
+
449
+ def build_skill_prompt_block(message: str) -> str:
450
+ return activate_external_skills(message).prompt_block
451
+
452
+
453
+ def recent_skill_activation_traces(limit: int = 20) -> list[SkillActivationTrace]:
454
+ bounded = max(1, min(int(limit), len(_ACTIVATION_HISTORY) or 1))
455
+ return list(_ACTIVATION_HISTORY)[-bounded:]
@@ -0,0 +1,84 @@
1
+ """Skill manifests for model-facing workflows."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from typing import List
7
+
8
+ from aria_code.packages.aria_core import CapabilityManifest, PermissionLevel, ServiceKind
9
+
10
+
11
+ @dataclass(frozen=True)
12
+ class SkillSpec:
13
+ name: str
14
+ description: str
15
+ tools: List[str] = field(default_factory=list)
16
+ agents: List[str] = field(default_factory=list)
17
+ permissions: List[PermissionLevel] = field(default_factory=list)
18
+
19
+ def manifest(self) -> CapabilityManifest:
20
+ return CapabilityManifest(
21
+ name=self.name,
22
+ kind=ServiceKind.SKILL,
23
+ description=self.description,
24
+ capabilities=[f"tool:{name}" for name in self.tools] + [f"agent:{name}" for name in self.agents],
25
+ permissions=self.permissions,
26
+ required_services=self.tools + self.agents,
27
+ tags=["skill"],
28
+ )
29
+
30
+
31
+ def builtin_skill_specs() -> List[SkillSpec]:
32
+ return [
33
+ SkillSpec(
34
+ name="financial-research",
35
+ description="Multi-source quote, fundamentals, technical analysis, and narrative report generation.",
36
+ tools=["get_market_data", "get_market_history", "get_risk_metrics", "analyze_news"],
37
+ agents=["technical", "fundamental", "macro", "risk", "synthesis"],
38
+ permissions=[PermissionLevel.NETWORK],
39
+ ),
40
+ SkillSpec(
41
+ name="equity-research-report",
42
+ description=(
43
+ "Evidence-backed equity report workflow with specialist agents, "
44
+ "deterministic fallbacks, provenance, critique, and completion gates."
45
+ ),
46
+ tools=[
47
+ "get_market_data",
48
+ "get_market_history",
49
+ "calculate_factors",
50
+ "get_risk_metrics",
51
+ "analyze_news",
52
+ ],
53
+ agents=[
54
+ "technical",
55
+ "fundamental",
56
+ "macro",
57
+ "risk",
58
+ "news",
59
+ "catalyst",
60
+ "sector",
61
+ "synthesis",
62
+ ],
63
+ permissions=[PermissionLevel.NETWORK, PermissionLevel.WORKSPACE_WRITE],
64
+ ),
65
+ SkillSpec(
66
+ name="strategy-backtest",
67
+ description="Generate and validate trading strategies with historical simulation and artifacts.",
68
+ tools=["get_market_data"],
69
+ agents=["technical", "risk"],
70
+ permissions=[PermissionLevel.NETWORK, PermissionLevel.WORKSPACE_WRITE],
71
+ ),
72
+ SkillSpec(
73
+ name="workspace-coding",
74
+ description="Read, edit, and verify local project files with explicit workspace permissions.",
75
+ tools=["read_file", "list_files", "search_code", "edit_file", "write_file", "run_command"],
76
+ permissions=[PermissionLevel.READ_ONLY, PermissionLevel.WORKSPACE_WRITE],
77
+ ),
78
+ SkillSpec(
79
+ name="broker-portfolio",
80
+ description="Read broker account state and propose guarded orders with user approval.",
81
+ tools=["broker_query", "broker_order"],
82
+ permissions=[PermissionLevel.BROKER_READ, PermissionLevel.BROKER_TRADE],
83
+ ),
84
+ ]
@@ -0,0 +1,5 @@
1
+ """Tool registry facade for Aria Code."""
2
+
3
+ from .registry import ToolSpec, ToolRegistry, build_registry_from_legacy
4
+
5
+ __all__ = ["ToolSpec", "ToolRegistry", "build_registry_from_legacy"]