@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.
- package/LICENSE +21 -0
- package/README.md +286 -0
- package/dist/aliases.d.ts +51 -0
- package/dist/aliases.d.ts.map +1 -0
- package/dist/aliases.js +115 -0
- package/dist/aliases.js.map +1 -0
- package/dist/cache.d.ts +57 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +123 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli-commands.d.ts +142 -0
- package/dist/cli-commands.d.ts.map +1 -0
- package/dist/cli-commands.js +746 -0
- package/dist/cli-commands.js.map +1 -0
- package/dist/cli-format.d.ts +119 -0
- package/dist/cli-format.d.ts.map +1 -0
- package/dist/cli-format.js +171 -0
- package/dist/cli-format.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +143 -0
- package/dist/cli.js.map +1 -0
- package/dist/credentials/index.d.ts +2 -0
- package/dist/credentials/index.d.ts.map +1 -0
- package/dist/credentials/index.js +2 -0
- package/dist/credentials/index.js.map +1 -0
- package/dist/credentials/resolver.d.ts +170 -0
- package/dist/credentials/resolver.d.ts.map +1 -0
- package/dist/credentials/resolver.js +597 -0
- package/dist/credentials/resolver.js.map +1 -0
- package/dist/discovery/anthropic.d.ts +49 -0
- package/dist/discovery/anthropic.d.ts.map +1 -0
- package/dist/discovery/anthropic.js +101 -0
- package/dist/discovery/anthropic.js.map +1 -0
- package/dist/discovery/base.d.ts +59 -0
- package/dist/discovery/base.d.ts.map +1 -0
- package/dist/discovery/base.js +123 -0
- package/dist/discovery/base.js.map +1 -0
- package/dist/discovery/bedrock.d.ts +122 -0
- package/dist/discovery/bedrock.d.ts.map +1 -0
- package/dist/discovery/bedrock.js +356 -0
- package/dist/discovery/bedrock.js.map +1 -0
- package/dist/discovery/cerebras.d.ts +43 -0
- package/dist/discovery/cerebras.d.ts.map +1 -0
- package/dist/discovery/cerebras.js +65 -0
- package/dist/discovery/cerebras.js.map +1 -0
- package/dist/discovery/cohere.d.ts +57 -0
- package/dist/discovery/cohere.d.ts.map +1 -0
- package/dist/discovery/cohere.js +82 -0
- package/dist/discovery/cohere.js.map +1 -0
- package/dist/discovery/deepinfra.d.ts +41 -0
- package/dist/discovery/deepinfra.d.ts.map +1 -0
- package/dist/discovery/deepinfra.js +86 -0
- package/dist/discovery/deepinfra.js.map +1 -0
- package/dist/discovery/deepseek.d.ts +17 -0
- package/dist/discovery/deepseek.d.ts.map +1 -0
- package/dist/discovery/deepseek.js +45 -0
- package/dist/discovery/deepseek.js.map +1 -0
- package/dist/discovery/fireworks.d.ts +48 -0
- package/dist/discovery/fireworks.d.ts.map +1 -0
- package/dist/discovery/fireworks.js +101 -0
- package/dist/discovery/fireworks.js.map +1 -0
- package/dist/discovery/glm.d.ts +17 -0
- package/dist/discovery/glm.d.ts.map +1 -0
- package/dist/discovery/glm.js +52 -0
- package/dist/discovery/glm.js.map +1 -0
- package/dist/discovery/google.d.ts +53 -0
- package/dist/discovery/google.d.ts.map +1 -0
- package/dist/discovery/google.js +122 -0
- package/dist/discovery/google.js.map +1 -0
- package/dist/discovery/groq.d.ts +44 -0
- package/dist/discovery/groq.d.ts.map +1 -0
- package/dist/discovery/groq.js +89 -0
- package/dist/discovery/groq.js.map +1 -0
- package/dist/discovery/index.d.ts +48 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +116 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/llama-cpp.d.ts +45 -0
- package/dist/discovery/llama-cpp.d.ts.map +1 -0
- package/dist/discovery/llama-cpp.js +137 -0
- package/dist/discovery/llama-cpp.js.map +1 -0
- package/dist/discovery/minimax.d.ts +16 -0
- package/dist/discovery/minimax.d.ts.map +1 -0
- package/dist/discovery/minimax.js +56 -0
- package/dist/discovery/minimax.js.map +1 -0
- package/dist/discovery/mistral.d.ts +45 -0
- package/dist/discovery/mistral.d.ts.map +1 -0
- package/dist/discovery/mistral.js +82 -0
- package/dist/discovery/mistral.js.map +1 -0
- package/dist/discovery/moonshot.d.ts +16 -0
- package/dist/discovery/moonshot.d.ts.map +1 -0
- package/dist/discovery/moonshot.js +46 -0
- package/dist/discovery/moonshot.js.map +1 -0
- package/dist/discovery/nvidia.d.ts +60 -0
- package/dist/discovery/nvidia.d.ts.map +1 -0
- package/dist/discovery/nvidia.js +145 -0
- package/dist/discovery/nvidia.js.map +1 -0
- package/dist/discovery/ollama.d.ts +57 -0
- package/dist/discovery/ollama.d.ts.map +1 -0
- package/dist/discovery/ollama.js +151 -0
- package/dist/discovery/ollama.js.map +1 -0
- package/dist/discovery/openai-compatible.d.ts +126 -0
- package/dist/discovery/openai-compatible.d.ts.map +1 -0
- package/dist/discovery/openai-compatible.js +161 -0
- package/dist/discovery/openai-compatible.js.map +1 -0
- package/dist/discovery/openai.d.ts +62 -0
- package/dist/discovery/openai.d.ts.map +1 -0
- package/dist/discovery/openai.js +157 -0
- package/dist/discovery/openai.js.map +1 -0
- package/dist/discovery/openrouter.d.ts +78 -0
- package/dist/discovery/openrouter.d.ts.map +1 -0
- package/dist/discovery/openrouter.js +184 -0
- package/dist/discovery/openrouter.js.map +1 -0
- package/dist/discovery/perplexity.d.ts +66 -0
- package/dist/discovery/perplexity.d.ts.map +1 -0
- package/dist/discovery/perplexity.js +86 -0
- package/dist/discovery/perplexity.js.map +1 -0
- package/dist/discovery/together.d.ts +41 -0
- package/dist/discovery/together.d.ts.map +1 -0
- package/dist/discovery/together.js +88 -0
- package/dist/discovery/together.js.map +1 -0
- package/dist/discovery/vertex.d.ts +146 -0
- package/dist/discovery/vertex.d.ts.map +1 -0
- package/dist/discovery/vertex.js +371 -0
- package/dist/discovery/vertex.js.map +1 -0
- package/dist/discovery/zai.d.ts +17 -0
- package/dist/discovery/zai.d.ts.map +1 -0
- package/dist/discovery/zai.js +51 -0
- package/dist/discovery/zai.js.map +1 -0
- package/dist/discovery-contract.d.ts +186 -0
- package/dist/discovery-contract.d.ts.map +1 -0
- package/dist/discovery-contract.js +115 -0
- package/dist/discovery-contract.js.map +1 -0
- package/dist/discovery-routes.d.ts +14 -0
- package/dist/discovery-routes.d.ts.map +1 -0
- package/dist/discovery-routes.js +98 -0
- package/dist/discovery-routes.js.map +1 -0
- package/dist/enrichment/index.d.ts +2 -0
- package/dist/enrichment/index.d.ts.map +1 -0
- package/dist/enrichment/index.js +2 -0
- package/dist/enrichment/index.js.map +1 -0
- package/dist/enrichment/litellm.d.ts +52 -0
- package/dist/enrichment/litellm.d.ts.map +1 -0
- package/dist/enrichment/litellm.js +205 -0
- package/dist/enrichment/litellm.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/normalize.d.ts +64 -0
- package/dist/normalize.d.ts.map +1 -0
- package/dist/normalize.js +166 -0
- package/dist/normalize.js.map +1 -0
- package/dist/provider-catalog.d.ts +62 -0
- package/dist/provider-catalog.d.ts.map +1 -0
- package/dist/provider-catalog.js +331 -0
- package/dist/provider-catalog.js.map +1 -0
- package/dist/registry-delta.d.ts +17 -0
- package/dist/registry-delta.d.ts.map +1 -0
- package/dist/registry-delta.js +74 -0
- package/dist/registry-delta.js.map +1 -0
- package/dist/registry-discovery.d.ts +66 -0
- package/dist/registry-discovery.d.ts.map +1 -0
- package/dist/registry-discovery.js +339 -0
- package/dist/registry-discovery.js.map +1 -0
- package/dist/registry-query.d.ts +74 -0
- package/dist/registry-query.d.ts.map +1 -0
- package/dist/registry-query.js +310 -0
- package/dist/registry-query.js.map +1 -0
- package/dist/registry-runtime.d.ts +48 -0
- package/dist/registry-runtime.d.ts.map +1 -0
- package/dist/registry-runtime.js +255 -0
- package/dist/registry-runtime.js.map +1 -0
- package/dist/registry-selection.d.ts +31 -0
- package/dist/registry-selection.d.ts.map +1 -0
- package/dist/registry-selection.js +167 -0
- package/dist/registry-selection.js.map +1 -0
- package/dist/registry-state.d.ts +92 -0
- package/dist/registry-state.d.ts.map +1 -0
- package/dist/registry-state.js +35 -0
- package/dist/registry-state.js.map +1 -0
- package/dist/registry.d.ts +127 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +248 -0
- package/dist/registry.js.map +1 -0
- package/dist/resilience.d.ts +212 -0
- package/dist/resilience.d.ts.map +1 -0
- package/dist/resilience.js +292 -0
- package/dist/resilience.js.map +1 -0
- package/dist/security.d.ts +44 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +184 -0
- package/dist/security.js.map +1 -0
- package/dist/server.d.ts +41 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +320 -0
- package/dist/server.js.map +1 -0
- package/dist/shell-safe.d.ts +15 -0
- package/dist/shell-safe.d.ts.map +1 -0
- package/dist/shell-safe.js +20 -0
- package/dist/shell-safe.js.map +1 -0
- package/dist/types.d.ts +365 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/logo.svg +81 -0
- 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"}
|