@gaunt-sloth/core 2.0.0-alpha.8 → 2.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/.gsloth.review.md +2 -0
  2. package/README.md +71 -20
  3. package/dist/config/colour.d.ts +38 -0
  4. package/dist/config/colour.js +36 -0
  5. package/dist/config/colour.js.map +1 -0
  6. package/dist/config/configDiscovery.d.ts +79 -0
  7. package/dist/config/configDiscovery.js +80 -0
  8. package/dist/config/configDiscovery.js.map +1 -0
  9. package/dist/config/defaults.d.ts +20 -20
  10. package/dist/config/defaults.js +10 -8
  11. package/dist/config/defaults.js.map +1 -1
  12. package/dist/config/filesystem-tools.d.ts +41 -0
  13. package/dist/config/filesystem-tools.js +56 -0
  14. package/dist/config/filesystem-tools.js.map +1 -0
  15. package/dist/config/loader.d.ts +171 -19
  16. package/dist/config/loader.js +1054 -144
  17. package/dist/config/loader.js.map +1 -1
  18. package/dist/config/mouse.d.ts +50 -0
  19. package/dist/config/mouse.js +44 -0
  20. package/dist/config/mouse.js.map +1 -0
  21. package/dist/config/profiles.d.ts +68 -0
  22. package/dist/config/profiles.js +93 -0
  23. package/dist/config/profiles.js.map +1 -0
  24. package/dist/config/providerKeys.d.ts +69 -0
  25. package/dist/config/providerKeys.js +69 -0
  26. package/dist/config/providerKeys.js.map +1 -0
  27. package/dist/config/schema.d.ts +2671 -138
  28. package/dist/config/schema.js +1361 -85
  29. package/dist/config/schema.js.map +1 -1
  30. package/dist/config/shell-policy.d.ts +899 -111
  31. package/dist/config/shell-policy.js +800 -70
  32. package/dist/config/shell-policy.js.map +1 -1
  33. package/dist/config/tool-descriptions.d.ts +211 -0
  34. package/dist/config/tool-descriptions.js +272 -0
  35. package/dist/config/tool-descriptions.js.map +1 -0
  36. package/dist/config/types.d.ts +352 -41
  37. package/dist/config/types.js +1 -0
  38. package/dist/config/types.js.map +1 -1
  39. package/dist/config.d.ts +35 -1
  40. package/dist/config.js +16 -1
  41. package/dist/config.js.map +1 -1
  42. package/dist/constants.d.ts +28 -1
  43. package/dist/constants.js +28 -1
  44. package/dist/constants.js.map +1 -1
  45. package/dist/core/GthAbstractAgent.d.ts +166 -11
  46. package/dist/core/GthAbstractAgent.js +484 -45
  47. package/dist/core/GthAbstractAgent.js.map +1 -1
  48. package/dist/core/GthAgentRunner.d.ts +543 -57
  49. package/dist/core/GthAgentRunner.js +1494 -140
  50. package/dist/core/GthAgentRunner.js.map +1 -1
  51. package/dist/core/GthLangChainAgent.d.ts +117 -2
  52. package/dist/core/GthLangChainAgent.js +602 -29
  53. package/dist/core/GthLangChainAgent.js.map +1 -1
  54. package/dist/core/approvals/annotations.d.ts +122 -0
  55. package/dist/core/approvals/annotations.js +137 -0
  56. package/dist/core/approvals/annotations.js.map +1 -0
  57. package/dist/core/approvals/grants.d.ts +216 -0
  58. package/dist/core/approvals/grants.js +469 -0
  59. package/dist/core/approvals/grants.js.map +1 -0
  60. package/dist/core/approvals/matcher.d.ts +202 -0
  61. package/dist/core/approvals/matcher.js +267 -0
  62. package/dist/core/approvals/matcher.js.map +1 -0
  63. package/dist/core/approvals/mcpSubjects.d.ts +40 -0
  64. package/dist/core/approvals/mcpSubjects.js +99 -0
  65. package/dist/core/approvals/mcpSubjects.js.map +1 -0
  66. package/dist/core/approvals/promptHeader.d.ts +28 -0
  67. package/dist/core/approvals/promptHeader.js +62 -0
  68. package/dist/core/approvals/promptHeader.js.map +1 -0
  69. package/dist/core/approvals/toolAnnotationSources.d.ts +105 -0
  70. package/dist/core/approvals/toolAnnotationSources.js +277 -0
  71. package/dist/core/approvals/toolAnnotationSources.js.map +1 -0
  72. package/dist/core/approvals/toolHost.d.ts +46 -0
  73. package/dist/core/approvals/toolHost.js +108 -0
  74. package/dist/core/approvals/toolHost.js.map +1 -0
  75. package/dist/core/debugCapture.d.ts +74 -0
  76. package/dist/core/debugCapture.js +100 -0
  77. package/dist/core/debugCapture.js.map +1 -0
  78. package/dist/core/gthLeanAgentFactory.d.ts +4 -4
  79. package/dist/core/gthLeanAgentFactory.js +4 -4
  80. package/dist/core/launchBanner.d.ts +127 -0
  81. package/dist/core/launchBanner.js +414 -0
  82. package/dist/core/launchBanner.js.map +1 -0
  83. package/dist/core/modelLabel.d.ts +19 -0
  84. package/dist/core/modelLabel.js +26 -0
  85. package/dist/core/modelLabel.js.map +1 -0
  86. package/dist/core/plainToolIndication.d.ts +15 -0
  87. package/dist/core/plainToolIndication.js +174 -0
  88. package/dist/core/plainToolIndication.js.map +1 -0
  89. package/dist/core/reasoningBlocks.d.ts +65 -0
  90. package/dist/core/reasoningBlocks.js +103 -0
  91. package/dist/core/reasoningBlocks.js.map +1 -0
  92. package/dist/core/refusal.d.ts +53 -0
  93. package/dist/core/refusal.js +133 -0
  94. package/dist/core/refusal.js.map +1 -0
  95. package/dist/core/runHeader.d.ts +38 -0
  96. package/dist/core/runHeader.js +42 -0
  97. package/dist/core/runHeader.js.map +1 -0
  98. package/dist/core/runStats.d.ts +14 -3
  99. package/dist/core/runStats.js +48 -3
  100. package/dist/core/runStats.js.map +1 -1
  101. package/dist/core/shell/ShellCommandFailedError.d.ts +3 -4
  102. package/dist/core/shell/ShellCommandFailedError.js +3 -4
  103. package/dist/core/shell/ShellCommandFailedError.js.map +1 -1
  104. package/dist/core/shell/abstention.d.ts +88 -0
  105. package/dist/core/shell/abstention.js +184 -0
  106. package/dist/core/shell/abstention.js.map +1 -0
  107. package/dist/core/shell/approvalCapture.d.ts +271 -0
  108. package/dist/core/shell/approvalCapture.js +108 -0
  109. package/dist/core/shell/approvalCapture.js.map +1 -0
  110. package/dist/core/shell/approvalStop.d.ts +123 -0
  111. package/dist/core/shell/approvalStop.js +269 -0
  112. package/dist/core/shell/approvalStop.js.map +1 -0
  113. package/dist/core/shell/arity.d.ts +6 -0
  114. package/dist/core/shell/arity.js +20 -6
  115. package/dist/core/shell/arity.js.map +1 -1
  116. package/dist/core/shell/denylist.d.ts +11 -0
  117. package/dist/core/shell/denylist.js +37 -0
  118. package/dist/core/shell/denylist.js.map +1 -0
  119. package/dist/core/shell/escalationSeverity.d.ts +141 -0
  120. package/dist/core/shell/escalationSeverity.js +89 -0
  121. package/dist/core/shell/escalationSeverity.js.map +1 -0
  122. package/dist/core/shell/framing.d.ts +190 -0
  123. package/dist/core/shell/framing.js +633 -0
  124. package/dist/core/shell/framing.js.map +1 -0
  125. package/dist/core/shell/hardline.d.ts +103 -0
  126. package/dist/core/shell/hardline.js +780 -0
  127. package/dist/core/shell/hardline.js.map +1 -0
  128. package/dist/core/shell/negotiation.d.ts +328 -0
  129. package/dist/core/shell/negotiation.js +488 -0
  130. package/dist/core/shell/negotiation.js.map +1 -0
  131. package/dist/core/shell/normalize.d.ts +44 -4
  132. package/dist/core/shell/normalize.js +61 -7
  133. package/dist/core/shell/normalize.js.map +1 -1
  134. package/dist/core/shell/openWorld.d.ts +263 -0
  135. package/dist/core/shell/openWorld.js +1188 -0
  136. package/dist/core/shell/openWorld.js.map +1 -0
  137. package/dist/core/shell/rater.d.ts +873 -0
  138. package/dist/core/shell/rater.js +1454 -0
  139. package/dist/core/shell/rater.js.map +1 -0
  140. package/dist/core/shell/raterModel.d.ts +41 -0
  141. package/dist/core/shell/raterModel.js +51 -0
  142. package/dist/core/shell/raterModel.js.map +1 -0
  143. package/dist/core/shell/raterVocabulary.d.ts +121 -0
  144. package/dist/core/shell/raterVocabulary.js +116 -0
  145. package/dist/core/shell/raterVocabulary.js.map +1 -0
  146. package/dist/core/shell/rejection.d.ts +69 -0
  147. package/dist/core/shell/rejection.js +38 -0
  148. package/dist/core/shell/rejection.js.map +1 -0
  149. package/dist/core/toolCallRepair/grammar.d.ts +41 -0
  150. package/dist/core/toolCallRepair/grammar.js +116 -0
  151. package/dist/core/toolCallRepair/grammar.js.map +1 -0
  152. package/dist/core/toolCallRepair/index.d.ts +2 -0
  153. package/dist/core/toolCallRepair/index.js +7 -0
  154. package/dist/core/toolCallRepair/index.js.map +1 -0
  155. package/dist/core/toolCallRepair/payload.d.ts +36 -0
  156. package/dist/core/toolCallRepair/payload.js +341 -0
  157. package/dist/core/toolCallRepair/payload.js.map +1 -0
  158. package/dist/core/toolCallRepair/promote.d.ts +45 -0
  159. package/dist/core/toolCallRepair/promote.js +90 -0
  160. package/dist/core/toolCallRepair/promote.js.map +1 -0
  161. package/dist/core/toolDisplay.d.ts +123 -0
  162. package/dist/core/toolDisplay.js +451 -0
  163. package/dist/core/toolDisplay.js.map +1 -0
  164. package/dist/core/toolOutputChannel.d.ts +95 -0
  165. package/dist/core/toolOutputChannel.js +165 -0
  166. package/dist/core/toolOutputChannel.js.map +1 -0
  167. package/dist/core/types.d.ts +349 -16
  168. package/dist/core/types.js.map +1 -1
  169. package/dist/history/historyFormat.d.ts +12 -3
  170. package/dist/history/historyFormat.js +50 -8
  171. package/dist/history/historyFormat.js.map +1 -1
  172. package/dist/history/historyStore.d.ts +77 -0
  173. package/dist/history/historyStore.js +173 -6
  174. package/dist/history/historyStore.js.map +1 -1
  175. package/dist/history/recordSession.d.ts +10 -1
  176. package/dist/history/recordSession.js +27 -0
  177. package/dist/history/recordSession.js.map +1 -1
  178. package/dist/providers/anthropic.js +12 -0
  179. package/dist/providers/anthropic.js.map +1 -1
  180. package/dist/providers/configurationPassthrough.d.ts +107 -0
  181. package/dist/providers/configurationPassthrough.js +148 -0
  182. package/dist/providers/configurationPassthrough.js.map +1 -0
  183. package/dist/providers/geminiSchemaSanitizer.d.ts +55 -0
  184. package/dist/providers/geminiSchemaSanitizer.js +347 -0
  185. package/dist/providers/geminiSchemaSanitizer.js.map +1 -0
  186. package/dist/providers/geminiThinking.d.ts +60 -0
  187. package/dist/providers/geminiThinking.js +92 -0
  188. package/dist/providers/geminiThinking.js.map +1 -0
  189. package/dist/providers/google-genai.js +18 -1
  190. package/dist/providers/google-genai.js.map +1 -1
  191. package/dist/providers/groq.js +12 -0
  192. package/dist/providers/groq.js.map +1 -1
  193. package/dist/providers/huggingface.d.ts +25 -0
  194. package/dist/providers/huggingface.js +69 -0
  195. package/dist/providers/huggingface.js.map +1 -0
  196. package/dist/providers/modelCatalog.d.ts +109 -0
  197. package/dist/providers/modelCatalog.js +245 -0
  198. package/dist/providers/modelCatalog.js.map +1 -0
  199. package/dist/providers/modelDiscovery.d.ts +99 -5
  200. package/dist/providers/modelDiscovery.js +191 -35
  201. package/dist/providers/modelDiscovery.js.map +1 -1
  202. package/dist/providers/ollama.d.ts +18 -4
  203. package/dist/providers/ollama.js +67 -37
  204. package/dist/providers/ollama.js.map +1 -1
  205. package/dist/providers/openai.js +34 -0
  206. package/dist/providers/openai.js.map +1 -1
  207. package/dist/providers/openrouter.d.ts +26 -4
  208. package/dist/providers/openrouter.js +83 -26
  209. package/dist/providers/openrouter.js.map +1 -1
  210. package/dist/providers/vertexai.js +19 -1
  211. package/dist/providers/vertexai.js.map +1 -1
  212. package/dist/providers/xai.js +20 -0
  213. package/dist/providers/xai.js.map +1 -1
  214. package/dist/runtime/askStructured.d.ts +105 -0
  215. package/dist/runtime/askStructured.js +120 -0
  216. package/dist/runtime/askStructured.js.map +1 -0
  217. package/dist/runtime/conversation.d.ts +64 -0
  218. package/dist/runtime/conversation.js +171 -0
  219. package/dist/runtime/conversation.js.map +1 -0
  220. package/dist/runtime/singleShot.d.ts +37 -6
  221. package/dist/runtime/singleShot.js +113 -67
  222. package/dist/runtime/singleShot.js.map +1 -1
  223. package/dist/runtime/structuredOutput.d.ts +104 -0
  224. package/dist/runtime/structuredOutput.js +393 -0
  225. package/dist/runtime/structuredOutput.js.map +1 -0
  226. package/dist/utils/ProgressIndicator.d.ts +21 -0
  227. package/dist/utils/ProgressIndicator.js +30 -3
  228. package/dist/utils/ProgressIndicator.js.map +1 -1
  229. package/dist/utils/aiignoreUtils.js.map +1 -1
  230. package/dist/utils/binaryOutputUtils.js.map +1 -1
  231. package/dist/utils/consoleUtils.d.ts +95 -0
  232. package/dist/utils/consoleUtils.js +112 -2
  233. package/dist/utils/consoleUtils.js.map +1 -1
  234. package/dist/utils/crashHandler.d.ts +87 -0
  235. package/dist/utils/crashHandler.js +128 -0
  236. package/dist/utils/crashHandler.js.map +1 -0
  237. package/dist/utils/debugDump.d.ts +134 -0
  238. package/dist/utils/debugDump.js +381 -0
  239. package/dist/utils/debugDump.js.map +1 -0
  240. package/dist/utils/debugUtils.d.ts +13 -4
  241. package/dist/utils/debugUtils.js +36 -13
  242. package/dist/utils/debugUtils.js.map +1 -1
  243. package/dist/utils/displayWidth.d.ts +53 -0
  244. package/dist/utils/displayWidth.js +195 -0
  245. package/dist/utils/displayWidth.js.map +1 -0
  246. package/dist/utils/fileUtils.js.map +1 -1
  247. package/dist/utils/globalConfigUtils.d.ts +14 -2
  248. package/dist/utils/globalConfigUtils.js +22 -4
  249. package/dist/utils/globalConfigUtils.js.map +1 -1
  250. package/dist/utils/llmUtils.d.ts +39 -8
  251. package/dist/utils/llmUtils.js +76 -8
  252. package/dist/utils/llmUtils.js.map +1 -1
  253. package/dist/utils/redactSecrets.d.ts +63 -0
  254. package/dist/utils/redactSecrets.js +286 -0
  255. package/dist/utils/redactSecrets.js.map +1 -0
  256. package/dist/utils/systemPromptNotes.d.ts +222 -0
  257. package/dist/utils/systemPromptNotes.js +338 -0
  258. package/dist/utils/systemPromptNotes.js.map +1 -0
  259. package/dist/utils/systemUtils.d.ts +18 -1
  260. package/dist/utils/systemUtils.js +38 -3
  261. package/dist/utils/systemUtils.js.map +1 -1
  262. package/dist/utils/toolMatching.d.ts +30 -0
  263. package/dist/utils/toolMatching.js +44 -0
  264. package/dist/utils/toolMatching.js.map +1 -0
  265. package/dist/utils/untrustedText.d.ts +86 -0
  266. package/dist/utils/untrustedText.js +101 -0
  267. package/dist/utils/untrustedText.js.map +1 -0
  268. package/package.json +21 -7
  269. package/schema/gsloth-config.schema.json +1921 -326
  270. package/dist/core/shell/allowlist.d.ts +0 -75
  271. package/dist/core/shell/allowlist.js +0 -187
  272. package/dist/core/shell/allowlist.js.map +0 -1
  273. package/dist/core/shell/judge.d.ts +0 -161
  274. package/dist/core/shell/judge.js +0 -261
  275. package/dist/core/shell/judge.js.map +0 -1
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Model families to leave alone when ADDING a request for thought summaries. `@langchain/google`
3
+ * itself declines to send any thinking config for a 2.5 image model, so injecting one there would
4
+ * send a field the library deliberately withheld; image/tts generations have no reasoning panel to
5
+ * fill either way. Skipping them keeps the enable path to the models it is about.
6
+ *
7
+ * This gates the ENABLE direction only, and it must never gate the disable one. The sentence it
8
+ * encodes — "we are unsure this model produces a summary, so do not ask for one" — inverts into
9
+ * "…so let one through" the moment the same test is applied to a leak-prevention override, and
10
+ * these families are exactly where `@langchain/google` sets `includeThoughts: true` on its own
11
+ * once a thinking budget is configured.
12
+ */
13
+ function producesThoughtSummaries(model) {
14
+ if (typeof model !== 'string')
15
+ return true;
16
+ return !/image|tts/i.test(model);
17
+ }
18
+ /**
19
+ * Wire thought summaries into a `ChatGoogle` model. Overrides the instance's `invocationParams` so
20
+ * that `generationConfig.thinkingConfig.includeThoughts` is set — but ONLY when the library derived
21
+ * no thinking config at all, which is the "user configured nothing, the API default budget applies"
22
+ * case. When the user DID configure a budget or level, `@langchain/google` has already decided
23
+ * `includeThoughts` from it (true when thinking is on, false when they asked for none/minimal) and
24
+ * that decision is left exactly as it stands. Returns the same model instance for chaining.
25
+ */
26
+ export function applyGeminiThoughtSummaries(model) {
27
+ if (!producesThoughtSummaries(model.model)) {
28
+ return model;
29
+ }
30
+ return overrideThinkingConfig(model, (thinkingConfig) =>
31
+ // `thinkingConfig` is always PRESENT as a key and may hold `undefined`; an explicit value means
32
+ // the user's budget/level was honoured and must win.
33
+ thinkingConfig === undefined ? { includeThoughts: true } : thinkingConfig);
34
+ }
35
+ /**
36
+ * The inverse, for a surface that must not receive thought summaries at all: keep whatever thinking
37
+ * budget or level applies and force `includeThoughts: false`, so the model still thinks and only the
38
+ * summary is withheld. Never express this as a zero/minimal budget — that turns THINKING off, which
39
+ * is a different and much larger change, and the coercion differs between the 2.5 and 3.x presets.
40
+ *
41
+ * This exists because a consumer outside {@link GthAbstractAgent} routes content blocks by `type`,
42
+ * and Gemini's thought summary is typed `text` exactly like an answer block — so a third party has
43
+ * no way to tell them apart and prints the thinking as the assistant's answer. Not asking for the
44
+ * summary is the only thing that reliably stops that; nothing is stripped, so the message kept in
45
+ * graph state (and any `thoughtSignature` riding on it) is untouched. Returns the same instance.
46
+ *
47
+ * It applies to EVERY model family, including the image/tts ones the enable path skips: those are
48
+ * precisely where `@langchain/google` sets `includeThoughts: true` itself once a budget or level is
49
+ * configured, so a shared "does this model produce summaries?" guard would let exactly those
50
+ * summaries through. What it will not do is INTRODUCE a thinking config where the library built
51
+ * none — a request that carries no `thinkingConfig` gets no summary anyway (that is the whole
52
+ * premise of {@link applyGeminiThoughtSummaries}), and adding the field to a model family the
53
+ * library withholds it from would send something it deliberately did not.
54
+ */
55
+ export function disableGeminiThoughtSummaries(model) {
56
+ return overrideThinkingConfig(model, (thinkingConfig) => thinkingConfig === undefined
57
+ ? thinkingConfig
58
+ : {
59
+ ...(typeof thinkingConfig === 'object' && thinkingConfig !== null ? thinkingConfig : {}),
60
+ includeThoughts: false,
61
+ });
62
+ }
63
+ /**
64
+ * Shared plumbing: re-derive `generationConfig.thinkingConfig` on every built request. Models that
65
+ * build no `generationConfig` (every non-Google provider) are left completely alone, so this is a
66
+ * no-op wherever it does not apply. Which model families to skip is the CALLER's decision, because
67
+ * it differs by direction — see {@link producesThoughtSummaries}. Overrides stack: the outermost one
68
+ * sees what the inner ones produced, which is what lets a surface-level decision override the
69
+ * construction-time default.
70
+ */
71
+ function overrideThinkingConfig(model, next) {
72
+ const holder = model;
73
+ const original = holder.invocationParams;
74
+ if (typeof original !== 'function') {
75
+ return model;
76
+ }
77
+ const bound = original.bind(model);
78
+ holder.invocationParams = function invocationParamsWithThinkingConfig(options) {
79
+ const params = bound(options);
80
+ const generationConfig = params?.generationConfig;
81
+ if (!generationConfig) {
82
+ return params;
83
+ }
84
+ const thinkingConfig = next(generationConfig.thinkingConfig);
85
+ if (thinkingConfig === generationConfig.thinkingConfig) {
86
+ return params;
87
+ }
88
+ return { ...params, generationConfig: { ...generationConfig, thinkingConfig } };
89
+ };
90
+ return model;
91
+ }
92
+ //# sourceMappingURL=geminiThinking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geminiThinking.js","sourceRoot":"","sources":["../../src/providers/geminiThinking.ts"],"names":[],"mappings":"AAmCA;;;;;;;;;;;GAWG;AACH,SAAS,wBAAwB,CAAC,KAAc;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3C,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,2BAA2B,CAA0B,KAAQ;IAC3E,IAAI,CAAC,wBAAwB,CAAE,KAAwC,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,sBAAsB,CAAC,KAAK,EAAE,CAAC,cAAc,EAAE,EAAE;IACtD,gGAAgG;IAChG,qDAAqD;IACrD,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,cAAc,CAC1E,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,6BAA6B,CAA0B,KAAQ;IAC7E,OAAO,sBAAsB,CAAC,KAAK,EAAE,CAAC,cAAc,EAAE,EAAE,CACtD,cAAc,KAAK,SAAS;QAC1B,CAAC,CAAC,cAAc;QAChB,CAAC,CAAC;YACE,GAAG,CAAC,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;YACxF,eAAe,EAAE,KAAK;SACvB,CACN,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,sBAAsB,CAC7B,KAAQ,EACR,IAA2C;IAE3C,MAAM,MAAM,GAAG,KAA8E,CAAC;IAC9F,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC;IACzC,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAuB,CAAC;IACzD,MAAM,CAAC,gBAAgB,GAAG,SAAS,kCAAkC,CACnE,OAAiB;QAEjB,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,gBAAgB,GAAG,MAAM,EAAE,gBAAgB,CAAC;QAClD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,cAAc,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;QAC7D,IAAI,cAAc,KAAK,gBAAgB,CAAC,cAAc,EAAE,CAAC;YACvD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,EAAE,GAAG,MAAM,EAAE,gBAAgB,EAAE,EAAE,GAAG,gBAAgB,EAAE,cAAc,EAAE,EAAE,CAAC;IAClF,CAAC,CAAC;IACF,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -2,6 +2,9 @@ import { displayWarning } from '#src/utils/consoleUtils.js';
2
2
  import { env } from '#src/utils/systemUtils.js';
3
3
  import { writeConfigFileWithMessages } from '#src/utils/fileUtils.js';
4
4
  import { buildInitConfigContent, getCuratedFallbackModel } from '#src/providers/modelDiscovery.js';
5
+ import { applyGeminiToolSchemaSanitizer } from '#src/providers/geminiSchemaSanitizer.js';
6
+ import { applyGeminiThoughtSummaries } from '#src/providers/geminiThinking.js';
7
+ import { NATIVE_CLIENT_REASON, warnUnusedConfiguration, } from '#src/providers/configurationPassthrough.js';
5
8
  // Function to process JSON config and create Google GenAI LLM instance
6
9
  export async function processJsonConfig(llmConfig) {
7
10
  const { ChatGoogle } = await import('@langchain/google/node');
@@ -15,7 +18,21 @@ export async function processJsonConfig(llmConfig) {
15
18
  };
16
19
  delete configFields.type;
17
20
  delete configFields.apiKeyEnvironmentVariable;
18
- return new ChatGoogle(configFields);
21
+ // `ChatGoogle` is a native client for the Gemini API, so nothing in a `configuration` block
22
+ // reaches it — say so before dropping it.
23
+ warnUnusedConfiguration({
24
+ provider: 'google-genai',
25
+ configuration: llmConfig.configuration,
26
+ consumedPaths: [],
27
+ reason: NATIVE_CLIENT_REASON,
28
+ guidance: 'ChatGoogle talks to the Gemini API through its own client instead: set "customHeaders", ' +
29
+ '"endpoint" or "apiVersion" as top-level fields of the "llm" block beside "model".',
30
+ });
31
+ // GS2-58: normalise every tool's JSON-Schema at the ChatGoogle boundary so Gemini's OpenAPI-3.0
32
+ // subset accepts built-in, custom, and MCP tools alike (see geminiSchemaSanitizer).
33
+ // CFG-33: ask for the thought summaries of the thinking Gemini already does and already bills,
34
+ // so the reasoning channel is fed instead of discarded (see geminiThinking).
35
+ return applyGeminiThoughtSummaries(applyGeminiToolSchemaSanitizer(new ChatGoogle(configFields)));
19
36
  }
20
37
  export function init(configFileName, force = false, model) {
21
38
  // Determine which content to use based on file extension
@@ -1 +1 @@
1
- {"version":3,"file":"google-genai.js","sourceRoot":"","sources":["../../src/providers/google-genai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAIhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAEnG,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAmF;IAEnF,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IAC9D,wEAAwE;IACxE,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC,cAAc,CAAC;IAC5D,MAAM,YAAY,GAAG;QACnB,GAAG,SAAS;QACZ,MAAM,EAAE,YAAY;QACpB,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,uBAAuB,CAAC,cAAc,CAAC;QACjE,YAAY,EAAE,KAAc;KAC7B,CAAC;IACF,OAAO,YAAY,CAAC,IAAI,CAAC;IACzB,OAAO,YAAY,CAAC,yBAAyB,CAAC;IAC9C,OAAO,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,cAAsB,EAAE,KAAK,GAAG,KAAK,EAAE,KAAc;IACxE,yDAAyD;IACzD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,2BAA2B,CAAC,cAAc,EAAE,sBAAsB,CAAC,cAAc,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IAClG,cAAc,CACZ,2BAA2B,cAAc,qCAAqC;QAC5E,gDAAgD,CACnD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"google-genai.js","sourceRoot":"","sources":["../../src/providers/google-genai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAIhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AACnG,OAAO,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,4CAA4C,CAAC;AAEpD,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAmF;IAEnF,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IAC9D,wEAAwE;IACxE,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC,cAAc,CAAC;IAC5D,MAAM,YAAY,GAAG;QACnB,GAAG,SAAS;QACZ,MAAM,EAAE,YAAY;QACpB,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,uBAAuB,CAAC,cAAc,CAAC;QACjE,YAAY,EAAE,KAAc;KAC7B,CAAC;IACF,OAAO,YAAY,CAAC,IAAI,CAAC;IACzB,OAAO,YAAY,CAAC,yBAAyB,CAAC;IAC9C,4FAA4F;IAC5F,0CAA0C;IAC1C,uBAAuB,CAAC;QACtB,QAAQ,EAAE,cAAc;QACxB,aAAa,EAAG,SAAyC,CAAC,aAAa;QACvE,aAAa,EAAE,EAAE;QACjB,MAAM,EAAE,oBAAoB;QAC5B,QAAQ,EACN,0FAA0F;YAC1F,mFAAmF;KACtF,CAAC,CAAC;IACH,gGAAgG;IAChG,oFAAoF;IACpF,+FAA+F;IAC/F,6EAA6E;IAC7E,OAAO,2BAA2B,CAAC,8BAA8B,CAAC,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,cAAsB,EAAE,KAAK,GAAG,KAAK,EAAE,KAAc;IACxE,yDAAyD;IACzD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,2BAA2B,CAAC,cAAc,EAAE,sBAAsB,CAAC,cAAc,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IAClG,cAAc,CACZ,2BAA2B,cAAc,qCAAqC;QAC5E,gDAAgD,CACnD,CAAC;AACJ,CAAC"}
@@ -2,11 +2,23 @@ import { displayWarning } from '#src/utils/consoleUtils.js';
2
2
  import { env } from '#src/utils/systemUtils.js';
3
3
  import { writeConfigFileWithMessages } from '#src/utils/fileUtils.js';
4
4
  import { buildInitConfigContent, getCuratedFallbackModel } from '#src/providers/modelDiscovery.js';
5
+ import { NATIVE_CLIENT_REASON, warnUnusedConfiguration, } from '#src/providers/configurationPassthrough.js';
5
6
  // Function to process JSON config and create Groq LLM instance
6
7
  export async function processJsonConfig(llmConfig) {
7
8
  const groq = await import('@langchain/groq');
8
9
  // Use config value if available, otherwise use the environment variable
9
10
  const groqApiKey = llmConfig.apiKey || env.GROQ_API_KEY;
11
+ // `ChatGroq` builds a Groq SDK client from its own TOP-LEVEL fields, so nothing in a
12
+ // `configuration` block reaches it — say so before dropping it.
13
+ warnUnusedConfiguration({
14
+ provider: 'groq',
15
+ configuration: llmConfig.configuration,
16
+ consumedPaths: [],
17
+ reason: NATIVE_CLIENT_REASON,
18
+ guidance: 'ChatGroq builds a Groq SDK client from top-level fields of the "llm" block instead: set ' +
19
+ '"baseUrl" (note the lower-case "url"), "timeout", "defaultHeaders", "defaultQuery", ' +
20
+ '"httpAgent" or "fetch" beside "model".',
21
+ });
10
22
  return new groq.ChatGroq({
11
23
  ...llmConfig,
12
24
  apiKey: groqApiKey,
@@ -1 +1 @@
1
- {"version":3,"file":"groq.js","sourceRoot":"","sources":["../../src/providers/groq.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAIhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAEnG,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAAwB;IAC9D,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAC7C,wEAAwE;IACxE,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC,YAAY,CAAC;IACxD,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC;QACvB,GAAG,SAAS;QACZ,MAAM,EAAE,UAAU;QAClB,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,uBAAuB,CAAC,MAAM,CAAC;KAC1D,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,cAAsB,EAAE,KAAK,GAAG,KAAK,EAAE,KAAc;IACxE,yDAAyD;IACzD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,2BAA2B,CAAC,cAAc,EAAE,sBAAsB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IAC1F,cAAc,CACZ,yBAAyB,cAAc,uBAAuB;QAC5D,8CAA8C,CACjD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"groq.js","sourceRoot":"","sources":["../../src/providers/groq.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAIhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AACnG,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,4CAA4C,CAAC;AAEpD,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAAwB;IAC9D,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAC7C,wEAAwE;IACxE,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC,YAAY,CAAC;IACxD,qFAAqF;IACrF,gEAAgE;IAChE,uBAAuB,CAAC;QACtB,QAAQ,EAAE,MAAM;QAChB,aAAa,EAAG,SAAyC,CAAC,aAAa;QACvE,aAAa,EAAE,EAAE;QACjB,MAAM,EAAE,oBAAoB;QAC5B,QAAQ,EACN,0FAA0F;YAC1F,sFAAsF;YACtF,wCAAwC;KAC3C,CAAC,CAAC;IACH,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC;QACvB,GAAG,SAAS;QACZ,MAAM,EAAE,UAAU;QAClB,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,uBAAuB,CAAC,MAAM,CAAC;KAC1D,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,cAAsB,EAAE,KAAK,GAAG,KAAK,EAAE,KAAc;IACxE,yDAAyD;IACzD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,2BAA2B,CAAC,cAAc,EAAE,sBAAsB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IAC1F,cAAc,CACZ,yBAAyB,cAAc,uBAAuB;QAC5D,8CAA8C,CACjD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { BaseChatModel, type BaseChatModelParams } from '@langchain/core/language_models/chat_models';
2
+ import { OpenAIChatInput } from '@langchain/openai';
3
+ import { ChatOpenAIFields } from '@langchain/openai';
4
+ /**
5
+ * Hugging Face Inference Providers — OpenAI-compatible router.
6
+ *
7
+ * HF exposes a single OpenAI-compatible Chat Completions endpoint at
8
+ * `https://router.huggingface.co/v1` that fans requests out to the configured
9
+ * inference provider (Cerebras, Groq, Together, SambaNova, hf-inference, …). It
10
+ * supports tool/function calling, streaming and structured outputs, so we reuse
11
+ * LangChain's `ChatOpenAI` exactly like the OpenRouter provider — no dedicated
12
+ * `@langchain/huggingface` package is needed (the JS `@langchain/community`
13
+ * `HuggingFaceInference` is a text-completion LLM with no `bindTools`, so it is
14
+ * unusable for the agent loop).
15
+ *
16
+ * Auth uses a Hugging Face user access token with the "Inference Providers"
17
+ * permission, read from `HF_TOKEN` (canonical) or the `HUGGINGFACEHUB_API_TOKEN`
18
+ * / `HF_API_KEY` aliases.
19
+ *
20
+ * Model ids are Hub repo ids, e.g. `openai/gpt-oss-120b`. You may append a
21
+ * provider/policy suffix understood by the router (`:groq`, `:cheapest`,
22
+ * `:fastest`); it is part of the model id and passes straight through.
23
+ */
24
+ export declare function processJsonConfig(llmConfig: OpenAIChatInput & ChatOpenAIFields & BaseChatModelParams): Promise<BaseChatModel>;
25
+ export declare function init(configFileName: string, force?: boolean, model?: string): void;
@@ -0,0 +1,69 @@
1
+ import { displayWarning } from '#src/utils/consoleUtils.js';
2
+ import { env } from '#src/utils/systemUtils.js';
3
+ import { writeConfigFileWithMessages } from '#src/utils/fileUtils.js';
4
+ import { buildInitConfigContent, getCuratedFallbackModel } from '#src/providers/modelDiscovery.js';
5
+ /**
6
+ * Hugging Face Inference Providers — OpenAI-compatible router.
7
+ *
8
+ * HF exposes a single OpenAI-compatible Chat Completions endpoint at
9
+ * `https://router.huggingface.co/v1` that fans requests out to the configured
10
+ * inference provider (Cerebras, Groq, Together, SambaNova, hf-inference, …). It
11
+ * supports tool/function calling, streaming and structured outputs, so we reuse
12
+ * LangChain's `ChatOpenAI` exactly like the OpenRouter provider — no dedicated
13
+ * `@langchain/huggingface` package is needed (the JS `@langchain/community`
14
+ * `HuggingFaceInference` is a text-completion LLM with no `bindTools`, so it is
15
+ * unusable for the agent loop).
16
+ *
17
+ * Auth uses a Hugging Face user access token with the "Inference Providers"
18
+ * permission, read from `HF_TOKEN` (canonical) or the `HUGGINGFACEHUB_API_TOKEN`
19
+ * / `HF_API_KEY` aliases.
20
+ *
21
+ * Model ids are Hub repo ids, e.g. `openai/gpt-oss-120b`. You may append a
22
+ * provider/policy suffix understood by the router (`:groq`, `:cheapest`,
23
+ * `:fastest`); it is part of the model id and passes straight through.
24
+ */
25
+ // Function to process JSON config and create Hugging Face LLM instance
26
+ // noinspection JSUnusedGlobalSymbols
27
+ export async function processJsonConfig(llmConfig) {
28
+ const { ChatOpenAI } = await import('@langchain/openai');
29
+ // Use environment variable if available, otherwise use the config value
30
+ const huggingFaceToken = getApiKey(llmConfig);
31
+ if (!huggingFaceToken) {
32
+ throw new Error('You need to define HF_TOKEN environment variable (a Hugging Face access token ' +
33
+ 'with the "Inference Providers" permission), or set apiKey in your config file.');
34
+ }
35
+ const configFields = {
36
+ ...llmConfig,
37
+ apiKey: huggingFaceToken,
38
+ model: llmConfig.model || getCuratedFallbackModel('huggingface'),
39
+ configuration: {
40
+ baseURL: 'https://router.huggingface.co/v1',
41
+ ...(llmConfig.configuration || {}),
42
+ },
43
+ };
44
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
+ delete configFields.type;
46
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
+ delete configFields.apiKeyEnvironmentVariable;
48
+ return new ChatOpenAI(configFields);
49
+ }
50
+ function getApiKey(llmConfig) {
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ const conf = llmConfig;
53
+ if (conf.apiKeyEnvironmentVariable && env[conf.apiKeyEnvironmentVariable]) {
54
+ return env[conf.apiKeyEnvironmentVariable];
55
+ }
56
+ else {
57
+ return llmConfig.apiKey || env.HF_TOKEN || env.HUGGINGFACEHUB_API_TOKEN || env.HF_API_KEY;
58
+ }
59
+ }
60
+ export function init(configFileName, force = false, model) {
61
+ // Determine which content to use based on file extension
62
+ if (!configFileName.endsWith('.json')) {
63
+ throw new Error('Only JSON config is supported.');
64
+ }
65
+ writeConfigFileWithMessages(configFileName, buildInitConfigContent('huggingface', model), force);
66
+ displayWarning(`You need to edit your ${configFileName} to configure model, ` +
67
+ 'or define HF_TOKEN environment variable.');
68
+ }
69
+ //# sourceMappingURL=huggingface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"huggingface.js","sourceRoot":"","sources":["../../src/providers/huggingface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAQhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAEnG;;;;;;;;;;;;;;;;;;;GAmBG;AACH,uEAAuE;AACvE,qCAAqC;AACrC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAmE;IAEnE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACzD,wEAAwE;IACxE,MAAM,gBAAgB,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9C,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,gFAAgF;YAC9E,gFAAgF,CACnF,CAAC;IACJ,CAAC;IACD,MAAM,YAAY,GAAG;QACnB,GAAG,SAAS;QACZ,MAAM,EAAE,gBAAgB;QACxB,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,uBAAuB,CAAC,aAAa,CAAC;QAChE,aAAa,EAAE;YACb,OAAO,EAAE,kCAAkC;YAC3C,GAAG,CAAC,SAAS,CAAC,aAAa,IAAI,EAAE,CAAC;SACnC;KACF,CAAC;IACF,8DAA8D;IAC9D,OAAQ,YAAoB,CAAC,IAAI,CAAC;IAClC,8DAA8D;IAC9D,OAAQ,YAAoB,CAAC,yBAAyB,CAAC;IACvD,OAAO,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,SAAS,CAAC,SAAmE;IACpF,8DAA8D;IAC9D,MAAM,IAAI,GAAG,SAA0C,CAAC;IACxD,IAAI,IAAI,CAAC,yBAAyB,IAAI,GAAG,CAAC,IAAI,CAAC,yBAAyB,CAAC,EAAE,CAAC;QAC1E,OAAO,GAAG,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,OAAO,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,wBAAwB,IAAI,GAAG,CAAC,UAAU,CAAC;IAC5F,CAAC;AACH,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,cAAsB,EAAE,KAAK,GAAG,KAAK,EAAE,KAAc;IACxE,yDAAyD;IACzD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,2BAA2B,CAAC,cAAc,EAAE,sBAAsB,CAAC,aAAa,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IACjG,cAAc,CACZ,yBAAyB,cAAc,uBAAuB;QAC5D,0CAA0C,CAC7C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,109 @@
1
+ import type { ProviderId } from '#src/providers/modelDiscovery.js';
2
+ /** The single models.dev dataset endpoint (whole catalog; sliced per-provider on our side). */
3
+ export declare const MODELS_DEV_URL = "https://models.dev/api.json";
4
+ /**
5
+ * Cache freshness window. Pricing/limit metadata is near-static, so a day between refreshes is
6
+ * plenty; `gth models --refresh` is the manual escape hatch when a newer number is needed sooner.
7
+ */
8
+ export declare const CATALOG_TTL_MS: number;
9
+ /**
10
+ * Catalog fetch timeout. Deliberately generous (and separate from `/v1/models` discovery's 2 s
11
+ * interactive-path probe): `api.json` is a few MB and this fetch runs off the explicit `gth models`
12
+ * cache-fill path, not a first-run keystroke, so latency headroom matters more than snappiness.
13
+ */
14
+ export declare const CATALOG_TIMEOUT_MS = 10000;
15
+ /** Shown next to any enriched price/metadata. Costs from models.dev are US$ per 1M tokens. */
16
+ export declare const CATALOG_ATTRIBUTION = "* model prices provided by models.dev";
17
+ /**
18
+ * Map a Gaunt Sloth {@link ProviderId} to its models.dev top-level provider key. Cloud providers
19
+ * only; local/self-hosted providers (`ollama`) are intentionally absent so they get NO catalog
20
+ * lookup. Returns `undefined` for any provider without a models.dev slice.
21
+ */
22
+ export declare const MODELS_DEV_PROVIDER_KEY: Partial<Record<ProviderId, string>>;
23
+ /** Per-token cost metadata (US$ per 1M tokens), as published by models.dev. */
24
+ export interface ModelCost {
25
+ input?: number;
26
+ output?: number;
27
+ cacheRead?: number;
28
+ cacheWrite?: number;
29
+ }
30
+ /** Context / output token limits. */
31
+ export interface ModelLimit {
32
+ context?: number;
33
+ output?: number;
34
+ }
35
+ /** Input/output modalities (e.g. `text`, `image`, `pdf`). */
36
+ export interface ModelModalities {
37
+ input?: string[];
38
+ output?: string[];
39
+ }
40
+ /**
41
+ * Normalised catalog metadata for one model id — the models.dev fields we surface, camelCased and
42
+ * detached from models.dev's raw JSON shape so a schema change there is absorbed in the parser.
43
+ */
44
+ export interface ModelCatalogEntry {
45
+ /** models.dev display name (e.g. "Claude Opus 4.5"). */
46
+ name?: string;
47
+ cost?: ModelCost;
48
+ limit?: ModelLimit;
49
+ modalities?: ModelModalities;
50
+ /** True when the model exposes an extended-reasoning / thinking mode. */
51
+ reasoning?: boolean;
52
+ /** True when the model supports tool/function calling. */
53
+ toolCall?: boolean;
54
+ }
55
+ /** A provider's catalog slice: model-id → metadata, plus provenance for TTL / display. */
56
+ export interface ProviderCatalog {
57
+ /** Gaunt Sloth provider id this slice belongs to. */
58
+ providerId: ProviderId;
59
+ /** models.dev provider key it was sliced from. */
60
+ providerKey: string;
61
+ /** Epoch ms the slice was fetched (drives TTL freshness). */
62
+ fetchedAt: number;
63
+ /** Metadata keyed by model id, exactly as models.dev keys them. */
64
+ models: Record<string, ModelCatalogEntry>;
65
+ }
66
+ /** Options shared by catalog reads; every field is injectable for hermetic tests. */
67
+ export interface CatalogOptions {
68
+ /** Force a network refresh even when a fresh cache exists (backs `gth models --refresh`). */
69
+ refresh?: boolean;
70
+ /** Override the cache directory (defaults to `~/.gsloth/model-catalog`). */
71
+ cacheDir?: string;
72
+ /** Override "now" for TTL math (defaults to `Date.now()`). */
73
+ now?: number;
74
+ /** Override the fetch implementation (defaults to the global `fetch`). */
75
+ fetchImpl?: typeof fetch;
76
+ /** Override the TTL window in ms (defaults to {@link CATALOG_TTL_MS}). */
77
+ ttlMs?: number;
78
+ }
79
+ /**
80
+ * Get the models.dev catalog slice for one provider, cache-first.
81
+ *
82
+ * - **Local / self-hosted** (`ollama`, or any provider without a {@link MODELS_DEV_PROVIDER_KEY}):
83
+ * returns `null` immediately, with **no network call**.
84
+ * - **Cloud, fresh cache** (and not `refresh`): returns the cached slice, no network call.
85
+ * - **Cloud, missing / stale cache, or `refresh`**: fetches `api.json` once, slices this provider,
86
+ * writes the slice to the per-provider cache, and returns it.
87
+ * - **Fetch fails**: returns the stale cached slice if one exists (degrade, don't blank), else `null`.
88
+ *
89
+ * NEVER throws — catalog availability must never block model use.
90
+ */
91
+ export declare function getProviderCatalog(providerId: ProviderId, options?: CatalogOptions): Promise<ProviderCatalog | null>;
92
+ /** A {@link ModelInfo}-shaped record decorated with optional catalog metadata. */
93
+ export interface EnrichedModel {
94
+ id: string;
95
+ preferred: boolean;
96
+ /** models.dev metadata for this id, when the catalog has an entry; absent = unenriched. */
97
+ enrichment?: ModelCatalogEntry;
98
+ }
99
+ /**
100
+ * Enrich a provider's discovered model list with catalog metadata, cache-first.
101
+ *
102
+ * `/v1/models` stays authoritative: every input model is returned, in order, whether or not
103
+ * models.dev knows it. Matched ids gain an `enrichment`; unmatched ids (and every model when the
104
+ * catalog is unavailable or the provider is local) are returned untouched. NEVER throws.
105
+ */
106
+ export declare function enrichModels(providerId: ProviderId, models: ReadonlyArray<{
107
+ id: string;
108
+ preferred: boolean;
109
+ }>, options?: CatalogOptions): Promise<EnrichedModel[]>;
@@ -0,0 +1,245 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Model catalog (GS2-6 / B16) — enriches CLOUD model entries with cost, context-limit and
4
+ * capability metadata sourced from {@link https://models.dev | models.dev} (MIT-licensed).
5
+ *
6
+ * ## What this is (and is not)
7
+ * This is an **enrichment** layer, never a gate. The authoritative set of callable models stays
8
+ * `/v1/models` live discovery (see `modelDiscovery.ts`). models.dev only decorates cloud model
9
+ * ids with `{ cost, limit, modalities, reasoning, toolCall }` where a match exists; a cloud model
10
+ * that models.dev has never heard of is still listed and still callable, just unenriched. If
11
+ * models.dev is unreachable (offline / on-prem no-egress / down) every model keeps working — it
12
+ * simply carries no metadata until the cache fills. Nothing here ever blocks model use.
13
+ *
14
+ * ## Fetch / cache shape
15
+ * models.dev publishes a **single** dataset at {@link MODELS_DEV_URL} (`api.json`, ~3 MB); there is
16
+ * no per-provider endpoint. So "lazy, per-provider" is realised on the **cache side**: on a miss for
17
+ * provider *X* we fetch `api.json` once, **slice out just X's models**, and persist that slice to a
18
+ * per-provider cache file (`~/.gsloth/model-catalog/<providerKey>.json`). Subsequent reads are served
19
+ * **cache-first** from that per-provider file and never touch the network within the {@link CATALOG_TTL_MS}
20
+ * TTL. A stale cache is refreshed on read, or on demand via `gth models --refresh`. If a refresh fetch
21
+ * fails but a stale slice exists, the stale slice is returned (degrade, don't blank).
22
+ *
23
+ * ## Local / self-hosted
24
+ * Only cloud providers have a models.dev key (see {@link MODELS_DEV_PROVIDER_KEY}). `ollama` and any
25
+ * other local/self-hosted provider return `null` from {@link getProviderCatalog} **without any network
26
+ * call** — they rely solely on `/v1/models` discovery.
27
+ *
28
+ * ## Attribution
29
+ * Wherever enriched prices/metadata are shown, surface {@link CATALOG_ATTRIBUTION}. models.dev is MIT
30
+ * licensed; we do not bundle or redistribute a seed dataset here, so no license file needs shipping.
31
+ */
32
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
33
+ import { resolve } from 'node:path';
34
+ import { getGlobalGslothDir } from '#src/utils/globalConfigUtils.js';
35
+ import { displayDebug } from '#src/utils/consoleUtils.js';
36
+ /** The single models.dev dataset endpoint (whole catalog; sliced per-provider on our side). */
37
+ export const MODELS_DEV_URL = 'https://models.dev/api.json';
38
+ /**
39
+ * Cache freshness window. Pricing/limit metadata is near-static, so a day between refreshes is
40
+ * plenty; `gth models --refresh` is the manual escape hatch when a newer number is needed sooner.
41
+ */
42
+ export const CATALOG_TTL_MS = 24 * 60 * 60 * 1000; // 24h
43
+ /**
44
+ * Catalog fetch timeout. Deliberately generous (and separate from `/v1/models` discovery's 2 s
45
+ * interactive-path probe): `api.json` is a few MB and this fetch runs off the explicit `gth models`
46
+ * cache-fill path, not a first-run keystroke, so latency headroom matters more than snappiness.
47
+ */
48
+ export const CATALOG_TIMEOUT_MS = 10_000;
49
+ /** Shown next to any enriched price/metadata. Costs from models.dev are US$ per 1M tokens. */
50
+ export const CATALOG_ATTRIBUTION = '* model prices provided by models.dev';
51
+ /**
52
+ * Map a Gaunt Sloth {@link ProviderId} to its models.dev top-level provider key. Cloud providers
53
+ * only; local/self-hosted providers (`ollama`) are intentionally absent so they get NO catalog
54
+ * lookup. Returns `undefined` for any provider without a models.dev slice.
55
+ */
56
+ export const MODELS_DEV_PROVIDER_KEY = {
57
+ anthropic: 'anthropic',
58
+ openai: 'openai',
59
+ 'google-genai': 'google',
60
+ vertexai: 'google-vertex',
61
+ groq: 'groq',
62
+ deepseek: 'deepseek',
63
+ xai: 'xai',
64
+ openrouter: 'openrouter',
65
+ huggingface: 'huggingface',
66
+ // ollama — local, no models.dev entry (excluded on purpose).
67
+ };
68
+ /** Resolve the per-provider cache directory. */
69
+ function catalogCacheDir(options) {
70
+ return options.cacheDir ?? resolve(getGlobalGslothDir(), 'model-catalog');
71
+ }
72
+ /** Resolve the cache file path for one models.dev provider key. */
73
+ function catalogCacheFile(providerKey, options) {
74
+ return resolve(catalogCacheDir(options), `${providerKey}.json`);
75
+ }
76
+ /**
77
+ * Coerce one models.dev raw model object into a {@link ModelCatalogEntry}, keeping only the fields
78
+ * we surface and only when they are the expected type (defensive against dataset drift).
79
+ */
80
+ function normaliseEntry(raw) {
81
+ const m = (raw ?? {});
82
+ const entry = {};
83
+ if (typeof m.name === 'string')
84
+ entry.name = m.name;
85
+ if (typeof m.reasoning === 'boolean')
86
+ entry.reasoning = m.reasoning;
87
+ if (typeof m.tool_call === 'boolean')
88
+ entry.toolCall = m.tool_call;
89
+ const cost = m.cost;
90
+ if (cost && typeof cost === 'object') {
91
+ const c = {};
92
+ if (typeof cost.input === 'number')
93
+ c.input = cost.input;
94
+ if (typeof cost.output === 'number')
95
+ c.output = cost.output;
96
+ if (typeof cost.cache_read === 'number')
97
+ c.cacheRead = cost.cache_read;
98
+ if (typeof cost.cache_write === 'number')
99
+ c.cacheWrite = cost.cache_write;
100
+ if (Object.keys(c).length > 0)
101
+ entry.cost = c;
102
+ }
103
+ const limit = m.limit;
104
+ if (limit && typeof limit === 'object') {
105
+ const l = {};
106
+ if (typeof limit.context === 'number')
107
+ l.context = limit.context;
108
+ if (typeof limit.output === 'number')
109
+ l.output = limit.output;
110
+ if (Object.keys(l).length > 0)
111
+ entry.limit = l;
112
+ }
113
+ const modalities = m.modalities;
114
+ if (modalities && typeof modalities === 'object') {
115
+ const mod = {};
116
+ if (Array.isArray(modalities.input))
117
+ mod.input = modalities.input.filter((x) => typeof x === 'string');
118
+ if (Array.isArray(modalities.output))
119
+ mod.output = modalities.output.filter((x) => typeof x === 'string');
120
+ if ((mod.input?.length ?? 0) > 0 || (mod.output?.length ?? 0) > 0)
121
+ entry.modalities = mod;
122
+ }
123
+ return entry;
124
+ }
125
+ /**
126
+ * Slice one provider's models out of the full models.dev `api.json` payload and normalise them.
127
+ * Returns `{}` when the provider key is absent or malformed — an empty-but-present slice, which the
128
+ * caller still caches (models.dev simply has no data for that provider yet).
129
+ */
130
+ function sliceProvider(payload, providerKey) {
131
+ const providerBlock = payload?.[providerKey];
132
+ const models = providerBlock?.models;
133
+ if (!models || typeof models !== 'object')
134
+ return {};
135
+ const out = {};
136
+ for (const [id, raw] of Object.entries(models)) {
137
+ out[id] = normaliseEntry(raw);
138
+ }
139
+ return out;
140
+ }
141
+ /** Read and validate a cached per-provider slice; returns null on any miss / parse failure. */
142
+ function readCache(providerKey, options) {
143
+ const file = catalogCacheFile(providerKey, options);
144
+ if (!existsSync(file))
145
+ return null;
146
+ try {
147
+ const parsed = JSON.parse(readFileSync(file, 'utf8'));
148
+ if (parsed && typeof parsed.fetchedAt === 'number' && parsed.models)
149
+ return parsed;
150
+ return null;
151
+ }
152
+ catch (e) {
153
+ displayDebug(`Model catalog cache for "${providerKey}" is unreadable: ${errMsg(e)}`);
154
+ return null;
155
+ }
156
+ }
157
+ /** Persist a per-provider slice to the cache (best-effort; a write failure is non-fatal). */
158
+ function writeCache(catalog, options) {
159
+ try {
160
+ const dir = catalogCacheDir(options);
161
+ if (!existsSync(dir))
162
+ mkdirSync(dir, { recursive: true });
163
+ writeFileSync(catalogCacheFile(catalog.providerKey, options), JSON.stringify(catalog), 'utf8');
164
+ }
165
+ catch (e) {
166
+ displayDebug(`Failed to write model catalog cache for "${catalog.providerKey}": ${errMsg(e)}`);
167
+ }
168
+ }
169
+ function errMsg(e) {
170
+ return e instanceof Error ? e.message : String(e);
171
+ }
172
+ /** True when a cached slice is still within the TTL window. */
173
+ function isFresh(cache, options) {
174
+ const now = options.now ?? Date.now();
175
+ const ttl = options.ttlMs ?? CATALOG_TTL_MS;
176
+ return now - cache.fetchedAt < ttl;
177
+ }
178
+ /**
179
+ * Get the models.dev catalog slice for one provider, cache-first.
180
+ *
181
+ * - **Local / self-hosted** (`ollama`, or any provider without a {@link MODELS_DEV_PROVIDER_KEY}):
182
+ * returns `null` immediately, with **no network call**.
183
+ * - **Cloud, fresh cache** (and not `refresh`): returns the cached slice, no network call.
184
+ * - **Cloud, missing / stale cache, or `refresh`**: fetches `api.json` once, slices this provider,
185
+ * writes the slice to the per-provider cache, and returns it.
186
+ * - **Fetch fails**: returns the stale cached slice if one exists (degrade, don't blank), else `null`.
187
+ *
188
+ * NEVER throws — catalog availability must never block model use.
189
+ */
190
+ export async function getProviderCatalog(providerId, options = {}) {
191
+ const providerKey = MODELS_DEV_PROVIDER_KEY[providerId];
192
+ if (!providerKey)
193
+ return null; // local / unmapped provider → no catalog lookup at all.
194
+ const cached = readCache(providerKey, options);
195
+ if (cached && !options.refresh && isFresh(cached, options)) {
196
+ return cached;
197
+ }
198
+ const fetchImpl = options.fetchImpl ?? fetch;
199
+ try {
200
+ const res = await fetchImpl(MODELS_DEV_URL, {
201
+ method: 'GET',
202
+ headers: { Accept: 'application/json' },
203
+ signal: AbortSignal.timeout(CATALOG_TIMEOUT_MS),
204
+ });
205
+ if (!res.ok) {
206
+ displayDebug(`models.dev returned HTTP ${res.status}; using cached catalog if available.`);
207
+ return cached; // may be stale; may be null.
208
+ }
209
+ const payload = await res.json();
210
+ const catalog = {
211
+ providerId,
212
+ providerKey,
213
+ fetchedAt: options.now ?? Date.now(),
214
+ models: sliceProvider(payload, providerKey),
215
+ };
216
+ writeCache(catalog, options);
217
+ return catalog;
218
+ }
219
+ catch (e) {
220
+ // Offline / on-prem no-egress / timeout / malformed — degrade to the stale slice or nothing.
221
+ displayDebug(`models.dev fetch failed: ${errMsg(e)}; using cached catalog if available.`);
222
+ return cached;
223
+ }
224
+ }
225
+ /**
226
+ * Enrich a provider's discovered model list with catalog metadata, cache-first.
227
+ *
228
+ * `/v1/models` stays authoritative: every input model is returned, in order, whether or not
229
+ * models.dev knows it. Matched ids gain an `enrichment`; unmatched ids (and every model when the
230
+ * catalog is unavailable or the provider is local) are returned untouched. NEVER throws.
231
+ */
232
+ export async function enrichModels(providerId, models, options = {}) {
233
+ let catalog = null;
234
+ try {
235
+ catalog = await getProviderCatalog(providerId, options);
236
+ }
237
+ catch {
238
+ catalog = null; // defensive: getProviderCatalog already swallows, but never let enrichment throw.
239
+ }
240
+ return models.map((m) => {
241
+ const enrichment = catalog?.models[m.id];
242
+ return enrichment ? { ...m, enrichment } : { id: m.id, preferred: m.preferred };
243
+ });
244
+ }
245
+ //# sourceMappingURL=modelCatalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelCatalog.js","sourceRoot":"","sources":["../../src/providers/modelCatalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG1D,+FAA+F;AAC/F,MAAM,CAAC,MAAM,cAAc,GAAG,6BAA6B,CAAC;AAE5D;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,MAAM;AAEzD;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAEzC,8FAA8F;AAC9F,MAAM,CAAC,MAAM,mBAAmB,GAAG,uCAAuC,CAAC;AAE3E;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAwC;IAC1E,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,QAAQ;IAChB,cAAc,EAAE,QAAQ;IACxB,QAAQ,EAAE,eAAe;IACzB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,UAAU;IACpB,GAAG,EAAE,KAAK;IACV,UAAU,EAAE,YAAY;IACxB,WAAW,EAAE,aAAa;IAC1B,6DAA6D;CAC9D,CAAC;AAgEF,gDAAgD;AAChD,SAAS,eAAe,CAAC,OAAuB;IAC9C,OAAO,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,kBAAkB,EAAE,EAAE,eAAe,CAAC,CAAC;AAC5E,CAAC;AAED,mEAAmE;AACnE,SAAS,gBAAgB,CAAC,WAAmB,EAAE,OAAuB;IACpE,OAAO,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,GAAG,WAAW,OAAO,CAAC,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,GAAY;IAClC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAA4B,CAAC;IACjD,MAAM,KAAK,GAAsB,EAAE,CAAC;IAEpC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;QAAE,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;IACpD,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;IACpE,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,SAAS,CAAC;IAEnE,MAAM,IAAI,GAAG,CAAC,CAAC,IAA2C,CAAC;IAC3D,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrC,MAAM,CAAC,GAAc,EAAE,CAAC;QACxB,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;YAAE,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzD,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ;YAAE,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC5D,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ;YAAE,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;QACvE,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ;YAAE,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC;QAC1E,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,CAAC,KAA4C,CAAC;IAC7D,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,CAAC,GAAe,EAAE,CAAC;QACzB,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;YAAE,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QACjE,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;YAAE,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC9D,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,UAAU,GAAG,CAAC,CAAC,UAAiD,CAAC;IACvE,IAAI,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACjD,MAAM,GAAG,GAAoB,EAAE,CAAC;QAChC,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC;YACjC,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;QACjF,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;YAClC,GAAG,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;QACnF,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;YAAE,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;IAC5F,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,OAAgB,EAAE,WAAmB;IAC1D,MAAM,aAAa,GAAI,OAA0C,EAAE,CAAC,WAAW,CAC7B,CAAC;IACnD,MAAM,MAAM,GAAG,aAAa,EAAE,MAAM,CAAC;IACrC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACrD,MAAM,GAAG,GAAsC,EAAE,CAAC;IAClD,KAAK,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/C,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,+FAA+F;AAC/F,SAAS,SAAS,CAAC,WAAmB,EAAE,OAAuB;IAC7D,MAAM,IAAI,GAAG,gBAAgB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACpD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAoB,CAAC;QACzE,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM;YAAE,OAAO,MAAM,CAAC;QACnF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,YAAY,CAAC,4BAA4B,WAAW,oBAAoB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,6FAA6F;AAC7F,SAAS,UAAU,CAAC,OAAwB,EAAE,OAAuB;IACnE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;IACjG,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,YAAY,CAAC,4CAA4C,OAAO,CAAC,WAAW,MAAM,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACjG,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,CAAU;IACxB,OAAO,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,+DAA+D;AAC/D,SAAS,OAAO,CAAC,KAAsB,EAAE,OAAuB;IAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,IAAI,cAAc,CAAC;IAC5C,OAAO,GAAG,GAAG,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAsB,EACtB,OAAO,GAAmB,EAAE;IAE5B,MAAM,WAAW,GAAG,uBAAuB,CAAC,UAAU,CAAC,CAAC;IACxD,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC,CAAC,wDAAwD;IAEvF,MAAM,MAAM,GAAG,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;QAC3D,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,cAAc,EAAE;YAC1C,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;YACvC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;SAChD,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,YAAY,CAAC,4BAA4B,GAAG,CAAC,MAAM,sCAAsC,CAAC,CAAC;YAC3F,OAAO,MAAM,CAAC,CAAC,6BAA6B;QAC9C,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,OAAO,GAAoB;YAC/B,UAAU;YACV,WAAW;YACX,SAAS,EAAE,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE;YACpC,MAAM,EAAE,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC;SAC5C,CAAC;QACF,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7B,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,6FAA6F;QAC7F,YAAY,CAAC,4BAA4B,MAAM,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC;QAC1F,OAAO,MAAM,CAAC;IAChB,CAAC;AACH,CAAC;AAUD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,UAAsB,EACtB,MAAyD,EACzD,OAAO,GAAmB,EAAE;IAE5B,IAAI,OAAO,GAA2B,IAAI,CAAC;IAC3C,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,kBAAkB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,IAAI,CAAC,CAAC,kFAAkF;IACpG,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACtB,MAAM,UAAU,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzC,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;IAClF,CAAC,CAAC,CAAC;AACL,CAAC"}