calvyn-code 0.14.0

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 (1718) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +217 -0
  3. package/README.zh-CN.md +180 -0
  4. package/acp_adapter/__init__.py +1 -0
  5. package/acp_adapter/__main__.py +5 -0
  6. package/acp_adapter/auth.py +68 -0
  7. package/acp_adapter/bootstrap/__init__.py +0 -0
  8. package/acp_adapter/bootstrap/bootstrap_browser_tools.ps1 +288 -0
  9. package/acp_adapter/bootstrap/bootstrap_browser_tools.sh +399 -0
  10. package/acp_adapter/entry.py +292 -0
  11. package/acp_adapter/events.py +265 -0
  12. package/acp_adapter/permissions.py +148 -0
  13. package/acp_adapter/server.py +1713 -0
  14. package/acp_adapter/session.py +629 -0
  15. package/acp_adapter/tools.py +1180 -0
  16. package/agent/__init__.py +6 -0
  17. package/agent/__pycache__/__init__.cpython-312.pyc +0 -0
  18. package/agent/__pycache__/account_usage.cpython-312.pyc +0 -0
  19. package/agent/__pycache__/anthropic_adapter.cpython-312.pyc +0 -0
  20. package/agent/__pycache__/async_utils.cpython-312.pyc +0 -0
  21. package/agent/__pycache__/auxiliary_client.cpython-312.pyc +0 -0
  22. package/agent/__pycache__/codex_responses_adapter.cpython-312.pyc +0 -0
  23. package/agent/__pycache__/context_compressor.cpython-312.pyc +0 -0
  24. package/agent/__pycache__/context_engine.cpython-312.pyc +0 -0
  25. package/agent/__pycache__/context_references.cpython-312.pyc +0 -0
  26. package/agent/__pycache__/credential_pool.cpython-312.pyc +0 -0
  27. package/agent/__pycache__/curator.cpython-312.pyc +0 -0
  28. package/agent/__pycache__/display.cpython-312.pyc +0 -0
  29. package/agent/__pycache__/error_classifier.cpython-312.pyc +0 -0
  30. package/agent/__pycache__/file_safety.cpython-312.pyc +0 -0
  31. package/agent/__pycache__/google_code_assist.cpython-312.pyc +0 -0
  32. package/agent/__pycache__/google_oauth.cpython-312.pyc +0 -0
  33. package/agent/__pycache__/i18n.cpython-312.pyc +0 -0
  34. package/agent/__pycache__/image_gen_provider.cpython-312.pyc +0 -0
  35. package/agent/__pycache__/image_gen_registry.cpython-312.pyc +0 -0
  36. package/agent/__pycache__/insights.cpython-312.pyc +0 -0
  37. package/agent/__pycache__/lmstudio_reasoning.cpython-312.pyc +0 -0
  38. package/agent/__pycache__/manual_compression_feedback.cpython-312.pyc +0 -0
  39. package/agent/__pycache__/markdown_tables.cpython-312.pyc +0 -0
  40. package/agent/__pycache__/memory_manager.cpython-312.pyc +0 -0
  41. package/agent/__pycache__/memory_provider.cpython-312.pyc +0 -0
  42. package/agent/__pycache__/model_metadata.cpython-312.pyc +0 -0
  43. package/agent/__pycache__/models_dev.cpython-312.pyc +0 -0
  44. package/agent/__pycache__/moonshot_schema.cpython-312.pyc +0 -0
  45. package/agent/__pycache__/onboarding.cpython-312.pyc +0 -0
  46. package/agent/__pycache__/portal_tags.cpython-312.pyc +0 -0
  47. package/agent/__pycache__/prompt_builder.cpython-312.pyc +0 -0
  48. package/agent/__pycache__/prompt_caching.cpython-312.pyc +0 -0
  49. package/agent/__pycache__/redact.cpython-312.pyc +0 -0
  50. package/agent/__pycache__/retry_utils.cpython-312.pyc +0 -0
  51. package/agent/__pycache__/shell_hooks.cpython-312.pyc +0 -0
  52. package/agent/__pycache__/skill_commands.cpython-312.pyc +0 -0
  53. package/agent/__pycache__/skill_preprocessing.cpython-312.pyc +0 -0
  54. package/agent/__pycache__/skill_utils.cpython-312.pyc +0 -0
  55. package/agent/__pycache__/subdirectory_hints.cpython-312.pyc +0 -0
  56. package/agent/__pycache__/think_scrubber.cpython-312.pyc +0 -0
  57. package/agent/__pycache__/title_generator.cpython-312.pyc +0 -0
  58. package/agent/__pycache__/tool_guardrails.cpython-312.pyc +0 -0
  59. package/agent/__pycache__/tool_result_classification.cpython-312.pyc +0 -0
  60. package/agent/__pycache__/trajectory.cpython-312.pyc +0 -0
  61. package/agent/__pycache__/usage_pricing.cpython-312.pyc +0 -0
  62. package/agent/__pycache__/video_gen_provider.cpython-312.pyc +0 -0
  63. package/agent/__pycache__/video_gen_registry.cpython-312.pyc +0 -0
  64. package/agent/__pycache__/web_search_provider.cpython-312.pyc +0 -0
  65. package/agent/__pycache__/web_search_registry.cpython-312.pyc +0 -0
  66. package/agent/account_usage.py +326 -0
  67. package/agent/anthropic_adapter.py +2087 -0
  68. package/agent/async_utils.py +68 -0
  69. package/agent/auxiliary_client.py +4893 -0
  70. package/agent/bedrock_adapter.py +1276 -0
  71. package/agent/codex_responses_adapter.py +1084 -0
  72. package/agent/context_compressor.py +1583 -0
  73. package/agent/context_engine.py +211 -0
  74. package/agent/context_references.py +519 -0
  75. package/agent/copilot_acp_client.py +684 -0
  76. package/agent/credential_pool.py +1780 -0
  77. package/agent/credential_sources.py +449 -0
  78. package/agent/curator.py +1782 -0
  79. package/agent/curator_backup.py +694 -0
  80. package/agent/display.py +987 -0
  81. package/agent/error_classifier.py +1058 -0
  82. package/agent/file_safety.py +112 -0
  83. package/agent/gemini_cloudcode_adapter.py +909 -0
  84. package/agent/gemini_native_adapter.py +971 -0
  85. package/agent/gemini_schema.py +99 -0
  86. package/agent/google_code_assist.py +452 -0
  87. package/agent/google_oauth.py +1062 -0
  88. package/agent/i18n.py +258 -0
  89. package/agent/image_gen_provider.py +243 -0
  90. package/agent/image_gen_registry.py +145 -0
  91. package/agent/image_routing.py +301 -0
  92. package/agent/insights.py +931 -0
  93. package/agent/lmstudio_reasoning.py +48 -0
  94. package/agent/lsp/__init__.py +106 -0
  95. package/agent/lsp/__pycache__/__init__.cpython-312.pyc +0 -0
  96. package/agent/lsp/__pycache__/cli.cpython-312.pyc +0 -0
  97. package/agent/lsp/__pycache__/client.cpython-312.pyc +0 -0
  98. package/agent/lsp/__pycache__/eventlog.cpython-312.pyc +0 -0
  99. package/agent/lsp/__pycache__/manager.cpython-312.pyc +0 -0
  100. package/agent/lsp/__pycache__/protocol.cpython-312.pyc +0 -0
  101. package/agent/lsp/__pycache__/servers.cpython-312.pyc +0 -0
  102. package/agent/lsp/__pycache__/workspace.cpython-312.pyc +0 -0
  103. package/agent/lsp/cli.py +308 -0
  104. package/agent/lsp/client.py +930 -0
  105. package/agent/lsp/eventlog.py +213 -0
  106. package/agent/lsp/install.py +376 -0
  107. package/agent/lsp/manager.py +644 -0
  108. package/agent/lsp/protocol.py +196 -0
  109. package/agent/lsp/range_shift.py +149 -0
  110. package/agent/lsp/reporter.py +78 -0
  111. package/agent/lsp/servers.py +1040 -0
  112. package/agent/lsp/workspace.py +223 -0
  113. package/agent/manual_compression_feedback.py +49 -0
  114. package/agent/markdown_tables.py +309 -0
  115. package/agent/memory_manager.py +556 -0
  116. package/agent/memory_provider.py +279 -0
  117. package/agent/model_metadata.py +1827 -0
  118. package/agent/models_dev.py +724 -0
  119. package/agent/moonshot_schema.py +231 -0
  120. package/agent/nous_rate_guard.py +326 -0
  121. package/agent/onboarding.py +193 -0
  122. package/agent/plugin_llm.py +1046 -0
  123. package/agent/portal_tags.py +64 -0
  124. package/agent/prompt_builder.py +1457 -0
  125. package/agent/prompt_caching.py +79 -0
  126. package/agent/rate_limit_tracker.py +246 -0
  127. package/agent/redact.py +403 -0
  128. package/agent/retry_utils.py +57 -0
  129. package/agent/shell_hooks.py +837 -0
  130. package/agent/skill_commands.py +502 -0
  131. package/agent/skill_preprocessing.py +131 -0
  132. package/agent/skill_utils.py +512 -0
  133. package/agent/subdirectory_hints.py +224 -0
  134. package/agent/think_scrubber.py +386 -0
  135. package/agent/title_generator.py +171 -0
  136. package/agent/tool_guardrails.py +458 -0
  137. package/agent/tool_result_classification.py +26 -0
  138. package/agent/trajectory.py +56 -0
  139. package/agent/transports/__init__.py +68 -0
  140. package/agent/transports/__pycache__/__init__.cpython-312.pyc +0 -0
  141. package/agent/transports/__pycache__/anthropic.cpython-312.pyc +0 -0
  142. package/agent/transports/__pycache__/base.cpython-312.pyc +0 -0
  143. package/agent/transports/__pycache__/bedrock.cpython-312.pyc +0 -0
  144. package/agent/transports/__pycache__/chat_completions.cpython-312.pyc +0 -0
  145. package/agent/transports/__pycache__/codex.cpython-312.pyc +0 -0
  146. package/agent/transports/__pycache__/types.cpython-312.pyc +0 -0
  147. package/agent/transports/anthropic.py +179 -0
  148. package/agent/transports/base.py +89 -0
  149. package/agent/transports/bedrock.py +154 -0
  150. package/agent/transports/chat_completions.py +614 -0
  151. package/agent/transports/codex.py +283 -0
  152. package/agent/transports/codex_app_server.py +368 -0
  153. package/agent/transports/codex_app_server_session.py +810 -0
  154. package/agent/transports/codex_event_projector.py +312 -0
  155. package/agent/transports/hermes_tools_mcp_server.py +233 -0
  156. package/agent/transports/types.py +162 -0
  157. package/agent/usage_pricing.py +877 -0
  158. package/agent/video_gen_provider.py +300 -0
  159. package/agent/video_gen_registry.py +117 -0
  160. package/agent/web_search_provider.py +221 -0
  161. package/agent/web_search_registry.py +262 -0
  162. package/assets/banner.png +0 -0
  163. package/batch_runner.py +1303 -0
  164. package/bin/calvyn.js +67 -0
  165. package/calvyn_bootstrap.py +130 -0
  166. package/calvyn_constants.py +346 -0
  167. package/calvyn_logging.py +390 -0
  168. package/calvyn_state.py +2967 -0
  169. package/calvyn_time.py +105 -0
  170. package/cli.py +14160 -0
  171. package/cron/__init__.py +42 -0
  172. package/cron/__pycache__/__init__.cpython-312.pyc +0 -0
  173. package/cron/__pycache__/jobs.cpython-312.pyc +0 -0
  174. package/cron/__pycache__/scheduler.cpython-312.pyc +0 -0
  175. package/cron/jobs.py +1160 -0
  176. package/cron/scheduler.py +1832 -0
  177. package/gateway/__init__.py +35 -0
  178. package/gateway/__pycache__/__init__.cpython-312.pyc +0 -0
  179. package/gateway/__pycache__/channel_directory.cpython-312.pyc +0 -0
  180. package/gateway/__pycache__/config.cpython-312.pyc +0 -0
  181. package/gateway/__pycache__/delivery.cpython-312.pyc +0 -0
  182. package/gateway/__pycache__/display_config.cpython-312.pyc +0 -0
  183. package/gateway/__pycache__/hooks.cpython-312.pyc +0 -0
  184. package/gateway/__pycache__/pairing.cpython-312.pyc +0 -0
  185. package/gateway/__pycache__/platform_registry.cpython-312.pyc +0 -0
  186. package/gateway/__pycache__/restart.cpython-312.pyc +0 -0
  187. package/gateway/__pycache__/run.cpython-312.pyc +0 -0
  188. package/gateway/__pycache__/runtime_footer.cpython-312.pyc +0 -0
  189. package/gateway/__pycache__/session.cpython-312.pyc +0 -0
  190. package/gateway/__pycache__/session_context.cpython-312.pyc +0 -0
  191. package/gateway/__pycache__/shutdown_forensics.cpython-312.pyc +0 -0
  192. package/gateway/__pycache__/slash_access.cpython-312.pyc +0 -0
  193. package/gateway/__pycache__/status.cpython-312.pyc +0 -0
  194. package/gateway/__pycache__/stream_consumer.cpython-312.pyc +0 -0
  195. package/gateway/__pycache__/whatsapp_identity.cpython-312.pyc +0 -0
  196. package/gateway/assets/telegram-botfather-threads-settings.jpg +0 -0
  197. package/gateway/builtin_hooks/__init__.py +1 -0
  198. package/gateway/channel_directory.py +357 -0
  199. package/gateway/config.py +1873 -0
  200. package/gateway/delivery.py +258 -0
  201. package/gateway/display_config.py +206 -0
  202. package/gateway/hooks.py +210 -0
  203. package/gateway/mirror.py +179 -0
  204. package/gateway/pairing.py +322 -0
  205. package/gateway/platform_registry.py +260 -0
  206. package/gateway/platforms/ADDING_A_PLATFORM.md +374 -0
  207. package/gateway/platforms/__init__.py +45 -0
  208. package/gateway/platforms/__pycache__/__init__.cpython-312.pyc +0 -0
  209. package/gateway/platforms/__pycache__/base.cpython-312.pyc +0 -0
  210. package/gateway/platforms/__pycache__/helpers.cpython-312.pyc +0 -0
  211. package/gateway/platforms/__pycache__/telegram.cpython-312.pyc +0 -0
  212. package/gateway/platforms/__pycache__/telegram_network.cpython-312.pyc +0 -0
  213. package/gateway/platforms/__pycache__/yuanbao.cpython-312.pyc +0 -0
  214. package/gateway/platforms/__pycache__/yuanbao_media.cpython-312.pyc +0 -0
  215. package/gateway/platforms/__pycache__/yuanbao_proto.cpython-312.pyc +0 -0
  216. package/gateway/platforms/_http_client_limits.py +84 -0
  217. package/gateway/platforms/api_server.py +3488 -0
  218. package/gateway/platforms/base.py +3747 -0
  219. package/gateway/platforms/bluebubbles.py +937 -0
  220. package/gateway/platforms/dingtalk.py +1473 -0
  221. package/gateway/platforms/discord.py +5584 -0
  222. package/gateway/platforms/email.py +773 -0
  223. package/gateway/platforms/feishu.py +5059 -0
  224. package/gateway/platforms/feishu_comment.py +1382 -0
  225. package/gateway/platforms/feishu_comment_rules.py +430 -0
  226. package/gateway/platforms/helpers.py +279 -0
  227. package/gateway/platforms/homeassistant.py +449 -0
  228. package/gateway/platforms/matrix.py +2777 -0
  229. package/gateway/platforms/mattermost.py +852 -0
  230. package/gateway/platforms/msgraph_webhook.py +397 -0
  231. package/gateway/platforms/qqbot/__init__.py +91 -0
  232. package/gateway/platforms/qqbot/adapter.py +3072 -0
  233. package/gateway/platforms/qqbot/chunked_upload.py +602 -0
  234. package/gateway/platforms/qqbot/constants.py +74 -0
  235. package/gateway/platforms/qqbot/crypto.py +45 -0
  236. package/gateway/platforms/qqbot/keyboards.py +473 -0
  237. package/gateway/platforms/qqbot/onboard.py +220 -0
  238. package/gateway/platforms/qqbot/utils.py +71 -0
  239. package/gateway/platforms/signal.py +1518 -0
  240. package/gateway/platforms/signal_rate_limit.py +369 -0
  241. package/gateway/platforms/slack.py +3028 -0
  242. package/gateway/platforms/sms.py +377 -0
  243. package/gateway/platforms/telegram.py +4836 -0
  244. package/gateway/platforms/telegram_network.py +249 -0
  245. package/gateway/platforms/webhook.py +806 -0
  246. package/gateway/platforms/wecom.py +1610 -0
  247. package/gateway/platforms/wecom_callback.py +403 -0
  248. package/gateway/platforms/wecom_crypto.py +142 -0
  249. package/gateway/platforms/weixin.py +2170 -0
  250. package/gateway/platforms/whatsapp.py +1283 -0
  251. package/gateway/platforms/yuanbao.py +4873 -0
  252. package/gateway/platforms/yuanbao_media.py +645 -0
  253. package/gateway/platforms/yuanbao_proto.py +1209 -0
  254. package/gateway/platforms/yuanbao_sticker.py +558 -0
  255. package/gateway/restart.py +20 -0
  256. package/gateway/run.py +17074 -0
  257. package/gateway/runtime_footer.py +150 -0
  258. package/gateway/session.py +1399 -0
  259. package/gateway/session_context.py +156 -0
  260. package/gateway/shutdown_forensics.py +462 -0
  261. package/gateway/slash_access.py +229 -0
  262. package/gateway/status.py +972 -0
  263. package/gateway/sticker_cache.py +111 -0
  264. package/gateway/stream_consumer.py +1286 -0
  265. package/gateway/whatsapp_identity.py +156 -0
  266. package/hermes_cli/__init__.py +47 -0
  267. package/hermes_cli/__pycache__/__init__.cpython-312.pyc +0 -0
  268. package/hermes_cli/__pycache__/_parser.cpython-312.pyc +0 -0
  269. package/hermes_cli/__pycache__/auth.cpython-312.pyc +0 -0
  270. package/hermes_cli/__pycache__/banner.cpython-312.pyc +0 -0
  271. package/hermes_cli/__pycache__/browser_connect.cpython-312.pyc +0 -0
  272. package/hermes_cli/__pycache__/callbacks.cpython-312.pyc +0 -0
  273. package/hermes_cli/__pycache__/checkpoints.cpython-312.pyc +0 -0
  274. package/hermes_cli/__pycache__/cli_output.cpython-312.pyc +0 -0
  275. package/hermes_cli/__pycache__/codex_models.cpython-312.pyc +0 -0
  276. package/hermes_cli/__pycache__/codex_runtime_switch.cpython-312.pyc +0 -0
  277. package/hermes_cli/__pycache__/colors.cpython-312.pyc +0 -0
  278. package/hermes_cli/__pycache__/commands.cpython-312.pyc +0 -0
  279. package/hermes_cli/__pycache__/config.cpython-312.pyc +0 -0
  280. package/hermes_cli/__pycache__/copilot_auth.cpython-312.pyc +0 -0
  281. package/hermes_cli/__pycache__/curator.cpython-312.pyc +0 -0
  282. package/hermes_cli/__pycache__/curses_ui.cpython-312.pyc +0 -0
  283. package/hermes_cli/__pycache__/debug.cpython-312.pyc +0 -0
  284. package/hermes_cli/__pycache__/default_soul.cpython-312.pyc +0 -0
  285. package/hermes_cli/__pycache__/env_loader.cpython-312.pyc +0 -0
  286. package/hermes_cli/__pycache__/fallback_cmd.cpython-312.pyc +0 -0
  287. package/hermes_cli/__pycache__/gateway.cpython-312.pyc +0 -0
  288. package/hermes_cli/__pycache__/gateway_windows.cpython-312.pyc +0 -0
  289. package/hermes_cli/__pycache__/goals.cpython-312.pyc +0 -0
  290. package/hermes_cli/__pycache__/inventory.cpython-312.pyc +0 -0
  291. package/hermes_cli/__pycache__/kanban.cpython-312.pyc +0 -0
  292. package/hermes_cli/__pycache__/kanban_db.cpython-312.pyc +0 -0
  293. package/hermes_cli/__pycache__/main.cpython-312.pyc +0 -0
  294. package/hermes_cli/__pycache__/model_catalog.cpython-312.pyc +0 -0
  295. package/hermes_cli/__pycache__/model_normalize.cpython-312.pyc +0 -0
  296. package/hermes_cli/__pycache__/model_switch.cpython-312.pyc +0 -0
  297. package/hermes_cli/__pycache__/models.cpython-312.pyc +0 -0
  298. package/hermes_cli/__pycache__/nous_subscription.cpython-312.pyc +0 -0
  299. package/hermes_cli/__pycache__/pairing.cpython-312.pyc +0 -0
  300. package/hermes_cli/__pycache__/platforms.cpython-312.pyc +0 -0
  301. package/hermes_cli/__pycache__/plugins.cpython-312.pyc +0 -0
  302. package/hermes_cli/__pycache__/profiles.cpython-312.pyc +0 -0
  303. package/hermes_cli/__pycache__/providers.cpython-312.pyc +0 -0
  304. package/hermes_cli/__pycache__/pt_input_extras.cpython-312.pyc +0 -0
  305. package/hermes_cli/__pycache__/runtime_provider.cpython-312.pyc +0 -0
  306. package/hermes_cli/__pycache__/security_advisories.cpython-312.pyc +0 -0
  307. package/hermes_cli/__pycache__/setup.cpython-312.pyc +0 -0
  308. package/hermes_cli/__pycache__/skills_hub.cpython-312.pyc +0 -0
  309. package/hermes_cli/__pycache__/skin_engine.cpython-312.pyc +0 -0
  310. package/hermes_cli/__pycache__/stdio.cpython-312.pyc +0 -0
  311. package/hermes_cli/__pycache__/timeouts.cpython-312.pyc +0 -0
  312. package/hermes_cli/__pycache__/tips.cpython-312.pyc +0 -0
  313. package/hermes_cli/__pycache__/tools_config.cpython-312.pyc +0 -0
  314. package/hermes_cli/__pycache__/voice.cpython-312.pyc +0 -0
  315. package/hermes_cli/_parser.py +365 -0
  316. package/hermes_cli/_subprocess_compat.py +175 -0
  317. package/hermes_cli/auth.py +6299 -0
  318. package/hermes_cli/auth_commands.py +749 -0
  319. package/hermes_cli/azure_detect.py +300 -0
  320. package/hermes_cli/backup.py +938 -0
  321. package/hermes_cli/banner.py +703 -0
  322. package/hermes_cli/browser_connect.py +139 -0
  323. package/hermes_cli/callbacks.py +243 -0
  324. package/hermes_cli/checkpoints.py +244 -0
  325. package/hermes_cli/claw.py +810 -0
  326. package/hermes_cli/cli_output.py +78 -0
  327. package/hermes_cli/clipboard.py +495 -0
  328. package/hermes_cli/codex_models.py +198 -0
  329. package/hermes_cli/codex_runtime_plugin_migration.py +757 -0
  330. package/hermes_cli/codex_runtime_switch.py +266 -0
  331. package/hermes_cli/colors.py +38 -0
  332. package/hermes_cli/commands.py +1728 -0
  333. package/hermes_cli/completion.py +315 -0
  334. package/hermes_cli/config.py +5382 -0
  335. package/hermes_cli/copilot_auth.py +392 -0
  336. package/hermes_cli/cron.py +313 -0
  337. package/hermes_cli/curator.py +598 -0
  338. package/hermes_cli/curses_ui.py +472 -0
  339. package/hermes_cli/debug.py +747 -0
  340. package/hermes_cli/default_soul.py +11 -0
  341. package/hermes_cli/dep_ensure.py +107 -0
  342. package/hermes_cli/dingtalk_auth.py +293 -0
  343. package/hermes_cli/doctor.py +1863 -0
  344. package/hermes_cli/dump.py +326 -0
  345. package/hermes_cli/env_loader.py +175 -0
  346. package/hermes_cli/fallback_cmd.py +361 -0
  347. package/hermes_cli/gateway.py +5422 -0
  348. package/hermes_cli/gateway_windows.py +692 -0
  349. package/hermes_cli/goals.py +757 -0
  350. package/hermes_cli/hooks.py +385 -0
  351. package/hermes_cli/inventory.py +240 -0
  352. package/hermes_cli/kanban.py +2252 -0
  353. package/hermes_cli/kanban_db.py +4840 -0
  354. package/hermes_cli/kanban_diagnostics.py +776 -0
  355. package/hermes_cli/kanban_specify.py +266 -0
  356. package/hermes_cli/logs.py +391 -0
  357. package/hermes_cli/main.py +12396 -0
  358. package/hermes_cli/mcp_config.py +781 -0
  359. package/hermes_cli/memory_setup.py +465 -0
  360. package/hermes_cli/model_catalog.py +330 -0
  361. package/hermes_cli/model_normalize.py +473 -0
  362. package/hermes_cli/model_switch.py +1777 -0
  363. package/hermes_cli/models.py +3789 -0
  364. package/hermes_cli/nous_subscription.py +799 -0
  365. package/hermes_cli/oneshot.py +351 -0
  366. package/hermes_cli/pairing.py +115 -0
  367. package/hermes_cli/platforms.py +83 -0
  368. package/hermes_cli/plugins.py +1562 -0
  369. package/hermes_cli/plugins_cmd.py +1587 -0
  370. package/hermes_cli/profile_distribution.py +703 -0
  371. package/hermes_cli/profiles.py +1319 -0
  372. package/hermes_cli/providers.py +720 -0
  373. package/hermes_cli/proxy/__init__.py +20 -0
  374. package/hermes_cli/proxy/adapters/__init__.py +35 -0
  375. package/hermes_cli/proxy/adapters/base.py +94 -0
  376. package/hermes_cli/proxy/adapters/nous_portal.py +137 -0
  377. package/hermes_cli/proxy/cli.py +141 -0
  378. package/hermes_cli/proxy/server.py +265 -0
  379. package/hermes_cli/pt_input_extras.py +83 -0
  380. package/hermes_cli/pty_bridge.py +237 -0
  381. package/hermes_cli/relaunch.py +205 -0
  382. package/hermes_cli/runtime_provider.py +1428 -0
  383. package/hermes_cli/security_advisories.py +452 -0
  384. package/hermes_cli/setup.py +3559 -0
  385. package/hermes_cli/skills_config.py +177 -0
  386. package/hermes_cli/skills_hub.py +1595 -0
  387. package/hermes_cli/skin_engine.py +929 -0
  388. package/hermes_cli/slack_cli.py +160 -0
  389. package/hermes_cli/status.py +550 -0
  390. package/hermes_cli/stdio.py +252 -0
  391. package/hermes_cli/timeouts.py +82 -0
  392. package/hermes_cli/tips.py +487 -0
  393. package/hermes_cli/tools_config.py +3151 -0
  394. package/hermes_cli/uninstall.py +681 -0
  395. package/hermes_cli/vercel_auth.py +70 -0
  396. package/hermes_cli/voice.py +846 -0
  397. package/hermes_cli/web_server.py +4438 -0
  398. package/hermes_cli/webhook.py +275 -0
  399. package/locales/af.yaml +350 -0
  400. package/locales/de.yaml +350 -0
  401. package/locales/en.yaml +365 -0
  402. package/locales/es.yaml +350 -0
  403. package/locales/fr.yaml +350 -0
  404. package/locales/ga.yaml +354 -0
  405. package/locales/hu.yaml +350 -0
  406. package/locales/it.yaml +350 -0
  407. package/locales/ja.yaml +350 -0
  408. package/locales/ko.yaml +350 -0
  409. package/locales/pt.yaml +350 -0
  410. package/locales/ru.yaml +350 -0
  411. package/locales/tr.yaml +350 -0
  412. package/locales/uk.yaml +350 -0
  413. package/locales/zh-hant.yaml +350 -0
  414. package/locales/zh.yaml +350 -0
  415. package/mcp_serve.py +898 -0
  416. package/model_tools.py +899 -0
  417. package/optional-skills/DESCRIPTION.md +24 -0
  418. package/optional-skills/autonomous-ai-agents/DESCRIPTION.md +2 -0
  419. package/optional-skills/autonomous-ai-agents/blackbox/SKILL.md +144 -0
  420. package/optional-skills/autonomous-ai-agents/honcho/SKILL.md +431 -0
  421. package/optional-skills/blockchain/evm/SKILL.md +211 -0
  422. package/optional-skills/blockchain/evm/scripts/evm_client.py +1508 -0
  423. package/optional-skills/blockchain/hyperliquid/SKILL.md +211 -0
  424. package/optional-skills/blockchain/hyperliquid/scripts/hyperliquid_client.py +1660 -0
  425. package/optional-skills/blockchain/solana/SKILL.md +208 -0
  426. package/optional-skills/blockchain/solana/scripts/solana_client.py +698 -0
  427. package/optional-skills/communication/DESCRIPTION.md +1 -0
  428. package/optional-skills/communication/one-three-one-rule/SKILL.md +104 -0
  429. package/optional-skills/creative/blender-mcp/SKILL.md +117 -0
  430. package/optional-skills/creative/concept-diagrams/SKILL.md +362 -0
  431. package/optional-skills/creative/concept-diagrams/examples/apartment-floor-plan-conversion.md +244 -0
  432. package/optional-skills/creative/concept-diagrams/examples/automated-password-reset-flow.md +276 -0
  433. package/optional-skills/creative/concept-diagrams/examples/autonomous-llm-research-agent-flow.md +240 -0
  434. package/optional-skills/creative/concept-diagrams/examples/banana-journey-tree-to-smoothie.md +161 -0
  435. package/optional-skills/creative/concept-diagrams/examples/commercial-aircraft-structure.md +209 -0
  436. package/optional-skills/creative/concept-diagrams/examples/cpu-ooo-microarchitecture.md +236 -0
  437. package/optional-skills/creative/concept-diagrams/examples/electricity-grid-flow.md +182 -0
  438. package/optional-skills/creative/concept-diagrams/examples/feature-film-production-pipeline.md +172 -0
  439. package/optional-skills/creative/concept-diagrams/examples/hospital-emergency-department-flow.md +165 -0
  440. package/optional-skills/creative/concept-diagrams/examples/ml-benchmark-grouped-bar-chart.md +114 -0
  441. package/optional-skills/creative/concept-diagrams/examples/place-order-uml-sequence.md +325 -0
  442. package/optional-skills/creative/concept-diagrams/examples/smart-city-infrastructure.md +173 -0
  443. package/optional-skills/creative/concept-diagrams/examples/smartphone-layer-anatomy.md +154 -0
  444. package/optional-skills/creative/concept-diagrams/examples/sn2-reaction-mechanism.md +247 -0
  445. package/optional-skills/creative/concept-diagrams/examples/wind-turbine-structure.md +338 -0
  446. package/optional-skills/creative/concept-diagrams/references/dashboard-patterns.md +43 -0
  447. package/optional-skills/creative/concept-diagrams/references/infrastructure-patterns.md +144 -0
  448. package/optional-skills/creative/concept-diagrams/references/physical-shape-cookbook.md +42 -0
  449. package/optional-skills/creative/concept-diagrams/templates/template.html +174 -0
  450. package/optional-skills/creative/hyperframes/SKILL.md +191 -0
  451. package/optional-skills/creative/hyperframes/references/cli.md +185 -0
  452. package/optional-skills/creative/hyperframes/references/composition.md +129 -0
  453. package/optional-skills/creative/hyperframes/references/features.md +289 -0
  454. package/optional-skills/creative/hyperframes/references/gsap.md +136 -0
  455. package/optional-skills/creative/hyperframes/references/troubleshooting.md +137 -0
  456. package/optional-skills/creative/hyperframes/references/website-to-video.md +145 -0
  457. package/optional-skills/creative/hyperframes/scripts/setup.sh +135 -0
  458. package/optional-skills/creative/kanban-video-orchestrator/SKILL.md +207 -0
  459. package/optional-skills/creative/kanban-video-orchestrator/assets/brief.md.tmpl +79 -0
  460. package/optional-skills/creative/kanban-video-orchestrator/assets/setup.sh.tmpl +185 -0
  461. package/optional-skills/creative/kanban-video-orchestrator/assets/soul.md.tmpl +38 -0
  462. package/optional-skills/creative/kanban-video-orchestrator/references/examples.md +227 -0
  463. package/optional-skills/creative/kanban-video-orchestrator/references/intake.md +166 -0
  464. package/optional-skills/creative/kanban-video-orchestrator/references/kanban-setup.md +276 -0
  465. package/optional-skills/creative/kanban-video-orchestrator/references/monitoring.md +180 -0
  466. package/optional-skills/creative/kanban-video-orchestrator/references/role-archetypes.md +298 -0
  467. package/optional-skills/creative/kanban-video-orchestrator/references/tool-matrix.md +317 -0
  468. package/optional-skills/creative/kanban-video-orchestrator/scripts/bootstrap_pipeline.py +501 -0
  469. package/optional-skills/creative/kanban-video-orchestrator/scripts/monitor.py +195 -0
  470. package/optional-skills/creative/meme-generation/EXAMPLES.md +46 -0
  471. package/optional-skills/creative/meme-generation/SKILL.md +130 -0
  472. package/optional-skills/creative/meme-generation/scripts/generate_meme.py +471 -0
  473. package/optional-skills/creative/meme-generation/scripts/templates.json +97 -0
  474. package/optional-skills/devops/cli/SKILL.md +156 -0
  475. package/optional-skills/devops/cli/references/app-discovery.md +112 -0
  476. package/optional-skills/devops/cli/references/authentication.md +59 -0
  477. package/optional-skills/devops/cli/references/cli-reference.md +104 -0
  478. package/optional-skills/devops/cli/references/running-apps.md +171 -0
  479. package/optional-skills/devops/docker-management/SKILL.md +281 -0
  480. package/optional-skills/devops/pinggy-tunnel/SKILL.md +309 -0
  481. package/optional-skills/devops/watchers/SKILL.md +112 -0
  482. package/optional-skills/devops/watchers/scripts/_watermark.py +148 -0
  483. package/optional-skills/devops/watchers/scripts/watch_github.py +168 -0
  484. package/optional-skills/devops/watchers/scripts/watch_http_json.py +131 -0
  485. package/optional-skills/devops/watchers/scripts/watch_rss.py +121 -0
  486. package/optional-skills/dogfood/DESCRIPTION.md +3 -0
  487. package/optional-skills/dogfood/adversarial-ux-test/SKILL.md +191 -0
  488. package/optional-skills/email/agentmail/SKILL.md +126 -0
  489. package/optional-skills/finance/3-statement-model/SKILL.md +433 -0
  490. package/optional-skills/finance/3-statement-model/references/formatting.md +118 -0
  491. package/optional-skills/finance/3-statement-model/references/formulas.md +292 -0
  492. package/optional-skills/finance/3-statement-model/references/sec-filings.md +125 -0
  493. package/optional-skills/finance/comps-analysis/SKILL.md +662 -0
  494. package/optional-skills/finance/dcf-model/SKILL.md +1270 -0
  495. package/optional-skills/finance/dcf-model/TROUBLESHOOTING.md +40 -0
  496. package/optional-skills/finance/dcf-model/requirements.txt +7 -0
  497. package/optional-skills/finance/dcf-model/scripts/validate_dcf.py +292 -0
  498. package/optional-skills/finance/excel-author/SKILL.md +244 -0
  499. package/optional-skills/finance/excel-author/scripts/recalc.py +88 -0
  500. package/optional-skills/finance/lbo-model/SKILL.md +291 -0
  501. package/optional-skills/finance/merger-model/SKILL.md +144 -0
  502. package/optional-skills/finance/pptx-author/SKILL.md +173 -0
  503. package/optional-skills/finance/stocks/SKILL.md +95 -0
  504. package/optional-skills/finance/stocks/scripts/stocks_client.py +755 -0
  505. package/optional-skills/health/DESCRIPTION.md +1 -0
  506. package/optional-skills/health/fitness-nutrition/SKILL.md +256 -0
  507. package/optional-skills/health/fitness-nutrition/references/FORMULAS.md +100 -0
  508. package/optional-skills/health/fitness-nutrition/scripts/body_calc.py +210 -0
  509. package/optional-skills/health/fitness-nutrition/scripts/nutrition_search.py +86 -0
  510. package/optional-skills/health/neuroskill-bci/SKILL.md +459 -0
  511. package/optional-skills/health/neuroskill-bci/references/api.md +286 -0
  512. package/optional-skills/health/neuroskill-bci/references/metrics.md +220 -0
  513. package/optional-skills/health/neuroskill-bci/references/protocols.md +452 -0
  514. package/optional-skills/mcp/DESCRIPTION.md +3 -0
  515. package/optional-skills/mcp/fastmcp/SKILL.md +300 -0
  516. package/optional-skills/mcp/fastmcp/references/fastmcp-cli.md +110 -0
  517. package/optional-skills/mcp/fastmcp/scripts/scaffold_fastmcp.py +56 -0
  518. package/optional-skills/mcp/fastmcp/templates/api_wrapper.py +54 -0
  519. package/optional-skills/mcp/fastmcp/templates/database_server.py +77 -0
  520. package/optional-skills/mcp/fastmcp/templates/file_processor.py +55 -0
  521. package/optional-skills/mcp/mcporter/SKILL.md +123 -0
  522. package/optional-skills/migration/DESCRIPTION.md +2 -0
  523. package/optional-skills/migration/openclaw-migration/SKILL.md +298 -0
  524. package/optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py +3136 -0
  525. package/optional-skills/mlops/accelerate/SKILL.md +336 -0
  526. package/optional-skills/mlops/accelerate/references/custom-plugins.md +453 -0
  527. package/optional-skills/mlops/accelerate/references/megatron-integration.md +489 -0
  528. package/optional-skills/mlops/accelerate/references/performance.md +525 -0
  529. package/optional-skills/mlops/chroma/SKILL.md +410 -0
  530. package/optional-skills/mlops/chroma/references/integration.md +38 -0
  531. package/optional-skills/mlops/clip/SKILL.md +257 -0
  532. package/optional-skills/mlops/clip/references/applications.md +207 -0
  533. package/optional-skills/mlops/faiss/SKILL.md +225 -0
  534. package/optional-skills/mlops/faiss/references/index_types.md +280 -0
  535. package/optional-skills/mlops/flash-attention/SKILL.md +367 -0
  536. package/optional-skills/mlops/flash-attention/references/benchmarks.md +215 -0
  537. package/optional-skills/mlops/flash-attention/references/transformers-integration.md +293 -0
  538. package/optional-skills/mlops/guidance/SKILL.md +576 -0
  539. package/optional-skills/mlops/guidance/references/backends.md +554 -0
  540. package/optional-skills/mlops/guidance/references/constraints.md +674 -0
  541. package/optional-skills/mlops/guidance/references/examples.md +767 -0
  542. package/optional-skills/mlops/huggingface-tokenizers/SKILL.md +520 -0
  543. package/optional-skills/mlops/huggingface-tokenizers/references/algorithms.md +653 -0
  544. package/optional-skills/mlops/huggingface-tokenizers/references/integration.md +637 -0
  545. package/optional-skills/mlops/huggingface-tokenizers/references/pipeline.md +723 -0
  546. package/optional-skills/mlops/huggingface-tokenizers/references/training.md +565 -0
  547. package/optional-skills/mlops/inference/outlines/SKILL.md +656 -0
  548. package/optional-skills/mlops/inference/outlines/references/backends.md +615 -0
  549. package/optional-skills/mlops/inference/outlines/references/examples.md +773 -0
  550. package/optional-skills/mlops/inference/outlines/references/json_generation.md +652 -0
  551. package/optional-skills/mlops/instructor/SKILL.md +744 -0
  552. package/optional-skills/mlops/instructor/references/examples.md +107 -0
  553. package/optional-skills/mlops/instructor/references/providers.md +70 -0
  554. package/optional-skills/mlops/instructor/references/validation.md +606 -0
  555. package/optional-skills/mlops/lambda-labs/SKILL.md +549 -0
  556. package/optional-skills/mlops/lambda-labs/references/advanced-usage.md +611 -0
  557. package/optional-skills/mlops/lambda-labs/references/troubleshooting.md +530 -0
  558. package/optional-skills/mlops/llava/SKILL.md +308 -0
  559. package/optional-skills/mlops/llava/references/training.md +197 -0
  560. package/optional-skills/mlops/modal/SKILL.md +345 -0
  561. package/optional-skills/mlops/modal/references/advanced-usage.md +503 -0
  562. package/optional-skills/mlops/modal/references/troubleshooting.md +494 -0
  563. package/optional-skills/mlops/nemo-curator/SKILL.md +387 -0
  564. package/optional-skills/mlops/nemo-curator/references/deduplication.md +87 -0
  565. package/optional-skills/mlops/nemo-curator/references/filtering.md +102 -0
  566. package/optional-skills/mlops/peft/SKILL.md +435 -0
  567. package/optional-skills/mlops/peft/references/advanced-usage.md +514 -0
  568. package/optional-skills/mlops/peft/references/troubleshooting.md +480 -0
  569. package/optional-skills/mlops/pinecone/SKILL.md +362 -0
  570. package/optional-skills/mlops/pinecone/references/deployment.md +181 -0
  571. package/optional-skills/mlops/pytorch-fsdp/SKILL.md +130 -0
  572. package/optional-skills/mlops/pytorch-fsdp/references/index.md +7 -0
  573. package/optional-skills/mlops/pytorch-fsdp/references/other.md +4261 -0
  574. package/optional-skills/mlops/pytorch-lightning/SKILL.md +350 -0
  575. package/optional-skills/mlops/pytorch-lightning/references/callbacks.md +436 -0
  576. package/optional-skills/mlops/pytorch-lightning/references/distributed.md +490 -0
  577. package/optional-skills/mlops/pytorch-lightning/references/hyperparameter-tuning.md +556 -0
  578. package/optional-skills/mlops/qdrant/SKILL.md +497 -0
  579. package/optional-skills/mlops/qdrant/references/advanced-usage.md +648 -0
  580. package/optional-skills/mlops/qdrant/references/troubleshooting.md +631 -0
  581. package/optional-skills/mlops/saelens/SKILL.md +390 -0
  582. package/optional-skills/mlops/saelens/references/README.md +69 -0
  583. package/optional-skills/mlops/saelens/references/api.md +333 -0
  584. package/optional-skills/mlops/saelens/references/tutorials.md +318 -0
  585. package/optional-skills/mlops/simpo/SKILL.md +223 -0
  586. package/optional-skills/mlops/simpo/references/datasets.md +478 -0
  587. package/optional-skills/mlops/simpo/references/hyperparameters.md +452 -0
  588. package/optional-skills/mlops/simpo/references/loss-functions.md +350 -0
  589. package/optional-skills/mlops/slime/SKILL.md +468 -0
  590. package/optional-skills/mlops/slime/references/api-reference.md +392 -0
  591. package/optional-skills/mlops/slime/references/troubleshooting.md +386 -0
  592. package/optional-skills/mlops/stable-diffusion/SKILL.md +523 -0
  593. package/optional-skills/mlops/stable-diffusion/references/advanced-usage.md +716 -0
  594. package/optional-skills/mlops/stable-diffusion/references/troubleshooting.md +555 -0
  595. package/optional-skills/mlops/tensorrt-llm/SKILL.md +191 -0
  596. package/optional-skills/mlops/tensorrt-llm/references/multi-gpu.md +298 -0
  597. package/optional-skills/mlops/tensorrt-llm/references/optimization.md +242 -0
  598. package/optional-skills/mlops/tensorrt-llm/references/serving.md +470 -0
  599. package/optional-skills/mlops/torchtitan/SKILL.md +362 -0
  600. package/optional-skills/mlops/torchtitan/references/checkpoint.md +181 -0
  601. package/optional-skills/mlops/torchtitan/references/custom-models.md +258 -0
  602. package/optional-skills/mlops/torchtitan/references/float8.md +133 -0
  603. package/optional-skills/mlops/torchtitan/references/fsdp.md +126 -0
  604. package/optional-skills/mlops/training/axolotl/SKILL.md +166 -0
  605. package/optional-skills/mlops/training/axolotl/references/api.md +5548 -0
  606. package/optional-skills/mlops/training/axolotl/references/dataset-formats.md +1029 -0
  607. package/optional-skills/mlops/training/axolotl/references/index.md +15 -0
  608. package/optional-skills/mlops/training/axolotl/references/other.md +3563 -0
  609. package/optional-skills/mlops/training/trl-fine-tuning/SKILL.md +463 -0
  610. package/optional-skills/mlops/training/trl-fine-tuning/references/dpo-variants.md +227 -0
  611. package/optional-skills/mlops/training/trl-fine-tuning/references/grpo-training.md +504 -0
  612. package/optional-skills/mlops/training/trl-fine-tuning/references/online-rl.md +82 -0
  613. package/optional-skills/mlops/training/trl-fine-tuning/references/reward-modeling.md +122 -0
  614. package/optional-skills/mlops/training/trl-fine-tuning/references/sft-training.md +168 -0
  615. package/optional-skills/mlops/training/trl-fine-tuning/templates/basic_grpo_training.py +228 -0
  616. package/optional-skills/mlops/training/unsloth/SKILL.md +84 -0
  617. package/optional-skills/mlops/training/unsloth/references/index.md +7 -0
  618. package/optional-skills/mlops/training/unsloth/references/llms-full.md +16799 -0
  619. package/optional-skills/mlops/training/unsloth/references/llms-txt.md +12044 -0
  620. package/optional-skills/mlops/training/unsloth/references/llms.md +82 -0
  621. package/optional-skills/mlops/whisper/SKILL.md +321 -0
  622. package/optional-skills/mlops/whisper/references/languages.md +189 -0
  623. package/optional-skills/productivity/canvas/SKILL.md +98 -0
  624. package/optional-skills/productivity/canvas/scripts/canvas_api.py +157 -0
  625. package/optional-skills/productivity/here-now/SKILL.md +217 -0
  626. package/optional-skills/productivity/here-now/scripts/drive.sh +406 -0
  627. package/optional-skills/productivity/here-now/scripts/publish.sh +445 -0
  628. package/optional-skills/productivity/memento-flashcards/SKILL.md +324 -0
  629. package/optional-skills/productivity/memento-flashcards/scripts/memento_cards.py +353 -0
  630. package/optional-skills/productivity/memento-flashcards/scripts/youtube_quiz.py +88 -0
  631. package/optional-skills/productivity/shop-app/SKILL.md +340 -0
  632. package/optional-skills/productivity/shopify/SKILL.md +373 -0
  633. package/optional-skills/productivity/siyuan/SKILL.md +298 -0
  634. package/optional-skills/productivity/telephony/SKILL.md +418 -0
  635. package/optional-skills/productivity/telephony/scripts/telephony.py +1343 -0
  636. package/optional-skills/research/bioinformatics/SKILL.md +235 -0
  637. package/optional-skills/research/darwinian-evolver/SKILL.md +199 -0
  638. package/optional-skills/research/darwinian-evolver/scripts/parrot_openrouter.py +218 -0
  639. package/optional-skills/research/darwinian-evolver/scripts/show_snapshot.py +69 -0
  640. package/optional-skills/research/darwinian-evolver/templates/custom_problem_template.py +240 -0
  641. package/optional-skills/research/domain-intel/SKILL.md +97 -0
  642. package/optional-skills/research/domain-intel/scripts/domain_intel.py +397 -0
  643. package/optional-skills/research/drug-discovery/SKILL.md +227 -0
  644. package/optional-skills/research/drug-discovery/references/ADMET_REFERENCE.md +66 -0
  645. package/optional-skills/research/drug-discovery/scripts/chembl_target.py +53 -0
  646. package/optional-skills/research/drug-discovery/scripts/ro5_screen.py +44 -0
  647. package/optional-skills/research/duckduckgo-search/SKILL.md +238 -0
  648. package/optional-skills/research/duckduckgo-search/scripts/duckduckgo.sh +28 -0
  649. package/optional-skills/research/gitnexus-explorer/SKILL.md +214 -0
  650. package/optional-skills/research/gitnexus-explorer/scripts/proxy.mjs +92 -0
  651. package/optional-skills/research/osint-investigation/SKILL.md +277 -0
  652. package/optional-skills/research/osint-investigation/references/sources/courtlistener.md +98 -0
  653. package/optional-skills/research/osint-investigation/references/sources/gdelt.md +104 -0
  654. package/optional-skills/research/osint-investigation/references/sources/icij-offshore.md +104 -0
  655. package/optional-skills/research/osint-investigation/references/sources/nyc-acris.md +90 -0
  656. package/optional-skills/research/osint-investigation/references/sources/ofac-sdn.md +92 -0
  657. package/optional-skills/research/osint-investigation/references/sources/opencorporates.md +103 -0
  658. package/optional-skills/research/osint-investigation/references/sources/sec-edgar.md +83 -0
  659. package/optional-skills/research/osint-investigation/references/sources/senate-ld.md +89 -0
  660. package/optional-skills/research/osint-investigation/references/sources/usaspending.md +97 -0
  661. package/optional-skills/research/osint-investigation/references/sources/wayback.md +93 -0
  662. package/optional-skills/research/osint-investigation/references/sources/wikipedia.md +107 -0
  663. package/optional-skills/research/osint-investigation/scripts/_http.py +82 -0
  664. package/optional-skills/research/osint-investigation/scripts/_normalize.py +67 -0
  665. package/optional-skills/research/osint-investigation/scripts/build_findings.py +221 -0
  666. package/optional-skills/research/osint-investigation/scripts/entity_resolution.py +228 -0
  667. package/optional-skills/research/osint-investigation/scripts/fetch_courtlistener.py +149 -0
  668. package/optional-skills/research/osint-investigation/scripts/fetch_gdelt.py +162 -0
  669. package/optional-skills/research/osint-investigation/scripts/fetch_icij_offshore.py +234 -0
  670. package/optional-skills/research/osint-investigation/scripts/fetch_nyc_acris.py +203 -0
  671. package/optional-skills/research/osint-investigation/scripts/fetch_ofac_sdn.py +175 -0
  672. package/optional-skills/research/osint-investigation/scripts/fetch_opencorporates.py +192 -0
  673. package/optional-skills/research/osint-investigation/scripts/fetch_sec_edgar.py +184 -0
  674. package/optional-skills/research/osint-investigation/scripts/fetch_senate_ld.py +146 -0
  675. package/optional-skills/research/osint-investigation/scripts/fetch_usaspending.py +170 -0
  676. package/optional-skills/research/osint-investigation/scripts/fetch_wayback.py +142 -0
  677. package/optional-skills/research/osint-investigation/scripts/fetch_wikipedia.py +267 -0
  678. package/optional-skills/research/osint-investigation/scripts/timing_analysis.py +253 -0
  679. package/optional-skills/research/osint-investigation/templates/source-template.md +59 -0
  680. package/optional-skills/research/parallel-cli/SKILL.md +391 -0
  681. package/optional-skills/research/qmd/SKILL.md +441 -0
  682. package/optional-skills/research/scrapling/SKILL.md +336 -0
  683. package/optional-skills/research/searxng-search/SKILL.md +212 -0
  684. package/optional-skills/research/searxng-search/scripts/searxng.sh +22 -0
  685. package/optional-skills/security/1password/SKILL.md +163 -0
  686. package/optional-skills/security/1password/references/cli-examples.md +31 -0
  687. package/optional-skills/security/1password/references/get-started.md +21 -0
  688. package/optional-skills/security/DESCRIPTION.md +3 -0
  689. package/optional-skills/security/oss-forensics/SKILL.md +423 -0
  690. package/optional-skills/security/oss-forensics/references/evidence-types.md +89 -0
  691. package/optional-skills/security/oss-forensics/references/github-archive-guide.md +184 -0
  692. package/optional-skills/security/oss-forensics/references/investigation-templates.md +131 -0
  693. package/optional-skills/security/oss-forensics/references/recovery-techniques.md +164 -0
  694. package/optional-skills/security/oss-forensics/scripts/evidence-store.py +313 -0
  695. package/optional-skills/security/oss-forensics/templates/forensic-report.md +151 -0
  696. package/optional-skills/security/oss-forensics/templates/malicious-package-report.md +43 -0
  697. package/optional-skills/security/sherlock/SKILL.md +193 -0
  698. package/optional-skills/software-development/rest-graphql-debug/SKILL.md +514 -0
  699. package/optional-skills/web-development/DESCRIPTION.md +5 -0
  700. package/optional-skills/web-development/page-agent/SKILL.md +190 -0
  701. package/package.json +78 -0
  702. package/plugins/__init__.py +1 -0
  703. package/plugins/__pycache__/__init__.cpython-312.pyc +0 -0
  704. package/plugins/context_engine/__init__.py +219 -0
  705. package/plugins/disk-cleanup/README.md +51 -0
  706. package/plugins/disk-cleanup/__init__.py +316 -0
  707. package/plugins/disk-cleanup/disk_cleanup.py +497 -0
  708. package/plugins/disk-cleanup/plugin.yaml +7 -0
  709. package/plugins/example-dashboard/dashboard/manifest.json +14 -0
  710. package/plugins/example-dashboard/dashboard/plugin_api.py +17 -0
  711. package/plugins/google_meet/README.md +131 -0
  712. package/plugins/google_meet/SKILL.md +148 -0
  713. package/plugins/google_meet/__init__.py +103 -0
  714. package/plugins/google_meet/audio_bridge.py +244 -0
  715. package/plugins/google_meet/cli.py +479 -0
  716. package/plugins/google_meet/meet_bot.py +852 -0
  717. package/plugins/google_meet/node/__init__.py +54 -0
  718. package/plugins/google_meet/node/cli.py +125 -0
  719. package/plugins/google_meet/node/client.py +107 -0
  720. package/plugins/google_meet/node/protocol.py +124 -0
  721. package/plugins/google_meet/node/registry.py +113 -0
  722. package/plugins/google_meet/node/server.py +201 -0
  723. package/plugins/google_meet/plugin.yaml +16 -0
  724. package/plugins/google_meet/process_manager.py +324 -0
  725. package/plugins/google_meet/realtime/__init__.py +10 -0
  726. package/plugins/google_meet/realtime/openai_client.py +332 -0
  727. package/plugins/google_meet/tools.py +348 -0
  728. package/plugins/hermes-achievements/LICENSE +21 -0
  729. package/plugins/hermes-achievements/README.md +150 -0
  730. package/plugins/hermes-achievements/dashboard/dist/index.js +732 -0
  731. package/plugins/hermes-achievements/dashboard/dist/style.css +146 -0
  732. package/plugins/hermes-achievements/dashboard/manifest.json +11 -0
  733. package/plugins/hermes-achievements/dashboard/plugin_api.py +1062 -0
  734. package/plugins/hermes-achievements/docs/achievements-performance-implementation-plan.md +157 -0
  735. package/plugins/hermes-achievements/docs/achievements-performance-implementation-spec.md +219 -0
  736. package/plugins/hermes-achievements/docs/achievements-performance-spec.md +174 -0
  737. package/plugins/hermes-achievements/docs/assets/achievements-dashboard-hd.png +0 -0
  738. package/plugins/hermes-achievements/docs/assets/achievements-tier-showcase-hd.png +0 -0
  739. package/plugins/hermes-achievements/tests/test_achievement_engine.py +156 -0
  740. package/plugins/image_gen/openai/__init__.py +303 -0
  741. package/plugins/image_gen/openai/__pycache__/__init__.cpython-312.pyc +0 -0
  742. package/plugins/image_gen/openai/plugin.yaml +7 -0
  743. package/plugins/image_gen/openai-codex/__init__.py +378 -0
  744. package/plugins/image_gen/openai-codex/__pycache__/__init__.cpython-312.pyc +0 -0
  745. package/plugins/image_gen/openai-codex/plugin.yaml +5 -0
  746. package/plugins/image_gen/xai/__init__.py +316 -0
  747. package/plugins/image_gen/xai/__pycache__/__init__.cpython-312.pyc +0 -0
  748. package/plugins/image_gen/xai/plugin.yaml +7 -0
  749. package/plugins/kanban/dashboard/dist/index.js +3143 -0
  750. package/plugins/kanban/dashboard/dist/style.css +1500 -0
  751. package/plugins/kanban/dashboard/manifest.json +14 -0
  752. package/plugins/kanban/dashboard/plugin_api.py +1612 -0
  753. package/plugins/kanban/systemd/hermes-kanban-dispatcher.service +32 -0
  754. package/plugins/memory/__init__.py +408 -0
  755. package/plugins/memory/byterover/README.md +41 -0
  756. package/plugins/memory/byterover/__init__.py +384 -0
  757. package/plugins/memory/byterover/plugin.yaml +9 -0
  758. package/plugins/memory/hindsight/README.md +138 -0
  759. package/plugins/memory/hindsight/__init__.py +1758 -0
  760. package/plugins/memory/hindsight/plugin.yaml +8 -0
  761. package/plugins/memory/holographic/README.md +36 -0
  762. package/plugins/memory/holographic/__init__.py +409 -0
  763. package/plugins/memory/holographic/holographic.py +203 -0
  764. package/plugins/memory/holographic/plugin.yaml +5 -0
  765. package/plugins/memory/holographic/retrieval.py +593 -0
  766. package/plugins/memory/holographic/store.py +579 -0
  767. package/plugins/memory/honcho/README.md +328 -0
  768. package/plugins/memory/honcho/__init__.py +1329 -0
  769. package/plugins/memory/honcho/cli.py +1452 -0
  770. package/plugins/memory/honcho/client.py +784 -0
  771. package/plugins/memory/honcho/plugin.yaml +7 -0
  772. package/plugins/memory/honcho/session.py +1255 -0
  773. package/plugins/memory/mem0/README.md +38 -0
  774. package/plugins/memory/mem0/__init__.py +374 -0
  775. package/plugins/memory/mem0/plugin.yaml +5 -0
  776. package/plugins/memory/openviking/README.md +40 -0
  777. package/plugins/memory/openviking/__init__.py +945 -0
  778. package/plugins/memory/openviking/plugin.yaml +9 -0
  779. package/plugins/memory/retaindb/README.md +40 -0
  780. package/plugins/memory/retaindb/__init__.py +767 -0
  781. package/plugins/memory/retaindb/plugin.yaml +7 -0
  782. package/plugins/memory/supermemory/README.md +99 -0
  783. package/plugins/memory/supermemory/__init__.py +792 -0
  784. package/plugins/memory/supermemory/plugin.yaml +5 -0
  785. package/plugins/model-providers/README.md +70 -0
  786. package/plugins/model-providers/ai-gateway/__init__.py +43 -0
  787. package/plugins/model-providers/ai-gateway/__pycache__/__init__.cpython-312.pyc +0 -0
  788. package/plugins/model-providers/ai-gateway/plugin.yaml +5 -0
  789. package/plugins/model-providers/alibaba/__init__.py +13 -0
  790. package/plugins/model-providers/alibaba/__pycache__/__init__.cpython-312.pyc +0 -0
  791. package/plugins/model-providers/alibaba/plugin.yaml +5 -0
  792. package/plugins/model-providers/alibaba-coding-plan/__init__.py +21 -0
  793. package/plugins/model-providers/alibaba-coding-plan/__pycache__/__init__.cpython-312.pyc +0 -0
  794. package/plugins/model-providers/alibaba-coding-plan/plugin.yaml +5 -0
  795. package/plugins/model-providers/anthropic/__init__.py +52 -0
  796. package/plugins/model-providers/anthropic/__pycache__/__init__.cpython-312.pyc +0 -0
  797. package/plugins/model-providers/anthropic/plugin.yaml +5 -0
  798. package/plugins/model-providers/arcee/__init__.py +13 -0
  799. package/plugins/model-providers/arcee/__pycache__/__init__.cpython-312.pyc +0 -0
  800. package/plugins/model-providers/arcee/plugin.yaml +5 -0
  801. package/plugins/model-providers/azure-foundry/__init__.py +21 -0
  802. package/plugins/model-providers/azure-foundry/__pycache__/__init__.cpython-312.pyc +0 -0
  803. package/plugins/model-providers/azure-foundry/plugin.yaml +5 -0
  804. package/plugins/model-providers/bedrock/__init__.py +29 -0
  805. package/plugins/model-providers/bedrock/__pycache__/__init__.cpython-312.pyc +0 -0
  806. package/plugins/model-providers/bedrock/plugin.yaml +5 -0
  807. package/plugins/model-providers/copilot/__init__.py +58 -0
  808. package/plugins/model-providers/copilot/__pycache__/__init__.cpython-312.pyc +0 -0
  809. package/plugins/model-providers/copilot/plugin.yaml +5 -0
  810. package/plugins/model-providers/copilot-acp/__init__.py +34 -0
  811. package/plugins/model-providers/copilot-acp/__pycache__/__init__.cpython-312.pyc +0 -0
  812. package/plugins/model-providers/copilot-acp/plugin.yaml +5 -0
  813. package/plugins/model-providers/custom/__init__.py +68 -0
  814. package/plugins/model-providers/custom/__pycache__/__init__.cpython-312.pyc +0 -0
  815. package/plugins/model-providers/custom/plugin.yaml +5 -0
  816. package/plugins/model-providers/deepseek/__init__.py +99 -0
  817. package/plugins/model-providers/deepseek/__pycache__/__init__.cpython-312.pyc +0 -0
  818. package/plugins/model-providers/deepseek/plugin.yaml +5 -0
  819. package/plugins/model-providers/gemini/__init__.py +72 -0
  820. package/plugins/model-providers/gemini/__pycache__/__init__.cpython-312.pyc +0 -0
  821. package/plugins/model-providers/gemini/plugin.yaml +5 -0
  822. package/plugins/model-providers/gmi/__init__.py +31 -0
  823. package/plugins/model-providers/gmi/__pycache__/__init__.cpython-312.pyc +0 -0
  824. package/plugins/model-providers/gmi/plugin.yaml +5 -0
  825. package/plugins/model-providers/huggingface/__init__.py +20 -0
  826. package/plugins/model-providers/huggingface/__pycache__/__init__.cpython-312.pyc +0 -0
  827. package/plugins/model-providers/huggingface/plugin.yaml +5 -0
  828. package/plugins/model-providers/kilocode/__init__.py +14 -0
  829. package/plugins/model-providers/kilocode/__pycache__/__init__.cpython-312.pyc +0 -0
  830. package/plugins/model-providers/kilocode/plugin.yaml +5 -0
  831. package/plugins/model-providers/kimi-coding/__init__.py +71 -0
  832. package/plugins/model-providers/kimi-coding/__pycache__/__init__.cpython-312.pyc +0 -0
  833. package/plugins/model-providers/kimi-coding/plugin.yaml +5 -0
  834. package/plugins/model-providers/minimax/__init__.py +45 -0
  835. package/plugins/model-providers/minimax/__pycache__/__init__.cpython-312.pyc +0 -0
  836. package/plugins/model-providers/minimax/plugin.yaml +5 -0
  837. package/plugins/model-providers/nous/__init__.py +54 -0
  838. package/plugins/model-providers/nous/__pycache__/__init__.cpython-312.pyc +0 -0
  839. package/plugins/model-providers/nous/plugin.yaml +5 -0
  840. package/plugins/model-providers/novita/__init__.py +27 -0
  841. package/plugins/model-providers/novita/__pycache__/__init__.cpython-312.pyc +0 -0
  842. package/plugins/model-providers/novita/plugin.yaml +5 -0
  843. package/plugins/model-providers/nvidia/__init__.py +21 -0
  844. package/plugins/model-providers/nvidia/__pycache__/__init__.cpython-312.pyc +0 -0
  845. package/plugins/model-providers/nvidia/plugin.yaml +5 -0
  846. package/plugins/model-providers/ollama-cloud/__init__.py +14 -0
  847. package/plugins/model-providers/ollama-cloud/__pycache__/__init__.cpython-312.pyc +0 -0
  848. package/plugins/model-providers/ollama-cloud/plugin.yaml +5 -0
  849. package/plugins/model-providers/openai-codex/__init__.py +15 -0
  850. package/plugins/model-providers/openai-codex/__pycache__/__init__.cpython-312.pyc +0 -0
  851. package/plugins/model-providers/openai-codex/plugin.yaml +5 -0
  852. package/plugins/model-providers/opencode-zen/__init__.py +30 -0
  853. package/plugins/model-providers/opencode-zen/__pycache__/__init__.cpython-312.pyc +0 -0
  854. package/plugins/model-providers/opencode-zen/plugin.yaml +5 -0
  855. package/plugins/model-providers/openrouter/__init__.py +115 -0
  856. package/plugins/model-providers/openrouter/__pycache__/__init__.cpython-312.pyc +0 -0
  857. package/plugins/model-providers/openrouter/plugin.yaml +5 -0
  858. package/plugins/model-providers/qwen-oauth/__init__.py +82 -0
  859. package/plugins/model-providers/qwen-oauth/__pycache__/__init__.cpython-312.pyc +0 -0
  860. package/plugins/model-providers/qwen-oauth/plugin.yaml +5 -0
  861. package/plugins/model-providers/stepfun/__init__.py +14 -0
  862. package/plugins/model-providers/stepfun/__pycache__/__init__.cpython-312.pyc +0 -0
  863. package/plugins/model-providers/stepfun/plugin.yaml +5 -0
  864. package/plugins/model-providers/xai/__init__.py +15 -0
  865. package/plugins/model-providers/xai/__pycache__/__init__.cpython-312.pyc +0 -0
  866. package/plugins/model-providers/xai/plugin.yaml +5 -0
  867. package/plugins/model-providers/xiaomi/__init__.py +14 -0
  868. package/plugins/model-providers/xiaomi/__pycache__/__init__.cpython-312.pyc +0 -0
  869. package/plugins/model-providers/xiaomi/plugin.yaml +5 -0
  870. package/plugins/model-providers/zai/__init__.py +21 -0
  871. package/plugins/model-providers/zai/__pycache__/__init__.cpython-312.pyc +0 -0
  872. package/plugins/model-providers/zai/plugin.yaml +5 -0
  873. package/plugins/observability/langfuse/README.md +53 -0
  874. package/plugins/observability/langfuse/__init__.py +1004 -0
  875. package/plugins/observability/langfuse/plugin.yaml +14 -0
  876. package/plugins/platforms/google_chat/__init__.py +3 -0
  877. package/plugins/platforms/google_chat/__pycache__/__init__.cpython-312.pyc +0 -0
  878. package/plugins/platforms/google_chat/__pycache__/adapter.cpython-312.pyc +0 -0
  879. package/plugins/platforms/google_chat/adapter.py +3343 -0
  880. package/plugins/platforms/google_chat/oauth.py +639 -0
  881. package/plugins/platforms/google_chat/plugin.yaml +39 -0
  882. package/plugins/platforms/irc/__init__.py +3 -0
  883. package/plugins/platforms/irc/__pycache__/__init__.cpython-312.pyc +0 -0
  884. package/plugins/platforms/irc/__pycache__/adapter.cpython-312.pyc +0 -0
  885. package/plugins/platforms/irc/adapter.py +969 -0
  886. package/plugins/platforms/irc/plugin.yaml +54 -0
  887. package/plugins/platforms/line/__init__.py +3 -0
  888. package/plugins/platforms/line/__pycache__/__init__.cpython-312.pyc +0 -0
  889. package/plugins/platforms/line/__pycache__/adapter.cpython-312.pyc +0 -0
  890. package/plugins/platforms/line/adapter.py +1639 -0
  891. package/plugins/platforms/line/plugin.yaml +65 -0
  892. package/plugins/platforms/simplex/__init__.py +3 -0
  893. package/plugins/platforms/simplex/__pycache__/__init__.cpython-312.pyc +0 -0
  894. package/plugins/platforms/simplex/__pycache__/adapter.cpython-312.pyc +0 -0
  895. package/plugins/platforms/simplex/adapter.py +746 -0
  896. package/plugins/platforms/simplex/plugin.yaml +37 -0
  897. package/plugins/platforms/teams/__init__.py +3 -0
  898. package/plugins/platforms/teams/__pycache__/__init__.cpython-312.pyc +0 -0
  899. package/plugins/platforms/teams/__pycache__/adapter.cpython-312.pyc +0 -0
  900. package/plugins/platforms/teams/adapter.py +1188 -0
  901. package/plugins/platforms/teams/plugin.yaml +48 -0
  902. package/plugins/spotify/__init__.py +66 -0
  903. package/plugins/spotify/__pycache__/__init__.cpython-312.pyc +0 -0
  904. package/plugins/spotify/__pycache__/client.cpython-312.pyc +0 -0
  905. package/plugins/spotify/__pycache__/tools.cpython-312.pyc +0 -0
  906. package/plugins/spotify/client.py +435 -0
  907. package/plugins/spotify/plugin.yaml +13 -0
  908. package/plugins/spotify/tools.py +454 -0
  909. package/plugins/teams_pipeline/__init__.py +23 -0
  910. package/plugins/teams_pipeline/cli.py +463 -0
  911. package/plugins/teams_pipeline/meetings.py +333 -0
  912. package/plugins/teams_pipeline/models.py +350 -0
  913. package/plugins/teams_pipeline/pipeline.py +692 -0
  914. package/plugins/teams_pipeline/plugin.yaml +9 -0
  915. package/plugins/teams_pipeline/runtime.py +135 -0
  916. package/plugins/teams_pipeline/store.py +194 -0
  917. package/plugins/teams_pipeline/subscriptions.py +249 -0
  918. package/plugins/video_gen/fal/__init__.py +523 -0
  919. package/plugins/video_gen/fal/__pycache__/__init__.cpython-312.pyc +0 -0
  920. package/plugins/video_gen/fal/plugin.yaml +7 -0
  921. package/plugins/video_gen/xai/__init__.py +441 -0
  922. package/plugins/video_gen/xai/__pycache__/__init__.cpython-312.pyc +0 -0
  923. package/plugins/video_gen/xai/plugin.yaml +7 -0
  924. package/plugins/web/__init__.py +7 -0
  925. package/plugins/web/__pycache__/__init__.cpython-312.pyc +0 -0
  926. package/plugins/web/brave_free/__init__.py +14 -0
  927. package/plugins/web/brave_free/__pycache__/__init__.cpython-312.pyc +0 -0
  928. package/plugins/web/brave_free/__pycache__/provider.cpython-312.pyc +0 -0
  929. package/plugins/web/brave_free/plugin.yaml +7 -0
  930. package/plugins/web/brave_free/provider.py +137 -0
  931. package/plugins/web/ddgs/__init__.py +15 -0
  932. package/plugins/web/ddgs/__pycache__/__init__.cpython-312.pyc +0 -0
  933. package/plugins/web/ddgs/__pycache__/provider.cpython-312.pyc +0 -0
  934. package/plugins/web/ddgs/plugin.yaml +7 -0
  935. package/plugins/web/ddgs/provider.py +104 -0
  936. package/plugins/web/exa/__init__.py +15 -0
  937. package/plugins/web/exa/__pycache__/__init__.cpython-312.pyc +0 -0
  938. package/plugins/web/exa/__pycache__/provider.cpython-312.pyc +0 -0
  939. package/plugins/web/exa/plugin.yaml +7 -0
  940. package/plugins/web/exa/provider.py +212 -0
  941. package/plugins/web/firecrawl/__init__.py +28 -0
  942. package/plugins/web/firecrawl/__pycache__/__init__.cpython-312.pyc +0 -0
  943. package/plugins/web/firecrawl/__pycache__/provider.cpython-312.pyc +0 -0
  944. package/plugins/web/firecrawl/plugin.yaml +7 -0
  945. package/plugins/web/firecrawl/provider.py +773 -0
  946. package/plugins/web/parallel/__init__.py +16 -0
  947. package/plugins/web/parallel/__pycache__/__init__.cpython-312.pyc +0 -0
  948. package/plugins/web/parallel/__pycache__/provider.cpython-312.pyc +0 -0
  949. package/plugins/web/parallel/plugin.yaml +7 -0
  950. package/plugins/web/parallel/provider.py +291 -0
  951. package/plugins/web/searxng/__init__.py +15 -0
  952. package/plugins/web/searxng/__pycache__/__init__.cpython-312.pyc +0 -0
  953. package/plugins/web/searxng/__pycache__/provider.cpython-312.pyc +0 -0
  954. package/plugins/web/searxng/plugin.yaml +7 -0
  955. package/plugins/web/searxng/provider.py +140 -0
  956. package/plugins/web/tavily/__init__.py +15 -0
  957. package/plugins/web/tavily/__pycache__/__init__.cpython-312.pyc +0 -0
  958. package/plugins/web/tavily/__pycache__/provider.cpython-312.pyc +0 -0
  959. package/plugins/web/tavily/plugin.yaml +7 -0
  960. package/plugins/web/tavily/provider.py +285 -0
  961. package/providers/README.md +78 -0
  962. package/providers/__init__.py +192 -0
  963. package/providers/__pycache__/__init__.cpython-312.pyc +0 -0
  964. package/providers/__pycache__/base.cpython-312.pyc +0 -0
  965. package/providers/base.py +184 -0
  966. package/pyproject.toml +255 -0
  967. package/run_agent.py +16409 -0
  968. package/scripts/benchmark_browser_eval.py +138 -0
  969. package/scripts/build_model_catalog.py +95 -0
  970. package/scripts/build_skills_index.py +325 -0
  971. package/scripts/check-windows-footguns.py +624 -0
  972. package/scripts/contributor_audit.py +473 -0
  973. package/scripts/discord-voice-doctor.py +396 -0
  974. package/scripts/hermes-gateway +416 -0
  975. package/scripts/install.cmd +28 -0
  976. package/scripts/install.ps1 +1611 -0
  977. package/scripts/install.sh +2007 -0
  978. package/scripts/install_psutil_android.py +117 -0
  979. package/scripts/keystroke_diagnostic.py +81 -0
  980. package/scripts/kill_modal.sh +34 -0
  981. package/scripts/lib/node-bootstrap.sh +238 -0
  982. package/scripts/lint_diff.py +207 -0
  983. package/scripts/postinstall.js +150 -0
  984. package/scripts/profile-tui.py +626 -0
  985. package/scripts/release.py +1680 -0
  986. package/scripts/run_tests.sh +129 -0
  987. package/scripts/sample_and_compress.py +409 -0
  988. package/scripts/setup_open_webui.sh +349 -0
  989. package/scripts/whatsapp-bridge/allowlist.js +88 -0
  990. package/scripts/whatsapp-bridge/allowlist.test.mjs +80 -0
  991. package/scripts/whatsapp-bridge/bridge.js +729 -0
  992. package/scripts/whatsapp-bridge/package-lock.json +2141 -0
  993. package/scripts/whatsapp-bridge/package.json +19 -0
  994. package/skills/apple/DESCRIPTION.md +2 -0
  995. package/skills/apple/apple-notes/SKILL.md +90 -0
  996. package/skills/apple/apple-reminders/SKILL.md +98 -0
  997. package/skills/apple/findmy/SKILL.md +131 -0
  998. package/skills/apple/imessage/SKILL.md +102 -0
  999. package/skills/apple/macos-computer-use/SKILL.md +201 -0
  1000. package/skills/autonomous-ai-agents/DESCRIPTION.md +3 -0
  1001. package/skills/autonomous-ai-agents/claude-code/SKILL.md +745 -0
  1002. package/skills/autonomous-ai-agents/codex/SKILL.md +130 -0
  1003. package/skills/autonomous-ai-agents/hermes-agent/SKILL.md +1014 -0
  1004. package/skills/autonomous-ai-agents/opencode/SKILL.md +219 -0
  1005. package/skills/creative/DESCRIPTION.md +3 -0
  1006. package/skills/creative/architecture-diagram/SKILL.md +148 -0
  1007. package/skills/creative/architecture-diagram/templates/template.html +319 -0
  1008. package/skills/creative/ascii-art/SKILL.md +322 -0
  1009. package/skills/creative/ascii-video/README.md +290 -0
  1010. package/skills/creative/ascii-video/SKILL.md +241 -0
  1011. package/skills/creative/ascii-video/references/architecture.md +802 -0
  1012. package/skills/creative/ascii-video/references/composition.md +892 -0
  1013. package/skills/creative/ascii-video/references/effects.md +1865 -0
  1014. package/skills/creative/ascii-video/references/inputs.md +685 -0
  1015. package/skills/creative/ascii-video/references/optimization.md +688 -0
  1016. package/skills/creative/ascii-video/references/scenes.md +1011 -0
  1017. package/skills/creative/ascii-video/references/shaders.md +1385 -0
  1018. package/skills/creative/ascii-video/references/troubleshooting.md +367 -0
  1019. package/skills/creative/baoyu-comic/PORT_NOTES.md +77 -0
  1020. package/skills/creative/baoyu-comic/SKILL.md +247 -0
  1021. package/skills/creative/baoyu-comic/references/analysis-framework.md +176 -0
  1022. package/skills/creative/baoyu-comic/references/art-styles/chalk.md +101 -0
  1023. package/skills/creative/baoyu-comic/references/art-styles/ink-brush.md +97 -0
  1024. package/skills/creative/baoyu-comic/references/art-styles/ligne-claire.md +75 -0
  1025. package/skills/creative/baoyu-comic/references/art-styles/manga.md +93 -0
  1026. package/skills/creative/baoyu-comic/references/art-styles/minimalist.md +84 -0
  1027. package/skills/creative/baoyu-comic/references/art-styles/realistic.md +89 -0
  1028. package/skills/creative/baoyu-comic/references/auto-selection.md +71 -0
  1029. package/skills/creative/baoyu-comic/references/base-prompt.md +98 -0
  1030. package/skills/creative/baoyu-comic/references/character-template.md +180 -0
  1031. package/skills/creative/baoyu-comic/references/layouts/cinematic.md +23 -0
  1032. package/skills/creative/baoyu-comic/references/layouts/dense.md +23 -0
  1033. package/skills/creative/baoyu-comic/references/layouts/four-panel.md +40 -0
  1034. package/skills/creative/baoyu-comic/references/layouts/mixed.md +23 -0
  1035. package/skills/creative/baoyu-comic/references/layouts/splash.md +23 -0
  1036. package/skills/creative/baoyu-comic/references/layouts/standard.md +23 -0
  1037. package/skills/creative/baoyu-comic/references/layouts/webtoon.md +30 -0
  1038. package/skills/creative/baoyu-comic/references/ohmsha-guide.md +85 -0
  1039. package/skills/creative/baoyu-comic/references/partial-workflows.md +106 -0
  1040. package/skills/creative/baoyu-comic/references/presets/concept-story.md +121 -0
  1041. package/skills/creative/baoyu-comic/references/presets/four-panel.md +107 -0
  1042. package/skills/creative/baoyu-comic/references/presets/ohmsha.md +114 -0
  1043. package/skills/creative/baoyu-comic/references/presets/shoujo.md +116 -0
  1044. package/skills/creative/baoyu-comic/references/presets/wuxia.md +110 -0
  1045. package/skills/creative/baoyu-comic/references/storyboard-template.md +143 -0
  1046. package/skills/creative/baoyu-comic/references/tones/action.md +110 -0
  1047. package/skills/creative/baoyu-comic/references/tones/dramatic.md +95 -0
  1048. package/skills/creative/baoyu-comic/references/tones/energetic.md +105 -0
  1049. package/skills/creative/baoyu-comic/references/tones/neutral.md +63 -0
  1050. package/skills/creative/baoyu-comic/references/tones/romantic.md +100 -0
  1051. package/skills/creative/baoyu-comic/references/tones/vintage.md +104 -0
  1052. package/skills/creative/baoyu-comic/references/tones/warm.md +94 -0
  1053. package/skills/creative/baoyu-comic/references/workflow.md +401 -0
  1054. package/skills/creative/baoyu-infographic/PORT_NOTES.md +43 -0
  1055. package/skills/creative/baoyu-infographic/SKILL.md +237 -0
  1056. package/skills/creative/baoyu-infographic/references/analysis-framework.md +182 -0
  1057. package/skills/creative/baoyu-infographic/references/base-prompt.md +43 -0
  1058. package/skills/creative/baoyu-infographic/references/layouts/bento-grid.md +41 -0
  1059. package/skills/creative/baoyu-infographic/references/layouts/binary-comparison.md +48 -0
  1060. package/skills/creative/baoyu-infographic/references/layouts/bridge.md +41 -0
  1061. package/skills/creative/baoyu-infographic/references/layouts/circular-flow.md +41 -0
  1062. package/skills/creative/baoyu-infographic/references/layouts/comic-strip.md +41 -0
  1063. package/skills/creative/baoyu-infographic/references/layouts/comparison-matrix.md +41 -0
  1064. package/skills/creative/baoyu-infographic/references/layouts/dashboard.md +41 -0
  1065. package/skills/creative/baoyu-infographic/references/layouts/dense-modules.md +72 -0
  1066. package/skills/creative/baoyu-infographic/references/layouts/funnel.md +41 -0
  1067. package/skills/creative/baoyu-infographic/references/layouts/hierarchical-layers.md +48 -0
  1068. package/skills/creative/baoyu-infographic/references/layouts/hub-spoke.md +41 -0
  1069. package/skills/creative/baoyu-infographic/references/layouts/iceberg.md +41 -0
  1070. package/skills/creative/baoyu-infographic/references/layouts/isometric-map.md +41 -0
  1071. package/skills/creative/baoyu-infographic/references/layouts/jigsaw.md +41 -0
  1072. package/skills/creative/baoyu-infographic/references/layouts/linear-progression.md +48 -0
  1073. package/skills/creative/baoyu-infographic/references/layouts/periodic-table.md +41 -0
  1074. package/skills/creative/baoyu-infographic/references/layouts/story-mountain.md +41 -0
  1075. package/skills/creative/baoyu-infographic/references/layouts/structural-breakdown.md +48 -0
  1076. package/skills/creative/baoyu-infographic/references/layouts/tree-branching.md +41 -0
  1077. package/skills/creative/baoyu-infographic/references/layouts/venn-diagram.md +41 -0
  1078. package/skills/creative/baoyu-infographic/references/layouts/winding-roadmap.md +41 -0
  1079. package/skills/creative/baoyu-infographic/references/structured-content-template.md +244 -0
  1080. package/skills/creative/baoyu-infographic/references/styles/aged-academia.md +36 -0
  1081. package/skills/creative/baoyu-infographic/references/styles/bold-graphic.md +36 -0
  1082. package/skills/creative/baoyu-infographic/references/styles/chalkboard.md +61 -0
  1083. package/skills/creative/baoyu-infographic/references/styles/claymation.md +29 -0
  1084. package/skills/creative/baoyu-infographic/references/styles/corporate-memphis.md +29 -0
  1085. package/skills/creative/baoyu-infographic/references/styles/craft-handmade.md +44 -0
  1086. package/skills/creative/baoyu-infographic/references/styles/cyberpunk-neon.md +29 -0
  1087. package/skills/creative/baoyu-infographic/references/styles/hand-drawn-edu.md +63 -0
  1088. package/skills/creative/baoyu-infographic/references/styles/ikea-manual.md +29 -0
  1089. package/skills/creative/baoyu-infographic/references/styles/kawaii.md +29 -0
  1090. package/skills/creative/baoyu-infographic/references/styles/knolling.md +29 -0
  1091. package/skills/creative/baoyu-infographic/references/styles/lego-brick.md +29 -0
  1092. package/skills/creative/baoyu-infographic/references/styles/morandi-journal.md +60 -0
  1093. package/skills/creative/baoyu-infographic/references/styles/origami.md +29 -0
  1094. package/skills/creative/baoyu-infographic/references/styles/pixel-art.md +29 -0
  1095. package/skills/creative/baoyu-infographic/references/styles/pop-laboratory.md +48 -0
  1096. package/skills/creative/baoyu-infographic/references/styles/retro-pop-grid.md +47 -0
  1097. package/skills/creative/baoyu-infographic/references/styles/storybook-watercolor.md +29 -0
  1098. package/skills/creative/baoyu-infographic/references/styles/subway-map.md +29 -0
  1099. package/skills/creative/baoyu-infographic/references/styles/technical-schematic.md +36 -0
  1100. package/skills/creative/baoyu-infographic/references/styles/ui-wireframe.md +29 -0
  1101. package/skills/creative/claude-design/SKILL.md +591 -0
  1102. package/skills/creative/comfyui/SKILL.md +612 -0
  1103. package/skills/creative/comfyui/references/official-cli.md +255 -0
  1104. package/skills/creative/comfyui/references/rest-api.md +312 -0
  1105. package/skills/creative/comfyui/references/template-integrity.md +243 -0
  1106. package/skills/creative/comfyui/references/workflow-format.md +226 -0
  1107. package/skills/creative/comfyui/scripts/_common.py +835 -0
  1108. package/skills/creative/comfyui/scripts/auto_fix_deps.py +225 -0
  1109. package/skills/creative/comfyui/scripts/check_deps.py +437 -0
  1110. package/skills/creative/comfyui/scripts/comfyui_setup.sh +286 -0
  1111. package/skills/creative/comfyui/scripts/extract_schema.py +315 -0
  1112. package/skills/creative/comfyui/scripts/fetch_logs.py +158 -0
  1113. package/skills/creative/comfyui/scripts/hardware_check.py +497 -0
  1114. package/skills/creative/comfyui/scripts/health_check.py +223 -0
  1115. package/skills/creative/comfyui/scripts/run_batch.py +243 -0
  1116. package/skills/creative/comfyui/scripts/run_workflow.py +796 -0
  1117. package/skills/creative/comfyui/scripts/ws_monitor.py +267 -0
  1118. package/skills/creative/comfyui/tests/README.md +50 -0
  1119. package/skills/creative/comfyui/tests/conftest.py +64 -0
  1120. package/skills/creative/comfyui/tests/pytest.ini +5 -0
  1121. package/skills/creative/comfyui/tests/test_check_deps.py +68 -0
  1122. package/skills/creative/comfyui/tests/test_cloud_integration.py +95 -0
  1123. package/skills/creative/comfyui/tests/test_common.py +447 -0
  1124. package/skills/creative/comfyui/tests/test_extract_schema.py +185 -0
  1125. package/skills/creative/comfyui/tests/test_run_workflow.py +213 -0
  1126. package/skills/creative/comfyui/workflows/README.md +86 -0
  1127. package/skills/creative/comfyui/workflows/animatediff_video.json +64 -0
  1128. package/skills/creative/comfyui/workflows/flux_dev_txt2img.json +78 -0
  1129. package/skills/creative/comfyui/workflows/sd15_txt2img.json +49 -0
  1130. package/skills/creative/comfyui/workflows/sdxl_img2img.json +54 -0
  1131. package/skills/creative/comfyui/workflows/sdxl_inpaint.json +59 -0
  1132. package/skills/creative/comfyui/workflows/sdxl_txt2img.json +49 -0
  1133. package/skills/creative/comfyui/workflows/upscale_4x.json +27 -0
  1134. package/skills/creative/comfyui/workflows/wan_video_t2v.json +69 -0
  1135. package/skills/creative/creative-ideation/SKILL.md +152 -0
  1136. package/skills/creative/creative-ideation/references/full-prompt-library.md +110 -0
  1137. package/skills/creative/design-md/SKILL.md +199 -0
  1138. package/skills/creative/design-md/templates/starter.md +99 -0
  1139. package/skills/creative/excalidraw/SKILL.md +199 -0
  1140. package/skills/creative/excalidraw/references/colors.md +44 -0
  1141. package/skills/creative/excalidraw/references/dark-mode.md +68 -0
  1142. package/skills/creative/excalidraw/references/examples.md +141 -0
  1143. package/skills/creative/excalidraw/scripts/upload.py +133 -0
  1144. package/skills/creative/humanizer/LICENSE +21 -0
  1145. package/skills/creative/humanizer/SKILL.md +578 -0
  1146. package/skills/creative/manim-video/README.md +23 -0
  1147. package/skills/creative/manim-video/SKILL.md +269 -0
  1148. package/skills/creative/manim-video/references/animation-design-thinking.md +161 -0
  1149. package/skills/creative/manim-video/references/animations.md +282 -0
  1150. package/skills/creative/manim-video/references/camera-and-3d.md +135 -0
  1151. package/skills/creative/manim-video/references/decorations.md +202 -0
  1152. package/skills/creative/manim-video/references/equations.md +216 -0
  1153. package/skills/creative/manim-video/references/graphs-and-data.md +163 -0
  1154. package/skills/creative/manim-video/references/mobjects.md +333 -0
  1155. package/skills/creative/manim-video/references/paper-explainer.md +255 -0
  1156. package/skills/creative/manim-video/references/production-quality.md +190 -0
  1157. package/skills/creative/manim-video/references/rendering.md +185 -0
  1158. package/skills/creative/manim-video/references/scene-planning.md +118 -0
  1159. package/skills/creative/manim-video/references/troubleshooting.md +135 -0
  1160. package/skills/creative/manim-video/references/updaters-and-trackers.md +260 -0
  1161. package/skills/creative/manim-video/references/visual-design.md +124 -0
  1162. package/skills/creative/manim-video/scripts/setup.sh +14 -0
  1163. package/skills/creative/p5js/README.md +64 -0
  1164. package/skills/creative/p5js/SKILL.md +556 -0
  1165. package/skills/creative/p5js/references/animation.md +439 -0
  1166. package/skills/creative/p5js/references/color-systems.md +352 -0
  1167. package/skills/creative/p5js/references/core-api.md +410 -0
  1168. package/skills/creative/p5js/references/export-pipeline.md +566 -0
  1169. package/skills/creative/p5js/references/interaction.md +398 -0
  1170. package/skills/creative/p5js/references/shapes-and-geometry.md +300 -0
  1171. package/skills/creative/p5js/references/troubleshooting.md +532 -0
  1172. package/skills/creative/p5js/references/typography.md +302 -0
  1173. package/skills/creative/p5js/references/visual-effects.md +895 -0
  1174. package/skills/creative/p5js/references/webgl-and-3d.md +423 -0
  1175. package/skills/creative/p5js/scripts/export-frames.js +179 -0
  1176. package/skills/creative/p5js/scripts/render.sh +108 -0
  1177. package/skills/creative/p5js/scripts/serve.sh +28 -0
  1178. package/skills/creative/p5js/scripts/setup.sh +87 -0
  1179. package/skills/creative/p5js/templates/viewer.html +395 -0
  1180. package/skills/creative/pixel-art/ATTRIBUTION.md +54 -0
  1181. package/skills/creative/pixel-art/SKILL.md +218 -0
  1182. package/skills/creative/pixel-art/references/palettes.md +49 -0
  1183. package/skills/creative/pixel-art/scripts/__init__.py +0 -0
  1184. package/skills/creative/pixel-art/scripts/palettes.py +167 -0
  1185. package/skills/creative/pixel-art/scripts/pixel_art.py +162 -0
  1186. package/skills/creative/pixel-art/scripts/pixel_art_video.py +345 -0
  1187. package/skills/creative/popular-web-designs/SKILL.md +214 -0
  1188. package/skills/creative/popular-web-designs/templates/airbnb.md +259 -0
  1189. package/skills/creative/popular-web-designs/templates/airtable.md +102 -0
  1190. package/skills/creative/popular-web-designs/templates/apple.md +326 -0
  1191. package/skills/creative/popular-web-designs/templates/bmw.md +193 -0
  1192. package/skills/creative/popular-web-designs/templates/cal.md +272 -0
  1193. package/skills/creative/popular-web-designs/templates/claude.md +325 -0
  1194. package/skills/creative/popular-web-designs/templates/clay.md +317 -0
  1195. package/skills/creative/popular-web-designs/templates/clickhouse.md +294 -0
  1196. package/skills/creative/popular-web-designs/templates/cohere.md +279 -0
  1197. package/skills/creative/popular-web-designs/templates/coinbase.md +142 -0
  1198. package/skills/creative/popular-web-designs/templates/composio.md +320 -0
  1199. package/skills/creative/popular-web-designs/templates/cursor.md +322 -0
  1200. package/skills/creative/popular-web-designs/templates/elevenlabs.md +278 -0
  1201. package/skills/creative/popular-web-designs/templates/expo.md +294 -0
  1202. package/skills/creative/popular-web-designs/templates/figma.md +233 -0
  1203. package/skills/creative/popular-web-designs/templates/framer.md +259 -0
  1204. package/skills/creative/popular-web-designs/templates/hashicorp.md +291 -0
  1205. package/skills/creative/popular-web-designs/templates/ibm.md +345 -0
  1206. package/skills/creative/popular-web-designs/templates/intercom.md +159 -0
  1207. package/skills/creative/popular-web-designs/templates/kraken.md +138 -0
  1208. package/skills/creative/popular-web-designs/templates/linear.app.md +380 -0
  1209. package/skills/creative/popular-web-designs/templates/lovable.md +311 -0
  1210. package/skills/creative/popular-web-designs/templates/minimax.md +270 -0
  1211. package/skills/creative/popular-web-designs/templates/mintlify.md +339 -0
  1212. package/skills/creative/popular-web-designs/templates/miro.md +121 -0
  1213. package/skills/creative/popular-web-designs/templates/mistral.ai.md +274 -0
  1214. package/skills/creative/popular-web-designs/templates/mongodb.md +279 -0
  1215. package/skills/creative/popular-web-designs/templates/notion.md +322 -0
  1216. package/skills/creative/popular-web-designs/templates/nvidia.md +306 -0
  1217. package/skills/creative/popular-web-designs/templates/ollama.md +280 -0
  1218. package/skills/creative/popular-web-designs/templates/opencode.ai.md +294 -0
  1219. package/skills/creative/popular-web-designs/templates/pinterest.md +243 -0
  1220. package/skills/creative/popular-web-designs/templates/posthog.md +269 -0
  1221. package/skills/creative/popular-web-designs/templates/raycast.md +281 -0
  1222. package/skills/creative/popular-web-designs/templates/replicate.md +274 -0
  1223. package/skills/creative/popular-web-designs/templates/resend.md +316 -0
  1224. package/skills/creative/popular-web-designs/templates/revolut.md +198 -0
  1225. package/skills/creative/popular-web-designs/templates/runwayml.md +257 -0
  1226. package/skills/creative/popular-web-designs/templates/sanity.md +370 -0
  1227. package/skills/creative/popular-web-designs/templates/sentry.md +275 -0
  1228. package/skills/creative/popular-web-designs/templates/spacex.md +207 -0
  1229. package/skills/creative/popular-web-designs/templates/spotify.md +259 -0
  1230. package/skills/creative/popular-web-designs/templates/stripe.md +335 -0
  1231. package/skills/creative/popular-web-designs/templates/supabase.md +268 -0
  1232. package/skills/creative/popular-web-designs/templates/superhuman.md +265 -0
  1233. package/skills/creative/popular-web-designs/templates/together.ai.md +276 -0
  1234. package/skills/creative/popular-web-designs/templates/uber.md +308 -0
  1235. package/skills/creative/popular-web-designs/templates/vercel.md +323 -0
  1236. package/skills/creative/popular-web-designs/templates/voltagent.md +336 -0
  1237. package/skills/creative/popular-web-designs/templates/warp.md +266 -0
  1238. package/skills/creative/popular-web-designs/templates/webflow.md +105 -0
  1239. package/skills/creative/popular-web-designs/templates/wise.md +186 -0
  1240. package/skills/creative/popular-web-designs/templates/x.ai.md +270 -0
  1241. package/skills/creative/popular-web-designs/templates/zapier.md +341 -0
  1242. package/skills/creative/pretext/SKILL.md +220 -0
  1243. package/skills/creative/pretext/references/patterns.md +258 -0
  1244. package/skills/creative/pretext/templates/donut-orbit.html +1468 -0
  1245. package/skills/creative/pretext/templates/hello-orb-flow.html +95 -0
  1246. package/skills/creative/sketch/SKILL.md +218 -0
  1247. package/skills/creative/songwriting-and-ai-music/SKILL.md +287 -0
  1248. package/skills/creative/touchdesigner-mcp/SKILL.md +356 -0
  1249. package/skills/creative/touchdesigner-mcp/references/3d-scene.md +275 -0
  1250. package/skills/creative/touchdesigner-mcp/references/animation.md +221 -0
  1251. package/skills/creative/touchdesigner-mcp/references/audio-reactive.md +175 -0
  1252. package/skills/creative/touchdesigner-mcp/references/dat-scripting.md +352 -0
  1253. package/skills/creative/touchdesigner-mcp/references/external-data.md +322 -0
  1254. package/skills/creative/touchdesigner-mcp/references/geometry-comp.md +121 -0
  1255. package/skills/creative/touchdesigner-mcp/references/glsl.md +151 -0
  1256. package/skills/creative/touchdesigner-mcp/references/layout-compositor.md +131 -0
  1257. package/skills/creative/touchdesigner-mcp/references/mcp-tools.md +382 -0
  1258. package/skills/creative/touchdesigner-mcp/references/midi-osc.md +211 -0
  1259. package/skills/creative/touchdesigner-mcp/references/network-patterns.md +966 -0
  1260. package/skills/creative/touchdesigner-mcp/references/operator-tips.md +106 -0
  1261. package/skills/creative/touchdesigner-mcp/references/operators.md +239 -0
  1262. package/skills/creative/touchdesigner-mcp/references/panel-ui.md +281 -0
  1263. package/skills/creative/touchdesigner-mcp/references/particles.md +245 -0
  1264. package/skills/creative/touchdesigner-mcp/references/pitfalls.md +704 -0
  1265. package/skills/creative/touchdesigner-mcp/references/postfx.md +183 -0
  1266. package/skills/creative/touchdesigner-mcp/references/projection-mapping.md +211 -0
  1267. package/skills/creative/touchdesigner-mcp/references/python-api.md +463 -0
  1268. package/skills/creative/touchdesigner-mcp/references/replicator.md +198 -0
  1269. package/skills/creative/touchdesigner-mcp/references/troubleshooting.md +244 -0
  1270. package/skills/creative/touchdesigner-mcp/scripts/setup.sh +115 -0
  1271. package/skills/data-science/DESCRIPTION.md +3 -0
  1272. package/skills/data-science/jupyter-live-kernel/SKILL.md +167 -0
  1273. package/skills/devops/kanban-orchestrator/SKILL.md +189 -0
  1274. package/skills/devops/kanban-worker/SKILL.md +184 -0
  1275. package/skills/devops/webhook-subscriptions/SKILL.md +204 -0
  1276. package/skills/diagramming/DESCRIPTION.md +3 -0
  1277. package/skills/dogfood/SKILL.md +162 -0
  1278. package/skills/dogfood/references/issue-taxonomy.md +109 -0
  1279. package/skills/dogfood/templates/dogfood-report-template.md +86 -0
  1280. package/skills/domain/DESCRIPTION.md +24 -0
  1281. package/skills/email/DESCRIPTION.md +3 -0
  1282. package/skills/email/himalaya/SKILL.md +299 -0
  1283. package/skills/email/himalaya/references/configuration.md +227 -0
  1284. package/skills/email/himalaya/references/message-composition.md +199 -0
  1285. package/skills/gaming/DESCRIPTION.md +3 -0
  1286. package/skills/gaming/minecraft-modpack-server/SKILL.md +187 -0
  1287. package/skills/gaming/pokemon-player/SKILL.md +216 -0
  1288. package/skills/gifs/DESCRIPTION.md +3 -0
  1289. package/skills/github/DESCRIPTION.md +3 -0
  1290. package/skills/github/codebase-inspection/SKILL.md +116 -0
  1291. package/skills/github/github-auth/SKILL.md +247 -0
  1292. package/skills/github/github-auth/scripts/gh-env.sh +66 -0
  1293. package/skills/github/github-code-review/SKILL.md +481 -0
  1294. package/skills/github/github-code-review/references/review-output-template.md +74 -0
  1295. package/skills/github/github-issues/SKILL.md +370 -0
  1296. package/skills/github/github-issues/templates/bug-report.md +35 -0
  1297. package/skills/github/github-issues/templates/feature-request.md +31 -0
  1298. package/skills/github/github-pr-workflow/SKILL.md +367 -0
  1299. package/skills/github/github-pr-workflow/references/ci-troubleshooting.md +183 -0
  1300. package/skills/github/github-pr-workflow/references/conventional-commits.md +71 -0
  1301. package/skills/github/github-pr-workflow/templates/pr-body-bugfix.md +35 -0
  1302. package/skills/github/github-pr-workflow/templates/pr-body-feature.md +33 -0
  1303. package/skills/github/github-repo-management/SKILL.md +516 -0
  1304. package/skills/github/github-repo-management/references/github-api-cheatsheet.md +161 -0
  1305. package/skills/index-cache/anthropics_skills_skills_.json +1 -0
  1306. package/skills/index-cache/claude_marketplace_anthropics_skills.json +1 -0
  1307. package/skills/index-cache/lobehub_index.json +1 -0
  1308. package/skills/index-cache/openai_skills_skills_.json +1 -0
  1309. package/skills/inference-sh/DESCRIPTION.md +19 -0
  1310. package/skills/mcp/DESCRIPTION.md +3 -0
  1311. package/skills/mcp/native-mcp/SKILL.md +357 -0
  1312. package/skills/media/DESCRIPTION.md +3 -0
  1313. package/skills/media/gif-search/SKILL.md +91 -0
  1314. package/skills/media/heartmula/SKILL.md +171 -0
  1315. package/skills/media/songsee/SKILL.md +83 -0
  1316. package/skills/media/spotify/SKILL.md +135 -0
  1317. package/skills/media/youtube-content/SKILL.md +73 -0
  1318. package/skills/media/youtube-content/references/output-formats.md +56 -0
  1319. package/skills/media/youtube-content/scripts/fetch_transcript.py +124 -0
  1320. package/skills/mlops/DESCRIPTION.md +3 -0
  1321. package/skills/mlops/evaluation/DESCRIPTION.md +3 -0
  1322. package/skills/mlops/evaluation/lm-evaluation-harness/SKILL.md +498 -0
  1323. package/skills/mlops/evaluation/lm-evaluation-harness/references/api-evaluation.md +490 -0
  1324. package/skills/mlops/evaluation/lm-evaluation-harness/references/benchmark-guide.md +488 -0
  1325. package/skills/mlops/evaluation/lm-evaluation-harness/references/custom-tasks.md +602 -0
  1326. package/skills/mlops/evaluation/lm-evaluation-harness/references/distributed-eval.md +519 -0
  1327. package/skills/mlops/evaluation/weights-and-biases/SKILL.md +594 -0
  1328. package/skills/mlops/evaluation/weights-and-biases/references/artifacts.md +584 -0
  1329. package/skills/mlops/evaluation/weights-and-biases/references/integrations.md +700 -0
  1330. package/skills/mlops/evaluation/weights-and-biases/references/sweeps.md +847 -0
  1331. package/skills/mlops/huggingface-hub/SKILL.md +81 -0
  1332. package/skills/mlops/inference/DESCRIPTION.md +3 -0
  1333. package/skills/mlops/inference/llama-cpp/SKILL.md +249 -0
  1334. package/skills/mlops/inference/llama-cpp/references/advanced-usage.md +504 -0
  1335. package/skills/mlops/inference/llama-cpp/references/hub-discovery.md +168 -0
  1336. package/skills/mlops/inference/llama-cpp/references/optimization.md +89 -0
  1337. package/skills/mlops/inference/llama-cpp/references/quantization.md +243 -0
  1338. package/skills/mlops/inference/llama-cpp/references/server.md +150 -0
  1339. package/skills/mlops/inference/llama-cpp/references/troubleshooting.md +442 -0
  1340. package/skills/mlops/inference/obliteratus/SKILL.md +342 -0
  1341. package/skills/mlops/inference/obliteratus/references/analysis-modules.md +166 -0
  1342. package/skills/mlops/inference/obliteratus/references/methods-guide.md +141 -0
  1343. package/skills/mlops/inference/obliteratus/templates/abliteration-config.yaml +33 -0
  1344. package/skills/mlops/inference/obliteratus/templates/analysis-study.yaml +40 -0
  1345. package/skills/mlops/inference/obliteratus/templates/batch-abliteration.yaml +41 -0
  1346. package/skills/mlops/inference/vllm/SKILL.md +372 -0
  1347. package/skills/mlops/inference/vllm/references/optimization.md +226 -0
  1348. package/skills/mlops/inference/vllm/references/quantization.md +284 -0
  1349. package/skills/mlops/inference/vllm/references/server-deployment.md +255 -0
  1350. package/skills/mlops/inference/vllm/references/troubleshooting.md +447 -0
  1351. package/skills/mlops/models/DESCRIPTION.md +3 -0
  1352. package/skills/mlops/models/audiocraft/SKILL.md +568 -0
  1353. package/skills/mlops/models/audiocraft/references/advanced-usage.md +666 -0
  1354. package/skills/mlops/models/audiocraft/references/troubleshooting.md +504 -0
  1355. package/skills/mlops/models/segment-anything/SKILL.md +506 -0
  1356. package/skills/mlops/models/segment-anything/references/advanced-usage.md +589 -0
  1357. package/skills/mlops/models/segment-anything/references/troubleshooting.md +484 -0
  1358. package/skills/mlops/research/DESCRIPTION.md +3 -0
  1359. package/skills/mlops/research/dspy/SKILL.md +594 -0
  1360. package/skills/mlops/research/dspy/references/examples.md +663 -0
  1361. package/skills/mlops/research/dspy/references/modules.md +475 -0
  1362. package/skills/mlops/research/dspy/references/optimizers.md +566 -0
  1363. package/skills/mlops/training/DESCRIPTION.md +3 -0
  1364. package/skills/mlops/vector-databases/DESCRIPTION.md +3 -0
  1365. package/skills/note-taking/DESCRIPTION.md +3 -0
  1366. package/skills/note-taking/obsidian/SKILL.md +61 -0
  1367. package/skills/productivity/DESCRIPTION.md +3 -0
  1368. package/skills/productivity/airtable/SKILL.md +229 -0
  1369. package/skills/productivity/google-workspace/SKILL.md +335 -0
  1370. package/skills/productivity/google-workspace/references/gmail-search-syntax.md +63 -0
  1371. package/skills/productivity/google-workspace/scripts/_hermes_home.py +43 -0
  1372. package/skills/productivity/google-workspace/scripts/google_api.py +1221 -0
  1373. package/skills/productivity/google-workspace/scripts/gws_bridge.py +108 -0
  1374. package/skills/productivity/google-workspace/scripts/setup.py +454 -0
  1375. package/skills/productivity/linear/SKILL.md +380 -0
  1376. package/skills/productivity/linear/scripts/linear_api.py +445 -0
  1377. package/skills/productivity/maps/SKILL.md +195 -0
  1378. package/skills/productivity/maps/scripts/maps_client.py +1298 -0
  1379. package/skills/productivity/nano-pdf/SKILL.md +52 -0
  1380. package/skills/productivity/notion/SKILL.md +448 -0
  1381. package/skills/productivity/notion/references/block-types.md +112 -0
  1382. package/skills/productivity/ocr-and-documents/DESCRIPTION.md +3 -0
  1383. package/skills/productivity/ocr-and-documents/SKILL.md +172 -0
  1384. package/skills/productivity/ocr-and-documents/scripts/extract_marker.py +87 -0
  1385. package/skills/productivity/ocr-and-documents/scripts/extract_pymupdf.py +98 -0
  1386. package/skills/productivity/powerpoint/LICENSE.txt +30 -0
  1387. package/skills/productivity/powerpoint/SKILL.md +237 -0
  1388. package/skills/productivity/powerpoint/editing.md +205 -0
  1389. package/skills/productivity/powerpoint/pptxgenjs.md +420 -0
  1390. package/skills/productivity/powerpoint/scripts/__init__.py +0 -0
  1391. package/skills/productivity/powerpoint/scripts/add_slide.py +195 -0
  1392. package/skills/productivity/powerpoint/scripts/clean.py +286 -0
  1393. package/skills/productivity/powerpoint/scripts/office/helpers/__init__.py +0 -0
  1394. package/skills/productivity/powerpoint/scripts/office/helpers/merge_runs.py +199 -0
  1395. package/skills/productivity/powerpoint/scripts/office/helpers/simplify_redlines.py +197 -0
  1396. package/skills/productivity/powerpoint/scripts/office/pack.py +159 -0
  1397. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  1398. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  1399. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  1400. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  1401. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  1402. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  1403. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  1404. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  1405. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  1406. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  1407. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  1408. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  1409. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  1410. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  1411. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  1412. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  1413. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  1414. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  1415. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  1416. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  1417. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  1418. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  1419. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  1420. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  1421. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  1422. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  1423. package/skills/productivity/powerpoint/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  1424. package/skills/productivity/powerpoint/scripts/office/schemas/ecma/fourth-edition/opc-contentTypes.xsd +42 -0
  1425. package/skills/productivity/powerpoint/scripts/office/schemas/ecma/fourth-edition/opc-coreProperties.xsd +50 -0
  1426. package/skills/productivity/powerpoint/scripts/office/schemas/ecma/fourth-edition/opc-digSig.xsd +49 -0
  1427. package/skills/productivity/powerpoint/scripts/office/schemas/ecma/fourth-edition/opc-relationships.xsd +33 -0
  1428. package/skills/productivity/powerpoint/scripts/office/schemas/mce/mc.xsd +75 -0
  1429. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  1430. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  1431. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  1432. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  1433. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  1434. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  1435. package/skills/productivity/powerpoint/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  1436. package/skills/productivity/teams-meeting-pipeline/SKILL.md +116 -0
  1437. package/skills/red-teaming/godmode/SKILL.md +404 -0
  1438. package/skills/red-teaming/godmode/references/jailbreak-templates.md +128 -0
  1439. package/skills/red-teaming/godmode/references/refusal-detection.md +142 -0
  1440. package/skills/red-teaming/godmode/scripts/auto_jailbreak.py +769 -0
  1441. package/skills/red-teaming/godmode/scripts/godmode_race.py +530 -0
  1442. package/skills/red-teaming/godmode/scripts/load_godmode.py +45 -0
  1443. package/skills/red-teaming/godmode/scripts/parseltongue.py +550 -0
  1444. package/skills/red-teaming/godmode/templates/prefill-subtle.json +10 -0
  1445. package/skills/red-teaming/godmode/templates/prefill.json +18 -0
  1446. package/skills/research/DESCRIPTION.md +3 -0
  1447. package/skills/research/arxiv/SKILL.md +282 -0
  1448. package/skills/research/arxiv/scripts/search_arxiv.py +114 -0
  1449. package/skills/research/blogwatcher/SKILL.md +137 -0
  1450. package/skills/research/llm-wiki/SKILL.md +507 -0
  1451. package/skills/research/polymarket/SKILL.md +77 -0
  1452. package/skills/research/polymarket/references/api-endpoints.md +220 -0
  1453. package/skills/research/polymarket/scripts/polymarket.py +284 -0
  1454. package/skills/research/research-paper-writing/SKILL.md +2377 -0
  1455. package/skills/research/research-paper-writing/references/autoreason-methodology.md +394 -0
  1456. package/skills/research/research-paper-writing/references/checklists.md +434 -0
  1457. package/skills/research/research-paper-writing/references/citation-workflow.md +564 -0
  1458. package/skills/research/research-paper-writing/references/experiment-patterns.md +728 -0
  1459. package/skills/research/research-paper-writing/references/human-evaluation.md +476 -0
  1460. package/skills/research/research-paper-writing/references/paper-types.md +481 -0
  1461. package/skills/research/research-paper-writing/references/reviewer-guidelines.md +433 -0
  1462. package/skills/research/research-paper-writing/references/sources.md +191 -0
  1463. package/skills/research/research-paper-writing/references/writing-guide.md +474 -0
  1464. package/skills/research/research-paper-writing/templates/README.md +251 -0
  1465. package/skills/research/research-paper-writing/templates/aaai2026/README.md +534 -0
  1466. package/skills/research/research-paper-writing/templates/aaai2026/aaai2026-unified-supp.tex +144 -0
  1467. package/skills/research/research-paper-writing/templates/aaai2026/aaai2026-unified-template.tex +952 -0
  1468. package/skills/research/research-paper-writing/templates/aaai2026/aaai2026.bib +111 -0
  1469. package/skills/research/research-paper-writing/templates/aaai2026/aaai2026.bst +1493 -0
  1470. package/skills/research/research-paper-writing/templates/aaai2026/aaai2026.sty +315 -0
  1471. package/skills/research/research-paper-writing/templates/acl/README.md +50 -0
  1472. package/skills/research/research-paper-writing/templates/acl/acl.sty +312 -0
  1473. package/skills/research/research-paper-writing/templates/acl/acl_latex.tex +377 -0
  1474. package/skills/research/research-paper-writing/templates/acl/acl_lualatex.tex +101 -0
  1475. package/skills/research/research-paper-writing/templates/acl/acl_natbib.bst +1940 -0
  1476. package/skills/research/research-paper-writing/templates/acl/anthology.bib.txt +26 -0
  1477. package/skills/research/research-paper-writing/templates/acl/custom.bib +70 -0
  1478. package/skills/research/research-paper-writing/templates/acl/formatting.md +326 -0
  1479. package/skills/research/research-paper-writing/templates/colm2025/README.md +3 -0
  1480. package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.bib +11 -0
  1481. package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.bst +1440 -0
  1482. package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.pdf +0 -0
  1483. package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.sty +218 -0
  1484. package/skills/research/research-paper-writing/templates/colm2025/colm2025_conference.tex +305 -0
  1485. package/skills/research/research-paper-writing/templates/colm2025/fancyhdr.sty +485 -0
  1486. package/skills/research/research-paper-writing/templates/colm2025/math_commands.tex +508 -0
  1487. package/skills/research/research-paper-writing/templates/colm2025/natbib.sty +1246 -0
  1488. package/skills/research/research-paper-writing/templates/iclr2026/fancyhdr.sty +485 -0
  1489. package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.bib +24 -0
  1490. package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.bst +1440 -0
  1491. package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.pdf +0 -0
  1492. package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.sty +246 -0
  1493. package/skills/research/research-paper-writing/templates/iclr2026/iclr2026_conference.tex +414 -0
  1494. package/skills/research/research-paper-writing/templates/iclr2026/math_commands.tex +508 -0
  1495. package/skills/research/research-paper-writing/templates/iclr2026/natbib.sty +1246 -0
  1496. package/skills/research/research-paper-writing/templates/icml2026/algorithm.sty +79 -0
  1497. package/skills/research/research-paper-writing/templates/icml2026/algorithmic.sty +201 -0
  1498. package/skills/research/research-paper-writing/templates/icml2026/example_paper.bib +75 -0
  1499. package/skills/research/research-paper-writing/templates/icml2026/example_paper.pdf +0 -0
  1500. package/skills/research/research-paper-writing/templates/icml2026/example_paper.tex +662 -0
  1501. package/skills/research/research-paper-writing/templates/icml2026/fancyhdr.sty +864 -0
  1502. package/skills/research/research-paper-writing/templates/icml2026/icml2026.bst +1443 -0
  1503. package/skills/research/research-paper-writing/templates/icml2026/icml2026.sty +767 -0
  1504. package/skills/research/research-paper-writing/templates/icml2026/icml_numpapers.pdf +0 -0
  1505. package/skills/research/research-paper-writing/templates/neurips2025/Makefile +36 -0
  1506. package/skills/research/research-paper-writing/templates/neurips2025/extra_pkgs.tex +53 -0
  1507. package/skills/research/research-paper-writing/templates/neurips2025/main.tex +38 -0
  1508. package/skills/research/research-paper-writing/templates/neurips2025/neurips.sty +382 -0
  1509. package/skills/smart-home/DESCRIPTION.md +3 -0
  1510. package/skills/smart-home/openhue/SKILL.md +109 -0
  1511. package/skills/social-media/DESCRIPTION.md +3 -0
  1512. package/skills/social-media/xurl/SKILL.md +414 -0
  1513. package/skills/software-development/debugging-hermes-tui-commands/SKILL.md +152 -0
  1514. package/skills/software-development/hermes-agent-skill-authoring/SKILL.md +165 -0
  1515. package/skills/software-development/node-inspect-debugger/SKILL.md +319 -0
  1516. package/skills/software-development/plan/SKILL.md +58 -0
  1517. package/skills/software-development/python-debugpy/SKILL.md +375 -0
  1518. package/skills/software-development/requesting-code-review/SKILL.md +280 -0
  1519. package/skills/software-development/spike/SKILL.md +197 -0
  1520. package/skills/software-development/subagent-driven-development/SKILL.md +352 -0
  1521. package/skills/software-development/subagent-driven-development/references/context-budget-discipline.md +53 -0
  1522. package/skills/software-development/subagent-driven-development/references/gates-taxonomy.md +93 -0
  1523. package/skills/software-development/systematic-debugging/SKILL.md +367 -0
  1524. package/skills/software-development/test-driven-development/SKILL.md +343 -0
  1525. package/skills/software-development/writing-plans/SKILL.md +297 -0
  1526. package/skills/yuanbao/SKILL.md +108 -0
  1527. package/tools/__init__.py +25 -0
  1528. package/tools/__pycache__/__init__.cpython-312.pyc +0 -0
  1529. package/tools/__pycache__/approval.cpython-312.pyc +0 -0
  1530. package/tools/__pycache__/binary_extensions.cpython-312.pyc +0 -0
  1531. package/tools/__pycache__/browser_camofox.cpython-312.pyc +0 -0
  1532. package/tools/__pycache__/browser_camofox_state.cpython-312.pyc +0 -0
  1533. package/tools/__pycache__/browser_cdp_tool.cpython-312.pyc +0 -0
  1534. package/tools/__pycache__/browser_dialog_tool.cpython-312.pyc +0 -0
  1535. package/tools/__pycache__/browser_supervisor.cpython-312.pyc +0 -0
  1536. package/tools/__pycache__/browser_tool.cpython-312.pyc +0 -0
  1537. package/tools/__pycache__/budget_config.cpython-312.pyc +0 -0
  1538. package/tools/__pycache__/checkpoint_manager.cpython-312.pyc +0 -0
  1539. package/tools/__pycache__/clarify_gateway.cpython-312.pyc +0 -0
  1540. package/tools/__pycache__/clarify_tool.cpython-312.pyc +0 -0
  1541. package/tools/__pycache__/code_execution_tool.cpython-312.pyc +0 -0
  1542. package/tools/__pycache__/computer_use_tool.cpython-312.pyc +0 -0
  1543. package/tools/__pycache__/cronjob_tools.cpython-312.pyc +0 -0
  1544. package/tools/__pycache__/debug_helpers.cpython-312.pyc +0 -0
  1545. package/tools/__pycache__/delegate_tool.cpython-312.pyc +0 -0
  1546. package/tools/__pycache__/discord_tool.cpython-312.pyc +0 -0
  1547. package/tools/__pycache__/feishu_doc_tool.cpython-312.pyc +0 -0
  1548. package/tools/__pycache__/feishu_drive_tool.cpython-312.pyc +0 -0
  1549. package/tools/__pycache__/file_operations.cpython-312.pyc +0 -0
  1550. package/tools/__pycache__/file_state.cpython-312.pyc +0 -0
  1551. package/tools/__pycache__/file_tools.cpython-312.pyc +0 -0
  1552. package/tools/__pycache__/homeassistant_tool.cpython-312.pyc +0 -0
  1553. package/tools/__pycache__/image_generation_tool.cpython-312.pyc +0 -0
  1554. package/tools/__pycache__/interrupt.cpython-312.pyc +0 -0
  1555. package/tools/__pycache__/kanban_tools.cpython-312.pyc +0 -0
  1556. package/tools/__pycache__/lazy_deps.cpython-312.pyc +0 -0
  1557. package/tools/__pycache__/managed_tool_gateway.cpython-312.pyc +0 -0
  1558. package/tools/__pycache__/mcp_tool.cpython-312.pyc +0 -0
  1559. package/tools/__pycache__/memory_tool.cpython-312.pyc +0 -0
  1560. package/tools/__pycache__/mixture_of_agents_tool.cpython-312.pyc +0 -0
  1561. package/tools/__pycache__/openrouter_client.cpython-312.pyc +0 -0
  1562. package/tools/__pycache__/process_registry.cpython-312.pyc +0 -0
  1563. package/tools/__pycache__/registry.cpython-312.pyc +0 -0
  1564. package/tools/__pycache__/schema_sanitizer.cpython-312.pyc +0 -0
  1565. package/tools/__pycache__/send_message_tool.cpython-312.pyc +0 -0
  1566. package/tools/__pycache__/session_search_tool.cpython-312.pyc +0 -0
  1567. package/tools/__pycache__/skill_manager_tool.cpython-312.pyc +0 -0
  1568. package/tools/__pycache__/skill_provenance.cpython-312.pyc +0 -0
  1569. package/tools/__pycache__/skill_usage.cpython-312.pyc +0 -0
  1570. package/tools/__pycache__/skills_guard.cpython-312.pyc +0 -0
  1571. package/tools/__pycache__/skills_sync.cpython-312.pyc +0 -0
  1572. package/tools/__pycache__/skills_tool.cpython-312.pyc +0 -0
  1573. package/tools/__pycache__/slash_confirm.cpython-312.pyc +0 -0
  1574. package/tools/__pycache__/terminal_tool.cpython-312.pyc +0 -0
  1575. package/tools/__pycache__/tirith_security.cpython-312.pyc +0 -0
  1576. package/tools/__pycache__/todo_tool.cpython-312.pyc +0 -0
  1577. package/tools/__pycache__/tool_backend_helpers.cpython-312.pyc +0 -0
  1578. package/tools/__pycache__/tool_result_storage.cpython-312.pyc +0 -0
  1579. package/tools/__pycache__/tts_tool.cpython-312.pyc +0 -0
  1580. package/tools/__pycache__/url_safety.cpython-312.pyc +0 -0
  1581. package/tools/__pycache__/video_generation_tool.cpython-312.pyc +0 -0
  1582. package/tools/__pycache__/vision_tools.cpython-312.pyc +0 -0
  1583. package/tools/__pycache__/voice_mode.cpython-312.pyc +0 -0
  1584. package/tools/__pycache__/web_tools.cpython-312.pyc +0 -0
  1585. package/tools/__pycache__/website_policy.cpython-312.pyc +0 -0
  1586. package/tools/__pycache__/x_search_tool.cpython-312.pyc +0 -0
  1587. package/tools/__pycache__/xai_http.cpython-312.pyc +0 -0
  1588. package/tools/__pycache__/yuanbao_tools.cpython-312.pyc +0 -0
  1589. package/tools/ansi_strip.py +44 -0
  1590. package/tools/approval.py +1392 -0
  1591. package/tools/binary_extensions.py +42 -0
  1592. package/tools/browser_camofox.py +700 -0
  1593. package/tools/browser_camofox_state.py +48 -0
  1594. package/tools/browser_cdp_tool.py +569 -0
  1595. package/tools/browser_dialog_tool.py +148 -0
  1596. package/tools/browser_providers/__init__.py +10 -0
  1597. package/tools/browser_providers/__pycache__/__init__.cpython-312.pyc +0 -0
  1598. package/tools/browser_providers/__pycache__/base.cpython-312.pyc +0 -0
  1599. package/tools/browser_providers/__pycache__/browser_use.cpython-312.pyc +0 -0
  1600. package/tools/browser_providers/__pycache__/browserbase.cpython-312.pyc +0 -0
  1601. package/tools/browser_providers/__pycache__/firecrawl.cpython-312.pyc +0 -0
  1602. package/tools/browser_providers/base.py +59 -0
  1603. package/tools/browser_providers/browser_use.py +225 -0
  1604. package/tools/browser_providers/browserbase.py +222 -0
  1605. package/tools/browser_providers/firecrawl.py +112 -0
  1606. package/tools/browser_supervisor.py +1457 -0
  1607. package/tools/browser_tool.py +3676 -0
  1608. package/tools/budget_config.py +51 -0
  1609. package/tools/checkpoint_manager.py +1639 -0
  1610. package/tools/clarify_gateway.py +278 -0
  1611. package/tools/clarify_tool.py +141 -0
  1612. package/tools/code_execution_tool.py +1782 -0
  1613. package/tools/computer_use/__init__.py +43 -0
  1614. package/tools/computer_use/__pycache__/__init__.cpython-312.pyc +0 -0
  1615. package/tools/computer_use/__pycache__/backend.cpython-312.pyc +0 -0
  1616. package/tools/computer_use/__pycache__/schema.cpython-312.pyc +0 -0
  1617. package/tools/computer_use/__pycache__/tool.cpython-312.pyc +0 -0
  1618. package/tools/computer_use/backend.py +150 -0
  1619. package/tools/computer_use/cua_backend.py +682 -0
  1620. package/tools/computer_use/schema.py +191 -0
  1621. package/tools/computer_use/tool.py +521 -0
  1622. package/tools/computer_use_tool.py +39 -0
  1623. package/tools/credential_files.py +437 -0
  1624. package/tools/cronjob_tools.py +719 -0
  1625. package/tools/debug_helpers.py +106 -0
  1626. package/tools/delegate_tool.py +2797 -0
  1627. package/tools/discord_tool.py +959 -0
  1628. package/tools/env_passthrough.py +145 -0
  1629. package/tools/environments/__init__.py +14 -0
  1630. package/tools/environments/__pycache__/__init__.cpython-312.pyc +0 -0
  1631. package/tools/environments/__pycache__/base.cpython-312.pyc +0 -0
  1632. package/tools/environments/__pycache__/docker.cpython-312.pyc +0 -0
  1633. package/tools/environments/__pycache__/file_sync.cpython-312.pyc +0 -0
  1634. package/tools/environments/__pycache__/local.cpython-312.pyc +0 -0
  1635. package/tools/environments/__pycache__/managed_modal.cpython-312.pyc +0 -0
  1636. package/tools/environments/__pycache__/modal.cpython-312.pyc +0 -0
  1637. package/tools/environments/__pycache__/modal_utils.cpython-312.pyc +0 -0
  1638. package/tools/environments/__pycache__/singularity.cpython-312.pyc +0 -0
  1639. package/tools/environments/__pycache__/ssh.cpython-312.pyc +0 -0
  1640. package/tools/environments/base.py +844 -0
  1641. package/tools/environments/daytona.py +270 -0
  1642. package/tools/environments/docker.py +656 -0
  1643. package/tools/environments/file_sync.py +400 -0
  1644. package/tools/environments/local.py +658 -0
  1645. package/tools/environments/managed_modal.py +282 -0
  1646. package/tools/environments/modal.py +479 -0
  1647. package/tools/environments/modal_utils.py +199 -0
  1648. package/tools/environments/singularity.py +263 -0
  1649. package/tools/environments/ssh.py +295 -0
  1650. package/tools/environments/vercel_sandbox.py +655 -0
  1651. package/tools/feishu_doc_tool.py +138 -0
  1652. package/tools/feishu_drive_tool.py +431 -0
  1653. package/tools/file_operations.py +1825 -0
  1654. package/tools/file_state.py +332 -0
  1655. package/tools/file_tools.py +1172 -0
  1656. package/tools/fuzzy_match.py +703 -0
  1657. package/tools/homeassistant_tool.py +513 -0
  1658. package/tools/image_generation_tool.py +1098 -0
  1659. package/tools/interrupt.py +98 -0
  1660. package/tools/kanban_tools.py +1139 -0
  1661. package/tools/lazy_deps.py +608 -0
  1662. package/tools/managed_tool_gateway.py +168 -0
  1663. package/tools/mcp_oauth.py +633 -0
  1664. package/tools/mcp_oauth_manager.py +607 -0
  1665. package/tools/mcp_tool.py +3483 -0
  1666. package/tools/memory_tool.py +584 -0
  1667. package/tools/microsoft_graph_auth.py +245 -0
  1668. package/tools/microsoft_graph_client.py +408 -0
  1669. package/tools/mixture_of_agents_tool.py +542 -0
  1670. package/tools/neutts_samples/jo.txt +1 -0
  1671. package/tools/neutts_samples/jo.wav +0 -0
  1672. package/tools/neutts_synth.py +104 -0
  1673. package/tools/openrouter_client.py +33 -0
  1674. package/tools/osv_check.py +155 -0
  1675. package/tools/patch_parser.py +592 -0
  1676. package/tools/path_security.py +43 -0
  1677. package/tools/process_registry.py +1534 -0
  1678. package/tools/registry.py +589 -0
  1679. package/tools/schema_sanitizer.py +370 -0
  1680. package/tools/send_message_tool.py +1900 -0
  1681. package/tools/session_search_tool.py +613 -0
  1682. package/tools/skill_manager_tool.py +932 -0
  1683. package/tools/skill_provenance.py +78 -0
  1684. package/tools/skill_usage.py +610 -0
  1685. package/tools/skills_guard.py +932 -0
  1686. package/tools/skills_hub.py +3263 -0
  1687. package/tools/skills_sync.py +432 -0
  1688. package/tools/skills_tool.py +1569 -0
  1689. package/tools/slash_confirm.py +167 -0
  1690. package/tools/terminal_tool.py +2376 -0
  1691. package/tools/tirith_security.py +775 -0
  1692. package/tools/todo_tool.py +277 -0
  1693. package/tools/tool_backend_helpers.py +144 -0
  1694. package/tools/tool_output_limits.py +92 -0
  1695. package/tools/tool_result_storage.py +232 -0
  1696. package/tools/transcription_tools.py +936 -0
  1697. package/tools/tts_tool.py +2285 -0
  1698. package/tools/url_safety.py +330 -0
  1699. package/tools/video_generation_tool.py +561 -0
  1700. package/tools/vision_tools.py +1422 -0
  1701. package/tools/voice_mode.py +1019 -0
  1702. package/tools/web_tools.py +1551 -0
  1703. package/tools/website_policy.py +283 -0
  1704. package/tools/x_search_tool.py +424 -0
  1705. package/tools/xai_http.py +83 -0
  1706. package/tools/yuanbao_tools.py +736 -0
  1707. package/toolset_distributions.py +364 -0
  1708. package/toolsets.py +866 -0
  1709. package/trajectory_compressor.py +1509 -0
  1710. package/tui_gateway/__init__.py +0 -0
  1711. package/tui_gateway/entry.py +251 -0
  1712. package/tui_gateway/event_publisher.py +126 -0
  1713. package/tui_gateway/render.py +49 -0
  1714. package/tui_gateway/server.py +6623 -0
  1715. package/tui_gateway/slash_worker.py +76 -0
  1716. package/tui_gateway/transport.py +219 -0
  1717. package/tui_gateway/ws.py +178 -0
  1718. package/utils.py +361 -0
@@ -0,0 +1,1428 @@
1
+ """Shared runtime provider resolution for CLI, gateway, cron, and helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ import os
7
+ import re
8
+ from typing import Any, Dict, Optional
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ from hermes_cli import auth as auth_mod
13
+ from agent.credential_pool import CredentialPool, PooledCredential, get_custom_provider_pool_key, load_pool
14
+ from hermes_cli.auth import (
15
+ AuthError,
16
+ DEFAULT_CODEX_BASE_URL,
17
+ DEFAULT_QWEN_BASE_URL,
18
+ DEFAULT_XAI_OAUTH_BASE_URL,
19
+ PROVIDER_REGISTRY,
20
+ _agent_key_is_usable,
21
+ format_auth_error,
22
+ resolve_provider,
23
+ resolve_nous_runtime_credentials,
24
+ resolve_codex_runtime_credentials,
25
+ resolve_xai_oauth_runtime_credentials,
26
+ resolve_qwen_runtime_credentials,
27
+ resolve_gemini_oauth_runtime_credentials,
28
+ resolve_api_key_provider_credentials,
29
+ resolve_external_process_provider_credentials,
30
+ has_usable_secret,
31
+ )
32
+ from hermes_cli.config import get_compatible_custom_providers, load_config
33
+ from calvyn_constants import OPENROUTER_BASE_URL
34
+ from utils import base_url_host_matches, base_url_hostname
35
+
36
+
37
+ def _normalize_custom_provider_name(value: str) -> str:
38
+ return value.strip().lower().replace(" ", "-")
39
+
40
+
41
+ def _loopback_hostname(host: str) -> bool:
42
+ h = (host or "").lower().rstrip(".")
43
+ return h in {"localhost", "127.0.0.1", "::1", "0.0.0.0"}
44
+
45
+
46
+ def _config_base_url_trustworthy_for_bare_custom(cfg_base_url: str, cfg_provider: str) -> bool:
47
+ """Decide whether ``model.base_url`` may back bare ``custom`` runtime resolution.
48
+
49
+ GitHub #14676: the model picker can select Custom while ``model.provider`` still reflects a
50
+ previous provider. Reject non-loopback URLs unless the YAML provider is already ``custom``,
51
+ so a stale OpenRouter/Z.ai base_url cannot hijack local ``custom`` sessions.
52
+ """
53
+ cfg_provider_norm = (cfg_provider or "").strip().lower()
54
+ bu = (cfg_base_url or "").strip()
55
+ if not bu:
56
+ return False
57
+ if cfg_provider_norm == "custom":
58
+ return True
59
+ if base_url_host_matches(bu, "openrouter.ai"):
60
+ return False
61
+ return _loopback_hostname(base_url_hostname(bu))
62
+
63
+
64
+ def _detect_api_mode_for_url(base_url: str) -> Optional[str]:
65
+ """Auto-detect api_mode from the resolved base URL.
66
+
67
+ - Direct api.openai.com endpoints need the Responses API for GPT-5.x
68
+ tool calls with reasoning (chat/completions returns 400).
69
+ - Third-party Anthropic-compatible gateways (MiniMax, Zhipu GLM,
70
+ LiteLLM proxies, etc.) conventionally expose the native Anthropic
71
+ protocol under a ``/anthropic`` suffix — treat those as
72
+ ``anthropic_messages`` transport instead of the default
73
+ ``chat_completions``.
74
+ - Kimi Code's ``api.kimi.com/coding`` endpoint also speaks the
75
+ Anthropic Messages protocol (the /coding route accepts Claude
76
+ Code's native request shape).
77
+ """
78
+ normalized = (base_url or "").strip().lower().rstrip("/")
79
+ hostname = base_url_hostname(base_url)
80
+ if hostname == "api.x.ai":
81
+ return "codex_responses"
82
+ if hostname == "api.openai.com":
83
+ return "codex_responses"
84
+ if normalized.endswith("/anthropic"):
85
+ return "anthropic_messages"
86
+ if hostname == "api.kimi.com" and "/coding" in normalized:
87
+ return "anthropic_messages"
88
+ return None
89
+
90
+
91
+ def _auto_detect_local_model(base_url: str) -> str:
92
+ """Query a local server for its model name when only one model is loaded."""
93
+ if not base_url:
94
+ return ""
95
+ try:
96
+ import requests
97
+ url = base_url.rstrip("/")
98
+ if not url.endswith("/v1"):
99
+ url += "/v1"
100
+ resp = requests.get(url + "/models", timeout=5)
101
+ if resp.ok:
102
+ models = resp.json().get("data", [])
103
+ if len(models) == 1:
104
+ model_id = models[0].get("id", "")
105
+ if model_id:
106
+ return model_id
107
+ except Exception as exc:
108
+ # Log instead of silently swallowing — aids debugging when
109
+ # local model auto-detection fails unexpectedly.
110
+ logger.debug("Auto-detect model from %s failed: %s", base_url, exc)
111
+ return ""
112
+
113
+
114
+ def _get_model_config() -> Dict[str, Any]:
115
+ config = load_config()
116
+ model_cfg = config.get("model")
117
+ if isinstance(model_cfg, dict):
118
+ cfg = dict(model_cfg)
119
+ # Accept "model" as alias for "default" (users intuitively write model.model)
120
+ if not cfg.get("default") and cfg.get("model"):
121
+ cfg["default"] = cfg["model"]
122
+ default = (cfg.get("default") or "").strip()
123
+ base_url = (cfg.get("base_url") or "").strip()
124
+ is_local = "localhost" in base_url or "127.0.0.1" in base_url
125
+ is_fallback = not default
126
+ if is_local and is_fallback and base_url:
127
+ detected = _auto_detect_local_model(base_url)
128
+ if detected:
129
+ cfg["default"] = detected
130
+ return cfg
131
+ if isinstance(model_cfg, str) and model_cfg.strip():
132
+ return {"default": model_cfg.strip()}
133
+ return {}
134
+
135
+
136
+ def _provider_supports_explicit_api_mode(provider: Optional[str], configured_provider: Optional[str] = None) -> bool:
137
+ """Check whether a persisted api_mode should be honored for a given provider.
138
+
139
+ Prevents stale api_mode from a previous provider leaking into a
140
+ different one after a model/provider switch. Only applies the
141
+ persisted mode when the config's provider matches the runtime
142
+ provider (or when no configured provider is recorded).
143
+ """
144
+ normalized_provider = (provider or "").strip().lower()
145
+ normalized_configured = (configured_provider or "").strip().lower()
146
+ if not normalized_configured:
147
+ return True
148
+ if normalized_provider == "custom":
149
+ return normalized_configured == "custom" or normalized_configured.startswith("custom:")
150
+ return normalized_configured == normalized_provider
151
+
152
+
153
+ def _copilot_runtime_api_mode(model_cfg: Dict[str, Any], api_key: str) -> str:
154
+ configured_provider = str(model_cfg.get("provider") or "").strip().lower()
155
+ configured_mode = _parse_api_mode(model_cfg.get("api_mode"))
156
+ if configured_mode and _provider_supports_explicit_api_mode("copilot", configured_provider):
157
+ return configured_mode
158
+
159
+ model_name = str(model_cfg.get("default") or "").strip()
160
+ if not model_name:
161
+ return "chat_completions"
162
+
163
+ try:
164
+ from hermes_cli.models import copilot_model_api_mode
165
+
166
+ return copilot_model_api_mode(model_name, api_key=api_key)
167
+ except Exception:
168
+ return "chat_completions"
169
+
170
+
171
+ _VALID_API_MODES = {
172
+ "chat_completions",
173
+ "codex_responses",
174
+ "anthropic_messages",
175
+ "bedrock_converse",
176
+ # Optional opt-in: hand the entire turn to a `codex app-server` subprocess
177
+ # so terminal/file-ops/patching/sandboxing run inside Codex's own runtime
178
+ # instead of Hermes' tool dispatch. Gated behind config key
179
+ # `model.openai_runtime == "codex_app_server"` AND provider in
180
+ # {"openai", "openai-codex"}. Default is unchanged.
181
+ "codex_app_server",
182
+ }
183
+
184
+
185
+ def _parse_api_mode(raw: Any) -> Optional[str]:
186
+ """Validate an api_mode value from config. Returns None if invalid."""
187
+ if isinstance(raw, str):
188
+ normalized = raw.strip().lower()
189
+ if normalized in _VALID_API_MODES:
190
+ return normalized
191
+ return None
192
+
193
+
194
+ def _maybe_apply_codex_app_server_runtime(
195
+ *,
196
+ provider: str,
197
+ api_mode: str,
198
+ model_cfg: Optional[Dict[str, Any]],
199
+ ) -> str:
200
+ """Optional opt-in: rewrite api_mode → "codex_app_server" for OpenAI/Codex
201
+ providers when the user has explicitly enabled that runtime via
202
+ `model.openai_runtime: codex_app_server` in config.yaml.
203
+
204
+ Default behavior is preserved: when the key is unset, "auto", or empty,
205
+ this function is a no-op. Only providers in {"openai", "openai-codex"}
206
+ are eligible — other providers (anthropic, openrouter, etc.) cannot be
207
+ rerouted through codex.
208
+
209
+ Returns the (possibly-rewritten) api_mode."""
210
+ if not model_cfg:
211
+ return api_mode
212
+ if provider not in ("openai", "openai-codex"):
213
+ return api_mode
214
+ runtime = str(model_cfg.get("openai_runtime") or "").strip().lower()
215
+ if runtime == "codex_app_server":
216
+ return "codex_app_server"
217
+ return api_mode
218
+
219
+
220
+ def _resolve_runtime_from_pool_entry(
221
+ *,
222
+ provider: str,
223
+ entry: PooledCredential,
224
+ requested_provider: str,
225
+ model_cfg: Optional[Dict[str, Any]] = None,
226
+ pool: Optional[CredentialPool] = None,
227
+ target_model: Optional[str] = None,
228
+ ) -> Dict[str, Any]:
229
+ model_cfg = model_cfg or _get_model_config()
230
+ # When the caller is resolving for a specific target model (e.g. a /model
231
+ # mid-session switch), prefer that over the persisted model.default. This
232
+ # prevents api_mode being computed from a stale config default that no
233
+ # longer matches the model actually being used — the bug that caused
234
+ # opencode-zen /v1 to be stripped for chat_completions requests when
235
+ # config.default was still a Claude model.
236
+ effective_model = (target_model or model_cfg.get("default") or "")
237
+ base_url = (getattr(entry, "runtime_base_url", None) or getattr(entry, "base_url", None) or "").rstrip("/")
238
+ api_key = getattr(entry, "runtime_api_key", None) or getattr(entry, "access_token", "")
239
+ api_mode = "chat_completions"
240
+ if provider == "openai-codex":
241
+ api_mode = "codex_responses"
242
+ base_url = base_url or DEFAULT_CODEX_BASE_URL
243
+ elif provider == "xai-oauth":
244
+ api_mode = "codex_responses"
245
+ base_url = base_url or DEFAULT_XAI_OAUTH_BASE_URL
246
+ elif provider == "qwen-oauth":
247
+ api_mode = "chat_completions"
248
+ base_url = base_url or DEFAULT_QWEN_BASE_URL
249
+ elif provider == "google-gemini-cli":
250
+ api_mode = "chat_completions"
251
+ base_url = base_url or "cloudcode-pa://google"
252
+ elif provider == "minimax-oauth":
253
+ # MiniMax OAuth tokens are valid only against the Anthropic Messages
254
+ # compatible endpoint. Do not honor stale model.api_mode values from a
255
+ # prior OpenAI-compatible provider, or the client will hit
256
+ # /chat/completions under /anthropic and receive a bare nginx 404.
257
+ api_mode = "anthropic_messages"
258
+ pconfig = PROVIDER_REGISTRY.get(provider)
259
+ base_url = base_url or (pconfig.inference_base_url if pconfig else "")
260
+ elif provider == "anthropic":
261
+ api_mode = "anthropic_messages"
262
+ cfg_provider = str(model_cfg.get("provider") or "").strip().lower()
263
+ cfg_base_url = ""
264
+ if cfg_provider == "anthropic":
265
+ cfg_base_url = str(model_cfg.get("base_url") or "").strip().rstrip("/")
266
+ base_url = cfg_base_url or base_url or "https://api.anthropic.com"
267
+ elif provider == "openrouter":
268
+ base_url = base_url or OPENROUTER_BASE_URL
269
+ elif provider == "xai":
270
+ api_mode = "codex_responses"
271
+ elif provider == "nous":
272
+ api_mode = "chat_completions"
273
+ elif provider == "copilot":
274
+ api_mode = _copilot_runtime_api_mode(model_cfg, getattr(entry, "runtime_api_key", ""))
275
+ base_url = base_url or PROVIDER_REGISTRY["copilot"].inference_base_url
276
+ elif provider == "azure-foundry":
277
+ # Azure Foundry: read api_mode and base_url from config
278
+ cfg_provider = str(model_cfg.get("provider") or "").strip().lower()
279
+ if cfg_provider == "azure-foundry":
280
+ cfg_base_url = str(model_cfg.get("base_url") or "").strip().rstrip("/")
281
+ if cfg_base_url:
282
+ base_url = cfg_base_url
283
+ configured_mode = _parse_api_mode(model_cfg.get("api_mode"))
284
+ if configured_mode:
285
+ api_mode = configured_mode
286
+ # Model-family inference for GPT-5.x / codex / o1-o4: Azure rejects
287
+ # /chat/completions on these with 400 "operation unsupported" — see
288
+ # azure_foundry_model_api_mode() for rationale. Skip when the user
289
+ # explicitly picked anthropic_messages (Anthropic-style endpoint).
290
+ if effective_model and api_mode != "anthropic_messages":
291
+ try:
292
+ from hermes_cli.models import azure_foundry_model_api_mode
293
+
294
+ inferred = azure_foundry_model_api_mode(effective_model)
295
+ except Exception:
296
+ inferred = None
297
+ if inferred:
298
+ api_mode = inferred
299
+ # For Anthropic-style endpoints, strip /v1 suffix
300
+ if api_mode == "anthropic_messages":
301
+ base_url = re.sub(r"/v1/?$", "", base_url)
302
+ else:
303
+ configured_provider = str(model_cfg.get("provider") or "").strip().lower()
304
+ # Honour model.base_url from config.yaml when the configured provider
305
+ # matches this provider — same pattern as the Anthropic branch above.
306
+ # Only override when the pool entry has no explicit base_url (i.e. it
307
+ # fell back to the hardcoded default). Env var overrides win (#6039).
308
+ pconfig = PROVIDER_REGISTRY.get(provider)
309
+ pool_url_is_default = pconfig and base_url.rstrip("/") == pconfig.inference_base_url.rstrip("/")
310
+ if configured_provider == provider and pool_url_is_default:
311
+ cfg_base_url = str(model_cfg.get("base_url") or "").strip().rstrip("/")
312
+ if cfg_base_url:
313
+ base_url = cfg_base_url
314
+ configured_mode = _parse_api_mode(model_cfg.get("api_mode"))
315
+ if provider in {"opencode-zen", "opencode-go"}:
316
+ # Re-derive api_mode from the effective model rather than the
317
+ # persisted api_mode: the opencode providers serve both
318
+ # anthropic_messages and chat_completions models, so the previous
319
+ # session's mode must not leak across /model switches.
320
+ # Refs #16878.
321
+ from hermes_cli.models import opencode_model_api_mode
322
+ api_mode = opencode_model_api_mode(provider, effective_model)
323
+ elif configured_mode and _provider_supports_explicit_api_mode(provider, configured_provider):
324
+ api_mode = configured_mode
325
+ else:
326
+ # Auto-detect Anthropic-compatible endpoints (/anthropic suffix,
327
+ # Kimi /coding, api.openai.com → codex_responses, api.x.ai →
328
+ # codex_responses).
329
+ detected = _detect_api_mode_for_url(base_url)
330
+ if detected:
331
+ api_mode = detected
332
+
333
+ # OpenCode base URLs end with /v1 for OpenAI-compatible models, but the
334
+ # Anthropic SDK prepends its own /v1/messages to the base_url. Strip the
335
+ # trailing /v1 so the SDK constructs the correct path (e.g.
336
+ # https://opencode.ai/zen/go/v1/messages instead of .../v1/v1/messages).
337
+ if api_mode == "anthropic_messages" and provider in {"opencode-zen", "opencode-go"}:
338
+ base_url = re.sub(r"/v1/?$", "", base_url)
339
+
340
+ # Optional opt-in: route OpenAI/Codex turns through `codex app-server`.
341
+ # Inert when `model.openai_runtime` is unset or "auto".
342
+ api_mode = _maybe_apply_codex_app_server_runtime(
343
+ provider=provider, api_mode=api_mode, model_cfg=model_cfg
344
+ )
345
+
346
+ return {
347
+ "provider": provider,
348
+ "api_mode": api_mode,
349
+ "base_url": base_url,
350
+ "api_key": api_key,
351
+ "source": getattr(entry, "source", "pool"),
352
+ "credential_pool": pool,
353
+ "requested_provider": requested_provider,
354
+ }
355
+
356
+
357
+ def resolve_requested_provider(requested: Optional[str] = None) -> str:
358
+ """Resolve provider request from explicit arg, config, then env."""
359
+ if requested and requested.strip():
360
+ return requested.strip().lower()
361
+
362
+ model_cfg = _get_model_config()
363
+ cfg_provider = model_cfg.get("provider")
364
+ if isinstance(cfg_provider, str) and cfg_provider.strip():
365
+ return cfg_provider.strip().lower()
366
+
367
+ # Prefer the persisted config selection over any stale shell/.env
368
+ # provider override so chat uses the endpoint the user last saved.
369
+ env_provider = os.getenv("HERMES_INFERENCE_PROVIDER", "").strip().lower()
370
+ if env_provider:
371
+ return env_provider
372
+
373
+ return "auto"
374
+
375
+
376
+ def _try_resolve_from_custom_pool(
377
+ base_url: str,
378
+ provider_label: str,
379
+ api_mode_override: Optional[str] = None,
380
+ provider_name: Optional[str] = None,
381
+ ) -> Optional[Dict[str, Any]]:
382
+ """Check if a credential pool exists for a custom endpoint and return a runtime dict if so."""
383
+ pool_key = get_custom_provider_pool_key(base_url, provider_name=provider_name)
384
+ if not pool_key:
385
+ return None
386
+ try:
387
+ pool = load_pool(pool_key)
388
+ if not pool.has_credentials():
389
+ return None
390
+ entry = pool.select()
391
+ if entry is None:
392
+ return None
393
+ pool_api_key = getattr(entry, "runtime_api_key", None) or getattr(entry, "access_token", "")
394
+ if not pool_api_key:
395
+ return None
396
+ return {
397
+ "provider": provider_label,
398
+ "api_mode": api_mode_override or _detect_api_mode_for_url(base_url) or "chat_completions",
399
+ "base_url": base_url,
400
+ "api_key": pool_api_key,
401
+ "source": f"pool:{pool_key}",
402
+ "credential_pool": pool,
403
+ }
404
+ except Exception:
405
+ return None
406
+
407
+
408
+ def _get_named_custom_provider(requested_provider: str) -> Optional[Dict[str, Any]]:
409
+ requested_norm = _normalize_custom_provider_name(requested_provider or "")
410
+ if not requested_norm or requested_norm == "custom":
411
+ return None
412
+
413
+ # Raw names should only map to custom providers when they are not already
414
+ # valid built-in providers or aliases. Explicit menu keys like
415
+ # ``custom:local`` always target the saved custom provider.
416
+ if requested_norm == "auto":
417
+ return None
418
+ if not requested_norm.startswith("custom:"):
419
+ try:
420
+ canonical = auth_mod.resolve_provider(requested_norm)
421
+ except AuthError:
422
+ pass
423
+ else:
424
+ # A user-declared ``custom_providers`` entry whose name matches
425
+ # only an *alias* (``kimi`` → built-in ``kimi-coding``) is the
426
+ # user's intended target — alias rewriting would otherwise hijack
427
+ # the request. We only defer to the built-in when the raw name is
428
+ # the canonical provider itself (``nous``, ``openrouter``, …) so
429
+ # accidentally shadowing a canonical provider still resolves to
430
+ # the built-in. See tests/hermes_cli/test_runtime_provider_resolution.py
431
+ # ``test_named_custom_provider_does_not_shadow_builtin_provider``.
432
+ if (canonical or "").strip().lower() == requested_norm:
433
+ return None
434
+
435
+ config = load_config()
436
+
437
+ # First check providers: dict (new-style user-defined providers)
438
+ providers = config.get("providers")
439
+ if isinstance(providers, dict):
440
+ for ep_name, entry in providers.items():
441
+ if not isinstance(entry, dict):
442
+ continue
443
+ # Match exact name or normalized name
444
+ name_norm = _normalize_custom_provider_name(ep_name)
445
+ # Resolve the API key from the env var name stored in key_env
446
+ key_env = str(entry.get("key_env", "") or "").strip()
447
+ resolved_api_key = os.getenv(key_env, "").strip() if key_env else ""
448
+ # Fall back to inline api_key when key_env is absent or unresolvable
449
+ if not resolved_api_key:
450
+ resolved_api_key = str(entry.get("api_key", "") or "").strip()
451
+
452
+ if requested_norm in {ep_name, name_norm, f"custom:{name_norm}"}:
453
+ # Found match by provider key
454
+ base_url = entry.get("api") or entry.get("url") or entry.get("base_url") or ""
455
+ if base_url:
456
+ result = {
457
+ "name": entry.get("name", ep_name),
458
+ "base_url": base_url.strip(),
459
+ "api_key": resolved_api_key,
460
+ "model": entry.get("default_model", ""),
461
+ }
462
+ # The v11→v12 migration writes the API mode under the new
463
+ # ``transport`` field, but hand-edited configs may still
464
+ # use the legacy ``api_mode`` spelling. Accept both —
465
+ # the runtime normaliser ``_normalize_custom_provider_entry``
466
+ # already does, so without this lift every migrated config
467
+ # silently downgrades codex_responses / anthropic_messages
468
+ # providers to chat_completions in the resolved runtime.
469
+ api_mode = _parse_api_mode(entry.get("api_mode") or entry.get("transport"))
470
+ if api_mode:
471
+ result["api_mode"] = api_mode
472
+ return result
473
+ # Also check the 'name' field if present
474
+ display_name = entry.get("name", "")
475
+ if display_name:
476
+ display_norm = _normalize_custom_provider_name(display_name)
477
+ if requested_norm in {display_name, display_norm, f"custom:{display_norm}"}:
478
+ # Found match by display name
479
+ base_url = entry.get("api") or entry.get("url") or entry.get("base_url") or ""
480
+ if base_url:
481
+ result = {
482
+ "name": display_name,
483
+ "base_url": base_url.strip(),
484
+ "api_key": resolved_api_key,
485
+ "model": entry.get("default_model", ""),
486
+ }
487
+ api_mode = _parse_api_mode(entry.get("api_mode") or entry.get("transport"))
488
+ if api_mode:
489
+ result["api_mode"] = api_mode
490
+ return result
491
+
492
+ # Fall back to custom_providers: list (legacy format)
493
+ custom_providers = config.get("custom_providers")
494
+ if isinstance(custom_providers, dict):
495
+ logger.warning(
496
+ "custom_providers in config.yaml is a dict, not a list. "
497
+ "Each entry must be prefixed with '-' in YAML. "
498
+ "Run 'hermes doctor' for details."
499
+ )
500
+ return None
501
+
502
+ custom_providers = get_compatible_custom_providers(config)
503
+ if not custom_providers:
504
+ return None
505
+
506
+ for entry in custom_providers:
507
+ if not isinstance(entry, dict):
508
+ continue
509
+ name = entry.get("name")
510
+ base_url = entry.get("base_url")
511
+ if not isinstance(name, str) or not isinstance(base_url, str):
512
+ continue
513
+ name_norm = _normalize_custom_provider_name(name)
514
+ menu_key = f"custom:{name_norm}"
515
+ provider_key = str(entry.get("provider_key", "") or "").strip()
516
+ provider_key_norm = _normalize_custom_provider_name(provider_key) if provider_key else ""
517
+ provider_menu_key = f"custom:{provider_key_norm}" if provider_key_norm else ""
518
+ if requested_norm not in {name_norm, menu_key, provider_key_norm, provider_menu_key}:
519
+ continue
520
+ result = {
521
+ "name": name.strip(),
522
+ "base_url": base_url.strip(),
523
+ "api_key": str(entry.get("api_key", "") or "").strip(),
524
+ }
525
+ key_env = str(entry.get("key_env", "") or "").strip()
526
+ if key_env:
527
+ result["key_env"] = key_env
528
+ if provider_key:
529
+ result["provider_key"] = provider_key
530
+ api_mode = _parse_api_mode(entry.get("api_mode"))
531
+ if api_mode:
532
+ result["api_mode"] = api_mode
533
+ model_name = str(entry.get("model", "") or "").strip()
534
+ if model_name:
535
+ result["model"] = model_name
536
+ return result
537
+
538
+ return None
539
+
540
+
541
+ def _resolve_named_custom_runtime(
542
+ *,
543
+ requested_provider: str,
544
+ explicit_api_key: Optional[str] = None,
545
+ explicit_base_url: Optional[str] = None,
546
+ ) -> Optional[Dict[str, Any]]:
547
+ # Bare `provider="custom"` with an explicit base_url (e.g. propagated
548
+ # from a `model_aliases:` direct-alias resolution) — build a runtime
549
+ # directly so the alias's base_url actually takes effect.
550
+ requested_norm = (requested_provider or "").strip().lower()
551
+ if requested_norm == "custom" and explicit_base_url:
552
+ base_url = explicit_base_url.strip().rstrip("/")
553
+ # Check credential pool first — mirrors the named-custom-provider path
554
+ # so bare `provider: custom` with a configured custom_providers entry
555
+ # also gets its api_key from the pool instead of env var fallbacks.
556
+ pool_result = _try_resolve_from_custom_pool(base_url, "custom", None)
557
+ if pool_result:
558
+ pool_result["source"] = "direct-alias"
559
+ return pool_result
560
+ api_key_candidates = [
561
+ (explicit_api_key or "").strip(),
562
+ os.getenv("OPENAI_API_KEY", "").strip(),
563
+ os.getenv("OPENROUTER_API_KEY", "").strip(),
564
+ ]
565
+ api_key = next(
566
+ (c for c in api_key_candidates if has_usable_secret(c)),
567
+ "",
568
+ ) or "no-key-required"
569
+ return {
570
+ "provider": "custom",
571
+ "api_mode": _detect_api_mode_for_url(base_url) or "chat_completions",
572
+ "base_url": base_url,
573
+ "api_key": api_key,
574
+ "source": "direct-alias",
575
+ "requested_provider": requested_provider,
576
+ }
577
+
578
+ custom_provider = _get_named_custom_provider(requested_provider)
579
+ if not custom_provider:
580
+ return None
581
+
582
+ base_url = (
583
+ (explicit_base_url or "").strip()
584
+ or custom_provider.get("base_url", "")
585
+ ).rstrip("/")
586
+ if not base_url:
587
+ return None
588
+
589
+ # Check if a credential pool exists for this custom endpoint
590
+ pool_result = _try_resolve_from_custom_pool(base_url, "custom", custom_provider.get("api_mode"), provider_name=custom_provider.get("name"))
591
+ if pool_result:
592
+ # Propagate the model name even when using pooled credentials —
593
+ # the pool doesn't know about the custom_providers model field.
594
+ model_name = custom_provider.get("model")
595
+ if model_name:
596
+ pool_result["model"] = model_name
597
+ return pool_result
598
+
599
+ api_key_candidates = [
600
+ (explicit_api_key or "").strip(),
601
+ str(custom_provider.get("api_key", "") or "").strip(),
602
+ os.getenv(str(custom_provider.get("key_env", "") or "").strip(), "").strip(),
603
+ os.getenv("OPENAI_API_KEY", "").strip(),
604
+ os.getenv("OPENROUTER_API_KEY", "").strip(),
605
+ ]
606
+ api_key = next((candidate for candidate in api_key_candidates if has_usable_secret(candidate)), "")
607
+
608
+ result = {
609
+ "provider": "custom",
610
+ "api_mode": custom_provider.get("api_mode")
611
+ or _detect_api_mode_for_url(base_url)
612
+ or "chat_completions",
613
+ "base_url": base_url,
614
+ "api_key": api_key or "no-key-required",
615
+ "source": f"custom_provider:{custom_provider.get('name', requested_provider)}",
616
+ }
617
+ # Propagate the model name so callers can override self.model when the
618
+ # provider name differs from the actual model string the API expects.
619
+ if custom_provider.get("model"):
620
+ result["model"] = custom_provider["model"]
621
+ return result
622
+
623
+
624
+ def _resolve_openrouter_runtime(
625
+ *,
626
+ requested_provider: str,
627
+ explicit_api_key: Optional[str] = None,
628
+ explicit_base_url: Optional[str] = None,
629
+ ) -> Dict[str, Any]:
630
+ model_cfg = _get_model_config()
631
+ cfg_base_url = model_cfg.get("base_url") if isinstance(model_cfg.get("base_url"), str) else ""
632
+ cfg_provider = model_cfg.get("provider") if isinstance(model_cfg.get("provider"), str) else ""
633
+ cfg_api_key = ""
634
+ for k in ("api_key", "api"):
635
+ v = model_cfg.get(k)
636
+ if isinstance(v, str) and v.strip():
637
+ cfg_api_key = v.strip()
638
+ break
639
+ requested_norm = (requested_provider or "").strip().lower()
640
+ cfg_provider = cfg_provider.strip().lower()
641
+
642
+ env_openrouter_base_url = os.getenv("OPENROUTER_BASE_URL", "").strip()
643
+ env_custom_base_url = os.getenv("CUSTOM_BASE_URL", "").strip()
644
+
645
+ # Use config base_url when available and the provider context matches.
646
+ # OPENAI_BASE_URL env var is no longer consulted — config.yaml is
647
+ # the single source of truth for endpoint URLs.
648
+ use_config_base_url = False
649
+ if cfg_base_url.strip() and not explicit_base_url:
650
+ if requested_norm == "auto":
651
+ if not cfg_provider or cfg_provider == "auto":
652
+ use_config_base_url = True
653
+ elif requested_norm == "custom" and _config_base_url_trustworthy_for_bare_custom(
654
+ cfg_base_url, cfg_provider
655
+ ):
656
+ use_config_base_url = True
657
+
658
+ base_url = (
659
+ (explicit_base_url or "").strip()
660
+ or env_custom_base_url
661
+ or (cfg_base_url.strip() if use_config_base_url else "")
662
+ or env_openrouter_base_url
663
+ or OPENROUTER_BASE_URL
664
+ ).rstrip("/")
665
+
666
+ # Choose API key based on whether the resolved base_url targets OpenRouter.
667
+ # When hitting OpenRouter, prefer OPENROUTER_API_KEY (issue #289).
668
+ # When hitting a custom endpoint (e.g. Z.ai, local LLM), prefer
669
+ # OPENAI_API_KEY so the OpenRouter key doesn't leak to an unrelated
670
+ # provider (issues #420, #560).
671
+ _is_openrouter_url = base_url_host_matches(base_url, "openrouter.ai")
672
+ if _is_openrouter_url:
673
+ api_key_candidates = [
674
+ explicit_api_key,
675
+ os.getenv("OPENROUTER_API_KEY"),
676
+ os.getenv("OPENAI_API_KEY"),
677
+ ]
678
+ else:
679
+ # Custom endpoint: use api_key from config when using config base_url (#1760).
680
+ # When the endpoint is Ollama Cloud, check OLLAMA_API_KEY — it's
681
+ # the canonical env var for ollama.com authentication. Match on
682
+ # HOST, not substring — a custom base_url whose path contains
683
+ # "ollama.com" (e.g. http://127.0.0.1/ollama.com/v1) or whose
684
+ # hostname is a look-alike (ollama.com.attacker.test) must not
685
+ # receive the Ollama credential. See GHSA-76xc-57q6-vm5m.
686
+ _is_ollama_url = base_url_host_matches(base_url, "ollama.com")
687
+ api_key_candidates = [
688
+ explicit_api_key,
689
+ (cfg_api_key if use_config_base_url else ""),
690
+ (os.getenv("OLLAMA_API_KEY") if _is_ollama_url else ""),
691
+ os.getenv("OPENAI_API_KEY"),
692
+ os.getenv("OPENROUTER_API_KEY"),
693
+ ]
694
+ api_key = next(
695
+ (str(candidate or "").strip() for candidate in api_key_candidates if has_usable_secret(candidate)),
696
+ "",
697
+ )
698
+
699
+ source = "explicit" if (explicit_api_key or explicit_base_url) else "env/config"
700
+
701
+ # When "custom" was explicitly requested, preserve that as the provider
702
+ # name instead of silently relabeling to "openrouter" (#2562).
703
+ # Also provide a placeholder API key for local servers that don't require
704
+ # authentication — the OpenAI SDK requires a non-empty api_key string.
705
+ effective_provider = "custom" if requested_norm == "custom" else "openrouter"
706
+
707
+ # For custom endpoints, check if a credential pool exists
708
+ if effective_provider == "custom" and base_url:
709
+ # Pass requested_provider so pool lookup prefers name match over base_url,
710
+ # fixing credential mix-ups when multiple custom providers share a base_url.
711
+ pool_result = _try_resolve_from_custom_pool(
712
+ base_url, effective_provider, _parse_api_mode(model_cfg.get("api_mode")),
713
+ provider_name=requested_provider if requested_norm != "custom" else None,
714
+ )
715
+ if pool_result:
716
+ return pool_result
717
+
718
+ if effective_provider == "custom" and not api_key and not _is_openrouter_url:
719
+ api_key = "no-key-required"
720
+
721
+ return {
722
+ "provider": effective_provider,
723
+ "api_mode": _parse_api_mode(model_cfg.get("api_mode"))
724
+ or _detect_api_mode_for_url(base_url)
725
+ or "chat_completions",
726
+ "base_url": base_url,
727
+ "api_key": api_key,
728
+ "source": source,
729
+ }
730
+
731
+
732
+ def _resolve_azure_foundry_runtime(
733
+ *,
734
+ requested_provider: str,
735
+ model_cfg: Dict[str, Any],
736
+ explicit_api_key: Optional[str] = None,
737
+ explicit_base_url: Optional[str] = None,
738
+ target_model: Optional[str] = None,
739
+ ) -> Dict[str, Any]:
740
+ """Resolve an Azure Foundry runtime entry.
741
+
742
+ Reads ``model.base_url`` + ``model.api_mode`` from config.yaml (or
743
+ explicit overrides), pulls the API key from ``.env`` / env var, and
744
+ strips a trailing ``/v1`` for Anthropic-style endpoints because the
745
+ Anthropic SDK appends ``/v1/messages`` internally.
746
+
747
+ Raises :class:`AuthError` when required values are missing.
748
+ """
749
+ explicit_api_key = str(explicit_api_key or "").strip()
750
+ explicit_base_url_clean = str(explicit_base_url or "").strip().rstrip("/")
751
+
752
+ cfg_provider = str(model_cfg.get("provider") or "").strip().lower()
753
+ cfg_base_url = ""
754
+ cfg_api_mode = "chat_completions"
755
+ if cfg_provider == "azure-foundry":
756
+ cfg_base_url = str(model_cfg.get("base_url") or "").strip().rstrip("/")
757
+ cfg_api_mode = _parse_api_mode(model_cfg.get("api_mode")) or "chat_completions"
758
+
759
+ # Model-family inference: Azure Foundry deploys GPT-5.x / codex / o1-o4
760
+ # reasoning models as Responses-API-only. Calling /chat/completions
761
+ # against them returns 400 "The requested operation is unsupported."
762
+ # Upgrade api_mode when the model name matches, unless the user has
763
+ # explicitly chosen anthropic_messages (Anthropic-style endpoint).
764
+ effective_model = str(target_model or model_cfg.get("default") or "").strip()
765
+ if effective_model and cfg_api_mode != "anthropic_messages":
766
+ try:
767
+ from hermes_cli.models import azure_foundry_model_api_mode
768
+
769
+ inferred = azure_foundry_model_api_mode(effective_model)
770
+ except Exception:
771
+ inferred = None
772
+ if inferred:
773
+ cfg_api_mode = inferred
774
+
775
+ env_base_url = os.getenv("AZURE_FOUNDRY_BASE_URL", "").strip().rstrip("/")
776
+ base_url = explicit_base_url_clean or cfg_base_url or env_base_url
777
+ if not base_url:
778
+ raise AuthError(
779
+ "Azure Foundry requires a base URL. Set it via 'hermes model' or "
780
+ "the AZURE_FOUNDRY_BASE_URL environment variable."
781
+ )
782
+
783
+ api_key = explicit_api_key
784
+ if not api_key:
785
+ try:
786
+ from hermes_cli.config import get_env_value
787
+ api_key = get_env_value("AZURE_FOUNDRY_API_KEY") or ""
788
+ except Exception:
789
+ api_key = ""
790
+ if not api_key:
791
+ api_key = os.getenv("AZURE_FOUNDRY_API_KEY", "").strip()
792
+ if not api_key:
793
+ raise AuthError(
794
+ "Azure Foundry requires an API key. Set AZURE_FOUNDRY_API_KEY in "
795
+ "~/.hermes/.env or run 'hermes model' to configure."
796
+ )
797
+
798
+ # Anthropic SDK appends /v1/messages itself, so strip any trailing /v1
799
+ # we inherited from the configured base_url to avoid double-/v1 paths.
800
+ if cfg_api_mode == "anthropic_messages":
801
+ base_url = re.sub(r"/v1/?$", "", base_url)
802
+
803
+ source = "explicit" if (explicit_api_key or explicit_base_url) else "config"
804
+ return {
805
+ "provider": "azure-foundry",
806
+ "api_mode": cfg_api_mode,
807
+ "base_url": base_url,
808
+ "api_key": api_key,
809
+ "source": source,
810
+ "requested_provider": requested_provider,
811
+ }
812
+
813
+
814
+ def _resolve_explicit_runtime(
815
+ *,
816
+ provider: str,
817
+ requested_provider: str,
818
+ model_cfg: Dict[str, Any],
819
+ explicit_api_key: Optional[str] = None,
820
+ explicit_base_url: Optional[str] = None,
821
+ ) -> Optional[Dict[str, Any]]:
822
+ explicit_api_key = str(explicit_api_key or "").strip()
823
+ explicit_base_url = str(explicit_base_url or "").strip().rstrip("/")
824
+ if not explicit_api_key and not explicit_base_url:
825
+ return None
826
+
827
+ if provider == "anthropic":
828
+ cfg_provider = str(model_cfg.get("provider") or "").strip().lower()
829
+ cfg_base_url = ""
830
+ if cfg_provider == "anthropic":
831
+ cfg_base_url = str(model_cfg.get("base_url") or "").strip().rstrip("/")
832
+ base_url = explicit_base_url or cfg_base_url or "https://api.anthropic.com"
833
+ api_key = explicit_api_key
834
+ if not api_key:
835
+ from agent.anthropic_adapter import resolve_anthropic_token
836
+
837
+ api_key = resolve_anthropic_token()
838
+ if not api_key:
839
+ raise AuthError(
840
+ "No Anthropic credentials found. Set ANTHROPIC_TOKEN or ANTHROPIC_API_KEY, "
841
+ "run 'claude setup-token', or authenticate with 'claude /login'."
842
+ )
843
+ return {
844
+ "provider": "anthropic",
845
+ "api_mode": "anthropic_messages",
846
+ "base_url": base_url,
847
+ "api_key": api_key,
848
+ "source": "explicit",
849
+ "requested_provider": requested_provider,
850
+ }
851
+
852
+ if provider == "openai-codex":
853
+ base_url = explicit_base_url or DEFAULT_CODEX_BASE_URL
854
+ api_key = explicit_api_key
855
+ last_refresh = None
856
+ if not api_key:
857
+ creds = resolve_codex_runtime_credentials()
858
+ api_key = creds.get("api_key", "")
859
+ last_refresh = creds.get("last_refresh")
860
+ if not explicit_base_url:
861
+ base_url = creds.get("base_url", "").rstrip("/") or base_url
862
+ return {
863
+ "provider": "openai-codex",
864
+ "api_mode": "codex_responses",
865
+ "base_url": base_url,
866
+ "api_key": api_key,
867
+ "source": "explicit",
868
+ "last_refresh": last_refresh,
869
+ "requested_provider": requested_provider,
870
+ }
871
+
872
+ if provider == "nous":
873
+ state = auth_mod.get_provider_auth_state("nous") or {}
874
+ base_url = (
875
+ explicit_base_url
876
+ or str(state.get("inference_base_url") or auth_mod.DEFAULT_NOUS_INFERENCE_URL).strip().rstrip("/")
877
+ )
878
+ # Only use agent_key for inference — access_token is an OAuth token for the
879
+ # portal API (minting keys, refreshing tokens), not for the inference API.
880
+ # Falling back to access_token sends an OAuth bearer token to the inference
881
+ # endpoint, which returns 404 because it is not a valid inference credential.
882
+ api_key = explicit_api_key or str(state.get("agent_key") or "").strip()
883
+ expires_at = state.get("agent_key_expires_at") or state.get("expires_at")
884
+ if not api_key:
885
+ creds = resolve_nous_runtime_credentials(
886
+ min_key_ttl_seconds=max(60, int(os.getenv("HERMES_NOUS_MIN_KEY_TTL_SECONDS", "1800"))),
887
+ timeout_seconds=float(os.getenv("HERMES_NOUS_TIMEOUT_SECONDS", "15")),
888
+ )
889
+ api_key = creds.get("api_key", "")
890
+ expires_at = creds.get("expires_at")
891
+ if not explicit_base_url:
892
+ base_url = creds.get("base_url", "").rstrip("/") or base_url
893
+ return {
894
+ "provider": "nous",
895
+ "api_mode": "chat_completions",
896
+ "base_url": base_url,
897
+ "api_key": api_key,
898
+ "source": "explicit",
899
+ "expires_at": expires_at,
900
+ "requested_provider": requested_provider,
901
+ }
902
+
903
+ # Azure Foundry: user-configured endpoint with selectable API mode
904
+ if provider == "azure-foundry":
905
+ return _resolve_azure_foundry_runtime(
906
+ requested_provider=requested_provider,
907
+ model_cfg=model_cfg,
908
+ explicit_api_key=explicit_api_key,
909
+ explicit_base_url=explicit_base_url,
910
+ )
911
+
912
+ pconfig = PROVIDER_REGISTRY.get(provider)
913
+ if pconfig and pconfig.auth_type == "api_key":
914
+ env_url = ""
915
+ if pconfig.base_url_env_var:
916
+ env_url = os.getenv(pconfig.base_url_env_var, "").strip().rstrip("/")
917
+
918
+ base_url = explicit_base_url
919
+ if not base_url:
920
+ if provider in {"kimi-coding", "kimi-coding-cn"}:
921
+ creds = resolve_api_key_provider_credentials(provider)
922
+ base_url = creds.get("base_url", "").rstrip("/")
923
+ else:
924
+ base_url = env_url or pconfig.inference_base_url
925
+
926
+ api_key = explicit_api_key
927
+ if not api_key:
928
+ creds = resolve_api_key_provider_credentials(provider)
929
+ api_key = creds.get("api_key", "")
930
+ if not base_url:
931
+ base_url = creds.get("base_url", "").rstrip("/")
932
+
933
+ api_mode = "chat_completions"
934
+ if provider == "copilot":
935
+ api_mode = _copilot_runtime_api_mode(model_cfg, api_key)
936
+ elif provider == "xai":
937
+ api_mode = "codex_responses"
938
+ else:
939
+ configured_mode = _parse_api_mode(model_cfg.get("api_mode"))
940
+ if configured_mode:
941
+ api_mode = configured_mode
942
+ else:
943
+ # Auto-detect from URL (Anthropic /anthropic suffix,
944
+ # api.openai.com → Responses, Kimi /coding, etc.).
945
+ detected = _detect_api_mode_for_url(base_url)
946
+ if detected:
947
+ api_mode = detected
948
+
949
+ return {
950
+ "provider": provider,
951
+ "api_mode": api_mode,
952
+ "base_url": base_url.rstrip("/"),
953
+ "api_key": api_key,
954
+ "source": "explicit",
955
+ "requested_provider": requested_provider,
956
+ }
957
+
958
+ return None
959
+
960
+
961
+ def resolve_runtime_provider(
962
+ *,
963
+ requested: Optional[str] = None,
964
+ explicit_api_key: Optional[str] = None,
965
+ explicit_base_url: Optional[str] = None,
966
+ target_model: Optional[str] = None,
967
+ ) -> Dict[str, Any]:
968
+ """Resolve runtime provider credentials for agent execution.
969
+
970
+ target_model: Optional override for model_cfg.get("default") when
971
+ computing provider-specific api_mode (e.g. OpenCode Zen/Go where different
972
+ models route through different API surfaces). Callers performing an
973
+ explicit mid-session model switch should pass the new model here so
974
+ api_mode is derived from the model they are switching TO, not the stale
975
+ persisted default. Other callers can leave it None to preserve existing
976
+ behavior (api_mode derived from config).
977
+ """
978
+ requested_provider = resolve_requested_provider(requested)
979
+
980
+ # Azure Anthropic short-circuit: when explicitly targeting an Azure endpoint
981
+ # with provider="anthropic", bypass _resolve_named_custom_runtime (which would
982
+ # return provider="custom" with chat_completions api_mode and no valid key).
983
+ # Instead, use the Azure key directly with anthropic_messages api_mode.
984
+ _eff_base = (explicit_base_url or "").strip()
985
+ if requested_provider == "anthropic" and "azure.com" in _eff_base:
986
+ _azure_key = (
987
+ (explicit_api_key or "").strip()
988
+ or os.getenv("AZURE_ANTHROPIC_KEY", "").strip()
989
+ or os.getenv("ANTHROPIC_API_KEY", "").strip()
990
+ )
991
+ return {
992
+ "provider": "anthropic",
993
+ "api_mode": "anthropic_messages",
994
+ "base_url": _eff_base.rstrip("/"),
995
+ "api_key": _azure_key,
996
+ "source": "azure-explicit",
997
+ "requested_provider": requested_provider,
998
+ }
999
+
1000
+ # Azure Foundry: user-configured endpoint with selectable API mode
1001
+ # (OpenAI-style chat_completions or Anthropic-style anthropic_messages).
1002
+ # Resolve before the custom-runtime / pool / generic paths so Azure
1003
+ # config is always picked up from model.base_url + model.api_mode,
1004
+ # regardless of whether the caller passed explicit_* args.
1005
+ if requested_provider == "azure-foundry":
1006
+ azure_runtime = _resolve_azure_foundry_runtime(
1007
+ requested_provider=requested_provider,
1008
+ model_cfg=_get_model_config(),
1009
+ explicit_api_key=explicit_api_key,
1010
+ explicit_base_url=explicit_base_url,
1011
+ target_model=target_model,
1012
+ )
1013
+ return azure_runtime
1014
+
1015
+ custom_runtime = _resolve_named_custom_runtime(
1016
+ requested_provider=requested_provider,
1017
+ explicit_api_key=explicit_api_key,
1018
+ explicit_base_url=explicit_base_url,
1019
+ )
1020
+ if custom_runtime:
1021
+ custom_runtime["requested_provider"] = requested_provider
1022
+ return custom_runtime
1023
+
1024
+ provider = resolve_provider(
1025
+ requested_provider,
1026
+ explicit_api_key=explicit_api_key,
1027
+ explicit_base_url=explicit_base_url,
1028
+ )
1029
+ model_cfg = _get_model_config()
1030
+ explicit_runtime = _resolve_explicit_runtime(
1031
+ provider=provider,
1032
+ requested_provider=requested_provider,
1033
+ model_cfg=model_cfg,
1034
+ explicit_api_key=explicit_api_key,
1035
+ explicit_base_url=explicit_base_url,
1036
+ )
1037
+ if explicit_runtime:
1038
+ return explicit_runtime
1039
+
1040
+ should_use_pool = provider != "openrouter"
1041
+ if provider == "openrouter":
1042
+ cfg_provider = str(model_cfg.get("provider") or "").strip().lower()
1043
+ cfg_base_url = str(model_cfg.get("base_url") or "").strip()
1044
+ env_openai_base_url = os.getenv("OPENAI_BASE_URL", "").strip()
1045
+ env_openrouter_base_url = os.getenv("OPENROUTER_BASE_URL", "").strip()
1046
+ has_custom_endpoint = bool(
1047
+ explicit_base_url
1048
+ or env_openai_base_url
1049
+ or env_openrouter_base_url
1050
+ )
1051
+ if cfg_base_url and cfg_provider in {"auto", "custom"}:
1052
+ has_custom_endpoint = True
1053
+ has_runtime_override = bool(explicit_api_key or explicit_base_url)
1054
+ should_use_pool = (
1055
+ requested_provider in {"openrouter", "auto"}
1056
+ and not has_custom_endpoint
1057
+ and not has_runtime_override
1058
+ )
1059
+
1060
+ try:
1061
+ pool = load_pool(provider) if should_use_pool else None
1062
+ except Exception:
1063
+ pool = None
1064
+ if pool and pool.has_credentials():
1065
+ entry = pool.select()
1066
+ pool_api_key = ""
1067
+ if entry is not None:
1068
+ pool_api_key = (
1069
+ getattr(entry, "runtime_api_key", None)
1070
+ or getattr(entry, "access_token", "")
1071
+ )
1072
+ # For Nous, the pool entry's runtime_api_key is the agent_key — a
1073
+ # short-lived inference credential (~30 min TTL). The pool doesn't
1074
+ # refresh it during selection (that would trigger network calls in
1075
+ # non-runtime contexts like `hermes auth list`). If the key is
1076
+ # expired, clear pool_api_key so we fall through to
1077
+ # resolve_nous_runtime_credentials() which handles refresh + mint.
1078
+ if provider == "nous" and entry is not None and pool_api_key:
1079
+ min_ttl = max(60, int(os.getenv("HERMES_NOUS_MIN_KEY_TTL_SECONDS", "1800")))
1080
+ nous_state = {
1081
+ "agent_key": getattr(entry, "agent_key", None),
1082
+ "agent_key_expires_at": getattr(entry, "agent_key_expires_at", None),
1083
+ }
1084
+ if not _agent_key_is_usable(nous_state, min_ttl):
1085
+ logger.debug("Nous pool entry agent_key expired/missing, falling through to runtime resolution")
1086
+ pool_api_key = ""
1087
+ if entry is not None and pool_api_key:
1088
+ return _resolve_runtime_from_pool_entry(
1089
+ provider=provider,
1090
+ entry=entry,
1091
+ requested_provider=requested_provider,
1092
+ model_cfg=model_cfg,
1093
+ pool=pool,
1094
+ target_model=target_model,
1095
+ )
1096
+
1097
+ if provider == "nous":
1098
+ try:
1099
+ creds = resolve_nous_runtime_credentials(
1100
+ min_key_ttl_seconds=max(60, int(os.getenv("HERMES_NOUS_MIN_KEY_TTL_SECONDS", "1800"))),
1101
+ timeout_seconds=float(os.getenv("HERMES_NOUS_TIMEOUT_SECONDS", "15")),
1102
+ )
1103
+ return {
1104
+ "provider": "nous",
1105
+ "api_mode": "chat_completions",
1106
+ "base_url": creds.get("base_url", "").rstrip("/"),
1107
+ "api_key": creds.get("api_key", ""),
1108
+ "source": creds.get("source", "portal"),
1109
+ "expires_at": creds.get("expires_at"),
1110
+ "requested_provider": requested_provider,
1111
+ }
1112
+ except AuthError:
1113
+ if requested_provider != "auto":
1114
+ raise
1115
+ # Auto-detected Nous but credentials are stale/revoked —
1116
+ # fall through to env-var providers (e.g. OpenRouter).
1117
+ logger.info("Auto-detected Nous provider but credentials failed; "
1118
+ "falling through to next provider.")
1119
+
1120
+ if provider == "openai-codex":
1121
+ try:
1122
+ creds = resolve_codex_runtime_credentials()
1123
+ return {
1124
+ "provider": "openai-codex",
1125
+ "api_mode": "codex_responses",
1126
+ "base_url": creds.get("base_url", "").rstrip("/"),
1127
+ "api_key": creds.get("api_key", ""),
1128
+ "source": creds.get("source", "hermes-auth-store"),
1129
+ "last_refresh": creds.get("last_refresh"),
1130
+ "requested_provider": requested_provider,
1131
+ }
1132
+ except AuthError:
1133
+ if requested_provider != "auto":
1134
+ raise
1135
+ # Auto-detected Codex but credentials are stale/revoked —
1136
+ # fall through to env-var providers (e.g. OpenRouter).
1137
+ logger.info("Auto-detected Codex provider but credentials failed; "
1138
+ "falling through to next provider.")
1139
+
1140
+ if provider == "xai-oauth":
1141
+ try:
1142
+ creds = resolve_xai_oauth_runtime_credentials()
1143
+ return {
1144
+ "provider": "xai-oauth",
1145
+ "api_mode": "codex_responses",
1146
+ "base_url": (creds.get("base_url") or "").rstrip("/") or DEFAULT_XAI_OAUTH_BASE_URL,
1147
+ "api_key": creds.get("api_key", ""),
1148
+ "source": creds.get("source", "hermes-auth-store"),
1149
+ "last_refresh": creds.get("last_refresh"),
1150
+ "requested_provider": requested_provider,
1151
+ }
1152
+ except AuthError:
1153
+ if requested_provider != "auto":
1154
+ raise
1155
+ logger.info("Auto-detected xAI OAuth provider but credentials failed; "
1156
+ "falling through to next provider.")
1157
+
1158
+ if provider == "qwen-oauth":
1159
+ try:
1160
+ creds = resolve_qwen_runtime_credentials()
1161
+ return {
1162
+ "provider": "qwen-oauth",
1163
+ "api_mode": "chat_completions",
1164
+ "base_url": creds.get("base_url", "").rstrip("/"),
1165
+ "api_key": creds.get("api_key", ""),
1166
+ "source": creds.get("source", "qwen-cli"),
1167
+ "expires_at_ms": creds.get("expires_at_ms"),
1168
+ "requested_provider": requested_provider,
1169
+ }
1170
+ except AuthError:
1171
+ if requested_provider != "auto":
1172
+ raise
1173
+ logger.info("Qwen OAuth credentials failed; "
1174
+ "falling through to next provider.")
1175
+
1176
+ if provider == "minimax-oauth":
1177
+ pconfig = PROVIDER_REGISTRY.get(provider)
1178
+ if pconfig and pconfig.auth_type == "oauth_minimax":
1179
+ from hermes_cli.auth import resolve_minimax_oauth_runtime_credentials
1180
+ creds = resolve_minimax_oauth_runtime_credentials()
1181
+ return {
1182
+ "provider": provider,
1183
+ "api_mode": "anthropic_messages",
1184
+ "base_url": creds["base_url"],
1185
+ "api_key": creds["api_key"],
1186
+ "source": creds.get("source", "oauth"),
1187
+ "requested_provider": requested_provider,
1188
+ }
1189
+
1190
+ if provider == "google-gemini-cli":
1191
+ try:
1192
+ creds = resolve_gemini_oauth_runtime_credentials()
1193
+ return {
1194
+ "provider": "google-gemini-cli",
1195
+ "api_mode": "chat_completions",
1196
+ "base_url": creds.get("base_url", ""),
1197
+ "api_key": creds.get("api_key", ""),
1198
+ "source": creds.get("source", "google-oauth"),
1199
+ "expires_at_ms": creds.get("expires_at_ms"),
1200
+ "email": creds.get("email", ""),
1201
+ "project_id": creds.get("project_id", ""),
1202
+ "requested_provider": requested_provider,
1203
+ }
1204
+ except AuthError:
1205
+ if requested_provider != "auto":
1206
+ raise
1207
+ logger.info("Google Gemini OAuth credentials failed; "
1208
+ "falling through to next provider.")
1209
+
1210
+ if provider == "copilot-acp":
1211
+ creds = resolve_external_process_provider_credentials(provider)
1212
+ return {
1213
+ "provider": "copilot-acp",
1214
+ "api_mode": "chat_completions",
1215
+ "base_url": creds.get("base_url", "").rstrip("/"),
1216
+ "api_key": creds.get("api_key", ""),
1217
+ "command": creds.get("command", ""),
1218
+ "args": list(creds.get("args") or []),
1219
+ "source": creds.get("source", "process"),
1220
+ "requested_provider": requested_provider,
1221
+ }
1222
+
1223
+ # Anthropic (native Messages API)
1224
+ if provider == "anthropic":
1225
+ # Allow base URL override from config.yaml model.base_url, but only
1226
+ # when the configured provider is anthropic — otherwise a non-Anthropic
1227
+ # base_url (e.g. Codex endpoint) would leak into Anthropic requests.
1228
+ cfg_provider = str(model_cfg.get("provider") or "").strip().lower()
1229
+ cfg_base_url = ""
1230
+ if cfg_provider == "anthropic":
1231
+ cfg_base_url = (model_cfg.get("base_url") or "").strip().rstrip("/")
1232
+ base_url = cfg_base_url or "https://api.anthropic.com"
1233
+
1234
+ # For Azure AI Foundry endpoints, use ANTHROPIC_API_KEY directly —
1235
+ # Claude Code OAuth tokens (sk-ant-oat01) are not accepted by Azure.
1236
+ # Azure keys don't start with "sk-ant-" so resolve_anthropic_token()
1237
+ # would find the Claude Code OAuth token first (priority 3) and return
1238
+ # that instead, causing 401s. Detect Azure endpoints and use the env
1239
+ # key directly to bypass the OAuth priority chain.
1240
+ _is_azure_endpoint = "azure.com" in base_url.lower() or (
1241
+ cfg_base_url and "azure.com" in cfg_base_url.lower()
1242
+ )
1243
+ if _is_azure_endpoint:
1244
+ # Honor user-specified env var hints on the model config before
1245
+ # falling back to the built-in AZURE_ANTHROPIC_KEY / ANTHROPIC_API_KEY
1246
+ # chain. Accept both `key_env` (Hermes canonical — matches the
1247
+ # custom_providers field name) and `api_key_env` (documented in the
1248
+ # Azure Foundry guide and read by most Hermes-compatible importers).
1249
+ # Matches the config.yaml examples in website/docs/guides/azure-foundry.md.
1250
+ token = ""
1251
+ for hint_key in ("key_env", "api_key_env"):
1252
+ env_var = str(model_cfg.get(hint_key) or "").strip()
1253
+ if env_var:
1254
+ token = os.getenv(env_var, "").strip()
1255
+ if token:
1256
+ break
1257
+ # Next: an inline api_key on the model config (useful in multi-profile
1258
+ # setups that want to avoid env-var juggling).
1259
+ if not token:
1260
+ token = str(model_cfg.get("api_key") or "").strip()
1261
+ # Finally fall back to the historical fixed names.
1262
+ if not token:
1263
+ token = (
1264
+ os.getenv("AZURE_ANTHROPIC_KEY", "").strip()
1265
+ or os.getenv("ANTHROPIC_API_KEY", "").strip()
1266
+ )
1267
+ if not token:
1268
+ raise AuthError(
1269
+ "No Azure Anthropic API key found. Set AZURE_ANTHROPIC_KEY or "
1270
+ "ANTHROPIC_API_KEY, or point key_env/api_key_env in your "
1271
+ "config.yaml model section at a custom env var."
1272
+ )
1273
+ else:
1274
+ from agent.anthropic_adapter import resolve_anthropic_token
1275
+ token = resolve_anthropic_token()
1276
+ if not token:
1277
+ raise AuthError(
1278
+ "No Anthropic credentials found. Set ANTHROPIC_TOKEN or ANTHROPIC_API_KEY, "
1279
+ "run 'claude setup-token', or authenticate with 'claude /login'."
1280
+ )
1281
+ return {
1282
+ "provider": "anthropic",
1283
+ "api_mode": "anthropic_messages",
1284
+ "base_url": base_url,
1285
+ "api_key": token,
1286
+ "source": "env",
1287
+ "requested_provider": requested_provider,
1288
+ }
1289
+
1290
+ # AWS Bedrock (native Converse API via boto3)
1291
+ if provider == "bedrock":
1292
+ from agent.bedrock_adapter import (
1293
+ has_aws_credentials,
1294
+ resolve_aws_auth_env_var,
1295
+ resolve_bedrock_region,
1296
+ is_anthropic_bedrock_model,
1297
+ )
1298
+ # When the user explicitly selected bedrock (not auto-detected),
1299
+ # trust boto3's credential chain — it handles IMDS, ECS task roles,
1300
+ # Lambda execution roles, SSO, and other implicit sources that our
1301
+ # env-var check can't detect.
1302
+ is_explicit = requested_provider in {"bedrock", "aws", "aws-bedrock", "amazon-bedrock", "amazon"}
1303
+ if not is_explicit and not has_aws_credentials():
1304
+ raise AuthError(
1305
+ "No AWS credentials found for Bedrock. Configure one of:\n"
1306
+ " - AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY\n"
1307
+ " - AWS_PROFILE (for SSO / named profiles)\n"
1308
+ " - IAM instance role (EC2, ECS, Lambda)\n"
1309
+ "Or run 'aws configure' to set up credentials.",
1310
+ code="no_aws_credentials",
1311
+ )
1312
+ # Read bedrock-specific config from config.yaml
1313
+ _bedrock_cfg = load_config().get("bedrock", {})
1314
+ # Region priority: config.yaml bedrock.region → env var → us-east-1
1315
+ region = (_bedrock_cfg.get("region") or "").strip() or resolve_bedrock_region()
1316
+ auth_source = resolve_aws_auth_env_var() or "aws-sdk-default-chain"
1317
+ # Build guardrail config if configured
1318
+ _gr = _bedrock_cfg.get("guardrail", {})
1319
+ guardrail_config = None
1320
+ if _gr.get("guardrail_identifier") and _gr.get("guardrail_version"):
1321
+ guardrail_config = {
1322
+ "guardrailIdentifier": _gr["guardrail_identifier"],
1323
+ "guardrailVersion": _gr["guardrail_version"],
1324
+ }
1325
+ if _gr.get("stream_processing_mode"):
1326
+ guardrail_config["streamProcessingMode"] = _gr["stream_processing_mode"]
1327
+ if _gr.get("trace"):
1328
+ guardrail_config["trace"] = _gr["trace"]
1329
+ # Dual-path routing: Claude models use AnthropicBedrock SDK for full
1330
+ # feature parity (prompt caching, thinking budgets, adaptive thinking).
1331
+ # Non-Claude models use the Converse API for multi-model support.
1332
+ _current_model = str(model_cfg.get("default") or "").strip()
1333
+ if is_anthropic_bedrock_model(_current_model):
1334
+ # Claude on Bedrock → AnthropicBedrock SDK → anthropic_messages path
1335
+ runtime = {
1336
+ "provider": "bedrock",
1337
+ "api_mode": "anthropic_messages",
1338
+ "base_url": f"https://bedrock-runtime.{region}.amazonaws.com",
1339
+ "api_key": "aws-sdk",
1340
+ "source": auth_source,
1341
+ "region": region,
1342
+ "bedrock_anthropic": True, # Signal to use AnthropicBedrock client
1343
+ "requested_provider": requested_provider,
1344
+ }
1345
+ else:
1346
+ # Non-Claude (Nova, DeepSeek, Llama, etc.) → Converse API
1347
+ runtime = {
1348
+ "provider": "bedrock",
1349
+ "api_mode": "bedrock_converse",
1350
+ "base_url": f"https://bedrock-runtime.{region}.amazonaws.com",
1351
+ "api_key": "aws-sdk",
1352
+ "source": auth_source,
1353
+ "region": region,
1354
+ "requested_provider": requested_provider,
1355
+ }
1356
+ if guardrail_config:
1357
+ runtime["guardrail_config"] = guardrail_config
1358
+ return runtime
1359
+
1360
+ # API-key providers (z.ai/GLM, Kimi, MiniMax, MiniMax-CN)
1361
+ pconfig = PROVIDER_REGISTRY.get(provider)
1362
+ if pconfig and pconfig.auth_type == "api_key":
1363
+ creds = resolve_api_key_provider_credentials(provider)
1364
+ # Honour model.base_url from config.yaml when the configured provider
1365
+ # matches this provider — mirrors the Anthropic path above. Without
1366
+ # this, users who set model.base_url to e.g. api.minimaxi.com/anthropic
1367
+ # (China endpoint) still get the hardcoded api.minimax.io default (#6039).
1368
+ cfg_provider = str(model_cfg.get("provider") or "").strip().lower()
1369
+ cfg_base_url = ""
1370
+ if cfg_provider == provider:
1371
+ cfg_base_url = (model_cfg.get("base_url") or "").strip().rstrip("/")
1372
+ base_url = cfg_base_url or creds.get("base_url", "").rstrip("/")
1373
+ api_mode = "chat_completions"
1374
+ if provider == "copilot":
1375
+ api_mode = _copilot_runtime_api_mode(model_cfg, creds.get("api_key", ""))
1376
+ elif provider == "xai":
1377
+ api_mode = "codex_responses"
1378
+ else:
1379
+ configured_provider = str(model_cfg.get("provider") or "").strip().lower()
1380
+ # Only honor persisted api_mode when it belongs to the same provider family.
1381
+ configured_mode = _parse_api_mode(model_cfg.get("api_mode"))
1382
+ if provider in {"opencode-zen", "opencode-go"}:
1383
+ # opencode-zen/go must always re-derive api_mode from the
1384
+ # target model (not the stale persisted api_mode), because
1385
+ # the same provider serves both anthropic_messages
1386
+ # (e.g. minimax-m2.7) and chat_completions (e.g.
1387
+ # deepseek-v4-flash) and switching models via /model would
1388
+ # otherwise carry the previous mode forward, stripping /v1
1389
+ # from base_url for chat_completions models and 404'ing.
1390
+ # Refs #16878.
1391
+ from hermes_cli.models import opencode_model_api_mode
1392
+ _effective = target_model or model_cfg.get("default", "")
1393
+ api_mode = opencode_model_api_mode(provider, _effective)
1394
+ elif configured_mode and _provider_supports_explicit_api_mode(provider, configured_provider):
1395
+ api_mode = configured_mode
1396
+ else:
1397
+ # Auto-detect Anthropic-compatible endpoints by URL convention
1398
+ # (e.g. https://api.minimax.io/anthropic, https://dashscope.../anthropic)
1399
+ # plus api.openai.com → codex_responses and api.x.ai → codex_responses.
1400
+ detected = _detect_api_mode_for_url(base_url)
1401
+ if detected:
1402
+ api_mode = detected
1403
+ # Strip trailing /v1 for OpenCode Anthropic models (see comment above).
1404
+ if api_mode == "anthropic_messages" and provider in {"opencode-zen", "opencode-go"}:
1405
+ base_url = re.sub(r"/v1/?$", "", base_url)
1406
+ return {
1407
+ "provider": provider,
1408
+ "api_mode": api_mode,
1409
+ "base_url": base_url,
1410
+ "api_key": creds.get("api_key", ""),
1411
+ "source": creds.get("source", "env"),
1412
+ "requested_provider": requested_provider,
1413
+ }
1414
+
1415
+ runtime = _resolve_openrouter_runtime(
1416
+ requested_provider=requested_provider,
1417
+ explicit_api_key=explicit_api_key,
1418
+ explicit_base_url=explicit_base_url,
1419
+ )
1420
+ runtime["requested_provider"] = requested_provider
1421
+ return runtime
1422
+
1423
+
1424
+ def format_runtime_provider_error(error: Exception) -> str:
1425
+ if isinstance(error, AuthError):
1426
+ return format_auth_error(error)
1427
+ return str(error)
1428
+