tryaii-dre 0.2.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 +190 -0
- package/README.md +234 -0
- package/dist/banner.d.ts +24 -0
- package/dist/banner.d.ts.map +1 -0
- package/dist/banner.js +125 -0
- package/dist/banner.js.map +1 -0
- package/dist/benchmarks/index.d.ts +4 -0
- package/dist/benchmarks/index.d.ts.map +1 -0
- package/dist/benchmarks/index.js +3 -0
- package/dist/benchmarks/index.js.map +1 -0
- package/dist/benchmarks/registry.d.ts +69 -0
- package/dist/benchmarks/registry.d.ts.map +1 -0
- package/dist/benchmarks/registry.js +128 -0
- package/dist/benchmarks/registry.js.map +1 -0
- package/dist/benchmarks/standard.d.ts +6 -0
- package/dist/benchmarks/standard.d.ts.map +1 -0
- package/dist/benchmarks/standard.js +115 -0
- package/dist/benchmarks/standard.js.map +1 -0
- package/dist/budget.d.ts +65 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +344 -0
- package/dist/budget.js.map +1 -0
- package/dist/cache/index.d.ts +27 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +63 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/centroids/data/centroids_all-MiniLM-L6-v2.json +1 -0
- package/dist/centroids/data/trainingQueries.json +246 -0
- package/dist/centroids/generator.d.ts +63 -0
- package/dist/centroids/generator.d.ts.map +1 -0
- package/dist/centroids/generator.js +120 -0
- package/dist/centroids/generator.js.map +1 -0
- package/dist/centroids/index.d.ts +3 -0
- package/dist/centroids/index.d.ts.map +1 -0
- package/dist/centroids/index.js +3 -0
- package/dist/centroids/index.js.map +1 -0
- package/dist/centroids/loader.d.ts +87 -0
- package/dist/centroids/loader.d.ts.map +1 -0
- package/dist/centroids/loader.js +236 -0
- package/dist/centroids/loader.js.map +1 -0
- package/dist/classifiers/base.d.ts +56 -0
- package/dist/classifiers/base.d.ts.map +1 -0
- package/dist/classifiers/base.js +42 -0
- package/dist/classifiers/base.js.map +1 -0
- package/dist/classifiers/embedding.d.ts +68 -0
- package/dist/classifiers/embedding.d.ts.map +1 -0
- package/dist/classifiers/embedding.js +0 -0
- package/dist/classifiers/embedding.js.map +1 -0
- package/dist/classifiers/hybrid.d.ts +31 -0
- package/dist/classifiers/hybrid.d.ts.map +1 -0
- package/dist/classifiers/hybrid.js +61 -0
- package/dist/classifiers/hybrid.js.map +1 -0
- package/dist/classifiers/index.d.ts +4 -0
- package/dist/classifiers/index.d.ts.map +1 -0
- package/dist/classifiers/index.js +3 -0
- package/dist/classifiers/index.js.map +1 -0
- package/dist/classifiers/keyword.d.ts +29 -0
- package/dist/classifiers/keyword.d.ts.map +1 -0
- package/dist/classifiers/keyword.js +264 -0
- package/dist/classifiers/keyword.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +597 -0
- package/dist/cli.js.map +1 -0
- package/dist/client-types.d.ts +101 -0
- package/dist/client-types.d.ts.map +1 -0
- package/dist/client-types.js +5 -0
- package/dist/client-types.js.map +1 -0
- package/dist/client.d.ts +50 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +279 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +45 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +37 -0
- package/dist/config.js.map +1 -0
- package/dist/dashboard/index.d.ts +48 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +166 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/embeddings/base.d.ts +66 -0
- package/dist/embeddings/base.d.ts.map +1 -0
- package/dist/embeddings/base.js +77 -0
- package/dist/embeddings/base.js.map +1 -0
- package/dist/embeddings/index.d.ts +3 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +3 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/local.d.ts +42 -0
- package/dist/embeddings/local.d.ts.map +1 -0
- package/dist/embeddings/local.js +89 -0
- package/dist/embeddings/local.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/index.d.ts +3 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +2 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/openrouter.d.ts +84 -0
- package/dist/integrations/openrouter.d.ts.map +1 -0
- package/dist/integrations/openrouter.js +253 -0
- package/dist/integrations/openrouter.js.map +1 -0
- package/dist/registry/index.d.ts +2 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +2 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/models.d.ts +76 -0
- package/dist/registry/models.d.ts.map +1 -0
- package/dist/registry/models.js +170 -0
- package/dist/registry/models.js.map +1 -0
- package/dist/registry/presets/defaultModels.json +435 -0
- package/dist/router.d.ts +178 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +259 -0
- package/dist/router.js.map +1 -0
- package/dist/scoring/benchmarks.d.ts +35 -0
- package/dist/scoring/benchmarks.d.ts.map +1 -0
- package/dist/scoring/benchmarks.js +68 -0
- package/dist/scoring/benchmarks.js.map +1 -0
- package/dist/scoring/engine.d.ts +43 -0
- package/dist/scoring/engine.d.ts.map +1 -0
- package/dist/scoring/engine.js +267 -0
- package/dist/scoring/engine.js.map +1 -0
- package/dist/scoring/index.d.ts +6 -0
- package/dist/scoring/index.d.ts.map +1 -0
- package/dist/scoring/index.js +4 -0
- package/dist/scoring/index.js.map +1 -0
- package/dist/scoring/priorities.d.ts +41 -0
- package/dist/scoring/priorities.d.ts.map +1 -0
- package/dist/scoring/priorities.js +49 -0
- package/dist/scoring/priorities.js.map +1 -0
- package/dist/types.d.ts +47 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/cosine.d.ts +10 -0
- package/dist/utils/cosine.d.ts.map +1 -0
- package/dist/utils/cosine.js +18 -0
- package/dist/utils/cosine.js.map +1 -0
- package/dist/utils/math.d.ts +18 -0
- package/dist/utils/math.d.ts.map +1 -0
- package/dist/utils/math.js +54 -0
- package/dist/utils/math.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRouter integration -- active routing through OpenRouter's API.
|
|
3
|
+
*
|
|
4
|
+
* Wraps OpenRouter API calls so that TryAii-DRE automatically selects
|
|
5
|
+
* the best model based on the prompt, then forwards the request.
|
|
6
|
+
*
|
|
7
|
+
* Uses the native fetch() API (available in Node 18+).
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* import { Router } from 'tryaii-dre';
|
|
11
|
+
* import { OpenRouterIntegration } from 'tryaii-dre/integrations';
|
|
12
|
+
*
|
|
13
|
+
* const router = new Router();
|
|
14
|
+
* const openrouter = new OpenRouterIntegration(router, { apiKey: 'sk-or-...' });
|
|
15
|
+
*
|
|
16
|
+
* const response = await openrouter.chat('Write a Python quicksort implementation');
|
|
17
|
+
* console.log(response.modelUsed);
|
|
18
|
+
* console.log(response.content);
|
|
19
|
+
*/
|
|
20
|
+
import type { PrioritiesData } from '../scoring/priorities.js';
|
|
21
|
+
/** Mapping from our model IDs to OpenRouter model slugs. */
|
|
22
|
+
export declare const MODEL_ID_TO_OPENROUTER: Record<string, string>;
|
|
23
|
+
/** Response from an OpenRouter API call. */
|
|
24
|
+
export interface OpenRouterResponse {
|
|
25
|
+
/** The response text content. */
|
|
26
|
+
content: string;
|
|
27
|
+
/** TryAii-DRE model ID that was selected. */
|
|
28
|
+
modelUsed: string;
|
|
29
|
+
/** OpenRouter model slug (e.g., "openai/gpt-4o"). */
|
|
30
|
+
openrouterModel: string;
|
|
31
|
+
/** Why this model was chosen. */
|
|
32
|
+
routeReasoning: string;
|
|
33
|
+
/** Token usage information. */
|
|
34
|
+
usage: Record<string, unknown>;
|
|
35
|
+
/** Raw API response. */
|
|
36
|
+
rawResponse: Record<string, unknown> | null;
|
|
37
|
+
}
|
|
38
|
+
/** Options for chat() and stream() calls. */
|
|
39
|
+
export interface OpenRouterChatOptions {
|
|
40
|
+
/** Optional priority dict. */
|
|
41
|
+
priorities?: Partial<PrioritiesData>;
|
|
42
|
+
/** Optional system prompt. */
|
|
43
|
+
systemMessage?: string;
|
|
44
|
+
/** Sampling temperature (default: 0.7). */
|
|
45
|
+
temperature?: number;
|
|
46
|
+
/** Maximum response tokens. */
|
|
47
|
+
maxTokens?: number;
|
|
48
|
+
/** Skip routing and use this model directly. */
|
|
49
|
+
overrideModel?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Active routing integration with OpenRouter.
|
|
53
|
+
*
|
|
54
|
+
* Combines TryAii-DRE's semantic routing with OpenRouter's multi-provider
|
|
55
|
+
* API to automatically select and call the best model.
|
|
56
|
+
*/
|
|
57
|
+
export declare class OpenRouterIntegration {
|
|
58
|
+
static readonly OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1";
|
|
59
|
+
private _router;
|
|
60
|
+
private _apiKey;
|
|
61
|
+
private _appName;
|
|
62
|
+
constructor(router: any, opts?: {
|
|
63
|
+
apiKey?: string;
|
|
64
|
+
appName?: string;
|
|
65
|
+
});
|
|
66
|
+
private _ensureApiKey;
|
|
67
|
+
/** Convert TryAii-DRE model ID to OpenRouter slug. */
|
|
68
|
+
private _resolveModel;
|
|
69
|
+
/**
|
|
70
|
+
* Route and complete a chat request.
|
|
71
|
+
*
|
|
72
|
+
* @param prompt - User message.
|
|
73
|
+
* @param opts - Optional configuration (priorities, temperature, etc.).
|
|
74
|
+
* @returns OpenRouterResponse with content and routing info.
|
|
75
|
+
*/
|
|
76
|
+
chat(prompt: string, opts?: OpenRouterChatOptions): Promise<OpenRouterResponse>;
|
|
77
|
+
/**
|
|
78
|
+
* Route and stream a chat response.
|
|
79
|
+
*
|
|
80
|
+
* Yields content chunks as they arrive.
|
|
81
|
+
*/
|
|
82
|
+
stream(prompt: string, opts?: OpenRouterChatOptions): AsyncGenerator<string>;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=openrouter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter.d.ts","sourceRoot":"","sources":["../../src/integrations/openrouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAc,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE3E,4DAA4D;AAC5D,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAwCzD,CAAC;AAEF,4CAA4C;AAC5C,MAAM,WAAW,kBAAkB;IACjC,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,eAAe,EAAE,MAAM,CAAC;IACxB,iCAAiC;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,wBAAwB;IACxB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC7C;AAED,6CAA6C;AAC7C,MAAM,WAAW,qBAAqB;IACpC,8BAA8B;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACrC,8BAA8B;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,qBAAa,qBAAqB;IAChC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,kCAAkC;IAIrE,OAAO,CAAC,OAAO,CAAM;IACrB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;gBAIvB,MAAM,EAAE,GAAG,EACX,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB;IAOH,OAAO,CAAC,aAAa;IAMrB,sDAAsD;IACtD,OAAO,CAAC,aAAa;IAIrB;;;;;;OAMG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA+ErF;;;;OAIG;IACI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,cAAc,CAAC,MAAM,CAAC;CA6FpF"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRouter integration -- active routing through OpenRouter's API.
|
|
3
|
+
*
|
|
4
|
+
* Wraps OpenRouter API calls so that TryAii-DRE automatically selects
|
|
5
|
+
* the best model based on the prompt, then forwards the request.
|
|
6
|
+
*
|
|
7
|
+
* Uses the native fetch() API (available in Node 18+).
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* import { Router } from 'tryaii-dre';
|
|
11
|
+
* import { OpenRouterIntegration } from 'tryaii-dre/integrations';
|
|
12
|
+
*
|
|
13
|
+
* const router = new Router();
|
|
14
|
+
* const openrouter = new OpenRouterIntegration(router, { apiKey: 'sk-or-...' });
|
|
15
|
+
*
|
|
16
|
+
* const response = await openrouter.chat('Write a Python quicksort implementation');
|
|
17
|
+
* console.log(response.modelUsed);
|
|
18
|
+
* console.log(response.content);
|
|
19
|
+
*/
|
|
20
|
+
/** Mapping from our model IDs to OpenRouter model slugs. */
|
|
21
|
+
export const MODEL_ID_TO_OPENROUTER = {
|
|
22
|
+
// OpenAI
|
|
23
|
+
'gpt-4o': 'openai/gpt-4o',
|
|
24
|
+
'gpt-4o-mini': 'openai/gpt-4o-mini',
|
|
25
|
+
'o1': 'openai/o1',
|
|
26
|
+
'o3': 'openai/o3',
|
|
27
|
+
'o4-mini': 'openai/o4-mini',
|
|
28
|
+
'gpt-5': 'openai/gpt-5',
|
|
29
|
+
'gpt-5-mini': 'openai/gpt-5-mini',
|
|
30
|
+
'gpt-5.1': 'openai/gpt-5.1',
|
|
31
|
+
'gpt-5.2': 'openai/gpt-5.2',
|
|
32
|
+
'gpt-4.1': 'openai/gpt-4.1',
|
|
33
|
+
'gpt-4.1-nano': 'openai/gpt-4.1-nano',
|
|
34
|
+
'gpt-5-nano': 'openai/gpt-5-nano',
|
|
35
|
+
// Anthropic
|
|
36
|
+
'claude-3-7-sonnet-20250219': 'anthropic/claude-3.7-sonnet',
|
|
37
|
+
'claude-sonnet-4-20250514': 'anthropic/claude-sonnet-4',
|
|
38
|
+
'claude-sonnet-4-5-20250929': 'anthropic/claude-sonnet-4.5',
|
|
39
|
+
'claude-haiku-4-5-20251001': 'anthropic/claude-haiku-4.5',
|
|
40
|
+
'claude-opus-4-5-20251101': 'anthropic/claude-opus-4.5',
|
|
41
|
+
// Google
|
|
42
|
+
'gemini-2.5-pro': 'google/gemini-2.5-pro',
|
|
43
|
+
'gemini-2.0-flash': 'google/gemini-2.0-flash',
|
|
44
|
+
'gemini-2.5-flash': 'google/gemini-2.5-flash',
|
|
45
|
+
'gemini-2.5-flash-lite': 'google/gemini-2.5-flash-lite',
|
|
46
|
+
'gemini-3-pro-preview': 'google/gemini-3-pro-preview',
|
|
47
|
+
'gemini-3-flash-preview': 'google/gemini-3-flash-preview',
|
|
48
|
+
// DeepSeek
|
|
49
|
+
'deepseek-reasoner': 'deepseek/deepseek-reasoner',
|
|
50
|
+
'deepseek-chat': 'deepseek/deepseek-chat',
|
|
51
|
+
// xAI
|
|
52
|
+
'grok-3-latest': 'x-ai/grok-3',
|
|
53
|
+
'grok-3-mini-latest': 'x-ai/grok-3-mini',
|
|
54
|
+
'grok-4-latest': 'x-ai/grok-4',
|
|
55
|
+
'grok-4-fast': 'x-ai/grok-4-fast',
|
|
56
|
+
'grok-4-1-fast-reasoning-latest': 'x-ai/grok-4.1-fast-reasoning',
|
|
57
|
+
'grok-code-fast': 'x-ai/grok-code-fast',
|
|
58
|
+
// Mistral
|
|
59
|
+
'mistral-large-latest': 'mistralai/mistral-large',
|
|
60
|
+
'mistral-small-latest': 'mistralai/mistral-small',
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Active routing integration with OpenRouter.
|
|
64
|
+
*
|
|
65
|
+
* Combines TryAii-DRE's semantic routing with OpenRouter's multi-provider
|
|
66
|
+
* API to automatically select and call the best model.
|
|
67
|
+
*/
|
|
68
|
+
export class OpenRouterIntegration {
|
|
69
|
+
constructor(
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
71
|
+
router, opts) {
|
|
72
|
+
this._router = router;
|
|
73
|
+
this._apiKey = opts?.apiKey ?? '';
|
|
74
|
+
this._appName = opts?.appName ?? 'tryaii-dre';
|
|
75
|
+
}
|
|
76
|
+
_ensureApiKey() {
|
|
77
|
+
if (!this._apiKey) {
|
|
78
|
+
throw new Error('OpenRouterIntegration requires an explicit apiKey');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** Convert TryAii-DRE model ID to OpenRouter slug. */
|
|
82
|
+
_resolveModel(modelId) {
|
|
83
|
+
return MODEL_ID_TO_OPENROUTER[modelId] ?? modelId;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Route and complete a chat request.
|
|
87
|
+
*
|
|
88
|
+
* @param prompt - User message.
|
|
89
|
+
* @param opts - Optional configuration (priorities, temperature, etc.).
|
|
90
|
+
* @returns OpenRouterResponse with content and routing info.
|
|
91
|
+
*/
|
|
92
|
+
async chat(prompt, opts) {
|
|
93
|
+
this._ensureApiKey();
|
|
94
|
+
let modelId;
|
|
95
|
+
let reasoning;
|
|
96
|
+
if (opts?.overrideModel) {
|
|
97
|
+
modelId = opts.overrideModel;
|
|
98
|
+
reasoning = `Model override: ${opts.overrideModel}`;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
const { Priorities } = await import('../scoring/priorities.js');
|
|
102
|
+
const prio = opts?.priorities
|
|
103
|
+
? Priorities.fromDict(opts.priorities)
|
|
104
|
+
: undefined;
|
|
105
|
+
const routeResult = await this._router.route(prompt, { priorities: prio });
|
|
106
|
+
modelId = routeResult.bestModel;
|
|
107
|
+
reasoning = routeResult.scores[0]?.reasoning ?? '';
|
|
108
|
+
}
|
|
109
|
+
if (!modelId) {
|
|
110
|
+
throw new Error('routing returned no model for this prompt');
|
|
111
|
+
}
|
|
112
|
+
const openrouterModel = this._resolveModel(modelId);
|
|
113
|
+
// Build messages
|
|
114
|
+
const messages = [];
|
|
115
|
+
if (opts?.systemMessage) {
|
|
116
|
+
messages.push({ role: 'system', content: opts.systemMessage });
|
|
117
|
+
}
|
|
118
|
+
messages.push({ role: 'user', content: prompt });
|
|
119
|
+
// Build payload
|
|
120
|
+
const payload = {
|
|
121
|
+
model: openrouterModel,
|
|
122
|
+
messages,
|
|
123
|
+
temperature: opts?.temperature ?? 0.7,
|
|
124
|
+
};
|
|
125
|
+
// Only send max_tokens when it is a finite, positive number (0 is not meaningful).
|
|
126
|
+
if (opts?.maxTokens != null && Number.isFinite(opts.maxTokens) && opts.maxTokens > 0) {
|
|
127
|
+
payload.max_tokens = opts.maxTokens;
|
|
128
|
+
}
|
|
129
|
+
// Make API call using native fetch
|
|
130
|
+
const response = await fetch(`${OpenRouterIntegration.OPENROUTER_BASE_URL}/chat/completions`, {
|
|
131
|
+
method: 'POST',
|
|
132
|
+
headers: {
|
|
133
|
+
'Authorization': `Bearer ${this._apiKey}`,
|
|
134
|
+
'X-Title': this._appName,
|
|
135
|
+
'Content-Type': 'application/json',
|
|
136
|
+
},
|
|
137
|
+
body: JSON.stringify(payload),
|
|
138
|
+
});
|
|
139
|
+
if (!response.ok) {
|
|
140
|
+
throw new Error(`OpenRouter API error: ${response.status} ${response.statusText}`);
|
|
141
|
+
}
|
|
142
|
+
const data = await response.json();
|
|
143
|
+
// OpenRouter can return HTTP 200 with an { error } envelope and no choices.
|
|
144
|
+
// Surface the provider message instead of returning a fake-empty success.
|
|
145
|
+
if (!data.choices?.length && data.error != null) {
|
|
146
|
+
const err = data.error;
|
|
147
|
+
const message = typeof err === 'string' ? err : err.message ?? 'OpenRouter returned an error';
|
|
148
|
+
throw new Error(`OpenRouter API error: ${message}`);
|
|
149
|
+
}
|
|
150
|
+
const content = data.choices?.[0]?.message?.content ?? '';
|
|
151
|
+
const usage = data.usage ?? {};
|
|
152
|
+
return {
|
|
153
|
+
content,
|
|
154
|
+
modelUsed: modelId,
|
|
155
|
+
openrouterModel,
|
|
156
|
+
routeReasoning: reasoning,
|
|
157
|
+
usage,
|
|
158
|
+
rawResponse: data,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Route and stream a chat response.
|
|
163
|
+
*
|
|
164
|
+
* Yields content chunks as they arrive.
|
|
165
|
+
*/
|
|
166
|
+
async *stream(prompt, opts) {
|
|
167
|
+
this._ensureApiKey();
|
|
168
|
+
let modelId;
|
|
169
|
+
if (opts?.overrideModel) {
|
|
170
|
+
modelId = opts.overrideModel;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
const { Priorities } = await import('../scoring/priorities.js');
|
|
174
|
+
const prio = opts?.priorities
|
|
175
|
+
? Priorities.fromDict(opts.priorities)
|
|
176
|
+
: undefined;
|
|
177
|
+
const routeResult = await this._router.route(prompt, { priorities: prio });
|
|
178
|
+
modelId = routeResult.bestModel;
|
|
179
|
+
}
|
|
180
|
+
if (!modelId) {
|
|
181
|
+
throw new Error('routing returned no model for this prompt');
|
|
182
|
+
}
|
|
183
|
+
const openrouterModel = this._resolveModel(modelId);
|
|
184
|
+
const messages = [];
|
|
185
|
+
if (opts?.systemMessage) {
|
|
186
|
+
messages.push({ role: 'system', content: opts.systemMessage });
|
|
187
|
+
}
|
|
188
|
+
messages.push({ role: 'user', content: prompt });
|
|
189
|
+
const payload = {
|
|
190
|
+
model: openrouterModel,
|
|
191
|
+
messages,
|
|
192
|
+
temperature: opts?.temperature ?? 0.7,
|
|
193
|
+
stream: true,
|
|
194
|
+
};
|
|
195
|
+
// Only send max_tokens when it is a finite, positive number (0 is not meaningful).
|
|
196
|
+
if (opts?.maxTokens != null && Number.isFinite(opts.maxTokens) && opts.maxTokens > 0) {
|
|
197
|
+
payload.max_tokens = opts.maxTokens;
|
|
198
|
+
}
|
|
199
|
+
const response = await fetch(`${OpenRouterIntegration.OPENROUTER_BASE_URL}/chat/completions`, {
|
|
200
|
+
method: 'POST',
|
|
201
|
+
headers: {
|
|
202
|
+
'Authorization': `Bearer ${this._apiKey}`,
|
|
203
|
+
'X-Title': this._appName,
|
|
204
|
+
'Content-Type': 'application/json',
|
|
205
|
+
},
|
|
206
|
+
body: JSON.stringify(payload),
|
|
207
|
+
});
|
|
208
|
+
if (!response.ok) {
|
|
209
|
+
throw new Error(`OpenRouter API error: ${response.status} ${response.statusText}`);
|
|
210
|
+
}
|
|
211
|
+
if (!response.body) {
|
|
212
|
+
throw new Error('Response body is null');
|
|
213
|
+
}
|
|
214
|
+
const reader = response.body.getReader();
|
|
215
|
+
const decoder = new TextDecoder();
|
|
216
|
+
let buffer = '';
|
|
217
|
+
while (true) {
|
|
218
|
+
const { done, value } = await reader.read();
|
|
219
|
+
if (done)
|
|
220
|
+
break;
|
|
221
|
+
buffer += decoder.decode(value, { stream: true });
|
|
222
|
+
const lines = buffer.split('\n');
|
|
223
|
+
buffer = lines.pop() ?? '';
|
|
224
|
+
for (const line of lines) {
|
|
225
|
+
if (!line.startsWith('data: '))
|
|
226
|
+
continue;
|
|
227
|
+
const dataStr = line.slice(6).trim();
|
|
228
|
+
if (dataStr === '[DONE]')
|
|
229
|
+
return;
|
|
230
|
+
let chunk;
|
|
231
|
+
try {
|
|
232
|
+
chunk = JSON.parse(dataStr);
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
// Skip malformed SSE chunks
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
// OpenRouter can stream an { error } chunk; surface it before reading the delta.
|
|
239
|
+
// Thrown outside the parse try/catch so it is not swallowed as a malformed chunk.
|
|
240
|
+
if (chunk?.error != null) {
|
|
241
|
+
const err = chunk.error;
|
|
242
|
+
const message = typeof err === 'string' ? err : err.message ?? 'OpenRouter returned an error';
|
|
243
|
+
throw new Error(`OpenRouter stream error: ${message}`);
|
|
244
|
+
}
|
|
245
|
+
const content = chunk.choices?.[0]?.delta?.content ?? '';
|
|
246
|
+
if (content)
|
|
247
|
+
yield content;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
OpenRouterIntegration.OPENROUTER_BASE_URL = 'https://openrouter.ai/api/v1';
|
|
253
|
+
//# sourceMappingURL=openrouter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/integrations/openrouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/registry/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/registry/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model registry -- stores metadata about AI models.
|
|
3
|
+
*
|
|
4
|
+
* Each model has benchmark scores, pricing, latency, and capabilities.
|
|
5
|
+
* Ships with a default preset of 35+ models; users can add/remove/override.
|
|
6
|
+
*/
|
|
7
|
+
import type { LatencyTier, ModelData, ModelsJson } from '../types.js';
|
|
8
|
+
export declare class ModelPricing {
|
|
9
|
+
readonly inputPer1k: number;
|
|
10
|
+
readonly outputPer1k: number;
|
|
11
|
+
constructor(inputPer1k?: number, outputPer1k?: number);
|
|
12
|
+
get averagePer1k(): number;
|
|
13
|
+
}
|
|
14
|
+
export declare class ModelInfo {
|
|
15
|
+
readonly modelId: string;
|
|
16
|
+
readonly provider: string;
|
|
17
|
+
readonly benchmarkScores: Record<string, number>;
|
|
18
|
+
readonly capabilities: string[];
|
|
19
|
+
readonly pricing: ModelPricing | null;
|
|
20
|
+
readonly latency: LatencyTier | null;
|
|
21
|
+
readonly description: string;
|
|
22
|
+
constructor(opts: {
|
|
23
|
+
modelId: string;
|
|
24
|
+
provider: string;
|
|
25
|
+
benchmarkScores?: Record<string, number>;
|
|
26
|
+
capabilities?: string[];
|
|
27
|
+
pricing?: ModelPricing | null;
|
|
28
|
+
latency?: LatencyTier | null;
|
|
29
|
+
description?: string;
|
|
30
|
+
});
|
|
31
|
+
toDict(): ModelData;
|
|
32
|
+
static fromDict(d: ModelData): ModelInfo;
|
|
33
|
+
}
|
|
34
|
+
export declare class ModelRegistry {
|
|
35
|
+
private _models;
|
|
36
|
+
constructor();
|
|
37
|
+
/** Create a registry pre-loaded with the default model preset. */
|
|
38
|
+
static default(): ModelRegistry;
|
|
39
|
+
/** Add or update a model in the registry. */
|
|
40
|
+
addModel(model: ModelInfo): void;
|
|
41
|
+
/** Convenience method to add a model with keyword arguments. */
|
|
42
|
+
add(opts: {
|
|
43
|
+
modelId: string;
|
|
44
|
+
provider: string;
|
|
45
|
+
benchmarks?: Record<string, number>;
|
|
46
|
+
pricing?: [number, number];
|
|
47
|
+
latency?: LatencyTier;
|
|
48
|
+
capabilities?: string[];
|
|
49
|
+
description?: string;
|
|
50
|
+
}): ModelInfo;
|
|
51
|
+
/** Remove a model from the registry. Returns true if removed. */
|
|
52
|
+
removeModel(modelId: string): boolean;
|
|
53
|
+
/** Get a model by ID. */
|
|
54
|
+
getModel(modelId: string): ModelInfo | undefined;
|
|
55
|
+
/** Filter models by criteria. */
|
|
56
|
+
filter(opts?: {
|
|
57
|
+
provider?: string;
|
|
58
|
+
capability?: string;
|
|
59
|
+
maxInputCost?: number;
|
|
60
|
+
latency?: LatencyTier;
|
|
61
|
+
}): ModelInfo[];
|
|
62
|
+
/** All registered models. */
|
|
63
|
+
get allModels(): ModelInfo[];
|
|
64
|
+
/** All registered model IDs. */
|
|
65
|
+
get modelIds(): string[];
|
|
66
|
+
get length(): number;
|
|
67
|
+
has(modelId: string): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Load a preset model registry from bundled JSON.
|
|
70
|
+
* @returns Number of models loaded.
|
|
71
|
+
*/
|
|
72
|
+
loadPreset(name?: string): number;
|
|
73
|
+
/** Export registry to a JSON-serializable object. */
|
|
74
|
+
exportJson(): ModelsJson;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/registry/models.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEtE,qBAAa,YAAY;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,UAAU,SAAI,EAAE,WAAW,SAAI;IAK3C,IAAI,YAAY,IAAI,MAAM,CAEzB;CACF;AAED,qBAAa,SAAS;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,IAAI,EAAE;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;QAC9B,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;QAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB;IAUD,MAAM,IAAI,SAAS;IAcnB,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS;CAwBzC;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAyB;;IAMxC,kEAAkE;IAClE,MAAM,CAAC,OAAO,IAAI,aAAa;IAM/B,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAIhC,gEAAgE;IAChE,GAAG,CAAC,IAAI,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACpC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3B,OAAO,CAAC,EAAE,WAAW,CAAC;QACtB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,GAAG,SAAS;IAmBb,iEAAiE;IACjE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIrC,yBAAyB;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIhD,iCAAiC;IACjC,MAAM,CAAC,IAAI,CAAC,EAAE;QACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,OAAO,CAAC,EAAE,WAAW,CAAC;KACvB,GAAG,SAAS,EAAE;IAsBf,6BAA6B;IAC7B,IAAI,SAAS,IAAI,SAAS,EAAE,CAE3B;IAED,gCAAgC;IAChC,IAAI,QAAQ,IAAI,MAAM,EAAE,CAEvB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI7B;;;OAGG;IACH,UAAU,CAAC,IAAI,SAAY,GAAG,MAAM;IAqBpC,qDAAqD;IACrD,UAAU,IAAI,UAAU;CAKzB"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model registry -- stores metadata about AI models.
|
|
3
|
+
*
|
|
4
|
+
* Each model has benchmark scores, pricing, latency, and capabilities.
|
|
5
|
+
* Ships with a default preset of 35+ models; users can add/remove/override.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync } from 'node:fs';
|
|
8
|
+
import { dirname, join } from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
export class ModelPricing {
|
|
11
|
+
constructor(inputPer1k = 0, outputPer1k = 0) {
|
|
12
|
+
this.inputPer1k = inputPer1k;
|
|
13
|
+
this.outputPer1k = outputPer1k;
|
|
14
|
+
}
|
|
15
|
+
get averagePer1k() {
|
|
16
|
+
return (this.inputPer1k + this.outputPer1k) / 2;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class ModelInfo {
|
|
20
|
+
constructor(opts) {
|
|
21
|
+
this.modelId = opts.modelId;
|
|
22
|
+
this.provider = opts.provider;
|
|
23
|
+
this.benchmarkScores = opts.benchmarkScores ?? {};
|
|
24
|
+
this.capabilities = opts.capabilities ?? [];
|
|
25
|
+
this.pricing = opts.pricing ?? null;
|
|
26
|
+
this.latency = opts.latency ?? null;
|
|
27
|
+
this.description = opts.description ?? '';
|
|
28
|
+
}
|
|
29
|
+
toDict() {
|
|
30
|
+
return {
|
|
31
|
+
model_id: this.modelId,
|
|
32
|
+
provider: this.provider,
|
|
33
|
+
benchmark_scores: this.benchmarkScores,
|
|
34
|
+
capabilities: this.capabilities,
|
|
35
|
+
pricing: this.pricing
|
|
36
|
+
? { input_per_1k: this.pricing.inputPer1k, output_per_1k: this.pricing.outputPer1k }
|
|
37
|
+
: null,
|
|
38
|
+
latency: this.latency,
|
|
39
|
+
description: this.description,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
static fromDict(d) {
|
|
43
|
+
let pricing = null;
|
|
44
|
+
if (d.pricing) {
|
|
45
|
+
pricing = new ModelPricing(d.pricing.input_per_1k ?? 0, d.pricing.output_per_1k ?? 0);
|
|
46
|
+
}
|
|
47
|
+
// Filter out null benchmark scores
|
|
48
|
+
const benchmarkScores = {};
|
|
49
|
+
if (d.benchmark_scores) {
|
|
50
|
+
for (const [k, v] of Object.entries(d.benchmark_scores)) {
|
|
51
|
+
if (v != null)
|
|
52
|
+
benchmarkScores[k] = v;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return new ModelInfo({
|
|
56
|
+
modelId: d.model_id,
|
|
57
|
+
provider: d.provider,
|
|
58
|
+
benchmarkScores,
|
|
59
|
+
capabilities: d.capabilities ?? [],
|
|
60
|
+
pricing,
|
|
61
|
+
latency: d.latency ?? null,
|
|
62
|
+
description: d.description ?? '',
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export class ModelRegistry {
|
|
67
|
+
constructor() {
|
|
68
|
+
this._models = new Map();
|
|
69
|
+
}
|
|
70
|
+
/** Create a registry pre-loaded with the default model preset. */
|
|
71
|
+
static default() {
|
|
72
|
+
const registry = new ModelRegistry();
|
|
73
|
+
registry.loadPreset('default');
|
|
74
|
+
return registry;
|
|
75
|
+
}
|
|
76
|
+
/** Add or update a model in the registry. */
|
|
77
|
+
addModel(model) {
|
|
78
|
+
this._models.set(model.modelId, model);
|
|
79
|
+
}
|
|
80
|
+
/** Convenience method to add a model with keyword arguments. */
|
|
81
|
+
add(opts) {
|
|
82
|
+
let modelPricing = null;
|
|
83
|
+
if (opts.pricing) {
|
|
84
|
+
modelPricing = new ModelPricing(opts.pricing[0], opts.pricing[1]);
|
|
85
|
+
}
|
|
86
|
+
const model = new ModelInfo({
|
|
87
|
+
modelId: opts.modelId,
|
|
88
|
+
provider: opts.provider,
|
|
89
|
+
benchmarkScores: opts.benchmarks ?? {},
|
|
90
|
+
pricing: modelPricing,
|
|
91
|
+
latency: opts.latency ?? null,
|
|
92
|
+
capabilities: opts.capabilities ?? [],
|
|
93
|
+
description: opts.description ?? '',
|
|
94
|
+
});
|
|
95
|
+
this.addModel(model);
|
|
96
|
+
return model;
|
|
97
|
+
}
|
|
98
|
+
/** Remove a model from the registry. Returns true if removed. */
|
|
99
|
+
removeModel(modelId) {
|
|
100
|
+
return this._models.delete(modelId);
|
|
101
|
+
}
|
|
102
|
+
/** Get a model by ID. */
|
|
103
|
+
getModel(modelId) {
|
|
104
|
+
return this._models.get(modelId);
|
|
105
|
+
}
|
|
106
|
+
/** Filter models by criteria. */
|
|
107
|
+
filter(opts) {
|
|
108
|
+
let results = [...this._models.values()];
|
|
109
|
+
if (opts?.provider) {
|
|
110
|
+
const providerLower = opts.provider.toLowerCase();
|
|
111
|
+
results = results.filter((m) => m.provider.toLowerCase() === providerLower);
|
|
112
|
+
}
|
|
113
|
+
if (opts?.capability) {
|
|
114
|
+
const cap = opts.capability;
|
|
115
|
+
results = results.filter((m) => m.capabilities.includes(cap));
|
|
116
|
+
}
|
|
117
|
+
if (opts?.maxInputCost != null) {
|
|
118
|
+
const maxCost = opts.maxInputCost;
|
|
119
|
+
results = results.filter((m) => m.pricing != null && m.pricing.inputPer1k <= maxCost);
|
|
120
|
+
}
|
|
121
|
+
if (opts?.latency) {
|
|
122
|
+
results = results.filter((m) => m.latency === opts.latency);
|
|
123
|
+
}
|
|
124
|
+
return results;
|
|
125
|
+
}
|
|
126
|
+
/** All registered models. */
|
|
127
|
+
get allModels() {
|
|
128
|
+
return [...this._models.values()];
|
|
129
|
+
}
|
|
130
|
+
/** All registered model IDs. */
|
|
131
|
+
get modelIds() {
|
|
132
|
+
return [...this._models.keys()];
|
|
133
|
+
}
|
|
134
|
+
get length() {
|
|
135
|
+
return this._models.size;
|
|
136
|
+
}
|
|
137
|
+
has(modelId) {
|
|
138
|
+
return this._models.has(modelId);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Load a preset model registry from bundled JSON.
|
|
142
|
+
* @returns Number of models loaded.
|
|
143
|
+
*/
|
|
144
|
+
loadPreset(name = 'default') {
|
|
145
|
+
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
146
|
+
const presetFile = join(currentDir, 'presets', `${name}Models.json`);
|
|
147
|
+
let raw;
|
|
148
|
+
try {
|
|
149
|
+
raw = readFileSync(presetFile, 'utf-8');
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
throw new Error(`Preset '${name}' not found at ${presetFile}`);
|
|
153
|
+
}
|
|
154
|
+
const data = JSON.parse(raw);
|
|
155
|
+
let count = 0;
|
|
156
|
+
for (const modelData of data.models ?? []) {
|
|
157
|
+
const model = ModelInfo.fromDict(modelData);
|
|
158
|
+
this.addModel(model);
|
|
159
|
+
count++;
|
|
160
|
+
}
|
|
161
|
+
return count;
|
|
162
|
+
}
|
|
163
|
+
/** Export registry to a JSON-serializable object. */
|
|
164
|
+
exportJson() {
|
|
165
|
+
return {
|
|
166
|
+
models: [...this._models.values()].map((m) => m.toDict()),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/registry/models.ts"],"names":[],"mappings":"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"}
|