@sriinnu/kosha-discovery 0.5.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 (208) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +286 -0
  3. package/dist/aliases.d.ts +51 -0
  4. package/dist/aliases.d.ts.map +1 -0
  5. package/dist/aliases.js +115 -0
  6. package/dist/aliases.js.map +1 -0
  7. package/dist/cache.d.ts +57 -0
  8. package/dist/cache.d.ts.map +1 -0
  9. package/dist/cache.js +123 -0
  10. package/dist/cache.js.map +1 -0
  11. package/dist/cli-commands.d.ts +142 -0
  12. package/dist/cli-commands.d.ts.map +1 -0
  13. package/dist/cli-commands.js +746 -0
  14. package/dist/cli-commands.js.map +1 -0
  15. package/dist/cli-format.d.ts +119 -0
  16. package/dist/cli-format.d.ts.map +1 -0
  17. package/dist/cli-format.js +171 -0
  18. package/dist/cli-format.js.map +1 -0
  19. package/dist/cli.d.ts +15 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +143 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/credentials/index.d.ts +2 -0
  24. package/dist/credentials/index.d.ts.map +1 -0
  25. package/dist/credentials/index.js +2 -0
  26. package/dist/credentials/index.js.map +1 -0
  27. package/dist/credentials/resolver.d.ts +170 -0
  28. package/dist/credentials/resolver.d.ts.map +1 -0
  29. package/dist/credentials/resolver.js +597 -0
  30. package/dist/credentials/resolver.js.map +1 -0
  31. package/dist/discovery/anthropic.d.ts +49 -0
  32. package/dist/discovery/anthropic.d.ts.map +1 -0
  33. package/dist/discovery/anthropic.js +101 -0
  34. package/dist/discovery/anthropic.js.map +1 -0
  35. package/dist/discovery/base.d.ts +59 -0
  36. package/dist/discovery/base.d.ts.map +1 -0
  37. package/dist/discovery/base.js +123 -0
  38. package/dist/discovery/base.js.map +1 -0
  39. package/dist/discovery/bedrock.d.ts +122 -0
  40. package/dist/discovery/bedrock.d.ts.map +1 -0
  41. package/dist/discovery/bedrock.js +356 -0
  42. package/dist/discovery/bedrock.js.map +1 -0
  43. package/dist/discovery/cerebras.d.ts +43 -0
  44. package/dist/discovery/cerebras.d.ts.map +1 -0
  45. package/dist/discovery/cerebras.js +65 -0
  46. package/dist/discovery/cerebras.js.map +1 -0
  47. package/dist/discovery/cohere.d.ts +57 -0
  48. package/dist/discovery/cohere.d.ts.map +1 -0
  49. package/dist/discovery/cohere.js +82 -0
  50. package/dist/discovery/cohere.js.map +1 -0
  51. package/dist/discovery/deepinfra.d.ts +41 -0
  52. package/dist/discovery/deepinfra.d.ts.map +1 -0
  53. package/dist/discovery/deepinfra.js +86 -0
  54. package/dist/discovery/deepinfra.js.map +1 -0
  55. package/dist/discovery/deepseek.d.ts +17 -0
  56. package/dist/discovery/deepseek.d.ts.map +1 -0
  57. package/dist/discovery/deepseek.js +45 -0
  58. package/dist/discovery/deepseek.js.map +1 -0
  59. package/dist/discovery/fireworks.d.ts +48 -0
  60. package/dist/discovery/fireworks.d.ts.map +1 -0
  61. package/dist/discovery/fireworks.js +101 -0
  62. package/dist/discovery/fireworks.js.map +1 -0
  63. package/dist/discovery/glm.d.ts +17 -0
  64. package/dist/discovery/glm.d.ts.map +1 -0
  65. package/dist/discovery/glm.js +52 -0
  66. package/dist/discovery/glm.js.map +1 -0
  67. package/dist/discovery/google.d.ts +53 -0
  68. package/dist/discovery/google.d.ts.map +1 -0
  69. package/dist/discovery/google.js +122 -0
  70. package/dist/discovery/google.js.map +1 -0
  71. package/dist/discovery/groq.d.ts +44 -0
  72. package/dist/discovery/groq.d.ts.map +1 -0
  73. package/dist/discovery/groq.js +89 -0
  74. package/dist/discovery/groq.js.map +1 -0
  75. package/dist/discovery/index.d.ts +48 -0
  76. package/dist/discovery/index.d.ts.map +1 -0
  77. package/dist/discovery/index.js +116 -0
  78. package/dist/discovery/index.js.map +1 -0
  79. package/dist/discovery/llama-cpp.d.ts +45 -0
  80. package/dist/discovery/llama-cpp.d.ts.map +1 -0
  81. package/dist/discovery/llama-cpp.js +137 -0
  82. package/dist/discovery/llama-cpp.js.map +1 -0
  83. package/dist/discovery/minimax.d.ts +16 -0
  84. package/dist/discovery/minimax.d.ts.map +1 -0
  85. package/dist/discovery/minimax.js +56 -0
  86. package/dist/discovery/minimax.js.map +1 -0
  87. package/dist/discovery/mistral.d.ts +45 -0
  88. package/dist/discovery/mistral.d.ts.map +1 -0
  89. package/dist/discovery/mistral.js +82 -0
  90. package/dist/discovery/mistral.js.map +1 -0
  91. package/dist/discovery/moonshot.d.ts +16 -0
  92. package/dist/discovery/moonshot.d.ts.map +1 -0
  93. package/dist/discovery/moonshot.js +46 -0
  94. package/dist/discovery/moonshot.js.map +1 -0
  95. package/dist/discovery/nvidia.d.ts +60 -0
  96. package/dist/discovery/nvidia.d.ts.map +1 -0
  97. package/dist/discovery/nvidia.js +145 -0
  98. package/dist/discovery/nvidia.js.map +1 -0
  99. package/dist/discovery/ollama.d.ts +57 -0
  100. package/dist/discovery/ollama.d.ts.map +1 -0
  101. package/dist/discovery/ollama.js +151 -0
  102. package/dist/discovery/ollama.js.map +1 -0
  103. package/dist/discovery/openai-compatible.d.ts +126 -0
  104. package/dist/discovery/openai-compatible.d.ts.map +1 -0
  105. package/dist/discovery/openai-compatible.js +161 -0
  106. package/dist/discovery/openai-compatible.js.map +1 -0
  107. package/dist/discovery/openai.d.ts +62 -0
  108. package/dist/discovery/openai.d.ts.map +1 -0
  109. package/dist/discovery/openai.js +157 -0
  110. package/dist/discovery/openai.js.map +1 -0
  111. package/dist/discovery/openrouter.d.ts +78 -0
  112. package/dist/discovery/openrouter.d.ts.map +1 -0
  113. package/dist/discovery/openrouter.js +184 -0
  114. package/dist/discovery/openrouter.js.map +1 -0
  115. package/dist/discovery/perplexity.d.ts +66 -0
  116. package/dist/discovery/perplexity.d.ts.map +1 -0
  117. package/dist/discovery/perplexity.js +86 -0
  118. package/dist/discovery/perplexity.js.map +1 -0
  119. package/dist/discovery/together.d.ts +41 -0
  120. package/dist/discovery/together.d.ts.map +1 -0
  121. package/dist/discovery/together.js +88 -0
  122. package/dist/discovery/together.js.map +1 -0
  123. package/dist/discovery/vertex.d.ts +146 -0
  124. package/dist/discovery/vertex.d.ts.map +1 -0
  125. package/dist/discovery/vertex.js +371 -0
  126. package/dist/discovery/vertex.js.map +1 -0
  127. package/dist/discovery/zai.d.ts +17 -0
  128. package/dist/discovery/zai.d.ts.map +1 -0
  129. package/dist/discovery/zai.js +51 -0
  130. package/dist/discovery/zai.js.map +1 -0
  131. package/dist/discovery-contract.d.ts +186 -0
  132. package/dist/discovery-contract.d.ts.map +1 -0
  133. package/dist/discovery-contract.js +115 -0
  134. package/dist/discovery-contract.js.map +1 -0
  135. package/dist/discovery-routes.d.ts +14 -0
  136. package/dist/discovery-routes.d.ts.map +1 -0
  137. package/dist/discovery-routes.js +98 -0
  138. package/dist/discovery-routes.js.map +1 -0
  139. package/dist/enrichment/index.d.ts +2 -0
  140. package/dist/enrichment/index.d.ts.map +1 -0
  141. package/dist/enrichment/index.js +2 -0
  142. package/dist/enrichment/index.js.map +1 -0
  143. package/dist/enrichment/litellm.d.ts +52 -0
  144. package/dist/enrichment/litellm.d.ts.map +1 -0
  145. package/dist/enrichment/litellm.js +205 -0
  146. package/dist/enrichment/litellm.js.map +1 -0
  147. package/dist/index.d.ts +30 -0
  148. package/dist/index.d.ts.map +1 -0
  149. package/dist/index.js +33 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/normalize.d.ts +64 -0
  152. package/dist/normalize.d.ts.map +1 -0
  153. package/dist/normalize.js +166 -0
  154. package/dist/normalize.js.map +1 -0
  155. package/dist/provider-catalog.d.ts +62 -0
  156. package/dist/provider-catalog.d.ts.map +1 -0
  157. package/dist/provider-catalog.js +331 -0
  158. package/dist/provider-catalog.js.map +1 -0
  159. package/dist/registry-delta.d.ts +17 -0
  160. package/dist/registry-delta.d.ts.map +1 -0
  161. package/dist/registry-delta.js +74 -0
  162. package/dist/registry-delta.js.map +1 -0
  163. package/dist/registry-discovery.d.ts +66 -0
  164. package/dist/registry-discovery.d.ts.map +1 -0
  165. package/dist/registry-discovery.js +339 -0
  166. package/dist/registry-discovery.js.map +1 -0
  167. package/dist/registry-query.d.ts +74 -0
  168. package/dist/registry-query.d.ts.map +1 -0
  169. package/dist/registry-query.js +310 -0
  170. package/dist/registry-query.js.map +1 -0
  171. package/dist/registry-runtime.d.ts +48 -0
  172. package/dist/registry-runtime.d.ts.map +1 -0
  173. package/dist/registry-runtime.js +255 -0
  174. package/dist/registry-runtime.js.map +1 -0
  175. package/dist/registry-selection.d.ts +31 -0
  176. package/dist/registry-selection.d.ts.map +1 -0
  177. package/dist/registry-selection.js +167 -0
  178. package/dist/registry-selection.js.map +1 -0
  179. package/dist/registry-state.d.ts +92 -0
  180. package/dist/registry-state.d.ts.map +1 -0
  181. package/dist/registry-state.js +35 -0
  182. package/dist/registry-state.js.map +1 -0
  183. package/dist/registry.d.ts +127 -0
  184. package/dist/registry.d.ts.map +1 -0
  185. package/dist/registry.js +248 -0
  186. package/dist/registry.js.map +1 -0
  187. package/dist/resilience.d.ts +212 -0
  188. package/dist/resilience.d.ts.map +1 -0
  189. package/dist/resilience.js +292 -0
  190. package/dist/resilience.js.map +1 -0
  191. package/dist/security.d.ts +44 -0
  192. package/dist/security.d.ts.map +1 -0
  193. package/dist/security.js +184 -0
  194. package/dist/security.js.map +1 -0
  195. package/dist/server.d.ts +41 -0
  196. package/dist/server.d.ts.map +1 -0
  197. package/dist/server.js +320 -0
  198. package/dist/server.js.map +1 -0
  199. package/dist/shell-safe.d.ts +15 -0
  200. package/dist/shell-safe.d.ts.map +1 -0
  201. package/dist/shell-safe.js +20 -0
  202. package/dist/shell-safe.js.map +1 -0
  203. package/dist/types.d.ts +365 -0
  204. package/dist/types.d.ts.map +1 -0
  205. package/dist/types.js +10 -0
  206. package/dist/types.js.map +1 -0
  207. package/logo.svg +81 -0
  208. package/package.json +85 -0
@@ -0,0 +1,184 @@
1
+ /**
2
+ * kosha-discovery — OpenRouter aggregator discoverer.
3
+ *
4
+ * OpenRouter is a unified gateway that proxies requests to many upstream
5
+ * providers (OpenAI, Anthropic, Google, Meta, Mistral, etc.). Its model
6
+ * list endpoint returns rich metadata including pricing, context lengths,
7
+ * and architecture info — making it one of the most informative sources.
8
+ * @module
9
+ */
10
+ import { BaseDiscoverer } from "./base.js";
11
+ /**
12
+ * Discovers models available through the OpenRouter aggregator.
13
+ *
14
+ * OpenRouter acts as a single gateway to dozens of providers. Its model
15
+ * list is publicly accessible (no API key required), though an
16
+ * authenticated request gets higher rate limits.
17
+ */
18
+ export class OpenRouterDiscoverer extends BaseDiscoverer {
19
+ providerId = "openrouter";
20
+ providerName = "OpenRouter";
21
+ baseUrl = "https://openrouter.ai";
22
+ /**
23
+ * Fetch the full model catalogue from OpenRouter.
24
+ *
25
+ * @param credential - API key is **optional** for this provider.
26
+ * The endpoint works without auth, just with stricter rate limits.
27
+ * @param options - Optional timeout override (default 15 s — larger because the
28
+ * response contains hundreds of models).
29
+ */
30
+ async discover(credential, options) {
31
+ const timeoutMs = this.validateTimeout(options?.timeout, 15_000);
32
+ const headers = {};
33
+ // API key is optional — the /api/v1/models endpoint is publicly
34
+ // accessible; auth only provides higher rate limits
35
+ const apiKey = credential.apiKey ?? credential.accessToken;
36
+ if (apiKey) {
37
+ headers.Authorization = `Bearer ${apiKey}`;
38
+ }
39
+ const response = await this.fetchJSON(`${this.baseUrl}/api/v1/models`, Object.keys(headers).length > 0 ? headers : undefined, timeoutMs);
40
+ return response.data
41
+ .filter((model) => this.isAvailable(model))
42
+ .map((model) => this.toModelCard(model));
43
+ }
44
+ /**
45
+ * Filter out unavailable models. OpenRouter marks delisted models
46
+ * with `pricing.prompt === "-1"`.
47
+ */
48
+ isAvailable(model) {
49
+ return model.pricing?.prompt !== "-1";
50
+ }
51
+ /** Convert an OpenRouter model object into a normalized {@link ModelCard}. */
52
+ toModelCard(model) {
53
+ const mode = this.inferMode(model);
54
+ const capabilities = this.inferCapabilities(model);
55
+ const pricing = this.parsePricing(model.pricing);
56
+ const originProvider = this.extractOriginProvider(model.id);
57
+ return this.makeCard({
58
+ id: model.id,
59
+ name: model.name || model.id,
60
+ provider: this.providerId,
61
+ originProvider,
62
+ mode,
63
+ capabilities,
64
+ contextWindow: model.context_length ?? 0,
65
+ maxOutputTokens: model.top_provider?.max_completion_tokens ?? 0,
66
+ pricing,
67
+ });
68
+ }
69
+ /**
70
+ * Extract the canonical origin-provider slug from an OpenRouter compound
71
+ * model ID of the form `{vendor}/{model-name}`.
72
+ *
73
+ * OpenRouter uses vendor-namespaced IDs (e.g. `anthropic/claude-opus-4-6`,
74
+ * `meta-llama/llama-3-70b`). We take the prefix before the first `/` and
75
+ * normalise it to our canonical slug so that downstream consumers can group
76
+ * models by original creator regardless of which gateway serves them.
77
+ *
78
+ * @param modelId - Raw OpenRouter model ID.
79
+ * @returns Canonical provider slug (e.g. `"anthropic"`, `"meta"`, `"openai"`).
80
+ */
81
+ extractOriginProvider(modelId) {
82
+ const slashIndex = modelId.indexOf("/");
83
+ if (slashIndex === -1) {
84
+ // No vendor prefix — treat the whole ID as the slug
85
+ return modelId;
86
+ }
87
+ const prefix = modelId.slice(0, slashIndex);
88
+ // Map well-known OpenRouter vendor prefixes to canonical slugs.
89
+ // Unknown prefixes fall through and are returned as-is.
90
+ const vendorMap = {
91
+ anthropic: "anthropic",
92
+ openai: "openai",
93
+ google: "google",
94
+ "meta-llama": "meta",
95
+ mistralai: "mistral",
96
+ cohere: "cohere",
97
+ deepseek: "deepseek",
98
+ qwen: "qwen",
99
+ };
100
+ return vendorMap[prefix] ?? prefix;
101
+ }
102
+ /** Infer the primary {@link ModelMode} from modality and naming patterns. */
103
+ inferMode(model) {
104
+ const modality = (model.architecture?.modality ?? "").toLowerCase();
105
+ const id = model.id.toLowerCase();
106
+ const name = (model.name ?? "").toLowerCase();
107
+ if (modality.includes("image") && !modality.includes("text")) {
108
+ return "image";
109
+ }
110
+ if (modality.includes("audio")) {
111
+ return "audio";
112
+ }
113
+ if (id.includes("embed") || name.includes("embedding")) {
114
+ return "embedding";
115
+ }
116
+ return "chat";
117
+ }
118
+ /**
119
+ * Infer capability flags from architecture modality and model ID.
120
+ */
121
+ inferCapabilities(model) {
122
+ const modality = (model.architecture?.modality ?? "").toLowerCase();
123
+ const id = model.id.toLowerCase();
124
+ const capabilities = [];
125
+ if (id.includes("embed")) {
126
+ return ["embedding"];
127
+ }
128
+ // Image-generation-only models should advertise image capability.
129
+ if (modality.includes("image") && !modality.includes("text")) {
130
+ return ["image_generation"];
131
+ }
132
+ capabilities.push("chat");
133
+ // Vision from modality: "text+image" means multimodal input
134
+ if (modality.includes("image") && modality.includes("text")) {
135
+ capabilities.push("vision");
136
+ }
137
+ // Heuristic: well-known modern chat models support tool use and code
138
+ if (this.isModernChatModel(id)) {
139
+ capabilities.push("function_calling", "code", "nlu");
140
+ }
141
+ return capabilities;
142
+ }
143
+ /**
144
+ * Heuristic to identify "modern chat models" that support structured
145
+ * tool use (function calling), code generation, and NLU.
146
+ *
147
+ * We match on known provider/model family prefixes. This is intentionally
148
+ * broad — false positives are benign (extra capability flags), while false
149
+ * negatives would hide useful features.
150
+ */
151
+ isModernChatModel(id) {
152
+ return (id.includes("gpt-4") ||
153
+ id.includes("claude-3") ||
154
+ id.includes("claude-sonnet") ||
155
+ id.includes("claude-opus") ||
156
+ id.includes("gemini") ||
157
+ id.includes("command-r") ||
158
+ id.includes("mistral-large") ||
159
+ id.includes("llama-3") ||
160
+ id.includes("deepseek"));
161
+ }
162
+ /**
163
+ * Parse OpenRouter's per-token pricing into our per-million format.
164
+ *
165
+ * OpenRouter returns pricing as **cost per single token** (stringified
166
+ * floats). We multiply by 1,000,000 to convert to our standard
167
+ * per-million-token pricing representation.
168
+ */
169
+ parsePricing(pricing) {
170
+ if (!pricing)
171
+ return undefined;
172
+ const promptCost = Number.parseFloat(pricing.prompt);
173
+ const completionCost = Number.parseFloat(pricing.completion);
174
+ if (Number.isNaN(promptCost) || Number.isNaN(completionCost)) {
175
+ return undefined;
176
+ }
177
+ return {
178
+ // Convert per-token cost to per-million-token cost
179
+ inputPerMillion: promptCost * 1_000_000,
180
+ outputPerMillion: completionCost * 1_000_000,
181
+ };
182
+ }
183
+ }
184
+ //# sourceMappingURL=openrouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/discovery/openrouter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * kosha-discovery — Perplexity provider discoverer.
3
+ *
4
+ * Queries the Perplexity API `/v1/models` endpoint (OpenAI-compatible),
5
+ * and maps results into {@link ModelCard} objects.
6
+ *
7
+ * Perplexity is a single-vendor catalog — all models are Perplexity's own
8
+ * or their fine-tuned customisations (e.g. `r1-1776`, a DeepSeek R1 variant
9
+ * tuned and served by Perplexity). The origin provider is always "perplexity".
10
+ *
11
+ * Sonar models carry Perplexity's unique real-time web search / grounding
12
+ * feature, represented by the `web_search` capability flag.
13
+ *
14
+ * @module
15
+ */
16
+ import type { ModelClassification, OpenAICompatibleModel } from "./openai-compatible.js";
17
+ import { OpenAICompatibleDiscoverer } from "./openai-compatible.js";
18
+ /**
19
+ * Discovers models available through the Perplexity API.
20
+ *
21
+ * All models in the Perplexity catalog are served by Perplexity, so
22
+ * `originProvider` is always `"perplexity"`. The catalog is clean
23
+ * (no reward models, guard models, or embedding entries), so
24
+ * {@link isRelevantModel} keeps every entry.
25
+ *
26
+ * Classification rules:
27
+ * - Mode: always `"chat"`
28
+ * - Base capabilities: `["chat", "function_calling"]`
29
+ * - `"web_search"` added for any model whose ID contains `"sonar"`
30
+ * (Perplexity's grounding/search-augmented family)
31
+ * - `"nlu"` added for any model whose ID contains `"pro"`
32
+ * (enhanced reasoning / language understanding tier)
33
+ */
34
+ export declare class PerplexityDiscoverer extends OpenAICompatibleDiscoverer {
35
+ readonly providerId = "perplexity";
36
+ readonly providerName = "Perplexity";
37
+ readonly baseUrl = "https://api.perplexity.ai";
38
+ /**
39
+ * All models in the Perplexity catalog are relevant.
40
+ *
41
+ * The catalog is curated and does not include reward models,
42
+ * embedding models, or other non-inference entries.
43
+ */
44
+ protected isRelevantModel(_model: OpenAICompatibleModel): boolean;
45
+ /**
46
+ * Classify a Perplexity model.
47
+ *
48
+ * Origin is always "perplexity". Mode is always "chat".
49
+ * Capabilities are built from the model ID:
50
+ * - `"chat"` and `"function_calling"` for all models
51
+ * - `"web_search"` for sonar family models (real-time grounding)
52
+ * - `"nlu"` for pro-tier models (enhanced NLU / reasoning)
53
+ */
54
+ protected classifyModel(model: OpenAICompatibleModel): ModelClassification;
55
+ /**
56
+ * Build the capability list for a model based on its ID.
57
+ *
58
+ * Rules applied in order (all are additive — multiple can apply):
59
+ * 1. `"chat"` — always included
60
+ * 2. `"function_calling"` — always included (all Perplexity models support it)
61
+ * 3. `"web_search"` — added when the model ID contains `"sonar"`
62
+ * 4. `"nlu"` — added when the model ID contains `"pro"`
63
+ */
64
+ private buildCapabilities;
65
+ }
66
+ //# sourceMappingURL=perplexity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perplexity.d.ts","sourceRoot":"","sources":["../../src/discovery/perplexity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEpE;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,oBAAqB,SAAQ,0BAA0B;IACnE,QAAQ,CAAC,UAAU,gBAAgB;IACnC,QAAQ,CAAC,YAAY,gBAAgB;IACrC,QAAQ,CAAC,OAAO,+BAA+B;IAE/C;;;;;OAKG;IACH,SAAS,CAAC,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO;IAIjE;;;;;;;;OAQG;IACH,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,qBAAqB,GAAG,mBAAmB;IAW1E;;;;;;;;OAQG;IACH,OAAO,CAAC,iBAAiB;CAezB"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * kosha-discovery — Perplexity provider discoverer.
3
+ *
4
+ * Queries the Perplexity API `/v1/models` endpoint (OpenAI-compatible),
5
+ * and maps results into {@link ModelCard} objects.
6
+ *
7
+ * Perplexity is a single-vendor catalog — all models are Perplexity's own
8
+ * or their fine-tuned customisations (e.g. `r1-1776`, a DeepSeek R1 variant
9
+ * tuned and served by Perplexity). The origin provider is always "perplexity".
10
+ *
11
+ * Sonar models carry Perplexity's unique real-time web search / grounding
12
+ * feature, represented by the `web_search` capability flag.
13
+ *
14
+ * @module
15
+ */
16
+ import { OpenAICompatibleDiscoverer } from "./openai-compatible.js";
17
+ /**
18
+ * Discovers models available through the Perplexity API.
19
+ *
20
+ * All models in the Perplexity catalog are served by Perplexity, so
21
+ * `originProvider` is always `"perplexity"`. The catalog is clean
22
+ * (no reward models, guard models, or embedding entries), so
23
+ * {@link isRelevantModel} keeps every entry.
24
+ *
25
+ * Classification rules:
26
+ * - Mode: always `"chat"`
27
+ * - Base capabilities: `["chat", "function_calling"]`
28
+ * - `"web_search"` added for any model whose ID contains `"sonar"`
29
+ * (Perplexity's grounding/search-augmented family)
30
+ * - `"nlu"` added for any model whose ID contains `"pro"`
31
+ * (enhanced reasoning / language understanding tier)
32
+ */
33
+ export class PerplexityDiscoverer extends OpenAICompatibleDiscoverer {
34
+ providerId = "perplexity";
35
+ providerName = "Perplexity";
36
+ baseUrl = "https://api.perplexity.ai";
37
+ /**
38
+ * All models in the Perplexity catalog are relevant.
39
+ *
40
+ * The catalog is curated and does not include reward models,
41
+ * embedding models, or other non-inference entries.
42
+ */
43
+ isRelevantModel(_model) {
44
+ return true;
45
+ }
46
+ /**
47
+ * Classify a Perplexity model.
48
+ *
49
+ * Origin is always "perplexity". Mode is always "chat".
50
+ * Capabilities are built from the model ID:
51
+ * - `"chat"` and `"function_calling"` for all models
52
+ * - `"web_search"` for sonar family models (real-time grounding)
53
+ * - `"nlu"` for pro-tier models (enhanced NLU / reasoning)
54
+ */
55
+ classifyModel(model) {
56
+ const lower = model.id.toLowerCase();
57
+ const capabilities = this.buildCapabilities(lower);
58
+ return {
59
+ originProvider: "perplexity",
60
+ mode: "chat",
61
+ capabilities,
62
+ };
63
+ }
64
+ /**
65
+ * Build the capability list for a model based on its ID.
66
+ *
67
+ * Rules applied in order (all are additive — multiple can apply):
68
+ * 1. `"chat"` — always included
69
+ * 2. `"function_calling"` — always included (all Perplexity models support it)
70
+ * 3. `"web_search"` — added when the model ID contains `"sonar"`
71
+ * 4. `"nlu"` — added when the model ID contains `"pro"`
72
+ */
73
+ buildCapabilities(lower) {
74
+ const caps = ["chat", "function_calling"];
75
+ // Sonar models have built-in real-time web search / grounding
76
+ if (lower.includes("sonar")) {
77
+ caps.push("web_search");
78
+ }
79
+ // Pro-tier models have enhanced NLU / reasoning capabilities
80
+ if (lower.includes("pro")) {
81
+ caps.push("nlu");
82
+ }
83
+ return caps;
84
+ }
85
+ }
86
+ //# sourceMappingURL=perplexity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perplexity.js","sourceRoot":"","sources":["../../src/discovery/perplexity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEpE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,oBAAqB,SAAQ,0BAA0B;IAC1D,UAAU,GAAG,YAAY,CAAC;IAC1B,YAAY,GAAG,YAAY,CAAC;IAC5B,OAAO,GAAG,2BAA2B,CAAC;IAE/C;;;;;OAKG;IACO,eAAe,CAAC,MAA6B;QACtD,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;;;;OAQG;IACO,aAAa,CAAC,KAA4B;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAEnD,OAAO;YACN,cAAc,EAAE,YAAY;YAC5B,IAAI,EAAE,MAAM;YACZ,YAAY;SACZ,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACK,iBAAiB,CAAC,KAAa;QACtC,MAAM,IAAI,GAAa,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;QAEpD,8DAA8D;QAC9D,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzB,CAAC;QAED,6DAA6D;QAC7D,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;CACD"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * kosha-discovery — Together AI provider discoverer.
3
+ *
4
+ * Queries the Together AI `/v1/models` endpoint (OpenAI-compatible),
5
+ * filters relevant models, and maps them into {@link ModelCard} objects.
6
+ *
7
+ * Together AI's catalog is multi-vendor, hosting models from meta-llama,
8
+ * mistralai, Qwen, google, deepseek-ai, microsoft, nvidia, databricks,
9
+ * togethercomputer, and others.
10
+ * @module
11
+ */
12
+ import { OpenAICompatibleDiscoverer, type ModelClassification, type OpenAICompatibleModel } from "./openai-compatible.js";
13
+ /**
14
+ * Discovers models available through the Together AI API (api.together.xyz).
15
+ *
16
+ * The Together AI catalog serves models from multiple vendors using an
17
+ * OpenAI-compatible API. Model IDs are namespaced (e.g.
18
+ * `meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo`,
19
+ * `mistralai/Mixtral-8x22B-Instruct-v0.1`), allowing origin provider
20
+ * extraction from the prefix.
21
+ */
22
+ export declare class TogetherDiscoverer extends OpenAICompatibleDiscoverer {
23
+ readonly providerId = "together";
24
+ readonly providerName = "Together AI";
25
+ readonly baseUrl = "https://api.together.xyz";
26
+ /**
27
+ * Determine whether a model ID represents a model we want to track.
28
+ *
29
+ * We keep chat/instruct, embedding, code, and vision models and filter out:
30
+ * - Reward models (used for RLHF, not inference)
31
+ */
32
+ protected isRelevantModel(model: OpenAICompatibleModel): boolean;
33
+ /**
34
+ * Classify a Together AI model: determine origin provider, mode, and capabilities.
35
+ *
36
+ * Uses namespaced model IDs (vendor/model-name) to extract origin provider.
37
+ * Normalizes known prefixes via aliases map.
38
+ */
39
+ protected classifyModel(model: OpenAICompatibleModel): ModelClassification;
40
+ }
41
+ //# sourceMappingURL=together.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"together.d.ts","sourceRoot":"","sources":["../../src/discovery/together.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,0BAA0B,EAAE,KAAK,mBAAmB,EAAE,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE1H;;;;;;;;GAQG;AACH,qBAAa,kBAAmB,SAAQ,0BAA0B;IACjE,QAAQ,CAAC,UAAU,cAAc;IACjC,QAAQ,CAAC,YAAY,iBAAiB;IACtC,QAAQ,CAAC,OAAO,8BAA8B;IAE9C;;;;;OAKG;IACH,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO;IAShE;;;;;OAKG;IACH,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,qBAAqB,GAAG,mBAAmB;CAiD1E"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * kosha-discovery — Together AI provider discoverer.
3
+ *
4
+ * Queries the Together AI `/v1/models` endpoint (OpenAI-compatible),
5
+ * filters relevant models, and maps them into {@link ModelCard} objects.
6
+ *
7
+ * Together AI's catalog is multi-vendor, hosting models from meta-llama,
8
+ * mistralai, Qwen, google, deepseek-ai, microsoft, nvidia, databricks,
9
+ * togethercomputer, and others.
10
+ * @module
11
+ */
12
+ import { OpenAICompatibleDiscoverer } from "./openai-compatible.js";
13
+ /**
14
+ * Discovers models available through the Together AI API (api.together.xyz).
15
+ *
16
+ * The Together AI catalog serves models from multiple vendors using an
17
+ * OpenAI-compatible API. Model IDs are namespaced (e.g.
18
+ * `meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo`,
19
+ * `mistralai/Mixtral-8x22B-Instruct-v0.1`), allowing origin provider
20
+ * extraction from the prefix.
21
+ */
22
+ export class TogetherDiscoverer extends OpenAICompatibleDiscoverer {
23
+ providerId = "together";
24
+ providerName = "Together AI";
25
+ baseUrl = "https://api.together.xyz";
26
+ /**
27
+ * Determine whether a model ID represents a model we want to track.
28
+ *
29
+ * We keep chat/instruct, embedding, code, and vision models and filter out:
30
+ * - Reward models (used for RLHF, not inference)
31
+ */
32
+ isRelevantModel(model) {
33
+ const lower = model.id.toLowerCase();
34
+ // Skip reward models — used for RLHF, not direct inference
35
+ if (this.looksLikeReward(lower))
36
+ return false;
37
+ return true;
38
+ }
39
+ /**
40
+ * Classify a Together AI model: determine origin provider, mode, and capabilities.
41
+ *
42
+ * Uses namespaced model IDs (vendor/model-name) to extract origin provider.
43
+ * Normalizes known prefixes via aliases map.
44
+ */
45
+ classifyModel(model) {
46
+ const id = model.id;
47
+ const lower = id.toLowerCase();
48
+ // Extract origin from vendor/model-name format with alias normalization
49
+ const aliases = {
50
+ "meta-llama": "meta",
51
+ "mistralai": "mistral",
52
+ "deepseek-ai": "deepseek",
53
+ "togethercomputer": "together",
54
+ };
55
+ const originProvider = this.extractPrefixOrigin(id, "together", aliases);
56
+ // Detect mode: use model.type field for embedding, or infer from ID
57
+ let mode = "chat";
58
+ if (model.type === "embedding" || this.looksLikeEmbedding(lower)) {
59
+ mode = "embedding";
60
+ }
61
+ // Build capability flags
62
+ const capabilities = [];
63
+ if (mode === "embedding") {
64
+ capabilities.push("embedding");
65
+ }
66
+ else {
67
+ capabilities.push("chat");
68
+ // Add vision capability if detected
69
+ if (this.looksLikeVision(lower)) {
70
+ capabilities.push("vision");
71
+ }
72
+ // Add code capability if detected
73
+ if (this.looksLikeCode(lower)) {
74
+ capabilities.push("code");
75
+ }
76
+ // Add function_calling for instruct/chat models
77
+ if (lower.includes("instruct") || lower.includes("chat")) {
78
+ capabilities.push("function_calling");
79
+ }
80
+ }
81
+ return {
82
+ originProvider,
83
+ mode,
84
+ capabilities,
85
+ };
86
+ }
87
+ }
88
+ //# sourceMappingURL=together.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"together.js","sourceRoot":"","sources":["../../src/discovery/together.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,0BAA0B,EAAwD,MAAM,wBAAwB,CAAC;AAE1H;;;;;;;;GAQG;AACH,MAAM,OAAO,kBAAmB,SAAQ,0BAA0B;IACxD,UAAU,GAAG,UAAU,CAAC;IACxB,YAAY,GAAG,aAAa,CAAC;IAC7B,OAAO,GAAG,0BAA0B,CAAC;IAE9C;;;;;OAKG;IACO,eAAe,CAAC,KAA4B;QACrD,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;QAErC,2DAA2D;QAC3D,IAAI,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAE9C,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;OAKG;IACO,aAAa,CAAC,KAA4B;QACnD,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;QAE/B,wEAAwE;QACxE,MAAM,OAAO,GAA2B;YACvC,YAAY,EAAE,MAAM;YACpB,WAAW,EAAE,SAAS;YACtB,aAAa,EAAE,UAAU;YACzB,kBAAkB,EAAE,UAAU;SAC9B,CAAC;QACF,MAAM,cAAc,GAAG,IAAI,CAAC,mBAAmB,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QAEzE,oEAAoE;QACpE,IAAI,IAAI,GAAc,MAAM,CAAC;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;YAClE,IAAI,GAAG,WAAW,CAAC;QACpB,CAAC;QAED,yBAAyB;QACzB,MAAM,YAAY,GAAa,EAAE,CAAC;QAElC,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YAC1B,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACP,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAE1B,oCAAoC;YACpC,IAAI,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC;YAED,kCAAkC;YAClC,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/B,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3B,CAAC;YAED,gDAAgD;YAChD,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1D,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YACvC,CAAC;QACF,CAAC;QAED,OAAO;YACN,cAAc;YACd,IAAI;YACJ,YAAY;SACZ,CAAC;IACH,CAAC;CACD"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * kosha-discovery — Google Vertex AI provider discoverer.
3
+ *
4
+ * Resolution strategy (in order):
5
+ * 1. REST API with Application Default Credentials (ADC)
6
+ * 2. gcloud CLI fallback (`gcloud ai models list`)
7
+ * 3. Static fallback list of known Vertex AI models
8
+ *
9
+ * Credentials: Uses the Google ADC chain —
10
+ * ~/.config/gcloud/application_default_credentials.json,
11
+ * GOOGLE_APPLICATION_CREDENTIALS env var, or the GCP metadata server.
12
+ * @module
13
+ */
14
+ import type { CredentialResult, ModelCard } from "../types.js";
15
+ import { BaseDiscoverer } from "./base.js";
16
+ /**
17
+ * Discovers models available through Google Vertex AI.
18
+ *
19
+ * Works without an explicit API key: access tokens are resolved via the
20
+ * standard ADC chain, so it behaves correctly in local dev environments
21
+ * (after `gcloud auth application-default login`) and on GCP VMs (metadata
22
+ * server). When the REST API is unavailable it falls back to the gcloud CLI,
23
+ * and when that is missing it returns a curated static list so callers always
24
+ * receive useful results.
25
+ */
26
+ export declare class VertexDiscoverer extends BaseDiscoverer {
27
+ readonly providerId = "vertex";
28
+ readonly providerName = "Google Vertex AI";
29
+ /** Template string — region is substituted per-request. */
30
+ readonly baseUrl = "https://{region}-aiplatform.googleapis.com";
31
+ /**
32
+ * Discover models from Vertex AI using a three-tier fallback strategy:
33
+ * 1. Vertex AI REST API (requires an ADC access token + project ID)
34
+ * 2. `gcloud ai models list` CLI
35
+ * 3. Curated static list
36
+ *
37
+ * @param credential - Credential bag; `accessToken` is used when present.
38
+ * `metadata.projectId` and `metadata.region` take precedence over env vars.
39
+ * @param options - Optional timeout in ms (default 10 000).
40
+ */
41
+ discover(credential: CredentialResult, options?: {
42
+ timeout?: number;
43
+ }): Promise<ModelCard[]>;
44
+ /**
45
+ * Fetch models from the Vertex AI Publisher Models REST endpoint.
46
+ *
47
+ * URL: `https://{region}-aiplatform.googleapis.com/v1/projects/{project}/
48
+ * locations/{region}/publishers/google/models`
49
+ *
50
+ * @param credential - Used to obtain a Bearer token via {@link getAccessToken}.
51
+ * @param projectId - GCP project ID (required for the REST path).
52
+ * @param region - GCP region (e.g. "us-central1").
53
+ * @param options - Optional timeout override.
54
+ */
55
+ private discoverViaApi;
56
+ /**
57
+ * Resolve a Google OAuth2 access token using the ADC chain:
58
+ * 1. `credential.accessToken` — already resolved upstream
59
+ * 2. ADC JSON file containing `access_token` (service account / workload identity)
60
+ * 3. ADC JSON file with `refresh_token` — exchange via Google OAuth endpoint
61
+ * 4. `gcloud auth print-access-token` CLI fallback
62
+ *
63
+ * Returns `undefined` when no token can be obtained.
64
+ *
65
+ * @param credential - The credential bag from the discovery pipeline.
66
+ */
67
+ getAccessToken(credential: CredentialResult): Promise<string | undefined>;
68
+ /**
69
+ * Exchange a refresh token for a short-lived access token via Google OAuth2.
70
+ *
71
+ * @param clientId - OAuth2 client ID from the ADC file.
72
+ * @param clientSecret - OAuth2 client secret from the ADC file.
73
+ * @param refreshToken - Refresh token from the ADC file.
74
+ */
75
+ private exchangeRefreshToken;
76
+ /**
77
+ * Obtain an access token by calling `gcloud auth print-access-token`.
78
+ * Returns `undefined` when the CLI is not installed or the command fails.
79
+ */
80
+ private tokenFromGcloudCli;
81
+ /**
82
+ * Discover models by executing `gcloud ai models list` and parsing JSON output.
83
+ *
84
+ * @param projectId - GCP project ID passed as `--project`.
85
+ * @param region - GCP region passed as `--region`.
86
+ */
87
+ private discoverViaCli;
88
+ /**
89
+ * Resolve a GCP project ID from the active `gcloud` configuration.
90
+ * Returns `undefined` when the CLI is unavailable or unconfigured.
91
+ */
92
+ private resolveProjectFromCli;
93
+ /**
94
+ * Return a curated list of well-known Vertex AI models (Feb 2026).
95
+ *
96
+ * Used when neither the REST API nor the gcloud CLI is accessible.
97
+ * All entries carry `source: "manual"` so consumers can distinguish them
98
+ * from live API data.
99
+ *
100
+ * @param region - Propagated to each card's `region` field.
101
+ * @param projectId - Propagated to each card's `projectId` field (may be undefined).
102
+ */
103
+ private staticFallback;
104
+ /**
105
+ * Convert a Vertex AI REST API model object to a {@link ModelCard}.
106
+ *
107
+ * The `name` field is a full resource path such as
108
+ * `publishers/google/models/gemini-2.5-pro`; the prefix is stripped to
109
+ * obtain the bare model ID used in API calls.
110
+ *
111
+ * @param model - Raw Vertex API model entry.
112
+ * @param region - Region the model was fetched from.
113
+ * @param projectId - GCP project ID.
114
+ */
115
+ private toModelCard;
116
+ /**
117
+ * Convert a `gcloud ai models list` JSON entry to a {@link ModelCard}.
118
+ *
119
+ * gcloud returns full resource names such as
120
+ * `projects/{p}/locations/{r}/models/{id}` — we take only the last segment.
121
+ *
122
+ * @param model - Raw gcloud JSON model entry.
123
+ * @param region - Region used for the gcloud query.
124
+ * @param projectId - GCP project ID.
125
+ */
126
+ private gcloudModelToCard;
127
+ /**
128
+ * Determine the primary {@link ModelMode} from a model ID and its
129
+ * supported actions list.
130
+ *
131
+ * @param id - Bare model ID.
132
+ * @param actions - `supportedActions` array from the API response.
133
+ */
134
+ private inferMode;
135
+ /**
136
+ * Infer capability flags from a model ID and its supported actions.
137
+ *
138
+ * Gemini pro/flash/ultra variants receive vision + function_calling because
139
+ * all modern Gemini editions support multimodal input and tool use.
140
+ *
141
+ * @param id - Bare model ID.
142
+ * @param actions - `supportedActions` from the API response.
143
+ */
144
+ private inferCapabilities;
145
+ }
146
+ //# sourceMappingURL=vertex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vertex.d.ts","sourceRoot":"","sources":["../../src/discovery/vertex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAa,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAiD3C;;;;;;;;;GASG;AACH,qBAAa,gBAAiB,SAAQ,cAAc;IACnD,QAAQ,CAAC,UAAU,YAAY;IAC/B,QAAQ,CAAC,YAAY,sBAAsB;IAC3C,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,gDAAgD;IAEhE;;;;;;;;;OASG;IACG,QAAQ,CAAC,UAAU,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAwClG;;;;;;;;;;OAUG;YACW,cAAc;IA8B5B;;;;;;;;;;OAUG;IACG,cAAc,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IA8B/E;;;;;;OAMG;YACW,oBAAoB;IA0BlC;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAkB1B;;;;;OAKG;YACW,cAAc;IAuB5B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAmB7B;;;;;;;;;OASG;IACH,OAAO,CAAC,cAAc;IAkBtB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,WAAW;IAkBnB;;;;;;;;;OASG;IACH,OAAO,CAAC,iBAAiB;IAqBzB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IAOjB;;;;;;;;OAQG;IACH,OAAO,CAAC,iBAAiB;CAgBzB"}