@xopcai/xopc 0.0.8 → 0.0.11

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 (242) hide show
  1. package/dist/extensions/telegram/src/plugin.js +1 -1
  2. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  3. package/dist/extensions/weixin/src/plugin.js +1 -1
  4. package/dist/gateway/static/root/assets/{agents-BSNzJWbQ.js → agents-BdC4Y-HX.js} +2 -2
  5. package/dist/gateway/static/root/assets/agents-BdC4Y-HX.js.map +1 -0
  6. package/dist/gateway/static/root/assets/{apps-page-BKk9SB4D.js → apps-page-C-oaSHkm.js} +2 -2
  7. package/dist/gateway/static/root/assets/{apps-page-BKk9SB4D.js.map → apps-page-C-oaSHkm.js.map} +1 -1
  8. package/dist/gateway/static/root/assets/attachment-load-BDDlItdE.js +1 -0
  9. package/dist/gateway/static/root/assets/{channels-settings-_J6cQN6G.js → channels-settings-BqEUppPO.js} +2 -2
  10. package/dist/gateway/static/root/assets/{channels-settings-_J6cQN6G.js.map → channels-settings-BqEUppPO.js.map} +1 -1
  11. package/dist/gateway/static/root/assets/{chat-agents-api-DPb_0O8M.js → chat-agents-api-BhqjQ7iL.js} +2 -2
  12. package/dist/gateway/static/root/assets/{chat-agents-api-DPb_0O8M.js.map → chat-agents-api-BhqjQ7iL.js.map} +1 -1
  13. package/dist/gateway/static/root/assets/{cron-page-BUJOuuKX.js → cron-page-Cli49RKR.js} +2 -2
  14. package/dist/gateway/static/root/assets/{cron-page-BUJOuuKX.js.map → cron-page-Cli49RKR.js.map} +1 -1
  15. package/dist/gateway/static/root/assets/{cron-utils-Cn0YVg8x.js → cron-utils-Dkj-Ldpf.js} +2 -2
  16. package/dist/gateway/static/root/assets/{cron-utils-Cn0YVg8x.js.map → cron-utils-Dkj-Ldpf.js.map} +1 -1
  17. package/dist/gateway/static/root/assets/{electron-env-D9bm1FIu.js → electron-env-BDtJw9AY.js} +2 -2
  18. package/dist/gateway/static/root/assets/{electron-env-D9bm1FIu.js.map → electron-env-BDtJw9AY.js.map} +1 -1
  19. package/dist/gateway/static/root/assets/{extension-debug-page-DTz4O5Ua.js → extension-debug-page-BMcZlaxF.js} +2 -2
  20. package/dist/gateway/static/root/assets/{extension-debug-page-DTz4O5Ua.js.map → extension-debug-page-BMcZlaxF.js.map} +1 -1
  21. package/dist/gateway/static/root/assets/{extension-iframe-host-Cs1Kde9o.js → extension-iframe-host-D5HEF0KR.js} +2 -2
  22. package/dist/gateway/static/root/assets/{extension-iframe-host-Cs1Kde9o.js.map → extension-iframe-host-D5HEF0KR.js.map} +1 -1
  23. package/dist/gateway/static/root/assets/{extension-page-G52iX0Bo.js → extension-page-CXdCSSPl.js} +2 -2
  24. package/dist/gateway/static/root/assets/{extension-page-G52iX0Bo.js.map → extension-page-CXdCSSPl.js.map} +1 -1
  25. package/dist/gateway/static/root/assets/{extension-provider-CO2jxBA9.js → extension-provider-DZCZgQE2.js} +2 -2
  26. package/dist/gateway/static/root/assets/{extension-provider-CO2jxBA9.js.map → extension-provider-DZCZgQE2.js.map} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-settings-page-D9Ul8uSt.js → extension-settings-page-CX6STpx3.js} +2 -2
  28. package/dist/gateway/static/root/assets/{extension-settings-page-D9Ul8uSt.js.map → extension-settings-page-CX6STpx3.js.map} +1 -1
  29. package/dist/gateway/static/root/assets/{gateway-config-swr-Bc8SVD15.js → gateway-config-swr-Cph02QZn.js} +2 -2
  30. package/dist/gateway/static/root/assets/{gateway-config-swr-Bc8SVD15.js.map → gateway-config-swr-Cph02QZn.js.map} +1 -1
  31. package/dist/gateway/static/root/assets/index-Bty3m0mS.css +2 -0
  32. package/dist/gateway/static/root/assets/{index-BXUJbteW.js → index-iTUyfzNr.js} +10 -10
  33. package/dist/gateway/static/root/assets/index-iTUyfzNr.js.map +1 -0
  34. package/dist/gateway/static/root/assets/{logs-page-5V25JkQY.js → logs-page-B9O5l3I8.js} +2 -2
  35. package/dist/gateway/static/root/assets/{logs-page-5V25JkQY.js.map → logs-page-B9O5l3I8.js.map} +1 -1
  36. package/dist/gateway/static/root/assets/{model-selector-he3aQfme.js → model-selector-BLiY_O25.js} +2 -2
  37. package/dist/gateway/static/root/assets/{model-selector-he3aQfme.js.map → model-selector-BLiY_O25.js.map} +1 -1
  38. package/dist/gateway/static/root/assets/page-header-store-BFpnFTed.js +2 -0
  39. package/dist/gateway/static/root/assets/{page-header-store-DJHD9Ean.js.map → page-header-store-BFpnFTed.js.map} +1 -1
  40. package/dist/gateway/static/root/assets/{session-api-n-4O5d9U.js → session-api-DEhQXWJg.js} +2 -2
  41. package/dist/gateway/static/root/assets/{session-api-n-4O5d9U.js.map → session-api-DEhQXWJg.js.map} +1 -1
  42. package/dist/gateway/static/root/assets/{session-working-directory-control-B6dHLvbr.js → session-working-directory-control-DKOtWs3-.js} +2 -2
  43. package/dist/gateway/static/root/assets/{session-working-directory-control-B6dHLvbr.js.map → session-working-directory-control-DKOtWs3-.js.map} +1 -1
  44. package/dist/gateway/static/root/assets/{sessions-page-rBUfTdm3.js → sessions-page-BYlWP1ep.js} +2 -2
  45. package/dist/gateway/static/root/assets/{sessions-page-rBUfTdm3.js.map → sessions-page-BYlWP1ep.js.map} +1 -1
  46. package/dist/gateway/static/root/assets/{settings-page-B3QrJm-E.js → settings-page-oCnIavdg.js} +2 -2
  47. package/dist/gateway/static/root/assets/settings-page-oCnIavdg.js.map +1 -0
  48. package/dist/gateway/static/root/assets/{skill-api-vxtE8kI6.js → skill-api-DWrn8Az0.js} +2 -2
  49. package/dist/gateway/static/root/assets/{skill-api-vxtE8kI6.js.map → skill-api-DWrn8Az0.js.map} +1 -1
  50. package/dist/gateway/static/root/assets/{skills-page-D36_O2Ub.js → skills-page-C59WQpM1.js} +2 -2
  51. package/dist/gateway/static/root/assets/{skills-page-D36_O2Ub.js.map → skills-page-C59WQpM1.js.map} +1 -1
  52. package/dist/gateway/static/root/assets/{theme-store-CmiSsYBd.js → theme-store-CywXkKml.js} +2 -2
  53. package/dist/gateway/static/root/assets/{theme-store-CmiSsYBd.js.map → theme-store-CywXkKml.js.map} +1 -1
  54. package/dist/gateway/static/root/assets/url-D7yWllI8.js +2 -0
  55. package/dist/gateway/static/root/assets/url-D7yWllI8.js.map +1 -0
  56. package/dist/gateway/static/root/assets/{useTranslation-DYORQ7x6.js → useTranslation-CACj0DBJ.js} +2 -2
  57. package/dist/gateway/static/root/assets/{useTranslation-DYORQ7x6.js.map → useTranslation-CACj0DBJ.js.map} +1 -1
  58. package/dist/gateway/static/root/index.html +15 -15
  59. package/dist/package.js +1 -1
  60. package/dist/src/agent/agent-manager.d.ts +1 -0
  61. package/dist/src/agent/agent-manager.js +20 -12
  62. package/dist/src/agent/agent-manager.js.map +1 -1
  63. package/dist/src/agent/background-review/run-background-review.js +2 -0
  64. package/dist/src/agent/background-review/run-background-review.js.map +1 -1
  65. package/dist/src/agent/child-agent-factory.js +2 -0
  66. package/dist/src/agent/child-agent-factory.js.map +1 -1
  67. package/dist/src/agent/context/expand-at-file-mentions.d.ts +4 -0
  68. package/dist/src/agent/context/expand-at-file-mentions.js +69 -0
  69. package/dist/src/agent/context/expand-at-file-mentions.js.map +1 -0
  70. package/dist/src/agent/context/workspace-seed.js +1 -1
  71. package/dist/src/agent/image/understanding/pi-ai-provider.js.map +1 -1
  72. package/dist/src/agent/ipc/bus.js +1 -1
  73. package/dist/src/agent/ipc/inbox.js +1 -1
  74. package/dist/src/agent/ipc/socket.js +1 -1
  75. package/dist/src/agent/memory/compaction.d.ts +1 -1
  76. package/dist/src/agent/memory/compaction.js +38 -11
  77. package/dist/src/agent/memory/compaction.js.map +1 -1
  78. package/dist/src/agent/messaging/command-handler.d.ts +13 -0
  79. package/dist/src/agent/messaging/command-handler.js +14 -2
  80. package/dist/src/agent/messaging/command-handler.js.map +1 -1
  81. package/dist/src/agent/models/manager.js +1 -1
  82. package/dist/src/agent/orchestration/agent-orchestrator.js +6 -1
  83. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  84. package/dist/src/agent/prompt/service-prompt-builder.js +1 -1
  85. package/dist/src/agent/service.d.ts +16 -1
  86. package/dist/src/agent/service.js +178 -20
  87. package/dist/src/agent/service.js.map +1 -1
  88. package/dist/src/agent/skills/format-skills-prompt.js.map +1 -1
  89. package/dist/src/agent/skills/index.js +1 -1
  90. package/dist/src/agent/skills/scanner.js +1 -1
  91. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  92. package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
  93. package/dist/src/agent/skills/skill-manager.js +1 -1
  94. package/dist/src/agent/tools/browser/tools.js.map +1 -1
  95. package/dist/src/agent/tools/factory.js +1 -1
  96. package/dist/src/agent/tools/image-tool.js.map +1 -1
  97. package/dist/src/agent/tools/send-media.js +1 -1
  98. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  99. package/dist/src/agent/tools/write.js +1 -1
  100. package/dist/src/auth/credentials.js +2 -2
  101. package/dist/src/auth/sync-provider-auth.js +1 -1
  102. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  103. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  104. package/dist/src/channels/index.d.ts +1 -1
  105. package/dist/src/channels/index.js +2 -2
  106. package/dist/src/channels/pipeline.d.ts +8 -1
  107. package/dist/src/channels/pipeline.js +49 -4
  108. package/dist/src/channels/pipeline.js.map +1 -1
  109. package/dist/src/chat-commands/builtins/config.d.ts +4 -0
  110. package/dist/src/chat-commands/builtins/config.js +197 -0
  111. package/dist/src/chat-commands/builtins/config.js.map +1 -0
  112. package/dist/src/chat-commands/builtins/context.d.ts +4 -0
  113. package/dist/src/chat-commands/builtins/context.js +44 -0
  114. package/dist/src/chat-commands/builtins/context.js.map +1 -0
  115. package/dist/src/chat-commands/builtins/session.js +111 -0
  116. package/dist/src/chat-commands/builtins/session.js.map +1 -1
  117. package/dist/src/chat-commands/builtins/thinking.js +49 -21
  118. package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
  119. package/dist/src/chat-commands/config-paths.d.ts +10 -0
  120. package/dist/src/chat-commands/config-paths.js +45 -0
  121. package/dist/src/chat-commands/config-paths.js.map +1 -0
  122. package/dist/src/chat-commands/config-value.d.ts +12 -0
  123. package/dist/src/chat-commands/config-value.js +53 -0
  124. package/dist/src/chat-commands/config-value.js.map +1 -0
  125. package/dist/src/chat-commands/context.d.ts +24 -1
  126. package/dist/src/chat-commands/context.js +41 -0
  127. package/dist/src/chat-commands/context.js.map +1 -1
  128. package/dist/src/chat-commands/index.d.ts +2 -0
  129. package/dist/src/chat-commands/index.js +5 -1
  130. package/dist/src/chat-commands/index.js.map +1 -1
  131. package/dist/src/chat-commands/types.d.ts +33 -1
  132. package/dist/src/cli/commands/agent/interactive.js +1 -1
  133. package/dist/src/cli/commands/agent/interactive.js.map +1 -1
  134. package/dist/src/cli/commands/agent.js +22 -10
  135. package/dist/src/cli/commands/agent.js.map +1 -1
  136. package/dist/src/cli/commands/auth.js.map +1 -1
  137. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  138. package/dist/src/cli/commands/extension.js +10 -0
  139. package/dist/src/cli/commands/extension.js.map +1 -1
  140. package/dist/src/cli/commands/init.js +3 -4
  141. package/dist/src/cli/commands/init.js.map +1 -1
  142. package/dist/src/cli/commands/session/utils.js.map +1 -1
  143. package/dist/src/cli/commands/update.d.ts +1 -0
  144. package/dist/src/cli/commands/update.js +171 -0
  145. package/dist/src/cli/commands/update.js.map +1 -0
  146. package/dist/src/cli/index.d.ts +1 -1
  147. package/dist/src/cli/index.js +3 -1
  148. package/dist/src/cli/index.js.map +1 -1
  149. package/dist/src/config/index.d.ts +1 -0
  150. package/dist/src/config/index.js +5 -4
  151. package/dist/src/config/index.js.map +1 -1
  152. package/dist/src/config/loader.js +1 -1
  153. package/dist/src/config/models-json.js +1 -1
  154. package/dist/src/config/paths.js.map +1 -1
  155. package/dist/src/config/profile.js +2 -2
  156. package/dist/src/config/runtime-overrides.d.ts +8 -0
  157. package/dist/src/config/runtime-overrides.js +40 -0
  158. package/dist/src/config/runtime-overrides.js.map +1 -0
  159. package/dist/src/config/schema.d.ts +35 -0
  160. package/dist/src/config/schema.js +19 -3
  161. package/dist/src/config/schema.js.map +1 -1
  162. package/dist/src/cron/executor.js +2 -2
  163. package/dist/src/cron/persistence.js +1 -1
  164. package/dist/src/cron/run-log-store.js +1 -1
  165. package/dist/src/extensions/health.js +1 -1
  166. package/dist/src/extensions/loader.d.ts +1 -1
  167. package/dist/src/extensions/loader.js +6 -9
  168. package/dist/src/extensions/loader.js.map +1 -1
  169. package/dist/src/extensions/lockfile.js +1 -1
  170. package/dist/src/extensions/sdk/index.js +6 -1
  171. package/dist/src/extensions/sdk/index.js.map +1 -0
  172. package/dist/src/gateway/agents-admin.js +2 -2
  173. package/dist/src/gateway/agents-admin.js.map +1 -1
  174. package/dist/src/gateway/hono/oauth.js +1 -1
  175. package/dist/src/gateway/hono/routes/config.js +1 -1
  176. package/dist/src/gateway/hono/routes/index.js +2 -0
  177. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  178. package/dist/src/gateway/hono/routes/models.js +64 -11
  179. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  180. package/dist/src/gateway/hono/routes/public-gateway.js +10 -0
  181. package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
  182. package/dist/src/gateway/hono/routes/update.d.ts +3 -0
  183. package/dist/src/gateway/hono/routes/update.js +141 -0
  184. package/dist/src/gateway/hono/routes/update.js.map +1 -0
  185. package/dist/src/gateway/hono/routes/workspace.js +84 -4
  186. package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
  187. package/dist/src/gateway/hono/sse.js +2 -2
  188. package/dist/src/gateway/service.d.ts +1 -0
  189. package/dist/src/gateway/service.js +16 -4
  190. package/dist/src/gateway/service.js.map +1 -1
  191. package/dist/src/gateway/workspace-fs-file-list.d.ts +5 -0
  192. package/dist/src/gateway/workspace-fs-file-list.js +56 -0
  193. package/dist/src/gateway/workspace-fs-file-list.js.map +1 -0
  194. package/dist/src/gateway/workspace-heartbeat-path.js +1 -1
  195. package/dist/src/gateway/workspace-ripgrep.d.ts +5 -0
  196. package/dist/src/gateway/workspace-ripgrep.js +88 -4
  197. package/dist/src/gateway/workspace-ripgrep.js.map +1 -1
  198. package/dist/src/infra/update-channels.d.ts +14 -0
  199. package/dist/src/infra/update-channels.js +30 -0
  200. package/dist/src/infra/update-channels.js.map +1 -0
  201. package/dist/src/infra/update-check.d.ts +53 -0
  202. package/dist/src/infra/update-check.js +155 -0
  203. package/dist/src/infra/update-check.js.map +1 -0
  204. package/dist/src/infra/update-runner.d.ts +18 -0
  205. package/dist/src/infra/update-runner.js +112 -0
  206. package/dist/src/infra/update-runner.js.map +1 -0
  207. package/dist/src/infra/update-startup.d.ts +20 -0
  208. package/dist/src/infra/update-startup.js +246 -0
  209. package/dist/src/infra/update-startup.js.map +1 -0
  210. package/dist/src/providers/extension-stream-bridge.d.ts +3 -0
  211. package/dist/src/providers/extension-stream-bridge.js +239 -0
  212. package/dist/src/providers/extension-stream-bridge.js.map +1 -0
  213. package/dist/src/providers/index.d.ts +7 -2
  214. package/dist/src/providers/index.js +77 -14
  215. package/dist/src/providers/index.js.map +1 -1
  216. package/dist/src/providers/model-registry.js +1 -1
  217. package/dist/src/providers/plugin-registry.js +92 -87
  218. package/dist/src/providers/plugin-registry.js.map +1 -1
  219. package/dist/src/session/chat-export.d.ts +5 -0
  220. package/dist/src/session/chat-export.js +35 -0
  221. package/dist/src/session/chat-export.js.map +1 -0
  222. package/dist/src/session/config-store.js +1 -1
  223. package/dist/src/session/manager.d.ts +1 -1
  224. package/dist/src/session/manager.js +2 -2
  225. package/dist/src/session/manager.js.map +1 -1
  226. package/dist/src/session/session-title.js +1 -1
  227. package/dist/src/session/store.d.ts +1 -1
  228. package/dist/src/session/store.js +5 -5
  229. package/dist/src/session/store.js.map +1 -1
  230. package/dist/src/utils/logger/audit.js +1 -1
  231. package/dist/src/utils/logger/log-store.js +1 -1
  232. package/dist/src/utils/logger/rotation.js +1 -1
  233. package/dist/src/voice/tts/audio.js +1 -1
  234. package/package.json +2 -1
  235. package/dist/gateway/static/root/assets/agents-BSNzJWbQ.js.map +0 -1
  236. package/dist/gateway/static/root/assets/attachment-load-DXcJLSWT.js +0 -1
  237. package/dist/gateway/static/root/assets/index-BXUJbteW.js.map +0 -1
  238. package/dist/gateway/static/root/assets/index-CQLMxWSA.css +0 -2
  239. package/dist/gateway/static/root/assets/page-header-store-DJHD9Ean.js +0 -2
  240. package/dist/gateway/static/root/assets/settings-page-B3QrJm-E.js.map +0 -1
  241. package/dist/gateway/static/root/assets/url-CtSqjF9J.js +0 -2
  242. package/dist/gateway/static/root/assets/url-CtSqjF9J.js.map +0 -1
@@ -1,14 +1,16 @@
1
1
  import { __esmMin, __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
- import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
3
2
  import { PROVIDER_ENV_MAP, getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
4
- import { ModelRegistry, getModelRegistry, init_model_registry, resetModelRegistry } from "./model-registry.js";
5
3
  import { CredentialResolver, hasCredentials, init_credentials, resolveApiKey } from "../auth/credentials.js";
4
+ import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
5
+ import { ModelRegistry, getModelRegistry, init_model_registry, resetModelRegistry } from "./model-registry.js";
6
+ import { getProviderRegistry, init_plugin_registry } from "./plugin-registry.js";
6
7
  import { getModel, getModels, getProviders } from "@mariozechner/pi-ai";
7
8
  //#region src/providers/index.ts
8
9
  /**
9
10
  * Model provider module - integrates built-in models with custom models from models.json
10
11
  */
11
12
  var providers_exports = /* @__PURE__ */ __exportAll({
13
+ EXTENSION_PROVIDER_BASE_URL: () => EXTENSION_PROVIDER_BASE_URL,
12
14
  ModelRegistry: () => ModelRegistry,
13
15
  PROVIDER_ENV_MAP: () => PROVIDER_ENV_MAP,
14
16
  PROVIDER_META: () => PROVIDER_META,
@@ -28,16 +30,38 @@ var providers_exports = /* @__PURE__ */ __exportAll({
28
30
  getSortedProviders: () => getSortedProviders,
29
31
  isProviderConfigured: () => isProviderConfigured,
30
32
  isProviderConfiguredSync: () => isProviderConfiguredSync,
33
+ pluginModelToModel: () => pluginModelToModel,
31
34
  providerSupportsApiKey: () => providerSupportsApiKey,
32
35
  providerSupportsOAuth: () => providerSupportsOAuth,
33
36
  resetModelRegistry: () => resetModelRegistry,
34
37
  resolveModel: () => resolveModel
35
38
  });
39
+ /** Map a plugin registry model to the pi-ai {@link Model} shape. */
40
+ function pluginModelToModel(providerId, definition) {
41
+ return {
42
+ provider: providerId,
43
+ id: definition.id,
44
+ name: definition.name,
45
+ api: "openai-completions",
46
+ baseUrl: EXTENSION_PROVIDER_BASE_URL,
47
+ reasoning: false,
48
+ input: definition.supportsImages ? ["text", "image"] : ["text"],
49
+ contextWindow: definition.contextWindow ?? 128e3,
50
+ maxTokens: definition.maxOutputTokens ?? 4096,
51
+ cost: {
52
+ input: definition.pricing?.input ?? 0,
53
+ output: definition.pricing?.output ?? 0,
54
+ cacheRead: 0,
55
+ cacheWrite: 0
56
+ }
57
+ };
58
+ }
36
59
  /**
37
60
  * Get API key synchronously: checks registry (models.json) first, then environment variables.
38
61
  * Use this for Agent's getApiKey callback which must be synchronous.
39
62
  */
40
63
  function getApiKeySync(provider) {
64
+ if (getProviderRegistry().has(provider)) return "extension-managed";
41
65
  const registryKey = getModelRegistry().getApiKey(provider);
42
66
  if (registryKey) return registryKey;
43
67
  return getApiKeyFromEnv(provider);
@@ -53,9 +77,14 @@ function resolveModel(ref) {
53
77
  if (customModel) return customModel;
54
78
  if (ref.includes("/")) {
55
79
  const [provider, modelId] = ref.split("/");
56
- const model = getModel(provider, modelId);
57
- if (!model) throw new Error(`Model not found: ${ref}`);
58
- return model;
80
+ const piAiModel = getModel(provider, modelId);
81
+ if (piAiModel) return piAiModel;
82
+ const plugin = getProviderRegistry().get(provider);
83
+ if (plugin) {
84
+ const pluginModel = plugin.models.find((m) => m.id === modelId);
85
+ if (pluginModel) return pluginModelToModel(provider, pluginModel);
86
+ }
87
+ throw new Error(`Model not found: ${ref}`);
59
88
  }
60
89
  for (const provider of getProviders()) try {
61
90
  const found = getModels(provider).find((m) => m.id === ref);
@@ -63,19 +92,30 @@ function resolveModel(ref) {
63
92
  } catch {
64
93
  continue;
65
94
  }
95
+ const pluginRegistry = getProviderRegistry();
96
+ for (const plugin of pluginRegistry.listAll()) {
97
+ const found = plugin.models.find((m) => m.id === ref);
98
+ if (found) return pluginModelToModel(plugin.id, found);
99
+ }
66
100
  throw new Error(`Model not found: ${ref}. Use format: provider/model-id`);
67
101
  }
68
102
  function getModelsByProvider(provider) {
69
- return getModelRegistry().getAll().filter((m) => m.provider === provider);
103
+ const fromRegistry = getModelRegistry().getAll().filter((m) => m.provider === provider);
104
+ const plugin = getProviderRegistry().get(provider);
105
+ if (!plugin) return fromRegistry;
106
+ const pluginModels = plugin.models.map((m) => pluginModelToModel(provider, m));
107
+ return [...fromRegistry, ...pluginModels];
70
108
  }
71
109
  function getAllProviders() {
72
110
  const registry = getModelRegistry();
73
111
  const providers = /* @__PURE__ */ new Set();
74
112
  for (const p of getProviders()) providers.add(p);
75
113
  for (const m of registry.getAll()) providers.add(m.provider);
114
+ for (const plugin of getProviderRegistry().listAll()) providers.add(plugin.id);
76
115
  return Array.from(providers);
77
116
  }
78
117
  async function getApiKey(provider) {
118
+ if (getProviderRegistry().has(provider)) return "extension-managed";
79
119
  const credentialKey = await resolveApiKey(provider);
80
120
  if (credentialKey) return credentialKey;
81
121
  const registryKey = getModelRegistry().getApiKey(provider);
@@ -87,15 +127,18 @@ async function getApiKey(provider) {
87
127
  * Only checks environment variables and registry, not credential system
88
128
  */
89
129
  function isProviderConfiguredSync(provider) {
130
+ if (getProviderRegistry().has(provider)) return true;
90
131
  if (getModelRegistry().getApiKey(provider)) return true;
91
132
  if (getApiKeyFromEnv(provider)) return true;
92
133
  return hasProviderAuthOnDiskSync(provider);
93
134
  }
94
135
  async function isProviderConfigured(provider) {
136
+ if (getProviderRegistry().has(provider)) return true;
95
137
  if (getModelRegistry().getApiKey(provider)) return true;
96
138
  return await hasCredentials(provider);
97
139
  }
98
140
  async function getProviderActiveKeySource(provider) {
141
+ if (getProviderRegistry().has(provider)) return "extension";
99
142
  const fromCredentials = await new CredentialResolver().resolveApiKeySource(provider);
100
143
  if (fromCredentials === "agent") return "agent";
101
144
  if (fromCredentials === "global") return "gateway";
@@ -111,12 +154,26 @@ async function getConfiguredProviders() {
111
154
  return configured;
112
155
  }
113
156
  function getAllModels() {
114
- return getModelRegistry().getAll();
157
+ const registryModels = getModelRegistry().getAll();
158
+ const pluginProviders = getProviderRegistry().listAll();
159
+ if (pluginProviders.length === 0) return registryModels;
160
+ const existingIds = new Set(registryModels.map((m) => `${m.provider}/${m.id}`));
161
+ const merged = [...registryModels];
162
+ for (const plugin of pluginProviders) for (const model of plugin.models) {
163
+ const compositeId = `${plugin.id}/${model.id}`;
164
+ if (!existingIds.has(compositeId)) {
165
+ merged.push(pluginModelToModel(plugin.id, model));
166
+ existingIds.add(compositeId);
167
+ }
168
+ }
169
+ return merged;
115
170
  }
116
171
  async function getAvailableModels() {
117
- const allModels = getModelRegistry().getAll();
172
+ const allModels = getAllModels();
173
+ const pluginRegistry = getProviderRegistry();
118
174
  const available = [];
119
- for (const model of allModels) if (await isProviderConfigured(model.provider)) available.push(model);
175
+ for (const model of allModels) if (pluginRegistry.has(model.provider)) available.push(model);
176
+ else if (await isProviderConfigured(model.provider)) available.push(model);
120
177
  return available;
121
178
  }
122
179
  function getSortedProviders() {
@@ -125,16 +182,20 @@ function getSortedProviders() {
125
182
  common: 0,
126
183
  specialty: 1,
127
184
  enterprise: 2,
128
- oauth: 3
185
+ oauth: 3,
186
+ extension: 4
129
187
  };
188
+ const pluginRegistry = getProviderRegistry();
130
189
  return [...all].sort((a, b) => {
131
- const catA = PROVIDER_META[a]?.category ?? "specialty";
132
- const catB = PROVIDER_META[b]?.category ?? "specialty";
190
+ const catA = pluginRegistry.has(a) ? "extension" : PROVIDER_META[a]?.category ?? "specialty";
191
+ const catB = pluginRegistry.has(b) ? "extension" : PROVIDER_META[b]?.category ?? "specialty";
133
192
  if (catOrder[catA] !== catOrder[catB]) return catOrder[catA] - catOrder[catB];
134
193
  return a.localeCompare(b);
135
194
  });
136
195
  }
137
196
  function getProviderDisplayName(provider) {
197
+ const plugin = getProviderRegistry().get(provider);
198
+ if (plugin) return plugin.name;
138
199
  return PROVIDER_META[provider]?.name || provider;
139
200
  }
140
201
  function providerSupportsOAuth(provider) {
@@ -189,12 +250,14 @@ function getDefaultModelSync(config) {
189
250
  }
190
251
  return "anthropic/claude-sonnet-4-5";
191
252
  }
192
- var PROVIDER_META;
253
+ var EXTENSION_PROVIDER_BASE_URL, PROVIDER_META;
193
254
  var init_providers = __esmMin((() => {
194
255
  init_model_registry();
195
256
  init_credentials();
196
257
  init_sync_provider_auth();
197
258
  init_env_keys();
259
+ init_plugin_registry();
260
+ EXTENSION_PROVIDER_BASE_URL = "extension://provider-plugin";
198
261
  PROVIDER_META = {
199
262
  "openai": {
200
263
  name: "OpenAI (GPT-4, o1, o3)",
@@ -324,6 +387,6 @@ var init_providers = __esmMin((() => {
324
387
  }));
325
388
  //#endregion
326
389
  init_providers();
327
- export { ModelRegistry, PROVIDER_ENV_MAP, PROVIDER_META, getAllModels, getAllProviders, getApiKey, getApiKeyFromEnv, getApiKeySync, getAvailableModels, getConfiguredProviders, getDefaultModel, getDefaultModelSync, getModelRegistry, getModelsByProvider, getProviderActiveKeySource, getProviderDisplayName, getSortedProviders, init_providers, isProviderConfigured, isProviderConfiguredSync, providerSupportsApiKey, providerSupportsOAuth, providers_exports, resetModelRegistry, resolveModel };
390
+ export { EXTENSION_PROVIDER_BASE_URL, ModelRegistry, PROVIDER_ENV_MAP, PROVIDER_META, getAllModels, getAllProviders, getApiKey, getApiKeyFromEnv, getApiKeySync, getAvailableModels, getConfiguredProviders, getDefaultModel, getDefaultModelSync, getModelRegistry, getModelsByProvider, getProviderActiveKeySource, getProviderDisplayName, getSortedProviders, init_providers, isProviderConfigured, isProviderConfiguredSync, pluginModelToModel, providerSupportsApiKey, providerSupportsOAuth, providers_exports, resetModelRegistry, resolveModel };
328
391
 
329
392
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["getPiAiModel","getPiAiProviders","getPiAiModels"],"sources":["../../../src/providers/index.ts"],"sourcesContent":["/**\n * Model provider module - integrates built-in models with custom models from models.json\n */\n\nimport {\n\tgetModel as getPiAiModel,\n\tgetModels as getPiAiModels,\n\tgetProviders as getPiAiProviders,\n\ttype Model,\n\ttype Api,\n} from '@mariozechner/pi-ai';\nimport type { Config } from '../config/schema.js';\nimport { getModelRegistry } from './model-registry.js';\nimport { CredentialResolver, resolveApiKey, hasCredentials } from '../auth/credentials.js';\nimport { hasProviderAuthOnDiskSync } from '../auth/sync-provider-auth.js';\nimport { getApiKeyFromEnv } from './env-keys.js';\n\nexport { getApiKeyFromEnv, PROVIDER_ENV_MAP } from './env-keys.js';\n\n/**\n * Get API key synchronously: checks registry (models.json) first, then environment variables.\n * Use this for Agent's getApiKey callback which must be synchronous.\n */\nexport function getApiKeySync(provider: string): string | undefined {\n const registry = getModelRegistry();\n const registryKey = registry.getApiKey(provider);\n if (registryKey) {\n return registryKey;\n }\n return getApiKeyFromEnv(provider);\n}\n\n/**\n * Resolve model reference. Supports:\n * - \"provider/modelId\" format\n * - \"modelId\" auto-detection via pi-ai or custom models\n * @throws if model not found\n */\nexport function resolveModel(ref: string): Model<Api> {\n\t// First try ModelRegistry (includes custom models)\n\tconst registry = getModelRegistry();\n\tconst customModel = registry.resolve(ref);\n\tif (customModel) {\n\t\treturn customModel;\n\t}\n\n\t// Fall back to built-in models\n\tif (ref.includes('/')) {\n\t\tconst [provider, modelId] = ref.split('/');\n\t\tconst model = getPiAiModel(provider as any, modelId as any);\n\t\tif (!model) throw new Error(`Model not found: ${ref}`);\n\t\treturn model as Model<Api>;\n\t}\n\n\tfor (const provider of getPiAiProviders()) {\n\t\ttry {\n\t\t\tconst models = getPiAiModels(provider);\n\t\t\tconst found = models.find(m => m.id === ref);\n\t\t\tif (found) return found as Model<Api>;\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t}\n\n\tthrow new Error(`Model not found: ${ref}. Use format: provider/model-id`);\n}\n\nexport function getModelsByProvider(provider: string): readonly Model<Api>[] {\n\t// Get from registry (includes custom models)\n\tconst registry = getModelRegistry();\n\treturn registry.getAll().filter(m => m.provider === provider);\n}\n\nexport function getAllProviders(): string[] {\n\tconst registry = getModelRegistry();\n\tconst providers = new Set<string>();\n\n\t// Add built-in providers\n\tfor (const p of getPiAiProviders()) {\n\t\tproviders.add(p);\n\t}\n\n\t// Add custom providers from registry\n\tfor (const m of registry.getAll()) {\n\t\tproviders.add(m.provider);\n\t}\n\n\treturn Array.from(providers);\n}\n\nexport async function getApiKey(provider: string): Promise<string | undefined> {\n\t// Use new credential resolver first (checks: agent private > global > oauth > env)\n\tconst credentialKey = await resolveApiKey(provider);\n\tif (credentialKey) {\n\t\treturn credentialKey;\n\t}\n\n\t// Check registry for custom providers (from models.json)\n\tconst registry = getModelRegistry();\n\tconst registryKey = registry.getApiKey(provider);\n\tif (registryKey) {\n\t\treturn registryKey;\n\t}\n\n\t// Fallback to environment variables\n\treturn getApiKeyFromEnv(provider);\n}\n\n/**\n * Synchronous version for use in non-async contexts\n * Only checks environment variables and registry, not credential system\n */\nexport function isProviderConfiguredSync(provider: string): boolean {\n\t// Check registry for custom providers\n\tconst registry = getModelRegistry();\n\tif (registry.getApiKey(provider)) {\n\t\treturn true;\n\t}\n\t// Check environment variables\n\tif (getApiKeyFromEnv(provider)) {\n\t\treturn true;\n\t}\n\t// Gateway UI / CLI store keys in auth-profiles.json (async CredentialResolver); sync path for fallback list\n\treturn hasProviderAuthOnDiskSync(provider);\n}\n\nexport async function isProviderConfigured(provider: string): Promise<boolean> {\n // Check registry first for custom providers (from models.json)\n const registry = getModelRegistry();\n if (registry.getApiKey(provider)) {\n return true;\n }\n return await hasCredentials(provider);\n}\n\n/** Where runtime {@link getApiKey} resolves the key from (no secret values). */\nexport type ProviderActiveKeySource = 'none' | 'agent' | 'gateway' | 'oauth' | 'env' | 'models_json';\n\nexport async function getProviderActiveKeySource(provider: string): Promise<ProviderActiveKeySource> {\n const resolver = new CredentialResolver();\n const fromCredentials = await resolver.resolveApiKeySource(provider);\n if (fromCredentials === 'agent') return 'agent';\n if (fromCredentials === 'global') return 'gateway';\n if (fromCredentials === 'oauth') return 'oauth';\n if (fromCredentials === 'env') return 'env';\n\n const registry = getModelRegistry();\n if (registry.getApiKey(provider)) {\n return 'models_json';\n }\n\n return 'none';\n}\n\nexport async function getConfiguredProviders(): Promise<string[]> {\n\tconst allProviders = getAllProviders();\n\tconst configured: string[] = [];\n\tfor (const p of allProviders) {\n\t\tif (await isProviderConfigured(p)) {\n\t\t\tconfigured.push(p);\n\t\t}\n\t}\n\treturn configured;\n}\n\nexport function getAllModels(): readonly Model<Api>[] {\n\tconst registry = getModelRegistry();\n\treturn registry.getAll();\n}\n\nexport async function getAvailableModels(): Promise<readonly Model<Api>[]> {\n\tconst registry = getModelRegistry();\n\tconst allModels = registry.getAll();\n\t\n\t// Filter models by checking if provider has auth configured\n\tconst available: Model<Api>[] = [];\n\tfor (const model of allModels) {\n\t\tif (await isProviderConfigured(model.provider)) {\n\t\t\tavailable.push(model);\n\t\t}\n\t}\n\treturn available;\n}\n\nexport type { Model, Api } from '@mariozechner/pi-ai';\n\nexport type ProviderCategory = 'common' | 'specialty' | 'oauth' | 'enterprise';\n\nexport interface ProviderMeta {\n name: string;\n category: ProviderCategory;\n supportsOAuth?: boolean;\n supportsApiKey?: boolean;\n}\n\nexport const PROVIDER_META: Record<string, ProviderMeta> = {\n 'openai': { name: 'OpenAI (GPT-4, o1, o3)', category: 'common', supportsApiKey: true },\n 'anthropic': { name: 'Anthropic Claude', category: 'common', supportsApiKey: true, supportsOAuth: true },\n 'google': { name: 'Google Gemini', category: 'common', supportsApiKey: true },\n 'groq': { name: 'Groq (Fast Inference)', category: 'common', supportsApiKey: true },\n 'minimax': { name: 'MiniMax', category: 'common', supportsApiKey: true, supportsOAuth: true },\n 'minimax-cn': { name: 'MiniMax CN', category: 'common', supportsApiKey: true, supportsOAuth: true },\n 'kimi-coding': { name: 'Kimi For Coding', category: 'common', supportsApiKey: true, supportsOAuth: true },\n 'xai': { name: 'xAI (Grok)', category: 'specialty', supportsApiKey: true },\n 'mistral': { name: 'Mistral AI', category: 'specialty', supportsApiKey: true },\n 'cerebras': { name: 'Cerebras', category: 'specialty', supportsApiKey: true },\n 'openrouter': { name: 'OpenRouter (Multi-provider)', category: 'specialty', supportsApiKey: true },\n 'huggingface': { name: 'Hugging Face', category: 'specialty', supportsApiKey: true },\n 'opencode': { name: 'OpenCode', category: 'specialty', supportsApiKey: true },\n 'opencode-go': { name: 'OpenCode Go', category: 'specialty', supportsApiKey: true },\n /** DashScope (Alibaba) — image, speech, STT; not an LLM KnownProvider. */\n 'dashscope': { name: 'DashScope (Alibaba)', category: 'specialty', supportsApiKey: true },\n /** International GLM (api.z.ai). Auth: API key (ZAI_API_KEY); no published OAuth for this HTTP API. */\n 'zai': { name: 'Zhipu GLM (International · z.ai)', category: 'common', supportsApiKey: true },\n 'amazon-bedrock': { name: 'Amazon Bedrock', category: 'enterprise', supportsApiKey: true },\n 'azure-openai-responses': { name: 'Azure OpenAI', category: 'enterprise', supportsApiKey: true },\n 'google-vertex': { name: 'Google Vertex AI', category: 'enterprise', supportsApiKey: true },\n 'vercel-ai-gateway': { name: 'Vercel AI Gateway', category: 'enterprise', supportsApiKey: true },\n 'github-copilot': { name: 'GitHub Copilot (OAuth)', category: 'oauth', supportsOAuth: true },\n 'openai-codex': { name: 'OpenAI Codex (OAuth)', category: 'oauth', supportsOAuth: true },\n 'google-gemini-cli': { name: 'Google Gemini CLI (OAuth)', category: 'oauth', supportsOAuth: true },\n 'google-antigravity': { name: 'Google Antigravity (OAuth)', category: 'oauth', supportsOAuth: true },\n};\n\nexport function getSortedProviders(): string[] {\n const all = getAllProviders();\n const catOrder: Record<ProviderCategory, number> = { common: 0, specialty: 1, enterprise: 2, oauth: 3 };\n \n return [...all].sort((a, b) => {\n const catA = PROVIDER_META[a]?.category ?? 'specialty';\n const catB = PROVIDER_META[b]?.category ?? 'specialty';\n if (catOrder[catA] !== catOrder[catB]) {\n return catOrder[catA] - catOrder[catB];\n }\n return a.localeCompare(b);\n });\n}\n\nexport function getProviderDisplayName(provider: string): string {\n return PROVIDER_META[provider]?.name || provider;\n}\n\nexport function providerSupportsOAuth(provider: string): boolean {\n return PROVIDER_META[provider]?.supportsOAuth ?? false;\n}\n\nexport function providerSupportsApiKey(provider: string): boolean {\n return PROVIDER_META[provider]?.supportsApiKey ?? true;\n}\n\n// ============================================\n// Dynamic Default Model Resolution\n// ============================================\n\n/**\n * Get a default model reference.\n * Priority:\n * 1. First available model with configured API key\n * 2. First model from pi-ai catalog\n * 3. Fallback to anthropic/claude-sonnet-4-5 as last resort\n */\nexport async function getDefaultModel(config?: Config | null | undefined): Promise<string> {\n const availableModels = await getAvailableModels();\n \n // Try to find configured default model first\n const defaultModel = config?.agents?.defaults?.model;\n if (defaultModel) {\n const modelRef = typeof defaultModel === 'string' ? defaultModel : defaultModel.primary;\n if (modelRef) {\n // Check if the configured model has valid API key\n const configured = availableModels.find(m => \n `${m.provider}/${m.id}` === modelRef ||\n m.id === modelRef\n );\n if (configured) {\n return `${configured.provider}/${configured.id}`;\n }\n }\n }\n \n // Return first available model\n if (availableModels.length > 0) {\n return `${availableModels[0].provider}/${availableModels[0].id}`;\n }\n \n // Try to get first model from pi-ai catalog\n for (const provider of getPiAiProviders()) {\n try {\n const models = getPiAiModels(provider);\n if (models.length > 0) {\n return `${provider}/${models[0].id}`;\n }\n } catch {\n continue;\n }\n }\n \n // Last resort fallback\n return 'anthropic/claude-sonnet-4-5';\n}\n\n/**\n * Synchronous default model resolution for constructors and sync code paths.\n * Uses catalog/registry only (no async credential checks).\n */\nexport function getDefaultModelSync(config?: Config | null | undefined): string {\n const defaultModel = config?.agents?.defaults?.model;\n if (defaultModel) {\n const modelRef = typeof defaultModel === 'string' ? defaultModel : defaultModel.primary;\n if (modelRef) {\n return modelRef;\n }\n }\n const all = getAllModels();\n if (all.length > 0) {\n return `${all[0].provider}/${all[0].id}`;\n }\n for (const provider of getPiAiProviders()) {\n try {\n const models = getPiAiModels(provider);\n if (models.length > 0) {\n return `${provider}/${models[0].id}`;\n }\n } catch {\n continue;\n }\n }\n return 'anthropic/claude-sonnet-4-5';\n}\n\n// Re-export ModelRegistry for advanced use cases\nexport { ModelRegistry, getModelRegistry, resetModelRegistry } from './model-registry.js';\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["getPiAiModel","getPiAiProviders","getPiAiModels"],"sources":["../../../src/providers/index.ts"],"sourcesContent":["/**\n * Model provider module - integrates built-in models with custom models from models.json\n */\n\nimport {\n\tgetModel as getPiAiModel,\n\tgetModels as getPiAiModels,\n\tgetProviders as getPiAiProviders,\n\ttype Model,\n\ttype Api,\n} from '@mariozechner/pi-ai';\nimport type { Config } from '../config/schema.js';\nimport { getModelRegistry } from './model-registry.js';\nimport { CredentialResolver, resolveApiKey, hasCredentials } from '../auth/credentials.js';\nimport { hasProviderAuthOnDiskSync } from '../auth/sync-provider-auth.js';\nimport { getApiKeyFromEnv } from './env-keys.js';\nimport { getProviderRegistry } from './plugin-registry.js';\nimport type { ProviderModelDefinition } from '../extensions/types/providers.js';\n\nexport { getApiKeyFromEnv, PROVIDER_ENV_MAP } from './env-keys.js';\n\n/** Sentinel base URL: model is served by an extension {@link ProviderPluginRegistry} provider. */\nexport const EXTENSION_PROVIDER_BASE_URL = 'extension://provider-plugin';\n\n/** Map a plugin registry model to the pi-ai {@link Model} shape. */\nexport function pluginModelToModel(providerId: string, definition: ProviderModelDefinition): Model<Api> {\n\treturn {\n\t\tprovider: providerId,\n\t\tid: definition.id,\n\t\tname: definition.name,\n\t\tapi: 'openai-completions' as Api,\n\t\tbaseUrl: EXTENSION_PROVIDER_BASE_URL,\n\t\treasoning: false,\n\t\tinput: definition.supportsImages ? (['text', 'image'] as ('text' | 'image')[]) : (['text'] as ('text' | 'image')[]),\n\t\tcontextWindow: definition.contextWindow ?? 128000,\n\t\tmaxTokens: definition.maxOutputTokens ?? 4096,\n\t\tcost: {\n\t\t\tinput: definition.pricing?.input ?? 0,\n\t\t\toutput: definition.pricing?.output ?? 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t},\n\t} as Model<Api>;\n}\n\n/**\n * Get API key synchronously: checks registry (models.json) first, then environment variables.\n * Use this for Agent's getApiKey callback which must be synchronous.\n */\nexport function getApiKeySync(provider: string): string | undefined {\n const pluginRegistry = getProviderRegistry();\n if (pluginRegistry.has(provider)) return 'extension-managed';\n\n const registry = getModelRegistry();\n const registryKey = registry.getApiKey(provider);\n if (registryKey) {\n return registryKey;\n }\n return getApiKeyFromEnv(provider);\n}\n\n/**\n * Resolve model reference. Supports:\n * - \"provider/modelId\" format\n * - \"modelId\" auto-detection via pi-ai or custom models\n * @throws if model not found\n */\nexport function resolveModel(ref: string): Model<Api> {\n\t// First try ModelRegistry (includes custom models)\n\tconst registry = getModelRegistry();\n\tconst customModel = registry.resolve(ref);\n\tif (customModel) {\n\t\treturn customModel;\n\t}\n\n\tif (ref.includes('/')) {\n\t\tconst [provider, modelId] = ref.split('/');\n\t\tconst piAiModel = getPiAiModel(provider as any, modelId as any);\n\t\tif (piAiModel) return piAiModel as Model<Api>;\n\n\t\tconst pluginRegistry = getProviderRegistry();\n\t\tconst plugin = pluginRegistry.get(provider);\n\t\tif (plugin) {\n\t\t\tconst pluginModel = plugin.models.find(m => m.id === modelId);\n\t\t\tif (pluginModel) return pluginModelToModel(provider, pluginModel);\n\t\t}\n\t\tthrow new Error(`Model not found: ${ref}`);\n\t}\n\n\tfor (const provider of getPiAiProviders()) {\n\t\ttry {\n\t\t\tconst models = getPiAiModels(provider);\n\t\t\tconst found = models.find(m => m.id === ref);\n\t\t\tif (found) return found as Model<Api>;\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t}\n\n\tconst pluginRegistry = getProviderRegistry();\n\tfor (const plugin of pluginRegistry.listAll()) {\n\t\tconst found = plugin.models.find(m => m.id === ref);\n\t\tif (found) return pluginModelToModel(plugin.id, found);\n\t}\n\n\tthrow new Error(`Model not found: ${ref}. Use format: provider/model-id`);\n}\n\nexport function getModelsByProvider(provider: string): readonly Model<Api>[] {\n\tconst registry = getModelRegistry();\n\tconst fromRegistry = registry.getAll().filter(m => m.provider === provider);\n\tconst plugin = getProviderRegistry().get(provider);\n\tif (!plugin) return fromRegistry;\n\tconst pluginModels = plugin.models.map(m => pluginModelToModel(provider, m));\n\treturn [...fromRegistry, ...pluginModels];\n}\n\nexport function getAllProviders(): string[] {\n\tconst registry = getModelRegistry();\n\tconst providers = new Set<string>();\n\n\t// Add built-in providers\n\tfor (const p of getPiAiProviders()) {\n\t\tproviders.add(p);\n\t}\n\n\t// Add custom providers from registry\n\tfor (const m of registry.getAll()) {\n\t\tproviders.add(m.provider);\n\t}\n\n\tfor (const plugin of getProviderRegistry().listAll()) {\n\t\tproviders.add(plugin.id);\n\t}\n\n\treturn Array.from(providers);\n}\n\nexport async function getApiKey(provider: string): Promise<string | undefined> {\n\tif (getProviderRegistry().has(provider)) return 'extension-managed';\n\n\t// Use new credential resolver first (checks: agent private > global > oauth > env)\n\tconst credentialKey = await resolveApiKey(provider);\n\tif (credentialKey) {\n\t\treturn credentialKey;\n\t}\n\n\t// Check registry for custom providers (from models.json)\n\tconst registry = getModelRegistry();\n\tconst registryKey = registry.getApiKey(provider);\n\tif (registryKey) {\n\t\treturn registryKey;\n\t}\n\n\t// Fallback to environment variables\n\treturn getApiKeyFromEnv(provider);\n}\n\n/**\n * Synchronous version for use in non-async contexts\n * Only checks environment variables and registry, not credential system\n */\nexport function isProviderConfiguredSync(provider: string): boolean {\n\tif (getProviderRegistry().has(provider)) return true;\n\n\t// Check registry for custom providers\n\tconst registry = getModelRegistry();\n\tif (registry.getApiKey(provider)) {\n\t\treturn true;\n\t}\n\t// Check environment variables\n\tif (getApiKeyFromEnv(provider)) {\n\t\treturn true;\n\t}\n\t// Gateway UI / CLI store keys in auth-profiles.json (async CredentialResolver); sync path for fallback list\n\treturn hasProviderAuthOnDiskSync(provider);\n}\n\nexport async function isProviderConfigured(provider: string): Promise<boolean> {\n if (getProviderRegistry().has(provider)) return true;\n\n // Check registry first for custom providers (from models.json)\n const registry = getModelRegistry();\n if (registry.getApiKey(provider)) {\n return true;\n }\n return await hasCredentials(provider);\n}\n\n/** Where runtime {@link getApiKey} resolves the key from (no secret values). */\nexport type ProviderActiveKeySource = 'none' | 'agent' | 'gateway' | 'oauth' | 'env' | 'models_json' | 'extension';\n\nexport async function getProviderActiveKeySource(provider: string): Promise<ProviderActiveKeySource> {\n if (getProviderRegistry().has(provider)) return 'extension';\n\n const resolver = new CredentialResolver();\n const fromCredentials = await resolver.resolveApiKeySource(provider);\n if (fromCredentials === 'agent') return 'agent';\n if (fromCredentials === 'global') return 'gateway';\n if (fromCredentials === 'oauth') return 'oauth';\n if (fromCredentials === 'env') return 'env';\n\n const registry = getModelRegistry();\n if (registry.getApiKey(provider)) {\n return 'models_json';\n }\n\n return 'none';\n}\n\nexport async function getConfiguredProviders(): Promise<string[]> {\n\tconst allProviders = getAllProviders();\n\tconst configured: string[] = [];\n\tfor (const p of allProviders) {\n\t\tif (await isProviderConfigured(p)) {\n\t\t\tconfigured.push(p);\n\t\t}\n\t}\n\treturn configured;\n}\n\nexport function getAllModels(): readonly Model<Api>[] {\n\tconst registry = getModelRegistry();\n\tconst registryModels = registry.getAll();\n\tconst pluginProviders = getProviderRegistry().listAll();\n\tif (pluginProviders.length === 0) return registryModels;\n\n\tconst existingIds = new Set(registryModels.map(m => `${m.provider}/${m.id}`));\n\tconst merged: Model<Api>[] = [...registryModels];\n\tfor (const plugin of pluginProviders) {\n\t\tfor (const model of plugin.models) {\n\t\t\tconst compositeId = `${plugin.id}/${model.id}`;\n\t\t\tif (!existingIds.has(compositeId)) {\n\t\t\t\tmerged.push(pluginModelToModel(plugin.id, model));\n\t\t\t\texistingIds.add(compositeId);\n\t\t\t}\n\t\t}\n\t}\n\treturn merged;\n}\n\nexport async function getAvailableModels(): Promise<readonly Model<Api>[]> {\n\tconst allModels = getAllModels();\n\tconst pluginRegistry = getProviderRegistry();\n\tconst available: Model<Api>[] = [];\n\n\tfor (const model of allModels) {\n\t\tif (pluginRegistry.has(model.provider)) {\n\t\t\tavailable.push(model);\n\t\t} else if (await isProviderConfigured(model.provider)) {\n\t\t\tavailable.push(model);\n\t\t}\n\t}\n\treturn available;\n}\n\nexport type { Model, Api } from '@mariozechner/pi-ai';\n\nexport type ProviderCategory = 'common' | 'specialty' | 'oauth' | 'enterprise' | 'extension';\n\nexport interface ProviderMeta {\n name: string;\n category: ProviderCategory;\n supportsOAuth?: boolean;\n supportsApiKey?: boolean;\n}\n\nexport const PROVIDER_META: Record<string, ProviderMeta> = {\n 'openai': { name: 'OpenAI (GPT-4, o1, o3)', category: 'common', supportsApiKey: true },\n 'anthropic': { name: 'Anthropic Claude', category: 'common', supportsApiKey: true, supportsOAuth: true },\n 'google': { name: 'Google Gemini', category: 'common', supportsApiKey: true },\n 'groq': { name: 'Groq (Fast Inference)', category: 'common', supportsApiKey: true },\n 'minimax': { name: 'MiniMax', category: 'common', supportsApiKey: true, supportsOAuth: true },\n 'minimax-cn': { name: 'MiniMax CN', category: 'common', supportsApiKey: true, supportsOAuth: true },\n 'kimi-coding': { name: 'Kimi For Coding', category: 'common', supportsApiKey: true, supportsOAuth: true },\n 'xai': { name: 'xAI (Grok)', category: 'specialty', supportsApiKey: true },\n 'mistral': { name: 'Mistral AI', category: 'specialty', supportsApiKey: true },\n 'cerebras': { name: 'Cerebras', category: 'specialty', supportsApiKey: true },\n 'openrouter': { name: 'OpenRouter (Multi-provider)', category: 'specialty', supportsApiKey: true },\n 'huggingface': { name: 'Hugging Face', category: 'specialty', supportsApiKey: true },\n 'opencode': { name: 'OpenCode', category: 'specialty', supportsApiKey: true },\n 'opencode-go': { name: 'OpenCode Go', category: 'specialty', supportsApiKey: true },\n /** DashScope (Alibaba) — image, speech, STT; not an LLM KnownProvider. */\n 'dashscope': { name: 'DashScope (Alibaba)', category: 'specialty', supportsApiKey: true },\n /** International GLM (api.z.ai). Auth: API key (ZAI_API_KEY); no published OAuth for this HTTP API. */\n 'zai': { name: 'Zhipu GLM (International · z.ai)', category: 'common', supportsApiKey: true },\n 'amazon-bedrock': { name: 'Amazon Bedrock', category: 'enterprise', supportsApiKey: true },\n 'azure-openai-responses': { name: 'Azure OpenAI', category: 'enterprise', supportsApiKey: true },\n 'google-vertex': { name: 'Google Vertex AI', category: 'enterprise', supportsApiKey: true },\n 'vercel-ai-gateway': { name: 'Vercel AI Gateway', category: 'enterprise', supportsApiKey: true },\n 'github-copilot': { name: 'GitHub Copilot (OAuth)', category: 'oauth', supportsOAuth: true },\n 'openai-codex': { name: 'OpenAI Codex (OAuth)', category: 'oauth', supportsOAuth: true },\n 'google-gemini-cli': { name: 'Google Gemini CLI (OAuth)', category: 'oauth', supportsOAuth: true },\n 'google-antigravity': { name: 'Google Antigravity (OAuth)', category: 'oauth', supportsOAuth: true },\n};\n\nexport function getSortedProviders(): string[] {\n const all = getAllProviders();\n const catOrder: Record<ProviderCategory, number> = { common: 0, specialty: 1, enterprise: 2, oauth: 3, extension: 4 };\n const pluginRegistry = getProviderRegistry();\n\n return [...all].sort((a, b) => {\n const catA = pluginRegistry.has(a) ? 'extension' : (PROVIDER_META[a]?.category ?? 'specialty');\n const catB = pluginRegistry.has(b) ? 'extension' : (PROVIDER_META[b]?.category ?? 'specialty');\n if (catOrder[catA] !== catOrder[catB]) {\n return catOrder[catA] - catOrder[catB];\n }\n return a.localeCompare(b);\n });\n}\n\nexport function getProviderDisplayName(provider: string): string {\n const plugin = getProviderRegistry().get(provider);\n if (plugin) return plugin.name;\n return PROVIDER_META[provider]?.name || provider;\n}\n\nexport function providerSupportsOAuth(provider: string): boolean {\n return PROVIDER_META[provider]?.supportsOAuth ?? false;\n}\n\nexport function providerSupportsApiKey(provider: string): boolean {\n return PROVIDER_META[provider]?.supportsApiKey ?? true;\n}\n\n// ============================================\n// Dynamic Default Model Resolution\n// ============================================\n\n/**\n * Get a default model reference.\n * Priority:\n * 1. First available model with configured API key\n * 2. First model from pi-ai catalog\n * 3. Fallback to anthropic/claude-sonnet-4-5 as last resort\n */\nexport async function getDefaultModel(config?: Config | null | undefined): Promise<string> {\n const availableModels = await getAvailableModels();\n \n // Try to find configured default model first\n const defaultModel = config?.agents?.defaults?.model;\n if (defaultModel) {\n const modelRef = typeof defaultModel === 'string' ? defaultModel : defaultModel.primary;\n if (modelRef) {\n // Check if the configured model has valid API key\n const configured = availableModels.find(m => \n `${m.provider}/${m.id}` === modelRef ||\n m.id === modelRef\n );\n if (configured) {\n return `${configured.provider}/${configured.id}`;\n }\n }\n }\n \n // Return first available model\n if (availableModels.length > 0) {\n return `${availableModels[0].provider}/${availableModels[0].id}`;\n }\n \n // Try to get first model from pi-ai catalog\n for (const provider of getPiAiProviders()) {\n try {\n const models = getPiAiModels(provider);\n if (models.length > 0) {\n return `${provider}/${models[0].id}`;\n }\n } catch {\n continue;\n }\n }\n \n // Last resort fallback\n return 'anthropic/claude-sonnet-4-5';\n}\n\n/**\n * Synchronous default model resolution for constructors and sync code paths.\n * Uses catalog/registry only (no async credential checks).\n */\nexport function getDefaultModelSync(config?: Config | null | undefined): string {\n const defaultModel = config?.agents?.defaults?.model;\n if (defaultModel) {\n const modelRef = typeof defaultModel === 'string' ? defaultModel : defaultModel.primary;\n if (modelRef) {\n return modelRef;\n }\n }\n const all = getAllModels();\n if (all.length > 0) {\n return `${all[0].provider}/${all[0].id}`;\n }\n for (const provider of getPiAiProviders()) {\n try {\n const models = getPiAiModels(provider);\n if (models.length > 0) {\n return `${provider}/${models[0].id}`;\n }\n } catch {\n continue;\n }\n }\n return 'anthropic/claude-sonnet-4-5';\n}\n\n// Re-export ModelRegistry for advanced use cases\nexport { ModelRegistry, getModelRegistry, resetModelRegistry } from './model-registry.js';\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
2
  import { createLogger } from "../utils/logger/index.js";
3
3
  import { init_logger } from "../utils/logger.js";
4
+ import { getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
4
5
  import { resolveModelsJsonPath } from "../config/paths.js";
5
6
  import { init_resolve_config_value, resolveConfigValue, resolveHeaders } from "../config/resolve-config-value.js";
6
7
  import { getDefaultModelValues, init_models_json, validateModelsConfig } from "../config/models-json.js";
7
- import { getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
8
8
  import { existsSync, readFileSync } from "fs";
9
9
  import { getModels, getProviders } from "@mariozechner/pi-ai";
10
10
  //#region src/providers/model-registry.ts
@@ -1,92 +1,7 @@
1
+ import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
1
2
  import { createLogger } from "../utils/logger/index.js";
2
3
  import { init_logger } from "../utils/logger.js";
3
4
  //#region src/providers/plugin-registry.ts
4
- init_logger();
5
- const log = createLogger("Provider:Registry");
6
- var ProviderPluginRegistry = class {
7
- providers = /* @__PURE__ */ new Map();
8
- /**
9
- * Register a new provider
10
- */
11
- register(provider) {
12
- if (this.providers.has(provider.id)) log.warn(`Provider "${provider.id}" already registered, overwriting`);
13
- if (!provider.id) throw new Error("Provider must have an id");
14
- if (!provider.name) throw new Error("Provider must have a name");
15
- if (!provider.createStream || typeof provider.createStream !== "function") throw new Error("Provider must implement createStream method");
16
- this.providers.set(provider.id, provider);
17
- log.info(`Registered provider: ${provider.name} (${provider.id})`);
18
- }
19
- /**
20
- * Get a provider by ID
21
- */
22
- get(id) {
23
- return this.providers.get(id);
24
- }
25
- /**
26
- * List all registered providers
27
- */
28
- listAll() {
29
- return Array.from(this.providers.values());
30
- }
31
- /**
32
- * Get models for a specific provider
33
- */
34
- getModels(providerId) {
35
- return this.providers.get(providerId)?.models || [];
36
- }
37
- /**
38
- * Check if a provider is registered
39
- */
40
- has(id) {
41
- return this.providers.has(id);
42
- }
43
- /**
44
- * Unregister a provider
45
- */
46
- unregister(id) {
47
- const deleted = this.providers.delete(id);
48
- if (deleted) log.info(`Unregistered provider: ${id}`);
49
- return deleted;
50
- }
51
- /**
52
- * Get all available model IDs across all providers
53
- */
54
- getAllModelIds() {
55
- const modelIds = [];
56
- for (const provider of this.providers.values()) for (const model of provider.models) modelIds.push(`${provider.id}:${model.id}`);
57
- return modelIds;
58
- }
59
- /**
60
- * Find a model across all providers
61
- */
62
- findModel(modelId) {
63
- if (modelId.includes(":")) {
64
- const [providerId, actualModelId] = modelId.split(":");
65
- const provider = this.providers.get(providerId);
66
- if (provider) {
67
- const model = provider.models.find((m) => m.id === actualModelId);
68
- if (model) return {
69
- provider,
70
- model
71
- };
72
- }
73
- }
74
- for (const provider of this.providers.values()) {
75
- const model = provider.models.find((m) => m.id === modelId);
76
- if (model) return {
77
- provider,
78
- model
79
- };
80
- }
81
- }
82
- /**
83
- * Get provider by model ID
84
- */
85
- getProviderForModel(modelId) {
86
- return this.findModel(modelId)?.provider;
87
- }
88
- };
89
- let globalRegistry = null;
90
5
  function getProviderRegistry() {
91
6
  if (!globalRegistry) globalRegistry = new ProviderPluginRegistry();
92
7
  return globalRegistry;
@@ -94,7 +9,97 @@ function getProviderRegistry() {
94
9
  function setProviderRegistry(registry) {
95
10
  globalRegistry = registry;
96
11
  }
12
+ var log, ProviderPluginRegistry, globalRegistry;
13
+ var init_plugin_registry = __esmMin((() => {
14
+ init_logger();
15
+ log = createLogger("Provider:Registry");
16
+ ProviderPluginRegistry = class {
17
+ providers = /* @__PURE__ */ new Map();
18
+ /**
19
+ * Register a new provider
20
+ */
21
+ register(provider) {
22
+ if (this.providers.has(provider.id)) log.warn(`Provider "${provider.id}" already registered, overwriting`);
23
+ if (!provider.id) throw new Error("Provider must have an id");
24
+ if (!provider.name) throw new Error("Provider must have a name");
25
+ if (!provider.createStream || typeof provider.createStream !== "function") throw new Error("Provider must implement createStream method");
26
+ this.providers.set(provider.id, provider);
27
+ log.info(`Registered provider: ${provider.name} (${provider.id})`);
28
+ }
29
+ /**
30
+ * Get a provider by ID
31
+ */
32
+ get(id) {
33
+ return this.providers.get(id);
34
+ }
35
+ /**
36
+ * List all registered providers
37
+ */
38
+ listAll() {
39
+ return Array.from(this.providers.values());
40
+ }
41
+ /**
42
+ * Get models for a specific provider
43
+ */
44
+ getModels(providerId) {
45
+ return this.providers.get(providerId)?.models || [];
46
+ }
47
+ /**
48
+ * Check if a provider is registered
49
+ */
50
+ has(id) {
51
+ return this.providers.has(id);
52
+ }
53
+ /**
54
+ * Unregister a provider
55
+ */
56
+ unregister(id) {
57
+ const deleted = this.providers.delete(id);
58
+ if (deleted) log.info(`Unregistered provider: ${id}`);
59
+ return deleted;
60
+ }
61
+ /**
62
+ * Get all available model IDs across all providers
63
+ */
64
+ getAllModelIds() {
65
+ const modelIds = [];
66
+ for (const provider of this.providers.values()) for (const model of provider.models) modelIds.push(`${provider.id}:${model.id}`);
67
+ return modelIds;
68
+ }
69
+ /**
70
+ * Find a model across all providers
71
+ */
72
+ findModel(modelId) {
73
+ if (modelId.includes(":")) {
74
+ const [providerId, actualModelId] = modelId.split(":");
75
+ const provider = this.providers.get(providerId);
76
+ if (provider) {
77
+ const model = provider.models.find((m) => m.id === actualModelId);
78
+ if (model) return {
79
+ provider,
80
+ model
81
+ };
82
+ }
83
+ }
84
+ for (const provider of this.providers.values()) {
85
+ const model = provider.models.find((m) => m.id === modelId);
86
+ if (model) return {
87
+ provider,
88
+ model
89
+ };
90
+ }
91
+ }
92
+ /**
93
+ * Get provider by model ID
94
+ */
95
+ getProviderForModel(modelId) {
96
+ return this.findModel(modelId)?.provider;
97
+ }
98
+ };
99
+ globalRegistry = null;
100
+ }));
97
101
  //#endregion
98
- export { ProviderPluginRegistry, getProviderRegistry, setProviderRegistry };
102
+ init_plugin_registry();
103
+ export { ProviderPluginRegistry, getProviderRegistry, init_plugin_registry, setProviderRegistry };
99
104
 
100
105
  //# sourceMappingURL=plugin-registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-registry.js","names":[],"sources":["../../../src/providers/plugin-registry.ts"],"sourcesContent":["/**\n * Provider Plugin Registry\n * \n * Registry for managing plugin-based LLM providers.\n */\n\nimport type { ProviderPlugin, ProviderRegistry, ProviderModelDefinition } from '../extensions/types/providers.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst log = createLogger('Provider:Registry');\n\n// ============================================================================\n// Provider Plugin Registry Implementation\n// ============================================================================\n\nexport class ProviderPluginRegistry implements ProviderRegistry {\n private providers = new Map<string, ProviderPlugin>();\n\n /**\n * Register a new provider\n */\n register(provider: ProviderPlugin): void {\n if (this.providers.has(provider.id)) {\n log.warn(`Provider \"${provider.id}\" already registered, overwriting`);\n }\n \n // Validate provider\n if (!provider.id) {\n throw new Error('Provider must have an id');\n }\n if (!provider.name) {\n throw new Error('Provider must have a name');\n }\n if (!provider.createStream || typeof provider.createStream !== 'function') {\n throw new Error('Provider must implement createStream method');\n }\n \n this.providers.set(provider.id, provider);\n log.info(`Registered provider: ${provider.name} (${provider.id})`);\n }\n\n /**\n * Get a provider by ID\n */\n get(id: string): ProviderPlugin | undefined {\n return this.providers.get(id);\n }\n\n /**\n * List all registered providers\n */\n listAll(): ProviderPlugin[] {\n return Array.from(this.providers.values());\n }\n\n /**\n * Get models for a specific provider\n */\n getModels(providerId: string): ProviderModelDefinition[] {\n const provider = this.providers.get(providerId);\n return provider?.models || [];\n }\n\n /**\n * Check if a provider is registered\n */\n has(id: string): boolean {\n return this.providers.has(id);\n }\n\n /**\n * Unregister a provider\n */\n unregister(id: string): boolean {\n const deleted = this.providers.delete(id);\n if (deleted) {\n log.info(`Unregistered provider: ${id}`);\n }\n return deleted;\n }\n\n /**\n * Get all available model IDs across all providers\n */\n getAllModelIds(): string[] {\n const modelIds: string[] = [];\n for (const provider of this.providers.values()) {\n for (const model of provider.models) {\n modelIds.push(`${provider.id}:${model.id}`);\n }\n }\n return modelIds;\n }\n\n /**\n * Find a model across all providers\n */\n findModel(modelId: string): { provider: ProviderPlugin; model: ProviderModelDefinition } | undefined {\n // Check if it's prefixed with provider:model\n if (modelId.includes(':')) {\n const [providerId, actualModelId] = modelId.split(':');\n const provider = this.providers.get(providerId);\n if (provider) {\n const model = provider.models.find(m => m.id === actualModelId);\n if (model) {\n return { provider, model };\n }\n }\n }\n \n // Search across all providers\n for (const provider of this.providers.values()) {\n const model = provider.models.find(m => m.id === modelId);\n if (model) {\n return { provider, model };\n }\n }\n \n return undefined;\n }\n\n /**\n * Get provider by model ID\n */\n getProviderForModel(modelId: string): ProviderPlugin | undefined {\n return this.findModel(modelId)?.provider;\n }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet globalRegistry: ProviderPluginRegistry | null = null;\n\nexport function getProviderRegistry(): ProviderPluginRegistry {\n if (!globalRegistry) {\n globalRegistry = new ProviderPluginRegistry();\n }\n return globalRegistry;\n}\n\nexport function setProviderRegistry(registry: ProviderPluginRegistry): void {\n globalRegistry = registry;\n}\n"],"mappings":";;;aAOkD;AAElD,MAAM,MAAM,aAAa,oBAAoB;AAM7C,IAAa,yBAAb,MAAgE;CAC9D,4BAAoB,IAAI,KAA6B;;;;CAKrD,SAAS,UAAgC;AACvC,MAAI,KAAK,UAAU,IAAI,SAAS,GAAG,CACjC,KAAI,KAAK,aAAa,SAAS,GAAG,mCAAmC;AAIvE,MAAI,CAAC,SAAS,GACZ,OAAM,IAAI,MAAM,2BAA2B;AAE7C,MAAI,CAAC,SAAS,KACZ,OAAM,IAAI,MAAM,4BAA4B;AAE9C,MAAI,CAAC,SAAS,gBAAgB,OAAO,SAAS,iBAAiB,WAC7D,OAAM,IAAI,MAAM,8CAA8C;AAGhE,OAAK,UAAU,IAAI,SAAS,IAAI,SAAS;AACzC,MAAI,KAAK,wBAAwB,SAAS,KAAK,IAAI,SAAS,GAAG,GAAG;;;;;CAMpE,IAAI,IAAwC;AAC1C,SAAO,KAAK,UAAU,IAAI,GAAG;;;;;CAM/B,UAA4B;AAC1B,SAAO,MAAM,KAAK,KAAK,UAAU,QAAQ,CAAC;;;;;CAM5C,UAAU,YAA+C;AAEvD,SADiB,KAAK,UAAU,IAAI,WAAW,EAC9B,UAAU,EAAE;;;;;CAM/B,IAAI,IAAqB;AACvB,SAAO,KAAK,UAAU,IAAI,GAAG;;;;;CAM/B,WAAW,IAAqB;EAC9B,MAAM,UAAU,KAAK,UAAU,OAAO,GAAG;AACzC,MAAI,QACF,KAAI,KAAK,0BAA0B,KAAK;AAE1C,SAAO;;;;;CAMT,iBAA2B;EACzB,MAAM,WAAqB,EAAE;AAC7B,OAAK,MAAM,YAAY,KAAK,UAAU,QAAQ,CAC5C,MAAK,MAAM,SAAS,SAAS,OAC3B,UAAS,KAAK,GAAG,SAAS,GAAG,GAAG,MAAM,KAAK;AAG/C,SAAO;;;;;CAMT,UAAU,SAA2F;AAEnG,MAAI,QAAQ,SAAS,IAAI,EAAE;GACzB,MAAM,CAAC,YAAY,iBAAiB,QAAQ,MAAM,IAAI;GACtD,MAAM,WAAW,KAAK,UAAU,IAAI,WAAW;AAC/C,OAAI,UAAU;IACZ,MAAM,QAAQ,SAAS,OAAO,MAAK,MAAK,EAAE,OAAO,cAAc;AAC/D,QAAI,MACF,QAAO;KAAE;KAAU;KAAO;;;AAMhC,OAAK,MAAM,YAAY,KAAK,UAAU,QAAQ,EAAE;GAC9C,MAAM,QAAQ,SAAS,OAAO,MAAK,MAAK,EAAE,OAAO,QAAQ;AACzD,OAAI,MACF,QAAO;IAAE;IAAU;IAAO;;;;;;CAUhC,oBAAoB,SAA6C;AAC/D,SAAO,KAAK,UAAU,QAAQ,EAAE;;;AAQpC,IAAI,iBAAgD;AAEpD,SAAgB,sBAA8C;AAC5D,KAAI,CAAC,eACH,kBAAiB,IAAI,wBAAwB;AAE/C,QAAO;;AAGT,SAAgB,oBAAoB,UAAwC;AAC1E,kBAAiB"}
1
+ {"version":3,"file":"plugin-registry.js","names":[],"sources":["../../../src/providers/plugin-registry.ts"],"sourcesContent":["/**\n * Provider Plugin Registry\n * \n * Registry for managing plugin-based LLM providers.\n */\n\nimport type { ProviderPlugin, ProviderRegistry, ProviderModelDefinition } from '../extensions/types/providers.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst log = createLogger('Provider:Registry');\n\n// ============================================================================\n// Provider Plugin Registry Implementation\n// ============================================================================\n\nexport class ProviderPluginRegistry implements ProviderRegistry {\n private providers = new Map<string, ProviderPlugin>();\n\n /**\n * Register a new provider\n */\n register(provider: ProviderPlugin): void {\n if (this.providers.has(provider.id)) {\n log.warn(`Provider \"${provider.id}\" already registered, overwriting`);\n }\n \n // Validate provider\n if (!provider.id) {\n throw new Error('Provider must have an id');\n }\n if (!provider.name) {\n throw new Error('Provider must have a name');\n }\n if (!provider.createStream || typeof provider.createStream !== 'function') {\n throw new Error('Provider must implement createStream method');\n }\n \n this.providers.set(provider.id, provider);\n log.info(`Registered provider: ${provider.name} (${provider.id})`);\n }\n\n /**\n * Get a provider by ID\n */\n get(id: string): ProviderPlugin | undefined {\n return this.providers.get(id);\n }\n\n /**\n * List all registered providers\n */\n listAll(): ProviderPlugin[] {\n return Array.from(this.providers.values());\n }\n\n /**\n * Get models for a specific provider\n */\n getModels(providerId: string): ProviderModelDefinition[] {\n const provider = this.providers.get(providerId);\n return provider?.models || [];\n }\n\n /**\n * Check if a provider is registered\n */\n has(id: string): boolean {\n return this.providers.has(id);\n }\n\n /**\n * Unregister a provider\n */\n unregister(id: string): boolean {\n const deleted = this.providers.delete(id);\n if (deleted) {\n log.info(`Unregistered provider: ${id}`);\n }\n return deleted;\n }\n\n /**\n * Get all available model IDs across all providers\n */\n getAllModelIds(): string[] {\n const modelIds: string[] = [];\n for (const provider of this.providers.values()) {\n for (const model of provider.models) {\n modelIds.push(`${provider.id}:${model.id}`);\n }\n }\n return modelIds;\n }\n\n /**\n * Find a model across all providers\n */\n findModel(modelId: string): { provider: ProviderPlugin; model: ProviderModelDefinition } | undefined {\n // Check if it's prefixed with provider:model\n if (modelId.includes(':')) {\n const [providerId, actualModelId] = modelId.split(':');\n const provider = this.providers.get(providerId);\n if (provider) {\n const model = provider.models.find(m => m.id === actualModelId);\n if (model) {\n return { provider, model };\n }\n }\n }\n \n // Search across all providers\n for (const provider of this.providers.values()) {\n const model = provider.models.find(m => m.id === modelId);\n if (model) {\n return { provider, model };\n }\n }\n \n return undefined;\n }\n\n /**\n * Get provider by model ID\n */\n getProviderForModel(modelId: string): ProviderPlugin | undefined {\n return this.findModel(modelId)?.provider;\n }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet globalRegistry: ProviderPluginRegistry | null = null;\n\nexport function getProviderRegistry(): ProviderPluginRegistry {\n if (!globalRegistry) {\n globalRegistry = new ProviderPluginRegistry();\n }\n return globalRegistry;\n}\n\nexport function setProviderRegistry(registry: ProviderPluginRegistry): void {\n globalRegistry = registry;\n}\n"],"mappings":";;;;AAuIA,SAAgB,sBAA8C;AAC5D,KAAI,CAAC,eACH,kBAAiB,IAAI,wBAAwB;AAE/C,QAAO;;AAGT,SAAgB,oBAAoB,UAAwC;AAC1E,kBAAiB;;;;cAxI+B;AAE5C,OAAM,aAAa,oBAAoB;AAMhC,0BAAb,MAAgE;EAC9D,4BAAoB,IAAI,KAA6B;;;;EAKrD,SAAS,UAAgC;AACvC,OAAI,KAAK,UAAU,IAAI,SAAS,GAAG,CACjC,KAAI,KAAK,aAAa,SAAS,GAAG,mCAAmC;AAIvE,OAAI,CAAC,SAAS,GACZ,OAAM,IAAI,MAAM,2BAA2B;AAE7C,OAAI,CAAC,SAAS,KACZ,OAAM,IAAI,MAAM,4BAA4B;AAE9C,OAAI,CAAC,SAAS,gBAAgB,OAAO,SAAS,iBAAiB,WAC7D,OAAM,IAAI,MAAM,8CAA8C;AAGhE,QAAK,UAAU,IAAI,SAAS,IAAI,SAAS;AACzC,OAAI,KAAK,wBAAwB,SAAS,KAAK,IAAI,SAAS,GAAG,GAAG;;;;;EAMpE,IAAI,IAAwC;AAC1C,UAAO,KAAK,UAAU,IAAI,GAAG;;;;;EAM/B,UAA4B;AAC1B,UAAO,MAAM,KAAK,KAAK,UAAU,QAAQ,CAAC;;;;;EAM5C,UAAU,YAA+C;AAEvD,UADiB,KAAK,UAAU,IAAI,WAAW,EAC9B,UAAU,EAAE;;;;;EAM/B,IAAI,IAAqB;AACvB,UAAO,KAAK,UAAU,IAAI,GAAG;;;;;EAM/B,WAAW,IAAqB;GAC9B,MAAM,UAAU,KAAK,UAAU,OAAO,GAAG;AACzC,OAAI,QACF,KAAI,KAAK,0BAA0B,KAAK;AAE1C,UAAO;;;;;EAMT,iBAA2B;GACzB,MAAM,WAAqB,EAAE;AAC7B,QAAK,MAAM,YAAY,KAAK,UAAU,QAAQ,CAC5C,MAAK,MAAM,SAAS,SAAS,OAC3B,UAAS,KAAK,GAAG,SAAS,GAAG,GAAG,MAAM,KAAK;AAG/C,UAAO;;;;;EAMT,UAAU,SAA2F;AAEnG,OAAI,QAAQ,SAAS,IAAI,EAAE;IACzB,MAAM,CAAC,YAAY,iBAAiB,QAAQ,MAAM,IAAI;IACtD,MAAM,WAAW,KAAK,UAAU,IAAI,WAAW;AAC/C,QAAI,UAAU;KACZ,MAAM,QAAQ,SAAS,OAAO,MAAK,MAAK,EAAE,OAAO,cAAc;AAC/D,SAAI,MACF,QAAO;MAAE;MAAU;MAAO;;;AAMhC,QAAK,MAAM,YAAY,KAAK,UAAU,QAAQ,EAAE;IAC9C,MAAM,QAAQ,SAAS,OAAO,MAAK,MAAK,EAAE,OAAO,QAAQ;AACzD,QAAI,MACF,QAAO;KAAE;KAAU;KAAO;;;;;;EAUhC,oBAAoB,SAA6C;AAC/D,UAAO,KAAK,UAAU,QAAQ,EAAE;;;AAQhC,kBAAgD"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Helpers for exporting chat session transcripts to workspace files (HTML wrapper).
3
+ */
4
+ export declare function escapeHtml(text: string): string;
5
+ export declare function wrapMarkdownExportAsHtml(title: string, markdownBody: string): string;
@@ -0,0 +1,35 @@
1
+ //#region src/session/chat-export.ts
2
+ /**
3
+ * Helpers for exporting chat session transcripts to workspace files (HTML wrapper).
4
+ */
5
+ function escapeHtml(text) {
6
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
7
+ }
8
+ function wrapMarkdownExportAsHtml(title, markdownBody) {
9
+ const safeTitle = escapeHtml(title);
10
+ return `<!DOCTYPE html>
11
+ <html lang="en">
12
+ <head>
13
+ <meta charset="utf-8"/>
14
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
15
+ <title>${safeTitle}</title>
16
+ <style>
17
+ body { font-family: system-ui, sans-serif; max-width: 52rem; margin: 2rem auto; padding: 0 1rem; line-height: 1.5; }
18
+ pre { white-space: pre-wrap; word-break: break-word; background: #f4f4f5; padding: 1rem; border-radius: 8px; }
19
+ @media (prefers-color-scheme: dark) {
20
+ body { background: #18181b; color: #e4e4e7; }
21
+ pre { background: #27272a; }
22
+ }
23
+ </style>
24
+ </head>
25
+ <body>
26
+ <h1>${safeTitle}</h1>
27
+ <pre>${escapeHtml(markdownBody)}</pre>
28
+ </body>
29
+ </html>
30
+ `;
31
+ }
32
+ //#endregion
33
+ export { escapeHtml, wrapMarkdownExportAsHtml };
34
+
35
+ //# sourceMappingURL=chat-export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-export.js","names":[],"sources":["../../../src/session/chat-export.ts"],"sourcesContent":["/**\n * Helpers for exporting chat session transcripts to workspace files (HTML wrapper).\n */\n\nexport function escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nexport function wrapMarkdownExportAsHtml(title: string, markdownBody: string): string {\n const safeTitle = escapeHtml(title);\n const body = escapeHtml(markdownBody);\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\"/>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>\n <title>${safeTitle}</title>\n <style>\n body { font-family: system-ui, sans-serif; max-width: 52rem; margin: 2rem auto; padding: 0 1rem; line-height: 1.5; }\n pre { white-space: pre-wrap; word-break: break-word; background: #f4f4f5; padding: 1rem; border-radius: 8px; }\n @media (prefers-color-scheme: dark) {\n body { background: #18181b; color: #e4e4e7; }\n pre { background: #27272a; }\n }\n </style>\n</head>\n<body>\n <h1>${safeTitle}</h1>\n <pre>${body}</pre>\n</body>\n</html>\n`;\n\n}\n"],"mappings":";;;;AAIA,SAAgB,WAAW,MAAsB;AAC/C,QAAO,KACJ,QAAQ,MAAM,QAAQ,CACtB,QAAQ,MAAM,OAAO,CACrB,QAAQ,MAAM,OAAO,CACrB,QAAQ,MAAM,SAAS;;AAG5B,SAAgB,yBAAyB,OAAe,cAA8B;CACpF,MAAM,YAAY,WAAW,MAAM;AAEnC,QAAO;;;;;WAKE,UAAU;;;;;;;;;;;QAWb,UAAU;SAjBH,WAAW,aAAa,CAkBzB"}
@@ -1,8 +1,8 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
+ import { mkdir, readFile, writeFile } from "fs/promises";
3
4
  import { join } from "path";
4
5
  import { existsSync } from "fs";
5
- import { mkdir, readFile, writeFile } from "fs/promises";
6
6
  //#region src/session/config-store.ts
7
7
  /**
8
8
  * Session Config Store
@@ -95,7 +95,7 @@ export declare class SessionManager extends EventEmitter {
95
95
  stats?: ReturnType<any>;
96
96
  };
97
97
  /** Compact session messages */
98
- compact(key: string, messages: any[], contextWindow: number, instructions?: string): Promise<CompactionResult>;
98
+ compact(key: string, messages: any[], contextWindow: number, instructions?: string, force?: boolean): Promise<CompactionResult>;
99
99
  /** Compaction stats for a session */
100
100
  getCompactionStats(key: string): Promise<{
101
101
  compactionCount: number;
@@ -190,8 +190,8 @@ var SessionManager = class extends EventEmitter$1 {
190
190
  return this.store.prepareCompaction(key, messages, contextWindow);
191
191
  }
192
192
  /** Compact session messages */
193
- compact(key, messages, contextWindow, instructions) {
194
- return this.store.compact(key, messages, contextWindow, instructions);
193
+ compact(key, messages, contextWindow, instructions, force) {
194
+ return this.store.compact(key, messages, contextWindow, instructions, force);
195
195
  }
196
196
  /** Compaction stats for a session */
197
197
  async getCompactionStats(key) {