@dexto/core 1.5.6 → 1.5.8

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 (217) hide show
  1. package/dist/agent/DextoAgent.cjs +189 -30
  2. package/dist/agent/DextoAgent.d.ts +44 -9
  3. package/dist/agent/DextoAgent.d.ts.map +1 -1
  4. package/dist/agent/DextoAgent.js +190 -31
  5. package/dist/agent/schemas.cjs +5 -0
  6. package/dist/agent/schemas.d.ts +456 -66
  7. package/dist/agent/schemas.d.ts.map +1 -1
  8. package/dist/agent/schemas.js +5 -0
  9. package/dist/context/manager.cjs +1 -1
  10. package/dist/context/manager.js +1 -1
  11. package/dist/context/utils.cjs +90 -17
  12. package/dist/context/utils.d.ts.map +1 -1
  13. package/dist/context/utils.js +90 -17
  14. package/dist/errors/types.cjs +2 -1
  15. package/dist/errors/types.d.ts +2 -1
  16. package/dist/errors/types.d.ts.map +1 -1
  17. package/dist/errors/types.js +2 -1
  18. package/dist/events/index.cjs +4 -1
  19. package/dist/events/index.d.ts +37 -2
  20. package/dist/events/index.d.ts.map +1 -1
  21. package/dist/events/index.js +4 -1
  22. package/dist/image/types.d.ts +15 -0
  23. package/dist/image/types.d.ts.map +1 -1
  24. package/dist/index.browser.d.ts +1 -1
  25. package/dist/index.browser.d.ts.map +1 -1
  26. package/dist/llm/curation-config.cjs +82 -0
  27. package/dist/llm/curation-config.d.ts +13 -0
  28. package/dist/llm/curation-config.d.ts.map +1 -0
  29. package/dist/llm/curation-config.js +59 -0
  30. package/dist/llm/curation.cjs +57 -0
  31. package/dist/llm/curation.d.ts +16 -0
  32. package/dist/llm/curation.d.ts.map +1 -0
  33. package/dist/llm/curation.js +34 -0
  34. package/dist/llm/error-codes.cjs +1 -0
  35. package/dist/llm/error-codes.d.ts +1 -0
  36. package/dist/llm/error-codes.d.ts.map +1 -1
  37. package/dist/llm/error-codes.js +1 -0
  38. package/dist/llm/errors.cjs +16 -1
  39. package/dist/llm/errors.d.ts +15 -8
  40. package/dist/llm/errors.d.ts.map +1 -1
  41. package/dist/llm/errors.js +16 -1
  42. package/dist/llm/executor/provider-options.cjs +1 -1
  43. package/dist/llm/executor/provider-options.js +1 -1
  44. package/dist/llm/executor/turn-executor.cjs +35 -2
  45. package/dist/llm/executor/turn-executor.d.ts.map +1 -1
  46. package/dist/llm/executor/turn-executor.js +35 -2
  47. package/dist/llm/index.cjs +14 -3
  48. package/dist/llm/index.d.ts +3 -1
  49. package/dist/llm/index.d.ts.map +1 -1
  50. package/dist/llm/index.js +13 -2
  51. package/dist/llm/registry/auto-update.cjs +263 -0
  52. package/dist/llm/registry/auto-update.d.ts +27 -0
  53. package/dist/llm/registry/auto-update.d.ts.map +1 -0
  54. package/dist/llm/registry/auto-update.js +227 -0
  55. package/dist/llm/registry/index.cjs +806 -0
  56. package/dist/llm/{registry.d.ts → registry/index.d.ts} +67 -13
  57. package/dist/llm/registry/index.d.ts.map +1 -0
  58. package/dist/llm/registry/index.js +756 -0
  59. package/dist/llm/registry/models.generated.cjs +4861 -0
  60. package/dist/llm/registry/models.generated.d.ts +431 -0
  61. package/dist/llm/registry/models.generated.d.ts.map +1 -0
  62. package/dist/llm/registry/models.generated.js +4838 -0
  63. package/dist/llm/registry/models.manual.cjs +44 -0
  64. package/dist/llm/registry/models.manual.d.ts +22 -0
  65. package/dist/llm/registry/models.manual.d.ts.map +1 -0
  66. package/dist/llm/registry/models.manual.js +21 -0
  67. package/dist/llm/registry/sync.cjs +354 -0
  68. package/dist/llm/registry/sync.d.ts +41 -0
  69. package/dist/llm/registry/sync.d.ts.map +1 -0
  70. package/dist/llm/registry/sync.js +328 -0
  71. package/dist/llm/resolver.cjs +29 -7
  72. package/dist/llm/resolver.d.ts +1 -1
  73. package/dist/llm/resolver.d.ts.map +1 -1
  74. package/dist/llm/resolver.js +31 -8
  75. package/dist/llm/schemas.cjs +13 -1
  76. package/dist/llm/schemas.d.ts +59 -59
  77. package/dist/llm/schemas.d.ts.map +1 -1
  78. package/dist/llm/schemas.js +14 -1
  79. package/dist/llm/services/factory.cjs +43 -27
  80. package/dist/llm/services/factory.d.ts +20 -1
  81. package/dist/llm/services/factory.d.ts.map +1 -1
  82. package/dist/llm/services/factory.js +44 -28
  83. package/dist/llm/services/test-utils.integration.cjs +5 -1
  84. package/dist/llm/services/test-utils.integration.d.ts.map +1 -1
  85. package/dist/llm/services/test-utils.integration.js +5 -1
  86. package/dist/llm/services/vercel.cjs +4 -1
  87. package/dist/llm/services/vercel.d.ts +1 -0
  88. package/dist/llm/services/vercel.d.ts.map +1 -1
  89. package/dist/llm/services/vercel.js +4 -1
  90. package/dist/llm/types.cjs +5 -2
  91. package/dist/llm/types.d.ts +1 -1
  92. package/dist/llm/types.d.ts.map +1 -1
  93. package/dist/llm/types.js +5 -2
  94. package/dist/llm/validation.cjs +1 -1
  95. package/dist/llm/validation.js +1 -1
  96. package/dist/logger/v2/dexto-logger.cjs +4 -0
  97. package/dist/logger/v2/dexto-logger.d.ts +3 -0
  98. package/dist/logger/v2/dexto-logger.d.ts.map +1 -1
  99. package/dist/logger/v2/dexto-logger.js +4 -0
  100. package/dist/logger/v2/types.d.ts +2 -0
  101. package/dist/logger/v2/types.d.ts.map +1 -1
  102. package/dist/mcp/error-codes.cjs +1 -0
  103. package/dist/mcp/error-codes.d.ts +1 -0
  104. package/dist/mcp/error-codes.d.ts.map +1 -1
  105. package/dist/mcp/error-codes.js +1 -0
  106. package/dist/mcp/errors.cjs +13 -0
  107. package/dist/mcp/errors.d.ts +7 -0
  108. package/dist/mcp/errors.d.ts.map +1 -1
  109. package/dist/mcp/errors.js +13 -0
  110. package/dist/mcp/manager.cjs +46 -4
  111. package/dist/mcp/manager.d.ts +10 -2
  112. package/dist/mcp/manager.d.ts.map +1 -1
  113. package/dist/mcp/manager.js +46 -4
  114. package/dist/mcp/mcp-client.cjs +89 -5
  115. package/dist/mcp/mcp-client.d.ts +5 -1
  116. package/dist/mcp/mcp-client.d.ts.map +1 -1
  117. package/dist/mcp/mcp-client.js +89 -5
  118. package/dist/mcp/schemas.cjs +6 -1
  119. package/dist/mcp/schemas.d.ts +1 -1
  120. package/dist/mcp/schemas.d.ts.map +1 -1
  121. package/dist/mcp/schemas.js +6 -1
  122. package/dist/mcp/types.d.ts +5 -0
  123. package/dist/mcp/types.d.ts.map +1 -1
  124. package/dist/prompts/index.d.ts +1 -1
  125. package/dist/prompts/index.d.ts.map +1 -1
  126. package/dist/prompts/prompt-manager.cjs +90 -4
  127. package/dist/prompts/prompt-manager.d.ts +16 -6
  128. package/dist/prompts/prompt-manager.d.ts.map +1 -1
  129. package/dist/prompts/prompt-manager.js +90 -4
  130. package/dist/prompts/providers/config-prompt-provider.cjs +104 -10
  131. package/dist/prompts/providers/config-prompt-provider.d.ts.map +1 -1
  132. package/dist/prompts/providers/config-prompt-provider.js +105 -11
  133. package/dist/prompts/providers/custom-prompt-provider.cjs +1 -0
  134. package/dist/prompts/providers/custom-prompt-provider.d.ts.map +1 -1
  135. package/dist/prompts/providers/custom-prompt-provider.js +1 -0
  136. package/dist/prompts/providers/mcp-prompt-provider.cjs +1 -0
  137. package/dist/prompts/providers/mcp-prompt-provider.d.ts.map +1 -1
  138. package/dist/prompts/providers/mcp-prompt-provider.js +1 -0
  139. package/dist/prompts/schemas.cjs +28 -2
  140. package/dist/prompts/schemas.d.ts +130 -0
  141. package/dist/prompts/schemas.d.ts.map +1 -1
  142. package/dist/prompts/schemas.js +28 -2
  143. package/dist/prompts/types.d.ts +55 -3
  144. package/dist/prompts/types.d.ts.map +1 -1
  145. package/dist/resources/handlers/filesystem-handler.cjs +25 -0
  146. package/dist/resources/handlers/filesystem-handler.d.ts +1 -0
  147. package/dist/resources/handlers/filesystem-handler.d.ts.map +1 -1
  148. package/dist/resources/handlers/filesystem-handler.js +25 -0
  149. package/dist/session/chat-session.cjs +1 -1
  150. package/dist/session/chat-session.d.ts +1 -1
  151. package/dist/session/chat-session.d.ts.map +1 -1
  152. package/dist/session/chat-session.js +1 -1
  153. package/dist/session/index.d.ts +1 -1
  154. package/dist/session/index.d.ts.map +1 -1
  155. package/dist/session/message-queue.cjs +29 -5
  156. package/dist/session/message-queue.d.ts +3 -1
  157. package/dist/session/message-queue.d.ts.map +1 -1
  158. package/dist/session/message-queue.js +29 -5
  159. package/dist/session/session-manager.cjs +84 -3
  160. package/dist/session/session-manager.d.ts +12 -0
  161. package/dist/session/session-manager.d.ts.map +1 -1
  162. package/dist/session/session-manager.js +74 -3
  163. package/dist/session/types.d.ts +1 -0
  164. package/dist/session/types.d.ts.map +1 -1
  165. package/dist/systemPrompt/contributors.cjs +42 -0
  166. package/dist/systemPrompt/contributors.d.ts +13 -0
  167. package/dist/systemPrompt/contributors.d.ts.map +1 -1
  168. package/dist/systemPrompt/contributors.js +41 -0
  169. package/dist/tools/errors.cjs +7 -3
  170. package/dist/tools/errors.d.ts +5 -1
  171. package/dist/tools/errors.d.ts.map +1 -1
  172. package/dist/tools/errors.js +7 -3
  173. package/dist/tools/internal-tools/constants.cjs +2 -1
  174. package/dist/tools/internal-tools/constants.d.ts +1 -1
  175. package/dist/tools/internal-tools/constants.d.ts.map +1 -1
  176. package/dist/tools/internal-tools/constants.js +2 -1
  177. package/dist/tools/internal-tools/implementations/invoke-skill-tool.cjs +140 -0
  178. package/dist/tools/internal-tools/implementations/invoke-skill-tool.d.ts +24 -0
  179. package/dist/tools/internal-tools/implementations/invoke-skill-tool.d.ts.map +1 -0
  180. package/dist/tools/internal-tools/implementations/invoke-skill-tool.js +117 -0
  181. package/dist/tools/internal-tools/provider.cjs +15 -0
  182. package/dist/tools/internal-tools/provider.d.ts +15 -1
  183. package/dist/tools/internal-tools/provider.d.ts.map +1 -1
  184. package/dist/tools/internal-tools/provider.js +15 -0
  185. package/dist/tools/internal-tools/registry.cjs +6 -0
  186. package/dist/tools/internal-tools/registry.d.ts +35 -1
  187. package/dist/tools/internal-tools/registry.d.ts.map +1 -1
  188. package/dist/tools/internal-tools/registry.js +6 -0
  189. package/dist/tools/schemas.d.ts +1 -1
  190. package/dist/tools/schemas.d.ts.map +1 -1
  191. package/dist/tools/tool-call-metadata.cjs +75 -0
  192. package/dist/tools/tool-call-metadata.d.ts +16 -0
  193. package/dist/tools/tool-call-metadata.d.ts.map +1 -0
  194. package/dist/tools/tool-call-metadata.js +51 -0
  195. package/dist/tools/tool-manager.cjs +481 -103
  196. package/dist/tools/tool-manager.d.ts +131 -9
  197. package/dist/tools/tool-manager.d.ts.map +1 -1
  198. package/dist/tools/tool-manager.js +482 -104
  199. package/dist/utils/api-key-resolver.cjs +5 -2
  200. package/dist/utils/api-key-resolver.d.ts.map +1 -1
  201. package/dist/utils/api-key-resolver.js +5 -2
  202. package/dist/utils/env.cjs +49 -0
  203. package/dist/utils/env.d.ts +4 -0
  204. package/dist/utils/env.d.ts.map +1 -0
  205. package/dist/utils/env.js +24 -0
  206. package/dist/utils/index.cjs +3 -1
  207. package/dist/utils/index.d.ts +1 -0
  208. package/dist/utils/index.d.ts.map +1 -1
  209. package/dist/utils/index.js +1 -0
  210. package/dist/utils/service-initializer.cjs +25 -7
  211. package/dist/utils/service-initializer.d.ts +24 -1
  212. package/dist/utils/service-initializer.d.ts.map +1 -1
  213. package/dist/utils/service-initializer.js +25 -7
  214. package/package.json +6 -2
  215. package/dist/llm/registry.cjs +0 -1631
  216. package/dist/llm/registry.d.ts.map +0 -1
  217. package/dist/llm/registry.js +0 -1586
@@ -125,7 +125,10 @@ class TurnExecutor {
125
125
  contributorContext,
126
126
  this.llmContext
127
127
  );
128
- const toolDefinitions = supportsTools ? await this.toolManager.getAllTools() : {};
128
+ const toolDefinitions = supportsTools ? this.toolManager.filterToolsForSession(
129
+ await this.toolManager.getAllTools(),
130
+ this.sessionId
131
+ ) : {};
129
132
  let estimatedTokens = await this.contextManager.getEstimatedNextInputTokens(
130
133
  prepared.systemPrompt,
131
134
  prepared.preparedHistory,
@@ -390,7 +393,10 @@ class TurnExecutor {
390
393
  * - StreamProcessor handles persistence via tool-result events
391
394
  */
392
395
  async createTools() {
393
- const tools = await this.toolManager.getAllTools();
396
+ const tools = this.toolManager.filterToolsForSession(
397
+ await this.toolManager.getAllTools(),
398
+ this.sessionId
399
+ );
394
400
  return Object.fromEntries(
395
401
  Object.entries(tools).map(([name, tool]) => [
396
402
  name,
@@ -786,6 +792,33 @@ class TurnExecutor {
786
792
  const headers = err.responseHeaders || {};
787
793
  const retryAfter = headers["retry-after"] ? Number(headers["retry-after"]) : void 0;
788
794
  const body = typeof err.responseBody === "string" ? err.responseBody : JSON.stringify(err.responseBody ?? "");
795
+ if (status === 402) {
796
+ let balance;
797
+ try {
798
+ const parsed = JSON.parse(body);
799
+ const msg = parsed?.error?.message || "";
800
+ const match = msg.match(/Balance:\s*\$?([\d.]+)/i);
801
+ if (match) {
802
+ balance = parseFloat(match[1]);
803
+ }
804
+ } catch {
805
+ }
806
+ return new DextoRuntimeError(
807
+ LLMErrorCode.INSUFFICIENT_CREDITS,
808
+ ErrorScope.LLM,
809
+ ErrorType.PAYMENT_REQUIRED,
810
+ `Insufficient Dexto credits${balance !== void 0 ? `. Balance: $${balance.toFixed(2)}` : ""}`,
811
+ {
812
+ sessionId: this.sessionId,
813
+ provider: this.llmContext.provider,
814
+ model: this.llmContext.model,
815
+ status,
816
+ balance,
817
+ body
818
+ },
819
+ "Run `dexto billing` to check your balance"
820
+ );
821
+ }
789
822
  if (status === 429) {
790
823
  return new DextoRuntimeError(
791
824
  LLMErrorCode.RATE_LIMIT_EXCEEDED,
@@ -19,30 +19,41 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
19
19
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
20
  var llm_exports = {};
21
21
  __export(llm_exports, {
22
+ getLlmRegistryAutoUpdateStatus: () => import_auto_update.getLlmRegistryAutoUpdateStatus,
22
23
  getOpenRouterModelContextLength: () => import_openrouter_model_registry.getOpenRouterModelContextLength,
23
24
  getOpenRouterModelInfo: () => import_openrouter_model_registry.getOpenRouterModelInfo,
25
+ loadLlmRegistryCache: () => import_auto_update.loadLlmRegistryCache,
24
26
  lookupOpenRouterModel: () => import_openrouter_model_registry.lookupOpenRouterModel,
25
- refreshOpenRouterModelCache: () => import_openrouter_model_registry.refreshOpenRouterModelCache
27
+ refreshLlmRegistryCache: () => import_auto_update.refreshLlmRegistryCache,
28
+ refreshOpenRouterModelCache: () => import_openrouter_model_registry.refreshOpenRouterModelCache,
29
+ startLlmRegistryAutoUpdate: () => import_auto_update.startLlmRegistryAutoUpdate
26
30
  });
27
31
  module.exports = __toCommonJS(llm_exports);
28
32
  __reExport(llm_exports, require("./errors.js"), module.exports);
29
33
  __reExport(llm_exports, require("./error-codes.js"), module.exports);
30
- __reExport(llm_exports, require("./registry.js"), module.exports);
34
+ __reExport(llm_exports, require("./registry/index.js"), module.exports);
35
+ __reExport(llm_exports, require("./curation.js"), module.exports);
31
36
  __reExport(llm_exports, require("./validation.js"), module.exports);
32
37
  __reExport(llm_exports, require("./types.js"), module.exports);
33
38
  __reExport(llm_exports, require("./services/index.js"), module.exports);
34
39
  __reExport(llm_exports, require("./schemas.js"), module.exports);
35
40
  var import_openrouter_model_registry = require("./providers/openrouter-model-registry.js");
41
+ var import_auto_update = require("./registry/auto-update.js");
36
42
  __reExport(llm_exports, require("./providers/local/index.js"), module.exports);
37
43
  // Annotate the CommonJS export names for ESM import in node:
38
44
  0 && (module.exports = {
45
+ getLlmRegistryAutoUpdateStatus,
39
46
  getOpenRouterModelContextLength,
40
47
  getOpenRouterModelInfo,
48
+ loadLlmRegistryCache,
41
49
  lookupOpenRouterModel,
50
+ refreshLlmRegistryCache,
42
51
  refreshOpenRouterModelCache,
52
+ startLlmRegistryAutoUpdate,
43
53
  ...require("./errors.js"),
44
54
  ...require("./error-codes.js"),
45
- ...require("./registry.js"),
55
+ ...require("./registry/index.js"),
56
+ ...require("./curation.js"),
46
57
  ...require("./validation.js"),
47
58
  ...require("./types.js"),
48
59
  ...require("./services/index.js"),
@@ -1,10 +1,12 @@
1
1
  export * from './errors.js';
2
2
  export * from './error-codes.js';
3
- export * from './registry.js';
3
+ export * from './registry/index.js';
4
+ export * from './curation.js';
4
5
  export * from './validation.js';
5
6
  export * from './types.js';
6
7
  export * from './services/index.js';
7
8
  export * from './schemas.js';
8
9
  export { lookupOpenRouterModel, refreshOpenRouterModelCache, getOpenRouterModelContextLength, getOpenRouterModelInfo, type LookupStatus, type OpenRouterModelInfo, } from './providers/openrouter-model-registry.js';
10
+ export { startLlmRegistryAutoUpdate, refreshLlmRegistryCache, loadLlmRegistryCache, getLlmRegistryAutoUpdateStatus, type LlmRegistryAutoUpdateStatus, } from './registry/auto-update.js';
9
11
  export * from './providers/local/index.js';
10
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/llm/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,OAAO,EACH,qBAAqB,EACrB,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,EACtB,KAAK,YAAY,EACjB,KAAK,mBAAmB,GAC3B,MAAM,0CAA0C,CAAC;AAGlD,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/llm/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,OAAO,EACH,qBAAqB,EACrB,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,EACtB,KAAK,YAAY,EACjB,KAAK,mBAAmB,GAC3B,MAAM,0CAA0C,CAAC;AAGlD,OAAO,EACH,0BAA0B,EAC1B,uBAAuB,EACvB,oBAAoB,EACpB,8BAA8B,EAC9B,KAAK,2BAA2B,GACnC,MAAM,2BAA2B,CAAC;AAGnC,cAAc,4BAA4B,CAAC"}
package/dist/llm/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import "../chunk-PTJYTZNU.js";
2
2
  export * from "./errors.js";
3
3
  export * from "./error-codes.js";
4
- export * from "./registry.js";
4
+ export * from "./registry/index.js";
5
+ export * from "./curation.js";
5
6
  export * from "./validation.js";
6
7
  export * from "./types.js";
7
8
  export * from "./services/index.js";
@@ -12,10 +13,20 @@ import {
12
13
  getOpenRouterModelContextLength,
13
14
  getOpenRouterModelInfo
14
15
  } from "./providers/openrouter-model-registry.js";
16
+ import {
17
+ startLlmRegistryAutoUpdate,
18
+ refreshLlmRegistryCache,
19
+ loadLlmRegistryCache,
20
+ getLlmRegistryAutoUpdateStatus
21
+ } from "./registry/auto-update.js";
15
22
  export * from "./providers/local/index.js";
16
23
  export {
24
+ getLlmRegistryAutoUpdateStatus,
17
25
  getOpenRouterModelContextLength,
18
26
  getOpenRouterModelInfo,
27
+ loadLlmRegistryCache,
19
28
  lookupOpenRouterModel,
20
- refreshOpenRouterModelCache
29
+ refreshLlmRegistryCache,
30
+ refreshOpenRouterModelCache,
31
+ startLlmRegistryAutoUpdate
21
32
  };
@@ -0,0 +1,263 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var auto_update_exports = {};
30
+ __export(auto_update_exports, {
31
+ getLlmRegistryAutoUpdateStatus: () => getLlmRegistryAutoUpdateStatus,
32
+ loadLlmRegistryCache: () => loadLlmRegistryCache,
33
+ refreshLlmRegistryCache: () => refreshLlmRegistryCache,
34
+ startLlmRegistryAutoUpdate: () => startLlmRegistryAutoUpdate
35
+ });
36
+ module.exports = __toCommonJS(auto_update_exports);
37
+ var import_node_fs = require("node:fs");
38
+ var import_node_fs2 = require("node:fs");
39
+ var import_node_path = __toESM(require("node:path"), 1);
40
+ var import_path = require("../../utils/path.js");
41
+ var import_logger = require("../../logger/logger.js");
42
+ var import_types = require("../types.js");
43
+ var import_index = require("./index.js");
44
+ var import_sync = require("./sync.js");
45
+ const CACHE_SUBDIR = "cache";
46
+ const CACHE_FILENAME = "llm-registry-models.json";
47
+ const CACHE_SCHEMA_VERSION = 1;
48
+ const DEFAULT_TTL_MS = 1e3 * 60 * 60;
49
+ const MIN_REFRESH_INTERVAL_MS = 1e3 * 60 * 5;
50
+ const UPDATABLE_PROVIDERS = [
51
+ "openai",
52
+ "anthropic",
53
+ "google",
54
+ "groq",
55
+ "xai",
56
+ "cohere",
57
+ "minimax",
58
+ "glm",
59
+ "vertex",
60
+ "bedrock"
61
+ ];
62
+ function truthyEnv(name) {
63
+ const v = process.env[name];
64
+ if (!v) return false;
65
+ return v === "1" || v === "true" || v === "yes" || v === "on";
66
+ }
67
+ function getTtlMs() {
68
+ const raw = process.env.DEXTO_LLM_REGISTRY_TTL_MS;
69
+ if (!raw) return DEFAULT_TTL_MS;
70
+ const n = Number(raw);
71
+ return Number.isFinite(n) && n > 0 ? n : DEFAULT_TTL_MS;
72
+ }
73
+ function getCachePath() {
74
+ return (0, import_path.getDextoGlobalPath)(CACHE_SUBDIR, CACHE_FILENAME);
75
+ }
76
+ function isModelInfo(value) {
77
+ if (typeof value !== "object" || value === null) return false;
78
+ const name = value.name;
79
+ return typeof name === "string" && name.trim() !== "";
80
+ }
81
+ function applyModelsByProvider(modelsByProvider) {
82
+ for (const provider of UPDATABLE_PROVIDERS) {
83
+ const incoming = modelsByProvider[provider] ?? [];
84
+ const existing = import_index.LLM_REGISTRY[provider].models ?? [];
85
+ const incomingByName = /* @__PURE__ */ new Map();
86
+ for (const m of incoming) {
87
+ incomingByName.set(m.name.toLowerCase(), m);
88
+ }
89
+ const existingDefault = existing.find((m) => m.default)?.name.toLowerCase();
90
+ const incomingDefault = incoming.find((m) => m.default)?.name.toLowerCase();
91
+ const merged = [];
92
+ const seen = /* @__PURE__ */ new Set();
93
+ for (const m of existing) {
94
+ const key = m.name.toLowerCase();
95
+ const updated = incomingByName.get(key);
96
+ if (!updated) {
97
+ merged.push(m);
98
+ } else {
99
+ const name = updated.name ?? m.name;
100
+ const maxInputTokens = typeof updated.maxInputTokens === "number" && updated.maxInputTokens > 0 ? updated.maxInputTokens : m.maxInputTokens;
101
+ const supportedFileTypes = Array.isArray(updated.supportedFileTypes) ? updated.supportedFileTypes : m.supportedFileTypes;
102
+ const displayName = updated.displayName ?? m.displayName;
103
+ const pricing = updated.pricing ?? m.pricing;
104
+ merged.push({
105
+ name,
106
+ maxInputTokens,
107
+ supportedFileTypes,
108
+ ...displayName ? { displayName } : {},
109
+ ...pricing ? { pricing } : {}
110
+ });
111
+ }
112
+ seen.add(key);
113
+ }
114
+ const newModels = incoming.filter((m) => !seen.has(m.name.toLowerCase()));
115
+ newModels.sort((a, b) => a.name.localeCompare(b.name));
116
+ merged.push(...newModels);
117
+ const chosenDefault = incomingDefault ?? existingDefault ?? merged[0]?.name.toLowerCase();
118
+ const finalMerged = merged.map((m) => {
119
+ const copy = { ...m };
120
+ delete copy.default;
121
+ return copy;
122
+ });
123
+ if (chosenDefault) {
124
+ const idx = finalMerged.findIndex((m) => m.name.toLowerCase() === chosenDefault);
125
+ if (idx >= 0) {
126
+ finalMerged[idx] = { ...finalMerged[idx], default: true };
127
+ }
128
+ }
129
+ import_index.LLM_REGISTRY[provider].models = finalMerged;
130
+ }
131
+ }
132
+ function normalizeModelsByProvider(raw) {
133
+ const out = {};
134
+ for (const p of import_types.LLM_PROVIDERS) {
135
+ const value = raw[p];
136
+ out[p] = Array.isArray(value) ? value.filter(isModelInfo) : [];
137
+ }
138
+ return out;
139
+ }
140
+ function tryLoadCacheFromDisk(log) {
141
+ const cachePath = getCachePath();
142
+ if (!(0, import_node_fs2.existsSync)(cachePath)) return null;
143
+ try {
144
+ const text = (0, import_node_fs2.readFileSync)(cachePath, "utf-8");
145
+ const parsed = JSON.parse(text);
146
+ if (parsed.schemaVersion !== CACHE_SCHEMA_VERSION) return null;
147
+ if (!parsed.fetchedAt || typeof parsed.fetchedAt !== "string") return null;
148
+ if (!parsed.modelsByProvider || typeof parsed.modelsByProvider !== "object") return null;
149
+ const fetchedAt = Date.parse(parsed.fetchedAt);
150
+ if (!Number.isFinite(fetchedAt)) return null;
151
+ const modelsByProvider = normalizeModelsByProvider(
152
+ parsed.modelsByProvider
153
+ );
154
+ return { fetchedAt, modelsByProvider };
155
+ } catch (e) {
156
+ log?.warn?.(
157
+ `Failed to load LLM registry cache (${cachePath}): ${e instanceof Error ? e.message : String(e)}`
158
+ );
159
+ return null;
160
+ }
161
+ }
162
+ let refreshPromise = null;
163
+ let lastRefreshAttemptAt = null;
164
+ let lastFetchedAt = null;
165
+ let lastSource = "snapshot";
166
+ let autoRefreshStarted = false;
167
+ function isFresh(now, fetchedAt, ttlMs) {
168
+ return now - fetchedAt < ttlMs;
169
+ }
170
+ function getLlmRegistryAutoUpdateStatus() {
171
+ const cachePath = getCachePath();
172
+ const fetchedAt = lastFetchedAt ? new Date(lastFetchedAt) : null;
173
+ const now = Date.now();
174
+ return {
175
+ cachePath,
176
+ lastFetchedAt: fetchedAt,
177
+ isFresh: lastFetchedAt ? isFresh(now, lastFetchedAt, getTtlMs()) : false,
178
+ source: lastSource
179
+ };
180
+ }
181
+ function loadLlmRegistryCache(options) {
182
+ const cache = tryLoadCacheFromDisk(options?.logger);
183
+ if (!cache) return false;
184
+ applyModelsByProvider(cache.modelsByProvider);
185
+ lastFetchedAt = cache.fetchedAt;
186
+ lastSource = "cache";
187
+ return true;
188
+ }
189
+ async function writeCacheFile(cachePath, modelsByProvider) {
190
+ await import_node_fs.promises.mkdir(import_node_path.default.dirname(cachePath), { recursive: true });
191
+ const payload = {
192
+ schemaVersion: CACHE_SCHEMA_VERSION,
193
+ fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
194
+ modelsByProvider
195
+ };
196
+ const tmpPath = `${cachePath}.tmp`;
197
+ await import_node_fs.promises.writeFile(tmpPath, JSON.stringify(payload), "utf-8");
198
+ await import_node_fs.promises.rename(tmpPath, cachePath);
199
+ }
200
+ async function refreshLlmRegistryCache(options) {
201
+ if (truthyEnv("DEXTO_LLM_REGISTRY_DISABLE_FETCH") || !options?.allowInTests && (process.env.NODE_ENV === "test" || truthyEnv("VITEST"))) {
202
+ return;
203
+ }
204
+ if (refreshPromise && !options?.force) {
205
+ await refreshPromise;
206
+ return;
207
+ }
208
+ const now = Date.now();
209
+ if (!options?.force && lastRefreshAttemptAt && now - lastRefreshAttemptAt < MIN_REFRESH_INTERVAL_MS) {
210
+ if (refreshPromise) await refreshPromise;
211
+ return;
212
+ }
213
+ lastRefreshAttemptAt = now;
214
+ const log = options?.logger ?? import_logger.logger;
215
+ refreshPromise = (async () => {
216
+ const modelsByProvider = await (0, import_sync.buildModelsByProviderFromRemote)({
217
+ userAgent: "dexto-llm-registry",
218
+ timeoutMs: 3e4
219
+ });
220
+ const cachePath = getCachePath();
221
+ await writeCacheFile(cachePath, modelsByProvider);
222
+ applyModelsByProvider(modelsByProvider);
223
+ lastFetchedAt = Date.now();
224
+ lastSource = "remote";
225
+ log?.debug?.(`Refreshed LLM registry cache (${cachePath})`);
226
+ })().catch((e) => {
227
+ log?.warn?.(
228
+ `Failed to refresh LLM registry cache: ${e instanceof Error ? e.message : String(e)}`
229
+ );
230
+ }).finally(() => {
231
+ refreshPromise = null;
232
+ });
233
+ await refreshPromise;
234
+ }
235
+ function startLlmRegistryAutoUpdate(options) {
236
+ if (autoRefreshStarted) return;
237
+ autoRefreshStarted = true;
238
+ const log = options?.logger ?? import_logger.logger;
239
+ const loaded = loadLlmRegistryCache({ logger: log });
240
+ if (loaded) {
241
+ log?.debug?.(`Loaded LLM registry cache from disk (${getCachePath()})`);
242
+ }
243
+ if (options?.refreshOnStart !== false) {
244
+ void refreshLlmRegistryCache({ logger: log });
245
+ }
246
+ const timer = setInterval(
247
+ () => {
248
+ const ttlMs = getTtlMs();
249
+ const now = Date.now();
250
+ if (lastFetchedAt && isFresh(now, lastFetchedAt, ttlMs)) return;
251
+ void refreshLlmRegistryCache({ logger: log });
252
+ },
253
+ Math.min(getTtlMs(), DEFAULT_TTL_MS)
254
+ );
255
+ timer.unref?.();
256
+ }
257
+ // Annotate the CommonJS export names for ESM import in node:
258
+ 0 && (module.exports = {
259
+ getLlmRegistryAutoUpdateStatus,
260
+ loadLlmRegistryCache,
261
+ refreshLlmRegistryCache,
262
+ startLlmRegistryAutoUpdate
263
+ });
@@ -0,0 +1,27 @@
1
+ import type { IDextoLogger } from '../../logger/v2/types.js';
2
+ type LogLike = Pick<IDextoLogger, 'debug' | 'info' | 'warn' | 'error'>;
3
+ export type LlmRegistryAutoUpdateStatus = {
4
+ cachePath: string;
5
+ lastFetchedAt: Date | null;
6
+ isFresh: boolean;
7
+ source: 'snapshot' | 'cache' | 'remote';
8
+ };
9
+ export declare function getLlmRegistryAutoUpdateStatus(): LlmRegistryAutoUpdateStatus;
10
+ export declare function loadLlmRegistryCache(options?: {
11
+ logger?: LogLike;
12
+ }): boolean;
13
+ export declare function refreshLlmRegistryCache(options?: {
14
+ logger?: LogLike;
15
+ force?: boolean;
16
+ /**
17
+ * Test-only escape hatch to validate refresh behavior with mocks while keeping
18
+ * network fetch disabled by default in CI/unit tests.
19
+ */
20
+ allowInTests?: boolean;
21
+ }): Promise<void>;
22
+ export declare function startLlmRegistryAutoUpdate(options?: {
23
+ logger?: LogLike;
24
+ refreshOnStart?: boolean;
25
+ }): void;
26
+ export {};
27
+ //# sourceMappingURL=auto-update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-update.d.ts","sourceRoot":"","sources":["../../../src/llm/registry/auto-update.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAO7D,KAAK,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAuKvE,MAAM,MAAM,2BAA2B,GAAG;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,IAAI,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;CAC3C,CAAC;AAMF,wBAAgB,8BAA8B,IAAI,2BAA2B,CAU5E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAO5E;AAiBD,wBAAsB,uBAAuB,CAAC,OAAO,CAAC,EAAE;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDhB;AAED,wBAAgB,0BAA0B,CAAC,OAAO,CAAC,EAAE;IACjD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B,GAAG,IAAI,CA6BP"}
@@ -0,0 +1,227 @@
1
+ import "../../chunk-PTJYTZNU.js";
2
+ import { promises as fs } from "node:fs";
3
+ import { existsSync, readFileSync } from "node:fs";
4
+ import path from "node:path";
5
+ import { getDextoGlobalPath } from "../../utils/path.js";
6
+ import { logger as defaultLogger } from "../../logger/logger.js";
7
+ import { LLM_PROVIDERS } from "../types.js";
8
+ import { LLM_REGISTRY } from "./index.js";
9
+ import { buildModelsByProviderFromRemote } from "./sync.js";
10
+ const CACHE_SUBDIR = "cache";
11
+ const CACHE_FILENAME = "llm-registry-models.json";
12
+ const CACHE_SCHEMA_VERSION = 1;
13
+ const DEFAULT_TTL_MS = 1e3 * 60 * 60;
14
+ const MIN_REFRESH_INTERVAL_MS = 1e3 * 60 * 5;
15
+ const UPDATABLE_PROVIDERS = [
16
+ "openai",
17
+ "anthropic",
18
+ "google",
19
+ "groq",
20
+ "xai",
21
+ "cohere",
22
+ "minimax",
23
+ "glm",
24
+ "vertex",
25
+ "bedrock"
26
+ ];
27
+ function truthyEnv(name) {
28
+ const v = process.env[name];
29
+ if (!v) return false;
30
+ return v === "1" || v === "true" || v === "yes" || v === "on";
31
+ }
32
+ function getTtlMs() {
33
+ const raw = process.env.DEXTO_LLM_REGISTRY_TTL_MS;
34
+ if (!raw) return DEFAULT_TTL_MS;
35
+ const n = Number(raw);
36
+ return Number.isFinite(n) && n > 0 ? n : DEFAULT_TTL_MS;
37
+ }
38
+ function getCachePath() {
39
+ return getDextoGlobalPath(CACHE_SUBDIR, CACHE_FILENAME);
40
+ }
41
+ function isModelInfo(value) {
42
+ if (typeof value !== "object" || value === null) return false;
43
+ const name = value.name;
44
+ return typeof name === "string" && name.trim() !== "";
45
+ }
46
+ function applyModelsByProvider(modelsByProvider) {
47
+ for (const provider of UPDATABLE_PROVIDERS) {
48
+ const incoming = modelsByProvider[provider] ?? [];
49
+ const existing = LLM_REGISTRY[provider].models ?? [];
50
+ const incomingByName = /* @__PURE__ */ new Map();
51
+ for (const m of incoming) {
52
+ incomingByName.set(m.name.toLowerCase(), m);
53
+ }
54
+ const existingDefault = existing.find((m) => m.default)?.name.toLowerCase();
55
+ const incomingDefault = incoming.find((m) => m.default)?.name.toLowerCase();
56
+ const merged = [];
57
+ const seen = /* @__PURE__ */ new Set();
58
+ for (const m of existing) {
59
+ const key = m.name.toLowerCase();
60
+ const updated = incomingByName.get(key);
61
+ if (!updated) {
62
+ merged.push(m);
63
+ } else {
64
+ const name = updated.name ?? m.name;
65
+ const maxInputTokens = typeof updated.maxInputTokens === "number" && updated.maxInputTokens > 0 ? updated.maxInputTokens : m.maxInputTokens;
66
+ const supportedFileTypes = Array.isArray(updated.supportedFileTypes) ? updated.supportedFileTypes : m.supportedFileTypes;
67
+ const displayName = updated.displayName ?? m.displayName;
68
+ const pricing = updated.pricing ?? m.pricing;
69
+ merged.push({
70
+ name,
71
+ maxInputTokens,
72
+ supportedFileTypes,
73
+ ...displayName ? { displayName } : {},
74
+ ...pricing ? { pricing } : {}
75
+ });
76
+ }
77
+ seen.add(key);
78
+ }
79
+ const newModels = incoming.filter((m) => !seen.has(m.name.toLowerCase()));
80
+ newModels.sort((a, b) => a.name.localeCompare(b.name));
81
+ merged.push(...newModels);
82
+ const chosenDefault = incomingDefault ?? existingDefault ?? merged[0]?.name.toLowerCase();
83
+ const finalMerged = merged.map((m) => {
84
+ const copy = { ...m };
85
+ delete copy.default;
86
+ return copy;
87
+ });
88
+ if (chosenDefault) {
89
+ const idx = finalMerged.findIndex((m) => m.name.toLowerCase() === chosenDefault);
90
+ if (idx >= 0) {
91
+ finalMerged[idx] = { ...finalMerged[idx], default: true };
92
+ }
93
+ }
94
+ LLM_REGISTRY[provider].models = finalMerged;
95
+ }
96
+ }
97
+ function normalizeModelsByProvider(raw) {
98
+ const out = {};
99
+ for (const p of LLM_PROVIDERS) {
100
+ const value = raw[p];
101
+ out[p] = Array.isArray(value) ? value.filter(isModelInfo) : [];
102
+ }
103
+ return out;
104
+ }
105
+ function tryLoadCacheFromDisk(log) {
106
+ const cachePath = getCachePath();
107
+ if (!existsSync(cachePath)) return null;
108
+ try {
109
+ const text = readFileSync(cachePath, "utf-8");
110
+ const parsed = JSON.parse(text);
111
+ if (parsed.schemaVersion !== CACHE_SCHEMA_VERSION) return null;
112
+ if (!parsed.fetchedAt || typeof parsed.fetchedAt !== "string") return null;
113
+ if (!parsed.modelsByProvider || typeof parsed.modelsByProvider !== "object") return null;
114
+ const fetchedAt = Date.parse(parsed.fetchedAt);
115
+ if (!Number.isFinite(fetchedAt)) return null;
116
+ const modelsByProvider = normalizeModelsByProvider(
117
+ parsed.modelsByProvider
118
+ );
119
+ return { fetchedAt, modelsByProvider };
120
+ } catch (e) {
121
+ log?.warn?.(
122
+ `Failed to load LLM registry cache (${cachePath}): ${e instanceof Error ? e.message : String(e)}`
123
+ );
124
+ return null;
125
+ }
126
+ }
127
+ let refreshPromise = null;
128
+ let lastRefreshAttemptAt = null;
129
+ let lastFetchedAt = null;
130
+ let lastSource = "snapshot";
131
+ let autoRefreshStarted = false;
132
+ function isFresh(now, fetchedAt, ttlMs) {
133
+ return now - fetchedAt < ttlMs;
134
+ }
135
+ function getLlmRegistryAutoUpdateStatus() {
136
+ const cachePath = getCachePath();
137
+ const fetchedAt = lastFetchedAt ? new Date(lastFetchedAt) : null;
138
+ const now = Date.now();
139
+ return {
140
+ cachePath,
141
+ lastFetchedAt: fetchedAt,
142
+ isFresh: lastFetchedAt ? isFresh(now, lastFetchedAt, getTtlMs()) : false,
143
+ source: lastSource
144
+ };
145
+ }
146
+ function loadLlmRegistryCache(options) {
147
+ const cache = tryLoadCacheFromDisk(options?.logger);
148
+ if (!cache) return false;
149
+ applyModelsByProvider(cache.modelsByProvider);
150
+ lastFetchedAt = cache.fetchedAt;
151
+ lastSource = "cache";
152
+ return true;
153
+ }
154
+ async function writeCacheFile(cachePath, modelsByProvider) {
155
+ await fs.mkdir(path.dirname(cachePath), { recursive: true });
156
+ const payload = {
157
+ schemaVersion: CACHE_SCHEMA_VERSION,
158
+ fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
159
+ modelsByProvider
160
+ };
161
+ const tmpPath = `${cachePath}.tmp`;
162
+ await fs.writeFile(tmpPath, JSON.stringify(payload), "utf-8");
163
+ await fs.rename(tmpPath, cachePath);
164
+ }
165
+ async function refreshLlmRegistryCache(options) {
166
+ if (truthyEnv("DEXTO_LLM_REGISTRY_DISABLE_FETCH") || !options?.allowInTests && (process.env.NODE_ENV === "test" || truthyEnv("VITEST"))) {
167
+ return;
168
+ }
169
+ if (refreshPromise && !options?.force) {
170
+ await refreshPromise;
171
+ return;
172
+ }
173
+ const now = Date.now();
174
+ if (!options?.force && lastRefreshAttemptAt && now - lastRefreshAttemptAt < MIN_REFRESH_INTERVAL_MS) {
175
+ if (refreshPromise) await refreshPromise;
176
+ return;
177
+ }
178
+ lastRefreshAttemptAt = now;
179
+ const log = options?.logger ?? defaultLogger;
180
+ refreshPromise = (async () => {
181
+ const modelsByProvider = await buildModelsByProviderFromRemote({
182
+ userAgent: "dexto-llm-registry",
183
+ timeoutMs: 3e4
184
+ });
185
+ const cachePath = getCachePath();
186
+ await writeCacheFile(cachePath, modelsByProvider);
187
+ applyModelsByProvider(modelsByProvider);
188
+ lastFetchedAt = Date.now();
189
+ lastSource = "remote";
190
+ log?.debug?.(`Refreshed LLM registry cache (${cachePath})`);
191
+ })().catch((e) => {
192
+ log?.warn?.(
193
+ `Failed to refresh LLM registry cache: ${e instanceof Error ? e.message : String(e)}`
194
+ );
195
+ }).finally(() => {
196
+ refreshPromise = null;
197
+ });
198
+ await refreshPromise;
199
+ }
200
+ function startLlmRegistryAutoUpdate(options) {
201
+ if (autoRefreshStarted) return;
202
+ autoRefreshStarted = true;
203
+ const log = options?.logger ?? defaultLogger;
204
+ const loaded = loadLlmRegistryCache({ logger: log });
205
+ if (loaded) {
206
+ log?.debug?.(`Loaded LLM registry cache from disk (${getCachePath()})`);
207
+ }
208
+ if (options?.refreshOnStart !== false) {
209
+ void refreshLlmRegistryCache({ logger: log });
210
+ }
211
+ const timer = setInterval(
212
+ () => {
213
+ const ttlMs = getTtlMs();
214
+ const now = Date.now();
215
+ if (lastFetchedAt && isFresh(now, lastFetchedAt, ttlMs)) return;
216
+ void refreshLlmRegistryCache({ logger: log });
217
+ },
218
+ Math.min(getTtlMs(), DEFAULT_TTL_MS)
219
+ );
220
+ timer.unref?.();
221
+ }
222
+ export {
223
+ getLlmRegistryAutoUpdateStatus,
224
+ loadLlmRegistryCache,
225
+ refreshLlmRegistryCache,
226
+ startLlmRegistryAutoUpdate
227
+ };