@x12i/ai-tools 1.0.2

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 (113) hide show
  1. package/README.md +214 -0
  2. package/dist/AiModelsCatalogClient-4RF5BCDL.cjs +9 -0
  3. package/dist/AiModelsCatalogClient-4RF5BCDL.cjs.map +1 -0
  4. package/dist/AiModelsCatalogClient-B-dNLXX0.d.ts +29 -0
  5. package/dist/AiModelsCatalogClient-CSVlKql5.d.cts +29 -0
  6. package/dist/AiModelsCatalogClient-NUF3CBLW.js +9 -0
  7. package/dist/AiModelsCatalogClient-NUF3CBLW.js.map +1 -0
  8. package/dist/aliases/index.cjs +11 -0
  9. package/dist/aliases/index.cjs.map +1 -0
  10. package/dist/aliases/index.d.cts +21 -0
  11. package/dist/aliases/index.d.ts +21 -0
  12. package/dist/aliases/index.js +11 -0
  13. package/dist/aliases/index.js.map +1 -0
  14. package/dist/catalox/index.cjs +21 -0
  15. package/dist/catalox/index.cjs.map +1 -0
  16. package/dist/catalox/index.d.cts +23 -0
  17. package/dist/catalox/index.d.ts +23 -0
  18. package/dist/catalox/index.js +21 -0
  19. package/dist/catalox/index.js.map +1 -0
  20. package/dist/chunk-2PYACSZ5.cjs +1 -0
  21. package/dist/chunk-2PYACSZ5.cjs.map +1 -0
  22. package/dist/chunk-3E67S427.cjs +1 -0
  23. package/dist/chunk-3E67S427.cjs.map +1 -0
  24. package/dist/chunk-4NAY6HRP.js +137 -0
  25. package/dist/chunk-4NAY6HRP.js.map +1 -0
  26. package/dist/chunk-5HNFAYTO.cjs +254 -0
  27. package/dist/chunk-5HNFAYTO.cjs.map +1 -0
  28. package/dist/chunk-6QGDZTGH.js +127 -0
  29. package/dist/chunk-6QGDZTGH.js.map +1 -0
  30. package/dist/chunk-7Q742NI3.cjs +106 -0
  31. package/dist/chunk-7Q742NI3.cjs.map +1 -0
  32. package/dist/chunk-AJEKEWWB.js +106 -0
  33. package/dist/chunk-AJEKEWWB.js.map +1 -0
  34. package/dist/chunk-AV6OE2YQ.cjs +127 -0
  35. package/dist/chunk-AV6OE2YQ.cjs.map +1 -0
  36. package/dist/chunk-COK34C6P.js +1 -0
  37. package/dist/chunk-COK34C6P.js.map +1 -0
  38. package/dist/chunk-DJ5SWJDY.js +729 -0
  39. package/dist/chunk-DJ5SWJDY.js.map +1 -0
  40. package/dist/chunk-F2F4UEFD.cjs +75 -0
  41. package/dist/chunk-F2F4UEFD.cjs.map +1 -0
  42. package/dist/chunk-G2G4KSC5.js +30 -0
  43. package/dist/chunk-G2G4KSC5.js.map +1 -0
  44. package/dist/chunk-HHNHWYTP.cjs +105 -0
  45. package/dist/chunk-HHNHWYTP.cjs.map +1 -0
  46. package/dist/chunk-HN6UAQAE.cjs +83 -0
  47. package/dist/chunk-HN6UAQAE.cjs.map +1 -0
  48. package/dist/chunk-KHODXGPV.js +1 -0
  49. package/dist/chunk-KHODXGPV.js.map +1 -0
  50. package/dist/chunk-KQOALKKX.js +75 -0
  51. package/dist/chunk-KQOALKKX.js.map +1 -0
  52. package/dist/chunk-LYOU7CA2.cjs +30 -0
  53. package/dist/chunk-LYOU7CA2.cjs.map +1 -0
  54. package/dist/chunk-ML2FRR4L.js +105 -0
  55. package/dist/chunk-ML2FRR4L.js.map +1 -0
  56. package/dist/chunk-MLRHYOCD.js +160 -0
  57. package/dist/chunk-MLRHYOCD.js.map +1 -0
  58. package/dist/chunk-O2A6OVEH.js +240 -0
  59. package/dist/chunk-O2A6OVEH.js.map +1 -0
  60. package/dist/chunk-ONA73BU6.cjs +160 -0
  61. package/dist/chunk-ONA73BU6.cjs.map +1 -0
  62. package/dist/chunk-QCRLKVB3.cjs +137 -0
  63. package/dist/chunk-QCRLKVB3.cjs.map +1 -0
  64. package/dist/chunk-QWAX7VQO.cjs +240 -0
  65. package/dist/chunk-QWAX7VQO.cjs.map +1 -0
  66. package/dist/chunk-TF4L2NEC.cjs +729 -0
  67. package/dist/chunk-TF4L2NEC.cjs.map +1 -0
  68. package/dist/chunk-XRBZQQQU.js +254 -0
  69. package/dist/chunk-XRBZQQQU.js.map +1 -0
  70. package/dist/chunk-YHO57D2V.js +83 -0
  71. package/dist/chunk-YHO57D2V.js.map +1 -0
  72. package/dist/cli/index.cjs +403 -0
  73. package/dist/cli/index.cjs.map +1 -0
  74. package/dist/cli/index.d.cts +1 -0
  75. package/dist/cli/index.d.ts +1 -0
  76. package/dist/cli/index.js +403 -0
  77. package/dist/cli/index.js.map +1 -0
  78. package/dist/cost/index.cjs +7 -0
  79. package/dist/cost/index.cjs.map +1 -0
  80. package/dist/cost/index.d.cts +52 -0
  81. package/dist/cost/index.d.ts +52 -0
  82. package/dist/cost/index.js +7 -0
  83. package/dist/cost/index.js.map +1 -0
  84. package/dist/index.cjs +104 -0
  85. package/dist/index.cjs.map +1 -0
  86. package/dist/index.d.cts +58 -0
  87. package/dist/index.d.ts +58 -0
  88. package/dist/index.js +104 -0
  89. package/dist/index.js.map +1 -0
  90. package/dist/modelNameResolver-Bn8QnkSj.d.ts +80 -0
  91. package/dist/modelNameResolver-bZD-eBSJ.d.cts +80 -0
  92. package/dist/models/index.cjs +33 -0
  93. package/dist/models/index.cjs.map +1 -0
  94. package/dist/models/index.d.cts +75 -0
  95. package/dist/models/index.d.ts +75 -0
  96. package/dist/models/index.js +33 -0
  97. package/dist/models/index.js.map +1 -0
  98. package/dist/sync/index.cjs +38 -0
  99. package/dist/sync/index.cjs.map +1 -0
  100. package/dist/sync/index.d.cts +12 -0
  101. package/dist/sync/index.d.ts +12 -0
  102. package/dist/sync/index.js +38 -0
  103. package/dist/sync/index.js.map +1 -0
  104. package/dist/toolbox/index.cjs +7 -0
  105. package/dist/toolbox/index.cjs.map +1 -0
  106. package/dist/toolbox/index.d.cts +72 -0
  107. package/dist/toolbox/index.d.ts +72 -0
  108. package/dist/toolbox/index.js +7 -0
  109. package/dist/toolbox/index.js.map +1 -0
  110. package/dist/types-DdGB3YaA.d.cts +278 -0
  111. package/dist/types-DdGB3YaA.d.ts +278 -0
  112. package/package.json +115 -0
  113. package/schemas/aliases.json +28 -0
package/README.md ADDED
@@ -0,0 +1,214 @@
1
+ # @x12i/ai-tools
2
+
3
+ TypeScript-first npm package for AI model catalog management, runtime cost calculation, project-local model aliases, and an integrated LLM utility belt — backed by [@x12i/catalox](https://www.npmjs.com/package/@x12i/catalox) and OpenRouter.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @x12i/ai-tools @x12i/catalox
9
+ ```
10
+
11
+ Optional peers: `firebase-admin`, `@x12i/helpers`, `openai`, `better-sqlite3` (for toolbox SQLite storage).
12
+
13
+ ## Quick start
14
+
15
+ ```ts
16
+ import { createCataloxFromEnv } from "@x12i/catalox/firebase";
17
+ import {
18
+ ensureAiModelsCatalog,
19
+ AiModelsCatalogClient,
20
+ CostCalculator,
21
+ } from "@x12i/ai-tools";
22
+
23
+ const { catalox } = createCataloxFromEnv();
24
+ await ensureAiModelsCatalog(catalox);
25
+
26
+ const catalog = new AiModelsCatalogClient({ catalox });
27
+ const calculator = new CostCalculator(catalog);
28
+
29
+ const result = await calculator.calculate({
30
+ tokens: { prompt: 1000, completion: 500, total: 1500 },
31
+ provider: "openrouter",
32
+ modelUsed: "openai/gpt-4o",
33
+ });
34
+
35
+ console.log(result.cost);
36
+ ```
37
+
38
+ ## Reasoning models
39
+
40
+ After sync, each catalog record includes **`supportsReasoning`** — use it to branch prompts, token limits, or cost handling.
41
+
42
+ ```ts
43
+ import { getModelInfo, isReasoningModel } from "@x12i/ai-tools";
44
+
45
+ const model = await getModelInfo("openai/o3-mini");
46
+ if (model?.supportsReasoning) {
47
+ // pass OpenRouter `reasoning: { effort: "medium" }`, bill reasoning tokens, etc.
48
+ }
49
+
50
+ // Same check without loading the full record field:
51
+ isReasoningModel(model!);
52
+ ```
53
+
54
+ Detection uses OpenRouter metadata:
55
+
56
+ - `supported_parameters` includes `reasoning` (or `include_reasoning`)
57
+ - pricing includes `internal_reasoning` (exposed as `pricing.reasoningUsdPerToken`)
58
+
59
+ ```bash
60
+ npx ai-tools models list --reasoning
61
+ npx ai-tools models count --reasoning
62
+ ```
63
+
64
+ Re-run `npm run seed` or `npx ai-tools sync` after upgrading so existing Firestore rows get `supportsReasoning` indexed.
65
+
66
+ ## Smart model name resolution
67
+
68
+ Callers often pass messy `provider` + `model` pairs (typos, missing namespaces, version suffixes, aliases used as provider names, or no provider at all). **`ModelNameResolver`** normalises input and runs a deterministic strategy pipeline against the cached catalog (no network calls during resolution).
69
+
70
+ ```ts
71
+ import { AiModelsCatalogClient, ModelNameResolver } from "@x12i/ai-tools";
72
+
73
+ const catalog = new AiModelsCatalogClient({ catalox });
74
+ const models = await catalog.getAllModels();
75
+
76
+ const resolver = new ModelNameResolver(models, { aliasRegistry });
77
+ const result = await catalog.resolveModel({
78
+ provider: "openrouter",
79
+ model: "gpt4o",
80
+ });
81
+
82
+ if (result.found) {
83
+ console.log(result.modelId); // openai/gpt-4o
84
+ console.log(result.confidence, result.resolvedVia);
85
+ console.log(result.routedViaOpenRouter);
86
+ }
87
+ ```
88
+
89
+ ### What it handles
90
+
91
+ | Input | Resolves to |
92
+ |-------|-------------|
93
+ | `openrouter` + `gpt-4o` | `openai/gpt-4o` (provider prefix inference) |
94
+ | `openrouter` + `gpt4o` | `openai/gpt-4o` (shorthand expansion) |
95
+ | `openrouter` + `gpt-4o-2024-08-06` | `openai/gpt-4o` (version suffix strip) |
96
+ | `openrouter` + `openai/claude-3-5-sonnet` | `anthropic/claude-3-5-sonnet-…` (cross-provider correction) |
97
+ | provider `best` (alias name) + any model | alias target (alias-as-provider correction) |
98
+ | model only (`gpt-4o`) | catalog alias or prefix inference |
99
+ | `ollama` + `llama3:8b` | passthrough (`record: null`, not an error) |
100
+
101
+ Each success includes `confidence`, `resolvedVia[]`, and `resolvedReason`. Below-threshold matches return `found: false` with `bestRejectedCandidate` when applicable.
102
+
103
+ ### OpenRouter vs direct provider (env defaults)
104
+
105
+ When the **provider is omitted** or ambiguous, routing defaults come from your `.env` (loaded via [@x12/env](https://www.npmjs.com/package/@x12i/env)):
106
+
107
+ | Condition | Default routing |
108
+ |-----------|-----------------|
109
+ | `OPENROUTER_API_KEY` is set **and** `USE_OPENROUTER=true` or `USE_OPENROUTER=1` | OpenRouter |
110
+ | `OPENROUTER_API_KEY` is set **and** `{VENDOR}_API_KEY` is missing for the resolved vendor | OpenRouter |
111
+ | `{VENDOR}_API_KEY` is set (and `USE_OPENROUTER` not forcing OR) | Direct to that vendor |
112
+
113
+ **Vendor API key naming:** `{VENDOR}_API_KEY` where `VENDOR` is the catalog `providerId` in `UPPER_SNAKE_CASE` (hyphens → underscores).
114
+
115
+ Examples:
116
+
117
+ - `openai` → `OPENAI_API_KEY`
118
+ - `anthropic` → `ANTHROPIC_API_KEY`
119
+ - `meta-llama` → `META_LLAMA_API_KEY`
120
+ - `x-ai` → `X_AI_API_KEY`
121
+
122
+ ```ts
123
+ import {
124
+ loadOpenRouterRoutingEnv,
125
+ shouldDefaultRouteViaOpenRouter,
126
+ } from "@x12i/ai-tools";
127
+
128
+ const routing = loadOpenRouterRoutingEnv();
129
+ shouldDefaultRouteViaOpenRouter("openai", routing); // true if OR key set but OPENAI_API_KEY missing
130
+ ```
131
+
132
+ Explicit `provider: "openrouter"` always sets `routedViaOpenRouter: true`. Explicit direct providers (`openai`, `anthropic`, …) use direct routing unless env rules above apply.
133
+
134
+ ### CLI
135
+
136
+ ```bash
137
+ npx ai-tools models resolve --provider openrouter --model gpt4o
138
+ npx ai-tools models resolve --model claude-sonnet --verbose
139
+ npx ai-tools models resolve --model turbomax-9000 --json
140
+ ```
141
+
142
+ ## Seed catalog (Firestore + OpenRouter)
143
+
144
+ ```bash
145
+ # Requires .env: GOOGLE_SERVICE_ACCOUNT_BASE64, FIREBASE_PROJECT_ID
146
+ # OpenRouter /models is public — no API key required
147
+ npm run seed
148
+ npm run seed:verbose
149
+ ```
150
+
151
+ ## Tests
152
+
153
+ ```bash
154
+ npm test # unit tests (mocked)
155
+ npm run test:live # live Firestore/Catalox tests (uses .env)
156
+ npm run test:all # both
157
+ ```
158
+
159
+ ## CLI
160
+
161
+ ```bash
162
+ npx ai-tools catalog ensure
163
+ npx ai-tools sync --verbose
164
+ npx ai-tools models list --provider openai
165
+ npx ai-tools models list --reasoning
166
+ npx ai-tools models resolve --model gpt4o --provider openrouter --verbose
167
+ npx ai-tools cost --model openai/gpt-4o --prompt-tokens 2000 --completion-tokens 800
168
+ npx ai-tools alias init
169
+ npx ai-tools alias set best anthropic/claude-opus-4 --provider openrouter
170
+ npx ai-tools alias check
171
+ ```
172
+
173
+ ### Environment variables
174
+
175
+ | Variable | Purpose |
176
+ |----------|---------|
177
+ | `OPENROUTER_API_KEY` | OpenRouter API key; used for routing defaults and optional sync auth |
178
+ | `USE_OPENROUTER` | Set to `true` or `1` to default API routing via OpenRouter when `OPENROUTER_API_KEY` is set |
179
+ | `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, … | Direct vendor keys — pattern `{PROVIDER_ID}_API_KEY` (see smart resolver above) |
180
+ | `GOOGLE_SERVICE_ACCOUNT_BASE64` | Firebase / Firestore credentials |
181
+ | `FIREBASE_PROJECT_ID` | GCP project |
182
+ | `FIRESTORE_DATABASE_ID` | Firestore database (default: `(default)`) |
183
+ | `AI_TOOLS_APP_ID` | Catalox appId (default: `ai-tools`) |
184
+ | `AI_TOOLS_CATALOG_ID` | Catalog id (default: `ai-models`) |
185
+ | `AI_TOOLS_CACHE_TTL_MS` | nx-cache TTL override |
186
+ | `AI_TOOLS_ALIASES_PATH` | Path to `aliases.json` |
187
+
188
+ ## Subpath exports
189
+
190
+ - `@x12i/ai-tools` — main API (`ModelNameResolver`, `loadOpenRouterRoutingEnv`, catalog, cost, aliases)
191
+ - `@x12i/ai-tools/cost`
192
+ - `@x12i/ai-tools/toolbox`
193
+ - `@x12i/ai-tools/sync` — sync + resolver types
194
+ - `@x12i/ai-tools/catalox`
195
+ - `@x12i/ai-tools/aliases`
196
+ - `@x12i/ai-tools/models`
197
+
198
+ ## Project aliases
199
+
200
+ Commit `./ai-tools/aliases.json` in your application repo so dev/staging/prod share the same model vocabulary. Alias targets that use shorthand or versioned ids are resolved through the same smart resolver as runtime model strings.
201
+
202
+ ## Publishing
203
+
204
+ Scoped packages (`@x12i/...`) require public access on the free npm plan:
205
+
206
+ ```bash
207
+ npm publish
208
+ ```
209
+
210
+ `package.json` includes `"publishConfig": { "access": "public" }`. If publish still fails, run `npm publish --access public`.
211
+
212
+ ## License
213
+
214
+ MIT
@@ -0,0 +1,9 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+ var _chunkF2F4UEFDcjs = require('./chunk-F2F4UEFD.cjs');
4
+ require('./chunk-TF4L2NEC.cjs');
5
+ require('./chunk-7Q742NI3.cjs');
6
+
7
+
8
+ exports.AiModelsCatalogClient = _chunkF2F4UEFDcjs.AiModelsCatalogClient;
9
+ //# sourceMappingURL=AiModelsCatalogClient-4RF5BCDL.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/AiModelsCatalogClient-4RF5BCDL.cjs"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B,gCAA6B;AAC7B,gCAA6B;AAC7B;AACE;AACF,wEAAC","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/AiModelsCatalogClient-4RF5BCDL.cjs"}
@@ -0,0 +1,29 @@
1
+ import { Catalox } from '@x12i/catalox';
2
+ import { l as ModelResolverOptions, a as AiModelRecord, h as ModelResolutionInput, j as ModelResolutionResult } from './types-DdGB3YaA.js';
3
+
4
+ type AiModelsCatalogClientOptions = {
5
+ catalox: Catalox;
6
+ appId?: string;
7
+ catalogId?: string;
8
+ cacheTtlMs?: number;
9
+ resolverOptions?: Omit<ModelResolverOptions, "aliasRegistry">;
10
+ };
11
+ declare class AiModelsCatalogClient {
12
+ private readonly catalox;
13
+ private readonly appId;
14
+ private readonly catalogId;
15
+ private readonly cacheTtlMs;
16
+ private readonly resolverOptions;
17
+ constructor(options: AiModelsCatalogClientOptions);
18
+ private context;
19
+ getAllModels(): Promise<Map<string, AiModelRecord>>;
20
+ private resolver;
21
+ /**
22
+ * Resolve a (provider, model) pair to a canonical model id and catalog record.
23
+ */
24
+ resolveModel(input: ModelResolutionInput, options?: ModelResolverOptions): Promise<ModelResolutionResult>;
25
+ getModel(modelId: string, provider?: string, options?: ModelResolverOptions): Promise<AiModelRecord | null>;
26
+ refresh(): Promise<void>;
27
+ }
28
+
29
+ export { AiModelsCatalogClient as A, type AiModelsCatalogClientOptions as a };
@@ -0,0 +1,29 @@
1
+ import { Catalox } from '@x12i/catalox';
2
+ import { l as ModelResolverOptions, a as AiModelRecord, h as ModelResolutionInput, j as ModelResolutionResult } from './types-DdGB3YaA.cjs';
3
+
4
+ type AiModelsCatalogClientOptions = {
5
+ catalox: Catalox;
6
+ appId?: string;
7
+ catalogId?: string;
8
+ cacheTtlMs?: number;
9
+ resolverOptions?: Omit<ModelResolverOptions, "aliasRegistry">;
10
+ };
11
+ declare class AiModelsCatalogClient {
12
+ private readonly catalox;
13
+ private readonly appId;
14
+ private readonly catalogId;
15
+ private readonly cacheTtlMs;
16
+ private readonly resolverOptions;
17
+ constructor(options: AiModelsCatalogClientOptions);
18
+ private context;
19
+ getAllModels(): Promise<Map<string, AiModelRecord>>;
20
+ private resolver;
21
+ /**
22
+ * Resolve a (provider, model) pair to a canonical model id and catalog record.
23
+ */
24
+ resolveModel(input: ModelResolutionInput, options?: ModelResolverOptions): Promise<ModelResolutionResult>;
25
+ getModel(modelId: string, provider?: string, options?: ModelResolverOptions): Promise<AiModelRecord | null>;
26
+ refresh(): Promise<void>;
27
+ }
28
+
29
+ export { AiModelsCatalogClient as A, type AiModelsCatalogClientOptions as a };
@@ -0,0 +1,9 @@
1
+ import {
2
+ AiModelsCatalogClient
3
+ } from "./chunk-KQOALKKX.js";
4
+ import "./chunk-DJ5SWJDY.js";
5
+ import "./chunk-AJEKEWWB.js";
6
+ export {
7
+ AiModelsCatalogClient
8
+ };
9
+ //# sourceMappingURL=AiModelsCatalogClient-NUF3CBLW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,11 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});require('../chunk-3E67S427.cjs');
2
+
3
+
4
+
5
+ var _chunkQWAX7VQOcjs = require('../chunk-QWAX7VQO.cjs');
6
+ require('../chunk-7Q742NI3.cjs');
7
+
8
+
9
+
10
+ exports.AliasRegistry = _chunkQWAX7VQOcjs.AliasRegistry; exports.AliasResolver = _chunkQWAX7VQOcjs.AliasResolver;
11
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/aliases/index.cjs"],"names":[],"mappings":"AAAA,0GAA8B;AAC9B;AACE;AACA;AACF,yDAA8B;AAC9B,iCAA8B;AAC9B;AACE;AACA;AACF,iHAAC","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/aliases/index.cjs"}
@@ -0,0 +1,21 @@
1
+ import { d as AliasRegistry, u as ResolvedModelRef, f as AliasValidationReport } from '../types-DdGB3YaA.cjs';
2
+ export { b as AliasEntry, c as AliasFileSchema, e as AliasRegistryOptions } from '../types-DdGB3YaA.cjs';
3
+ import { A as AiModelsCatalogClient } from '../AiModelsCatalogClient-CSVlKql5.cjs';
4
+ import '@x12i/catalox';
5
+
6
+ type AliasResolverOptions = {
7
+ registry: AliasRegistry;
8
+ catalogClient: AiModelsCatalogClient;
9
+ };
10
+ declare class AliasResolver {
11
+ private readonly registry;
12
+ private readonly catalogClient;
13
+ constructor(options: AliasResolverOptions);
14
+ getModel(aliasName: string): Promise<ResolvedModelRef>;
15
+ getModels(aliasNames: string[]): Promise<ResolvedModelRef[]>;
16
+ getAllResolved(): Promise<ResolvedModelRef[]>;
17
+ validate(): Promise<AliasValidationReport>;
18
+ private resolveEntry;
19
+ }
20
+
21
+ export { AliasRegistry, AliasResolver, type AliasResolverOptions, AliasValidationReport, ResolvedModelRef };
@@ -0,0 +1,21 @@
1
+ import { d as AliasRegistry, u as ResolvedModelRef, f as AliasValidationReport } from '../types-DdGB3YaA.js';
2
+ export { b as AliasEntry, c as AliasFileSchema, e as AliasRegistryOptions } from '../types-DdGB3YaA.js';
3
+ import { A as AiModelsCatalogClient } from '../AiModelsCatalogClient-B-dNLXX0.js';
4
+ import '@x12i/catalox';
5
+
6
+ type AliasResolverOptions = {
7
+ registry: AliasRegistry;
8
+ catalogClient: AiModelsCatalogClient;
9
+ };
10
+ declare class AliasResolver {
11
+ private readonly registry;
12
+ private readonly catalogClient;
13
+ constructor(options: AliasResolverOptions);
14
+ getModel(aliasName: string): Promise<ResolvedModelRef>;
15
+ getModels(aliasNames: string[]): Promise<ResolvedModelRef[]>;
16
+ getAllResolved(): Promise<ResolvedModelRef[]>;
17
+ validate(): Promise<AliasValidationReport>;
18
+ private resolveEntry;
19
+ }
20
+
21
+ export { AliasRegistry, AliasResolver, type AliasResolverOptions, AliasValidationReport, ResolvedModelRef };
@@ -0,0 +1,11 @@
1
+ import "../chunk-KHODXGPV.js";
2
+ import {
3
+ AliasRegistry,
4
+ AliasResolver
5
+ } from "../chunk-O2A6OVEH.js";
6
+ import "../chunk-AJEKEWWB.js";
7
+ export {
8
+ AliasRegistry,
9
+ AliasResolver
10
+ };
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,21 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+ var _chunkHHNHWYTPcjs = require('../chunk-HHNHWYTP.cjs');
8
+
9
+
10
+ var _chunkF2F4UEFDcjs = require('../chunk-F2F4UEFD.cjs');
11
+ require('../chunk-TF4L2NEC.cjs');
12
+ require('../chunk-7Q742NI3.cjs');
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+ exports.AiModelsCatalogClient = _chunkF2F4UEFDcjs.AiModelsCatalogClient; exports.batchUpsertAiModelRecords = _chunkHHNHWYTPcjs.batchUpsertAiModelRecords; exports.decodeModelFirestoreDocId = _chunkHHNHWYTPcjs.decodeModelFirestoreDocId; exports.encodeModelFirestoreDocId = _chunkHHNHWYTPcjs.encodeModelFirestoreDocId; exports.sanitizeForFirestore = _chunkHHNHWYTPcjs.sanitizeForFirestore; exports.upsertAiModelRecord = _chunkHHNHWYTPcjs.upsertAiModelRecord;
21
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/catalox/index.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACF,yDAA8B;AAC9B;AACE;AACF,yDAA8B;AAC9B,iCAA8B;AAC9B,iCAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACF,ucAAC","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/catalox/index.cjs"}
@@ -0,0 +1,23 @@
1
+ export { A as AiModelsCatalogClient, a as AiModelsCatalogClientOptions } from '../AiModelsCatalogClient-CSVlKql5.cjs';
2
+ import { Firestore } from 'firebase-admin/firestore';
3
+ import { CataloxContext } from '@x12i/catalox';
4
+ import { a as AiModelRecord } from '../types-DdGB3YaA.cjs';
5
+
6
+ declare function encodeModelFirestoreDocId(modelId: string): string;
7
+ declare function decodeModelFirestoreDocId(docId: string): string;
8
+
9
+ /** Firestore rejects `undefined` — strip before write. */
10
+ declare function sanitizeForFirestore<T>(value: T): T;
11
+ type UpsertAiModelRecordOptions = {
12
+ firestore: Firestore;
13
+ context: CataloxContext;
14
+ catalogId: string;
15
+ record: AiModelRecord;
16
+ };
17
+ /**
18
+ * Upserts one ai-models row via Firestore (safe doc ids for `provider/model` ids).
19
+ */
20
+ declare function upsertAiModelRecord(options: UpsertAiModelRecordOptions): Promise<void>;
21
+ declare function batchUpsertAiModelRecords(firestore: Firestore, catalogId: string, context: CataloxContext, records: AiModelRecord[]): Promise<void>;
22
+
23
+ export { batchUpsertAiModelRecords, decodeModelFirestoreDocId, encodeModelFirestoreDocId, sanitizeForFirestore, upsertAiModelRecord };
@@ -0,0 +1,23 @@
1
+ export { A as AiModelsCatalogClient, a as AiModelsCatalogClientOptions } from '../AiModelsCatalogClient-B-dNLXX0.js';
2
+ import { Firestore } from 'firebase-admin/firestore';
3
+ import { CataloxContext } from '@x12i/catalox';
4
+ import { a as AiModelRecord } from '../types-DdGB3YaA.js';
5
+
6
+ declare function encodeModelFirestoreDocId(modelId: string): string;
7
+ declare function decodeModelFirestoreDocId(docId: string): string;
8
+
9
+ /** Firestore rejects `undefined` — strip before write. */
10
+ declare function sanitizeForFirestore<T>(value: T): T;
11
+ type UpsertAiModelRecordOptions = {
12
+ firestore: Firestore;
13
+ context: CataloxContext;
14
+ catalogId: string;
15
+ record: AiModelRecord;
16
+ };
17
+ /**
18
+ * Upserts one ai-models row via Firestore (safe doc ids for `provider/model` ids).
19
+ */
20
+ declare function upsertAiModelRecord(options: UpsertAiModelRecordOptions): Promise<void>;
21
+ declare function batchUpsertAiModelRecords(firestore: Firestore, catalogId: string, context: CataloxContext, records: AiModelRecord[]): Promise<void>;
22
+
23
+ export { batchUpsertAiModelRecords, decodeModelFirestoreDocId, encodeModelFirestoreDocId, sanitizeForFirestore, upsertAiModelRecord };
@@ -0,0 +1,21 @@
1
+ import {
2
+ batchUpsertAiModelRecords,
3
+ decodeModelFirestoreDocId,
4
+ encodeModelFirestoreDocId,
5
+ sanitizeForFirestore,
6
+ upsertAiModelRecord
7
+ } from "../chunk-ML2FRR4L.js";
8
+ import {
9
+ AiModelsCatalogClient
10
+ } from "../chunk-KQOALKKX.js";
11
+ import "../chunk-DJ5SWJDY.js";
12
+ import "../chunk-AJEKEWWB.js";
13
+ export {
14
+ AiModelsCatalogClient,
15
+ batchUpsertAiModelRecords,
16
+ decodeModelFirestoreDocId,
17
+ encodeModelFirestoreDocId,
18
+ sanitizeForFirestore,
19
+ upsertAiModelRecord
20
+ };
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1 @@
1
+ "use strict";//# sourceMappingURL=chunk-2PYACSZ5.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-2PYACSZ5.cjs"],"names":[],"mappings":"AAAA","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-2PYACSZ5.cjs"}
@@ -0,0 +1 @@
1
+ "use strict";//# sourceMappingURL=chunk-3E67S427.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-3E67S427.cjs"],"names":[],"mappings":"AAAA","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-3E67S427.cjs"}
@@ -0,0 +1,137 @@
1
+ import {
2
+ AiModelsCatalogClient
3
+ } from "./chunk-KQOALKKX.js";
4
+
5
+ // src/models/filterModels.ts
6
+ function matchesSearch(record, search) {
7
+ const q = search.toLowerCase();
8
+ return record.modelId.toLowerCase().includes(q) || record.name.toLowerCase().includes(q) || record.description.toLowerCase().includes(q) || record.canonicalSlug.toLowerCase().includes(q) || record.aliases.some((a) => a.toLowerCase().includes(q));
9
+ }
10
+ function filterModels(models, filters = {}) {
11
+ let list = [...models];
12
+ if (filters.providerId) {
13
+ list = list.filter((m) => m.providerId === filters.providerId);
14
+ }
15
+ if (filters.status) {
16
+ list = list.filter((m) => m.status === filters.status);
17
+ }
18
+ if (filters.outputModality) {
19
+ list = list.filter((m) => m.outputModalities.includes(filters.outputModality));
20
+ }
21
+ if (filters.inputModality) {
22
+ list = list.filter((m) => m.inputModalities.includes(filters.inputModality));
23
+ }
24
+ if (filters.supportedParameter) {
25
+ list = list.filter((m) => m.supportedParameters.includes(filters.supportedParameter));
26
+ }
27
+ if (filters.supportsTools !== void 0) {
28
+ list = list.filter((m) => m.supportsTools === filters.supportsTools);
29
+ }
30
+ if (filters.supportsReasoning !== void 0) {
31
+ list = list.filter((m) => m.supportsReasoning === filters.supportsReasoning);
32
+ }
33
+ if (filters.search) {
34
+ list = list.filter((m) => matchesSearch(m, filters.search));
35
+ }
36
+ list.sort((a, b) => a.name.localeCompare(b.name));
37
+ const offset = filters.offset ?? 0;
38
+ const limit = filters.limit ?? list.length;
39
+ return list.slice(offset, offset + limit);
40
+ }
41
+ function countModels(models, filters = {}) {
42
+ return filterModels(models, { ...filters, limit: Number.MAX_SAFE_INTEGER, offset: 0 }).length;
43
+ }
44
+
45
+ // src/models/AiModelsService.ts
46
+ var AiModelsService = class {
47
+ client;
48
+ catalox;
49
+ appId;
50
+ catalogId;
51
+ constructor(options) {
52
+ this.catalox = options.catalox;
53
+ this.client = new AiModelsCatalogClient(options);
54
+ this.appId = options.appId ?? "ai-tools";
55
+ this.catalogId = options.catalogId ?? "ai-models";
56
+ }
57
+ context() {
58
+ return { appId: this.appId, superAdmin: true };
59
+ }
60
+ /** Load all models (cached). */
61
+ async getAllModels() {
62
+ return this.client.getAllModels();
63
+ }
64
+ /** List models with in-memory filters (fast after cache warm). */
65
+ async listModels(filters = {}) {
66
+ const all = await this.getAllModels();
67
+ const total = countModels(all.values(), filters);
68
+ const limit = filters.limit ?? 50;
69
+ const offset = filters.offset ?? 0;
70
+ const models = filterModels(all.values(), { ...filters, limit, offset });
71
+ return { models, total, limit, offset };
72
+ }
73
+ /** Count models matching filters. */
74
+ async countModels(filters = {}) {
75
+ const all = await this.getAllModels();
76
+ return countModels(all.values(), filters);
77
+ }
78
+ /**
79
+ * Full model record by id or alias (same resolution as cost calculator).
80
+ */
81
+ async getModelInfo(modelIdOrAlias) {
82
+ return this.client.getModel(modelIdOrAlias);
83
+ }
84
+ /**
85
+ * Query via Catalox indexed fields (provider, status, output modality, tools).
86
+ * Falls back to in-memory filter when Catalox returns partial pages.
87
+ */
88
+ async listModelsFromCatalog(filters = {}, options) {
89
+ const filter = {};
90
+ if (filters.providerId) filter.providerId = filters.providerId;
91
+ if (filters.status) filter.status = filters.status;
92
+ if (filters.outputModality) filter.primaryOutputModality = filters.outputModality;
93
+ if (filters.supportsTools !== void 0) filter.supportsTools = filters.supportsTools;
94
+ if (filters.supportsReasoning !== void 0) {
95
+ filter.supportsReasoning = filters.supportsReasoning;
96
+ }
97
+ const limit = filters.limit ?? 50;
98
+ const result = await this.catalox.listCatalogItems(this.context(), this.catalogId, {
99
+ limit: Math.min(limit, 1e4),
100
+ filter,
101
+ ...options
102
+ });
103
+ let models = result.items.map((item) => item.data);
104
+ if (filters.supportedParameter) {
105
+ models = models.filter((m) => m.supportedParameters?.includes(filters.supportedParameter));
106
+ }
107
+ if (filters.inputModality) {
108
+ models = models.filter((m) => m.inputModalities?.includes(filters.inputModality));
109
+ }
110
+ if (filters.search) {
111
+ models = filterModels(models, { search: filters.search });
112
+ }
113
+ return {
114
+ models,
115
+ total: models.length,
116
+ limit,
117
+ offset: filters.offset ?? 0
118
+ };
119
+ }
120
+ async resolve(modelIdOrAlias, provider) {
121
+ return this.client.resolveModel({ model: modelIdOrAlias, provider });
122
+ }
123
+ async refresh() {
124
+ await this.client.refresh();
125
+ }
126
+ };
127
+ async function getModelInfo(service, modelIdOrAlias) {
128
+ return service.getModelInfo(modelIdOrAlias);
129
+ }
130
+
131
+ export {
132
+ filterModels,
133
+ countModels,
134
+ AiModelsService,
135
+ getModelInfo
136
+ };
137
+ //# sourceMappingURL=chunk-4NAY6HRP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/models/filterModels.ts","../src/models/AiModelsService.ts"],"sourcesContent":["import type { AiModelRecord, ModelListFilters } from \"./types.js\";\n\nfunction matchesSearch(record: AiModelRecord, search: string): boolean {\n const q = search.toLowerCase();\n return (\n record.modelId.toLowerCase().includes(q) ||\n record.name.toLowerCase().includes(q) ||\n record.description.toLowerCase().includes(q) ||\n record.canonicalSlug.toLowerCase().includes(q) ||\n record.aliases.some((a) => a.toLowerCase().includes(q))\n );\n}\n\nexport function filterModels(\n models: Iterable<AiModelRecord>,\n filters: ModelListFilters = {},\n): AiModelRecord[] {\n let list = [...models];\n\n if (filters.providerId) {\n list = list.filter((m) => m.providerId === filters.providerId);\n }\n if (filters.status) {\n list = list.filter((m) => m.status === filters.status);\n }\n if (filters.outputModality) {\n list = list.filter((m) => m.outputModalities.includes(filters.outputModality!));\n }\n if (filters.inputModality) {\n list = list.filter((m) => m.inputModalities.includes(filters.inputModality!));\n }\n if (filters.supportedParameter) {\n list = list.filter((m) => m.supportedParameters.includes(filters.supportedParameter!));\n }\n if (filters.supportsTools !== undefined) {\n list = list.filter((m) => m.supportsTools === filters.supportsTools);\n }\n if (filters.supportsReasoning !== undefined) {\n list = list.filter((m) => m.supportsReasoning === filters.supportsReasoning);\n }\n if (filters.search) {\n list = list.filter((m) => matchesSearch(m, filters.search!));\n }\n\n list.sort((a, b) => a.name.localeCompare(b.name));\n\n const offset = filters.offset ?? 0;\n const limit = filters.limit ?? list.length;\n return list.slice(offset, offset + limit);\n}\n\nexport function countModels(\n models: Iterable<AiModelRecord>,\n filters: Omit<ModelListFilters, \"limit\" | \"offset\"> = {},\n): number {\n return filterModels(models, { ...filters, limit: Number.MAX_SAFE_INTEGER, offset: 0 }).length;\n}\n","import type { Catalox, CataloxContext } from \"@x12i/catalox\";\nimport type { CatalogQueryOptions } from \"@x12i/catalox\";\nimport { AiModelsCatalogClient } from \"../catalox/AiModelsCatalogClient.js\";\nimport { countModels, filterModels } from \"./filterModels.js\";\nimport type { AiModelRecord, ModelListFilters, ModelListResult } from \"./types.js\";\n\nexport type AiModelsServiceOptions = {\n catalox: Catalox;\n appId?: string;\n catalogId?: string;\n cacheTtlMs?: number;\n};\n\n/**\n * High-level model catalog API — list, filter, count, and get full model info.\n */\nexport class AiModelsService {\n private readonly client: AiModelsCatalogClient;\n private readonly catalox: Catalox;\n private readonly appId: string;\n private readonly catalogId: string;\n\n constructor(options: AiModelsServiceOptions) {\n this.catalox = options.catalox;\n this.client = new AiModelsCatalogClient(options);\n this.appId = options.appId ?? \"ai-tools\";\n this.catalogId = options.catalogId ?? \"ai-models\";\n }\n\n private context(): CataloxContext {\n return { appId: this.appId, superAdmin: true };\n }\n\n /** Load all models (cached). */\n async getAllModels(): Promise<Map<string, AiModelRecord>> {\n return this.client.getAllModels();\n }\n\n /** List models with in-memory filters (fast after cache warm). */\n async listModels(filters: ModelListFilters = {}): Promise<ModelListResult> {\n const all = await this.getAllModels();\n const total = countModels(all.values(), filters);\n const limit = filters.limit ?? 50;\n const offset = filters.offset ?? 0;\n const models = filterModels(all.values(), { ...filters, limit, offset });\n return { models, total, limit, offset };\n }\n\n /** Count models matching filters. */\n async countModels(filters: Omit<ModelListFilters, \"limit\" | \"offset\"> = {}): Promise<number> {\n const all = await this.getAllModels();\n return countModels(all.values(), filters);\n }\n\n /**\n * Full model record by id or alias (same resolution as cost calculator).\n */\n async getModelInfo(modelIdOrAlias: string): Promise<AiModelRecord | null> {\n return this.client.getModel(modelIdOrAlias);\n }\n\n /**\n * Query via Catalox indexed fields (provider, status, output modality, tools).\n * Falls back to in-memory filter when Catalox returns partial pages.\n */\n async listModelsFromCatalog(\n filters: ModelListFilters = {},\n options?: CatalogQueryOptions,\n ): Promise<ModelListResult> {\n const filter: Record<string, unknown> = {};\n if (filters.providerId) filter.providerId = filters.providerId;\n if (filters.status) filter.status = filters.status;\n if (filters.outputModality) filter.primaryOutputModality = filters.outputModality;\n if (filters.supportsTools !== undefined) filter.supportsTools = filters.supportsTools;\n if (filters.supportsReasoning !== undefined) {\n filter.supportsReasoning = filters.supportsReasoning;\n }\n\n const limit = filters.limit ?? 50;\n const result = await this.catalox.listCatalogItems(this.context(), this.catalogId, {\n limit: Math.min(limit, 10_000),\n filter,\n ...options,\n });\n\n let models = result.items.map((item) => item.data as unknown as AiModelRecord);\n\n if (filters.supportedParameter) {\n models = models.filter((m) => m.supportedParameters?.includes(filters.supportedParameter!));\n }\n if (filters.inputModality) {\n models = models.filter((m) => m.inputModalities?.includes(filters.inputModality!));\n }\n if (filters.search) {\n models = filterModels(models, { search: filters.search });\n }\n\n return {\n models,\n total: models.length,\n limit,\n offset: filters.offset ?? 0,\n };\n }\n\n async resolve(\n modelIdOrAlias: string,\n provider?: string,\n ): Promise<import(\"../sync/modelNameResolver/types.js\").ModelResolutionResult> {\n return this.client.resolveModel({ model: modelIdOrAlias, provider });\n }\n\n async refresh(): Promise<void> {\n await this.client.refresh();\n }\n}\n\n/** Convenience: getModelInfo */\nexport async function getModelInfo(\n service: AiModelsService,\n modelIdOrAlias: string,\n): Promise<AiModelRecord | null> {\n return service.getModelInfo(modelIdOrAlias);\n}\n"],"mappings":"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","names":[]}