@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
@@ -0,0 +1,254 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/toolbox/fallback.ts
2
+ function isRetriableError(error) {
3
+ if (error && typeof error === "object") {
4
+ const e = error;
5
+ if (typeof e.status === "number" && e.status >= 400) return true;
6
+ if (e.code === "ECONNRESET" || e.code === "ETIMEDOUT") return true;
7
+ }
8
+ if (error instanceof Error) {
9
+ return true;
10
+ }
11
+ return false;
12
+ }
13
+ function createFallback(onFallback) {
14
+ const trips = /* @__PURE__ */ new Map();
15
+ const isTripped = (provider) => {
16
+ const t = trips.get(provider);
17
+ if (!t) return false;
18
+ if (Date.now() < t.trippedUntil) return true;
19
+ trips.delete(provider);
20
+ return false;
21
+ };
22
+ const recordFailure = (provider) => {
23
+ const prev = _nullishCoalesce(trips.get(provider), () => ( { failures: 0, trippedUntil: 0 }));
24
+ const failures = prev.failures + 1;
25
+ if (failures >= 3) {
26
+ trips.set(provider, { failures, trippedUntil: Date.now() + 5 * 60 * 1e3 });
27
+ } else {
28
+ trips.set(provider, { failures, trippedUntil: 0 });
29
+ }
30
+ };
31
+ const recordSuccess = (provider) => {
32
+ trips.delete(provider);
33
+ };
34
+ return {
35
+ async execute(chain, fn) {
36
+ const models = [chain.primary, ...chain.fallbackChain];
37
+ const maxRetries = _nullishCoalesce(chain.maxRetries, () => ( 1));
38
+ let lastError;
39
+ for (let i = 0; i < models.length; i++) {
40
+ const model = models[i];
41
+ const provider = _nullishCoalesce(model.split("/")[0], () => ( model));
42
+ if (isTripped(provider)) {
43
+ continue;
44
+ }
45
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
46
+ try {
47
+ const result = await fn(model);
48
+ recordSuccess(provider);
49
+ if (i > 0) _optionalChain([onFallback, 'optionalCall', _ => _(model)]);
50
+ return result;
51
+ } catch (error) {
52
+ lastError = error;
53
+ if (!isRetriableError(error)) throw error;
54
+ recordFailure(provider);
55
+ }
56
+ }
57
+ }
58
+ throw _nullishCoalesce(lastError, () => ( new Error("All models in fallback chain failed")));
59
+ }
60
+ };
61
+ }
62
+
63
+ // src/toolbox/guard.ts
64
+ function repairJson(text) {
65
+ let s = text.trim();
66
+ if (s.startsWith("```")) {
67
+ s = s.replace(/^```(?:json)?\s*/i, "").replace(/\s*```$/, "");
68
+ }
69
+ s = s.replace(/,\s*([}\]])/g, "$1");
70
+ return s;
71
+ }
72
+ function tokenize(text) {
73
+ return new Set(
74
+ text.toLowerCase().split(/\W+/).filter((t) => t.length > 2)
75
+ );
76
+ }
77
+ function groundingScore(response, source) {
78
+ const resp = tokenize(response);
79
+ const src = tokenize(source);
80
+ if (resp.size === 0) return 0;
81
+ let overlap = 0;
82
+ for (const t of resp) {
83
+ if (src.has(t)) overlap++;
84
+ }
85
+ return overlap / resp.size;
86
+ }
87
+ function validateJsonSchema(value, schema) {
88
+ const s = schema;
89
+ const errors = [];
90
+ if (s.type === "object" && (value === null || typeof value !== "object" || Array.isArray(value))) {
91
+ errors.push("Expected object");
92
+ return errors;
93
+ }
94
+ if (s.type === "object" && s.required) {
95
+ const obj = value;
96
+ for (const key of s.required) {
97
+ if (!(key in obj)) errors.push(`Missing required field: ${key}`);
98
+ }
99
+ }
100
+ return errors;
101
+ }
102
+ function createGuard() {
103
+ return {
104
+ verify(response, config) {
105
+ const errors = [];
106
+ if (_optionalChain([config, 'access', _2 => _2.banPhrases, 'optionalAccess', _3 => _3.length])) {
107
+ const lower = response.toLowerCase();
108
+ for (const phrase of config.banPhrases) {
109
+ if (lower.includes(phrase.toLowerCase())) {
110
+ errors.push(`Response contains banned phrase: ${phrase}`);
111
+ }
112
+ }
113
+ }
114
+ if (config.jsonSchema) {
115
+ try {
116
+ const repaired = repairJson(response);
117
+ const parsed = JSON.parse(repaired);
118
+ errors.push(...validateJsonSchema(parsed, config.jsonSchema));
119
+ } catch (e2) {
120
+ errors.push("Response is not valid JSON");
121
+ }
122
+ }
123
+ if (config.minGroundingScore !== void 0 && config.sourceText) {
124
+ const score = groundingScore(response, config.sourceText);
125
+ if (score < config.minGroundingScore) {
126
+ errors.push(
127
+ `Grounding score ${score.toFixed(2)} below threshold ${config.minGroundingScore}`
128
+ );
129
+ }
130
+ }
131
+ return { isValid: errors.length === 0, errors };
132
+ }
133
+ };
134
+ }
135
+
136
+ // src/toolbox/router.ts
137
+ var TECH_KEYWORDS = [
138
+ "code",
139
+ "sql",
140
+ "diff",
141
+ "function",
142
+ "class",
143
+ "typescript",
144
+ "python",
145
+ "api",
146
+ "debug",
147
+ "refactor",
148
+ "algorithm"
149
+ ];
150
+ function createRouter(defaultModel = "openai/gpt-4o-mini") {
151
+ const rules = [];
152
+ return {
153
+ addRule(rule) {
154
+ rules.push(rule);
155
+ },
156
+ async determineModel(prompt) {
157
+ let complexity = "medium";
158
+ if (prompt.length < 200) {
159
+ complexity = "low";
160
+ } else if (TECH_KEYWORDS.some((kw) => prompt.toLowerCase().includes(kw))) {
161
+ complexity = "high";
162
+ }
163
+ const match = _nullishCoalesce(rules.find((r) => r.complexity === complexity), () => ( rules.find((r) => r.complexity === "medium")));
164
+ if (match) {
165
+ return {
166
+ model: match.targetModel,
167
+ reason: `Matched ${complexity} complexity rule`
168
+ };
169
+ }
170
+ return { model: defaultModel, reason: `Default model for ${complexity} complexity` };
171
+ }
172
+ };
173
+ }
174
+
175
+ // src/toolbox/tracker.ts
176
+ var _crypto = require('crypto');
177
+ var _events = require('events');
178
+ function estimateTokens(text) {
179
+ return Math.max(1, Math.ceil(text.length / 4));
180
+ }
181
+ function extractUsage(response) {
182
+ if (!response || typeof response !== "object") return null;
183
+ const r = response;
184
+ const usage = _nullishCoalesce(r.usage, () => ( r.data));
185
+ if (!usage) return null;
186
+ const prompt = _nullishCoalesce(_nullishCoalesce(usage.prompt_tokens, () => ( usage.promptTokens)), () => ( usage.input_tokens));
187
+ const completion = _nullishCoalesce(_nullishCoalesce(usage.completion_tokens, () => ( usage.completionTokens)), () => ( usage.output_tokens));
188
+ if (typeof prompt === "number" && typeof completion === "number") {
189
+ return { prompt, completion };
190
+ }
191
+ return null;
192
+ }
193
+ function createTracker(_options = {}) {
194
+ const emitter = new (0, _events.EventEmitter)();
195
+ const memoryLogs = [];
196
+ const logExchange = async (request, response) => {
197
+ const start = Date.now();
198
+ const usage = extractUsage(response);
199
+ const reqText = JSON.stringify(_nullishCoalesce(request, () => ( "")));
200
+ const promptTokens = _nullishCoalesce(_optionalChain([usage, 'optionalAccess', _4 => _4.prompt]), () => ( estimateTokens(reqText)));
201
+ const completionTokens = _nullishCoalesce(_optionalChain([usage, 'optionalAccess', _5 => _5.completion]), () => ( estimateTokens(JSON.stringify(_nullishCoalesce(response, () => ( ""))))));
202
+ const result = {
203
+ requestId: _crypto.randomUUID.call(void 0, ),
204
+ durationMs: Date.now() - start,
205
+ promptTokens,
206
+ completionTokens,
207
+ estimatedCostUSD: 0,
208
+ requestPayload: request,
209
+ responsePayload: response
210
+ };
211
+ memoryLogs.push(result);
212
+ emitter.emit("exchange", result);
213
+ return result;
214
+ };
215
+ return {
216
+ logExchange,
217
+ wrap(fn) {
218
+ const wrapped = (async (...args) => {
219
+ const request = args[0];
220
+ const response = await fn(...args);
221
+ await logExchange(request, response);
222
+ return response;
223
+ });
224
+ return wrapped;
225
+ },
226
+ on(event, handler) {
227
+ emitter.on(event, handler);
228
+ }
229
+ };
230
+ }
231
+
232
+ // src/toolbox/AIToolbox.ts
233
+ var AIToolbox = class {
234
+
235
+
236
+
237
+
238
+ constructor(options = {}) {
239
+ this.tracker = createTracker({
240
+ storage: options.storage,
241
+ sqlitePath: options.sqlitePath
242
+ });
243
+ this.router = createRouter(
244
+ _nullishCoalesce(options.defaultModel, () => ( (options.defaultProvider ? `${options.defaultProvider}/gpt-4o-mini` : "openai/gpt-4o-mini")))
245
+ );
246
+ this.guard = createGuard();
247
+ this.fallback = createFallback();
248
+ }
249
+ };
250
+
251
+
252
+
253
+ exports.AIToolbox = AIToolbox;
254
+ //# sourceMappingURL=chunk-5HNFAYTO.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-5HNFAYTO.cjs","../src/toolbox/fallback.ts","../src/toolbox/guard.ts","../src/toolbox/router.ts","../src/toolbox/tracker.ts","../src/toolbox/AIToolbox.ts"],"names":[],"mappings":"AAAA;ACYA,SAAS,gBAAA,CAAiB,KAAA,EAAyB;AACjD,EAAA,GAAA,CAAI,MAAA,GAAS,OAAO,MAAA,IAAU,QAAA,EAAU;AACtC,IAAA,MAAM,EAAA,EAAI,KAAA;AACV,IAAA,GAAA,CAAI,OAAO,CAAA,CAAE,OAAA,IAAW,SAAA,GAAY,CAAA,CAAE,OAAA,GAAU,GAAA,EAAK,OAAO,IAAA;AAC5D,IAAA,GAAA,CAAI,CAAA,CAAE,KAAA,IAAS,aAAA,GAAgB,CAAA,CAAE,KAAA,IAAS,WAAA,EAAa,OAAO,IAAA;AAAA,EAChE;AACA,EAAA,GAAA,CAAI,MAAA,WAAiB,KAAA,EAAO;AAC1B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA;AACT;AAEO,SAAS,cAAA,CAAe,UAAA,EAAgD;AAC7E,EAAA,MAAM,MAAA,kBAAQ,IAAI,GAAA,CAA0B,CAAA;AAE5C,EAAA,MAAM,UAAA,EAAY,CAAC,QAAA,EAAA,GAA8B;AAC/C,IAAA,MAAM,EAAA,EAAI,KAAA,CAAM,GAAA,CAAI,QAAQ,CAAA;AAC5B,IAAA,GAAA,CAAI,CAAC,CAAA,EAAG,OAAO,KAAA;AACf,IAAA,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,CAAA,CAAE,YAAA,EAAc,OAAO,IAAA;AACxC,IAAA,KAAA,CAAM,MAAA,CAAO,QAAQ,CAAA;AACrB,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,cAAA,EAAgB,CAAC,QAAA,EAAA,GAAqB;AAC1C,IAAA,MAAM,KAAA,mBAAO,KAAA,CAAM,GAAA,CAAI,QAAQ,CAAA,UAAK,EAAE,QAAA,EAAU,CAAA,EAAG,YAAA,EAAc,EAAE,GAAA;AACnE,IAAA,MAAM,SAAA,EAAW,IAAA,CAAK,SAAA,EAAW,CAAA;AACjC,IAAA,GAAA,CAAI,SAAA,GAAY,CAAA,EAAG;AACjB,MAAA,KAAA,CAAM,GAAA,CAAI,QAAA,EAAU,EAAE,QAAA,EAAU,YAAA,EAAc,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,EAAA,EAAI,GAAA,EAAK,IAAK,CAAC,CAAA;AAAA,IAC5E,EAAA,KAAO;AACL,MAAA,KAAA,CAAM,GAAA,CAAI,QAAA,EAAU,EAAE,QAAA,EAAU,YAAA,EAAc,EAAE,CAAC,CAAA;AAAA,IACnD;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,cAAA,EAAgB,CAAC,QAAA,EAAA,GAAqB;AAC1C,IAAA,KAAA,CAAM,MAAA,CAAO,QAAQ,CAAA;AAAA,EACvB,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,MAAM,OAAA,CAAW,KAAA,EAAsB,EAAA,EAA+C;AACpF,MAAA,MAAM,OAAA,EAAS,CAAC,KAAA,CAAM,OAAA,EAAS,GAAG,KAAA,CAAM,aAAa,CAAA;AACrD,MAAA,MAAM,WAAA,mBAAa,KAAA,CAAM,UAAA,UAAc,GAAA;AACvC,MAAA,IAAI,SAAA;AAEJ,MAAA,IAAA,CAAA,IAAS,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,MAAA,CAAO,MAAA,EAAQ,CAAA,EAAA,EAAK;AACtC,QAAA,MAAM,MAAA,EAAQ,MAAA,CAAO,CAAC,CAAA;AACtB,QAAA,MAAM,SAAA,mBAAW,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,UAAK,OAAA;AAExC,QAAA,GAAA,CAAI,SAAA,CAAU,QAAQ,CAAA,EAAG;AACvB,UAAA,QAAA;AAAA,QACF;AAEA,QAAA,IAAA,CAAA,IAAS,QAAA,EAAU,CAAA,EAAG,QAAA,GAAW,UAAA,EAAY,OAAA,EAAA,EAAW;AACtD,UAAA,IAAI;AACF,YAAA,MAAM,OAAA,EAAS,MAAM,EAAA,CAAG,KAAK,CAAA;AAC7B,YAAA,aAAA,CAAc,QAAQ,CAAA;AACtB,YAAA,GAAA,CAAI,EAAA,EAAI,CAAA,kBAAG,UAAA,wBAAA,CAAa,KAAK,GAAA;AAC7B,YAAA,OAAO,MAAA;AAAA,UACT,EAAA,MAAA,CAAS,KAAA,EAAO;AACd,YAAA,UAAA,EAAY,KAAA;AACZ,YAAA,GAAA,CAAI,CAAC,gBAAA,CAAiB,KAAK,CAAA,EAAG,MAAM,KAAA;AACpC,YAAA,aAAA,CAAc,QAAQ,CAAA;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAEA,MAAA,uBAAM,SAAA,UAAa,IAAI,KAAA,CAAM,qCAAqC,GAAA;AAAA,IACpE;AAAA,EACF,CAAA;AACF;ADnBA;AACA;AEnDA,SAAS,UAAA,CAAW,IAAA,EAAsB;AACxC,EAAA,IAAI,EAAA,EAAI,IAAA,CAAK,IAAA,CAAK,CAAA;AAClB,EAAA,GAAA,CAAI,CAAA,CAAE,UAAA,CAAW,KAAK,CAAA,EAAG;AACvB,IAAA,EAAA,EAAI,CAAA,CAAE,OAAA,CAAQ,mBAAA,EAAqB,EAAE,CAAA,CAAE,OAAA,CAAQ,SAAA,EAAW,EAAE,CAAA;AAAA,EAC9D;AACA,EAAA,EAAA,EAAI,CAAA,CAAE,OAAA,CAAQ,cAAA,EAAgB,IAAI,CAAA;AAClC,EAAA,OAAO,CAAA;AACT;AAEA,SAAS,QAAA,CAAS,IAAA,EAA2B;AAC3C,EAAA,OAAO,IAAI,GAAA;AAAA,IACT,IAAA,CACG,WAAA,CAAY,CAAA,CACZ,KAAA,CAAM,KAAK,CAAA,CACX,MAAA,CAAO,CAAC,CAAA,EAAA,GAAM,CAAA,CAAE,OAAA,EAAS,CAAC;AAAA,EAC/B,CAAA;AACF;AAEA,SAAS,cAAA,CAAe,QAAA,EAAkB,MAAA,EAAwB;AAChE,EAAA,MAAM,KAAA,EAAO,QAAA,CAAS,QAAQ,CAAA;AAC9B,EAAA,MAAM,IAAA,EAAM,QAAA,CAAS,MAAM,CAAA;AAC3B,EAAA,GAAA,CAAI,IAAA,CAAK,KAAA,IAAS,CAAA,EAAG,OAAO,CAAA;AAC5B,EAAA,IAAI,QAAA,EAAU,CAAA;AACd,EAAA,IAAA,CAAA,MAAW,EAAA,GAAK,IAAA,EAAM;AACpB,IAAA,GAAA,CAAI,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,EAAG,OAAA,EAAA;AAAA,EAClB;AACA,EAAA,OAAO,QAAA,EAAU,IAAA,CAAK,IAAA;AACxB;AAEA,SAAS,kBAAA,CAAmB,KAAA,EAAgB,MAAA,EAA0B;AACpE,EAAA,MAAM,EAAA,EAAI,MAAA;AACV,EAAA,MAAM,OAAA,EAAmB,CAAC,CAAA;AAE1B,EAAA,GAAA,CAAI,CAAA,CAAE,KAAA,IAAS,SAAA,GAAA,CAAa,MAAA,IAAU,KAAA,GAAQ,OAAO,MAAA,IAAU,SAAA,GAAY,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,CAAA,EAAI;AAChG,IAAA,MAAA,CAAO,IAAA,CAAK,iBAAiB,CAAA;AAC7B,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,GAAA,CAAI,CAAA,CAAE,KAAA,IAAS,SAAA,GAAY,CAAA,CAAE,QAAA,EAAU;AACrC,IAAA,MAAM,IAAA,EAAM,KAAA;AACZ,IAAA,IAAA,CAAA,MAAW,IAAA,GAAO,CAAA,CAAE,QAAA,EAAU;AAC5B,MAAA,GAAA,CAAI,CAAA,CAAE,IAAA,GAAO,GAAA,CAAA,EAAM,MAAA,CAAO,IAAA,CAAK,CAAA,wBAAA,EAA2B,GAAG,CAAA,CAAA;AAC/D,IAAA;AACF,EAAA;AAEO,EAAA;AACT;AAEqC;AAC5B,EAAA;AACyC,IAAA;AAClB,MAAA;AAEK,MAAA;AACM,QAAA;AACK,QAAA;AACI,UAAA;AACgB,YAAA;AAC1D,UAAA;AACF,QAAA;AACF,MAAA;AAEuB,MAAA;AACjB,QAAA;AACkC,UAAA;AACF,UAAA;AACe,UAAA;AAC3C,QAAA;AACkC,UAAA;AAC1C,QAAA;AACF,MAAA;AAEiE,MAAA;AACP,QAAA;AAClB,QAAA;AAC7B,UAAA;AACkD,YAAA;AACzD,UAAA;AACF,QAAA;AACF,MAAA;AAE8C,MAAA;AAChD,IAAA;AACF,EAAA;AACF;AFuCoE;AACA;AGhI9C;AACpB,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACF;AAO0E;AAC5C,EAAA;AAErB,EAAA;AACoB,IAAA;AACR,MAAA;AACjB,IAAA;AAEqC,IAAA;AACO,MAAA;AAEjB,MAAA;AACV,QAAA;AAC4C,MAAA;AAC5C,QAAA;AACf,MAAA;AAG+C,MAAA;AAGpC,MAAA;AACF,QAAA;AACQ,UAAA;AACgB,UAAA;AAC/B,QAAA;AACF,MAAA;AAE2D,MAAA;AAC7D,IAAA;AACF,EAAA;AACF;AHoHoE;AACA;AI9KzC;AACE;AAmBiB;AACC,EAAA;AAC/C;AAEwF;AAChC,EAAA;AAC5C,EAAA;AACsD,EAAA;AAG7C,EAAA;AAC+C,EAAA;AAE/B,EAAA;AAC+B,EAAA;AACpC,IAAA;AAC9B,EAAA;AACO,EAAA;AACT;AAQsE;AACnC,EAAA;AACE,EAAA;AAEsD,EAAA;AAChE,IAAA;AACY,IAAA;AACS,IAAA;AACgB,IAAA;AAEtB,IAAA;AAEV,IAAA;AACJ,MAAA;AACG,MAAA;AACzB,MAAA;AACA,MAAA;AACkB,MAAA;AACF,MAAA;AACC,MAAA;AACnB,IAAA;AAEsB,IAAA;AACS,IAAA;AACxB,IAAA;AACT,EAAA;AAEO,EAAA;AACL,IAAA;AACmE,IAAA;AAClB,MAAA;AACvB,QAAA;AACW,QAAA;AACE,QAAA;AAC5B,QAAA;AACT,MAAA;AACO,MAAA;AACT,IAAA;AAC4D,IAAA;AACjC,MAAA;AAC3B,IAAA;AACF,EAAA;AACF;AJ8IoE;AACA;AK1N7C;AACZ,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AAEmC,EAAA;AACb,IAAA;AACV,MAAA;AACG,MAAA;AACrB,IAAA;AACa,IAAA;AAGK,uBAAA;AAEnB,IAAA;AACyB,IAAA;AACM,IAAA;AACjC,EAAA;AACF;ALwNoE;AACA;AACA;AACA","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-5HNFAYTO.cjs","sourcesContent":[null,"export type FallbackChain = {\n primary: string;\n fallbackChain: string[];\n maxRetries?: number;\n};\n\ntype ProviderTrip = { failures: number; trippedUntil: number };\n\nexport interface Fallback {\n execute<T>(chain: FallbackChain, fn: (model: string) => Promise<T>): Promise<T>;\n}\n\nfunction isRetriableError(error: unknown): boolean {\n if (error && typeof error === \"object\") {\n const e = error as { status?: number; code?: string };\n if (typeof e.status === \"number\" && e.status >= 400) return true;\n if (e.code === \"ECONNRESET\" || e.code === \"ETIMEDOUT\") return true;\n }\n if (error instanceof Error) {\n return true;\n }\n return false;\n}\n\nexport function createFallback(onFallback?: (model: string) => void): Fallback {\n const trips = new Map<string, ProviderTrip>();\n\n const isTripped = (provider: string): boolean => {\n const t = trips.get(provider);\n if (!t) return false;\n if (Date.now() < t.trippedUntil) return true;\n trips.delete(provider);\n return false;\n };\n\n const recordFailure = (provider: string) => {\n const prev = trips.get(provider) ?? { failures: 0, trippedUntil: 0 };\n const failures = prev.failures + 1;\n if (failures >= 3) {\n trips.set(provider, { failures, trippedUntil: Date.now() + 5 * 60 * 1000 });\n } else {\n trips.set(provider, { failures, trippedUntil: 0 });\n }\n };\n\n const recordSuccess = (provider: string) => {\n trips.delete(provider);\n };\n\n return {\n async execute<T>(chain: FallbackChain, fn: (model: string) => Promise<T>): Promise<T> {\n const models = [chain.primary, ...chain.fallbackChain];\n const maxRetries = chain.maxRetries ?? 1;\n let lastError: unknown;\n\n for (let i = 0; i < models.length; i++) {\n const model = models[i]!;\n const provider = model.split(\"/\")[0] ?? model;\n\n if (isTripped(provider)) {\n continue;\n }\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const result = await fn(model);\n recordSuccess(provider);\n if (i > 0) onFallback?.(model);\n return result;\n } catch (error) {\n lastError = error;\n if (!isRetriableError(error)) throw error;\n recordFailure(provider);\n }\n }\n }\n\n throw lastError ?? new Error(\"All models in fallback chain failed\");\n },\n };\n}\n","export type GuardConfig = {\n jsonSchema?: object;\n banPhrases?: string[];\n minGroundingScore?: number;\n sourceText?: string;\n};\n\nexport interface Guard {\n verify(response: string, config: GuardConfig): { isValid: boolean; errors: string[] };\n}\n\nfunction repairJson(text: string): string {\n let s = text.trim();\n if (s.startsWith(\"```\")) {\n s = s.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```$/, \"\");\n }\n s = s.replace(/,\\s*([}\\]])/g, \"$1\");\n return s;\n}\n\nfunction tokenize(text: string): Set<string> {\n return new Set(\n text\n .toLowerCase()\n .split(/\\W+/)\n .filter((t) => t.length > 2),\n );\n}\n\nfunction groundingScore(response: string, source: string): number {\n const resp = tokenize(response);\n const src = tokenize(source);\n if (resp.size === 0) return 0;\n let overlap = 0;\n for (const t of resp) {\n if (src.has(t)) overlap++;\n }\n return overlap / resp.size;\n}\n\nfunction validateJsonSchema(value: unknown, schema: object): string[] {\n const s = schema as { type?: string; required?: string[]; properties?: Record<string, unknown> };\n const errors: string[] = [];\n\n if (s.type === \"object\" && (value === null || typeof value !== \"object\" || Array.isArray(value))) {\n errors.push(\"Expected object\");\n return errors;\n }\n\n if (s.type === \"object\" && s.required) {\n const obj = value as Record<string, unknown>;\n for (const key of s.required) {\n if (!(key in obj)) errors.push(`Missing required field: ${key}`);\n }\n }\n\n return errors;\n}\n\nexport function createGuard(): Guard {\n return {\n verify(response: string, config: GuardConfig) {\n const errors: string[] = [];\n\n if (config.banPhrases?.length) {\n const lower = response.toLowerCase();\n for (const phrase of config.banPhrases) {\n if (lower.includes(phrase.toLowerCase())) {\n errors.push(`Response contains banned phrase: ${phrase}`);\n }\n }\n }\n\n if (config.jsonSchema) {\n try {\n const repaired = repairJson(response);\n const parsed = JSON.parse(repaired);\n errors.push(...validateJsonSchema(parsed, config.jsonSchema));\n } catch {\n errors.push(\"Response is not valid JSON\");\n }\n }\n\n if (config.minGroundingScore !== undefined && config.sourceText) {\n const score = groundingScore(response, config.sourceText);\n if (score < config.minGroundingScore) {\n errors.push(\n `Grounding score ${score.toFixed(2)} below threshold ${config.minGroundingScore}`,\n );\n }\n }\n\n return { isValid: errors.length === 0, errors };\n },\n };\n}\n","export type RouteRule = {\n maxTokens?: number;\n keywords?: string[];\n complexity: \"low\" | \"medium\" | \"high\";\n targetModel: string;\n};\n\nconst TECH_KEYWORDS = [\n \"code\",\n \"sql\",\n \"diff\",\n \"function\",\n \"class\",\n \"typescript\",\n \"python\",\n \"api\",\n \"debug\",\n \"refactor\",\n \"algorithm\",\n];\n\nexport interface Router {\n addRule(rule: RouteRule): void;\n determineModel(prompt: string): Promise<{ model: string; reason: string }>;\n}\n\nexport function createRouter(defaultModel = \"openai/gpt-4o-mini\"): Router {\n const rules: RouteRule[] = [];\n\n return {\n addRule(rule: RouteRule) {\n rules.push(rule);\n },\n\n async determineModel(prompt: string) {\n let complexity: RouteRule[\"complexity\"] = \"medium\";\n\n if (prompt.length < 200) {\n complexity = \"low\";\n } else if (TECH_KEYWORDS.some((kw) => prompt.toLowerCase().includes(kw))) {\n complexity = \"high\";\n }\n\n const match =\n rules.find((r) => r.complexity === complexity) ??\n rules.find((r) => r.complexity === \"medium\");\n\n if (match) {\n return {\n model: match.targetModel,\n reason: `Matched ${complexity} complexity rule`,\n };\n }\n\n return { model: defaultModel, reason: `Default model for ${complexity} complexity` };\n },\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\n\nexport type TrackResult = {\n requestId: string;\n durationMs: number;\n promptTokens: number;\n completionTokens: number;\n estimatedCostUSD: number;\n requestPayload: unknown;\n responsePayload: unknown;\n};\n\nexport type TrackerStorage = \"memory\" | \"sqlite\";\n\nexport type TrackerOptions = {\n storage?: TrackerStorage;\n sqlitePath?: string;\n};\n\nfunction estimateTokens(text: string): number {\n return Math.max(1, Math.ceil(text.length / 4));\n}\n\nfunction extractUsage(response: unknown): { prompt: number; completion: number } | null {\n if (!response || typeof response !== \"object\") return null;\n const r = response as Record<string, unknown>;\n const usage = (r.usage ?? (r as { data?: { usage?: unknown } }).data) as\n | Record<string, number>\n | undefined;\n if (!usage) return null;\n const prompt = usage.prompt_tokens ?? usage.promptTokens ?? usage.input_tokens;\n const completion =\n usage.completion_tokens ?? usage.completionTokens ?? usage.output_tokens;\n if (typeof prompt === \"number\" && typeof completion === \"number\") {\n return { prompt, completion };\n }\n return null;\n}\n\nexport interface Tracker {\n logExchange(request: unknown, response: unknown): Promise<TrackResult>;\n wrap<T extends (...args: unknown[]) => Promise<unknown>>(fn: T): T;\n on(event: \"exchange\", handler: (data: TrackResult) => void): void;\n}\n\nexport function createTracker(_options: TrackerOptions = {}): Tracker {\n const emitter = new EventEmitter();\n const memoryLogs: TrackResult[] = [];\n\n const logExchange = async (request: unknown, response: unknown): Promise<TrackResult> => {\n const start = Date.now();\n const usage = extractUsage(response);\n const reqText = JSON.stringify(request ?? \"\");\n const promptTokens = usage?.prompt ?? estimateTokens(reqText);\n const completionTokens =\n usage?.completion ?? estimateTokens(JSON.stringify(response ?? \"\"));\n\n const result: TrackResult = {\n requestId: randomUUID(),\n durationMs: Date.now() - start,\n promptTokens,\n completionTokens,\n estimatedCostUSD: 0,\n requestPayload: request,\n responsePayload: response,\n };\n\n memoryLogs.push(result);\n emitter.emit(\"exchange\", result);\n return result;\n };\n\n return {\n logExchange,\n wrap<T extends (...args: unknown[]) => Promise<unknown>>(fn: T): T {\n const wrapped = (async (...args: unknown[]) => {\n const request = args[0];\n const response = await fn(...args);\n await logExchange(request, response);\n return response;\n }) as T;\n return wrapped;\n },\n on(event: \"exchange\", handler: (data: TrackResult) => void) {\n emitter.on(event, handler);\n },\n };\n}\n","import { createFallback, type Fallback } from \"./fallback.js\";\nimport { createGuard, type Guard } from \"./guard.js\";\nimport { createRouter, type Router } from \"./router.js\";\nimport { createTracker, type Tracker, type TrackerOptions } from \"./tracker.js\";\n\nexport type AiToolboxOptions = {\n defaultProvider?: string;\n defaultModel?: string;\n apiKey?: string;\n storage?: TrackerOptions[\"storage\"];\n sqlitePath?: string;\n};\n\nexport class AIToolbox {\n readonly tracker: Tracker;\n readonly router: Router;\n readonly guard: Guard;\n readonly fallback: Fallback;\n\n constructor(options: AiToolboxOptions = {}) {\n this.tracker = createTracker({\n storage: options.storage,\n sqlitePath: options.sqlitePath,\n });\n this.router = createRouter(\n options.defaultModel ??\n (options.defaultProvider\n ? `${options.defaultProvider}/gpt-4o-mini`\n : \"openai/gpt-4o-mini\"),\n );\n this.guard = createGuard();\n this.fallback = createFallback();\n }\n}\n"]}
@@ -0,0 +1,127 @@
1
+ // src/models/reasoningModel.ts
2
+ var REASONING_SUPPORTED_PARAMETERS = ["reasoning", "include_reasoning"];
3
+ function supportsReasoningParameter(model) {
4
+ return model.supportedParameters.some(
5
+ (p) => REASONING_SUPPORTED_PARAMETERS.includes(p)
6
+ );
7
+ }
8
+ function hasReasoningPricing(model) {
9
+ const raw = model.openRouterPricing?.internal_reasoning;
10
+ if (raw !== void 0 && raw !== null && String(raw).trim() !== "") {
11
+ return true;
12
+ }
13
+ return model.pricing.reasoningUsdPerToken !== void 0;
14
+ }
15
+ function computeSupportsReasoning(model) {
16
+ return supportsReasoningParameter(model) || hasReasoningPricing(model);
17
+ }
18
+ function isReasoningModel(model) {
19
+ if (model.supportsReasoning !== void 0) {
20
+ return model.supportsReasoning;
21
+ }
22
+ return computeSupportsReasoning(model);
23
+ }
24
+
25
+ // src/models/normalizeOpenRouterModel.ts
26
+ function parsePrice(value) {
27
+ if (value === void 0 || value === null || value === "") return 0;
28
+ const n = typeof value === "number" ? value : Number.parseFloat(String(value));
29
+ return Number.isFinite(n) ? n : 0;
30
+ }
31
+ function extractProviderId(modelId) {
32
+ const slash = modelId.indexOf("/");
33
+ if (slash > 0) return modelId.slice(0, slash);
34
+ return "other";
35
+ }
36
+ function buildAliases(modelId, name) {
37
+ const aliases = /* @__PURE__ */ new Set();
38
+ if (name) aliases.add(name);
39
+ const slash = modelId.indexOf("/");
40
+ if (slash > 0) {
41
+ const direct = modelId.slice(slash + 1);
42
+ aliases.add(direct);
43
+ const base = direct.replace(/-\d{4}-\d{2}-\d{2}$/, "").replace(/-\d{8}$/, "");
44
+ if (base !== direct) aliases.add(base);
45
+ }
46
+ return [...aliases];
47
+ }
48
+ function normalizePricing(raw) {
49
+ return {
50
+ promptUsdPerToken: parsePrice(raw.prompt),
51
+ completionUsdPerToken: parsePrice(raw.completion),
52
+ imageUsdPerUnit: parsePrice(raw.image),
53
+ requestUsdPerRequest: parsePrice(raw.request),
54
+ cacheReadUsdPerToken: raw.input_cache_read ? parsePrice(raw.input_cache_read) : void 0,
55
+ cacheWriteUsdPerToken: raw.input_cache_write ? parsePrice(raw.input_cache_write) : void 0,
56
+ reasoningUsdPerToken: raw.internal_reasoning ? parsePrice(raw.internal_reasoning) : void 0,
57
+ webSearchUsdPerRequest: raw.web_search ? parsePrice(raw.web_search) : void 0,
58
+ openRouterMarkupUsdPerInputToken: 0,
59
+ openRouterMarkupUsdPerOutputToken: 0,
60
+ pricedAt: (/* @__PURE__ */ new Date()).toISOString(),
61
+ source: "openrouter"
62
+ };
63
+ }
64
+ function resolveStatus(row) {
65
+ if (row.expiration_date) {
66
+ const exp = Date.parse(row.expiration_date);
67
+ if (!Number.isNaN(exp) && exp < Date.now()) return "deprecated";
68
+ }
69
+ return "active";
70
+ }
71
+ function normalizeOpenRouterModel(row, syncedAt) {
72
+ const outputModalities = row.architecture?.output_modalities ?? ["text"];
73
+ const inputModalities = row.architecture?.input_modalities ?? ["text"];
74
+ const supportedParameters = row.supported_parameters ?? [];
75
+ const pricing = normalizePricing(row.pricing);
76
+ const openRouterPricing = row.pricing;
77
+ const supportsReasoning = computeSupportsReasoning({
78
+ supportedParameters,
79
+ pricing,
80
+ openRouterPricing
81
+ });
82
+ return {
83
+ modelId: row.id,
84
+ name: row.name ?? row.id,
85
+ providerId: extractProviderId(row.id),
86
+ canonicalSlug: row.canonical_slug ?? row.id,
87
+ status: resolveStatus(row),
88
+ description: row.description ?? "",
89
+ created: row.created ?? 0,
90
+ expirationDate: row.expiration_date ?? null,
91
+ contextLength: row.context_length ?? row.top_provider?.context_length ?? 0,
92
+ maxCompletionTokens: row.top_provider?.max_completion_tokens ?? null,
93
+ isModerated: row.top_provider?.is_moderated ?? false,
94
+ modality: row.architecture?.modality ?? "",
95
+ inputModalities,
96
+ outputModalities,
97
+ tokenizer: row.architecture?.tokenizer ?? "",
98
+ instructType: row.architecture?.instruct_type ?? null,
99
+ supportedParameters,
100
+ defaultParameters: row.default_parameters ?? null,
101
+ perRequestLimits: row.per_request_limits ?? null,
102
+ pricing,
103
+ openRouterPricing,
104
+ architecture: row.architecture,
105
+ topProvider: row.top_provider,
106
+ openRouter: row,
107
+ aliases: buildAliases(row.id, row.name),
108
+ availableOnOpenRouter: true,
109
+ supportsStreaming: outputModalities.includes("text"),
110
+ supportsTools: supportedParameters.includes("tools"),
111
+ supportsReasoning,
112
+ primaryOutputModality: outputModalities[0] ?? "text",
113
+ syncedAt,
114
+ syncSource: "openrouter"
115
+ };
116
+ }
117
+
118
+ export {
119
+ REASONING_SUPPORTED_PARAMETERS,
120
+ supportsReasoningParameter,
121
+ hasReasoningPricing,
122
+ computeSupportsReasoning,
123
+ isReasoningModel,
124
+ extractProviderId,
125
+ normalizeOpenRouterModel
126
+ };
127
+ //# sourceMappingURL=chunk-6QGDZTGH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/models/reasoningModel.ts","../src/models/normalizeOpenRouterModel.ts"],"sourcesContent":["import type { AiModelRecord } from \"./types.js\";\n\n/** OpenRouter `supported_parameters` values that indicate reasoning API support. */\nexport const REASONING_SUPPORTED_PARAMETERS = [\"reasoning\", \"include_reasoning\"] as const;\n\nexport type ReasoningModelInput = Pick<\n AiModelRecord,\n \"supportedParameters\" | \"pricing\" | \"openRouterPricing\"\n> & {\n supportsReasoning?: boolean;\n};\n\n/**\n * Whether the model accepts OpenRouter's `reasoning` request parameter\n * (effort, max_tokens, exclude, enabled).\n */\nexport function supportsReasoningParameter(model: Pick<AiModelRecord, \"supportedParameters\">): boolean {\n return model.supportedParameters.some((p) =>\n (REASONING_SUPPORTED_PARAMETERS as readonly string[]).includes(p),\n );\n}\n\n/**\n * Whether the model bills separate reasoning / thinking tokens\n * (`internal_reasoning` in OpenRouter pricing).\n */\nexport function hasReasoningPricing(\n model: Pick<AiModelRecord, \"pricing\" | \"openRouterPricing\">,\n): boolean {\n const raw = model.openRouterPricing?.internal_reasoning;\n if (raw !== undefined && raw !== null && String(raw).trim() !== \"\") {\n return true;\n }\n return model.pricing.reasoningUsdPerToken !== undefined;\n}\n\n/**\n * Compute `supportsReasoning` from catalog fields (used during sync normalization).\n */\nexport function computeSupportsReasoning(model: ReasoningModelInput): boolean {\n return supportsReasoningParameter(model) || hasReasoningPricing(model);\n}\n\n/**\n * True when the model supports reasoning tokens (API param and/or separate reasoning pricing).\n *\n * Prefer `model.supportsReasoning` on {@link AiModelRecord} after catalog sync;\n * this helper also works when only partial fields are available.\n */\nexport function isReasoningModel(model: ReasoningModelInput): boolean {\n if (model.supportsReasoning !== undefined) {\n return model.supportsReasoning;\n }\n return computeSupportsReasoning(model);\n}\n","import { computeSupportsReasoning } from \"./reasoningModel.js\";\nimport type { AiModelPricing, AiModelRecord } from \"./types.js\";\nimport type { OpenRouterModelApi } from \"./openrouter.types.js\";\n\nfunction parsePrice(value: string | number | undefined): number {\n if (value === undefined || value === null || value === \"\") return 0;\n const n = typeof value === \"number\" ? value : Number.parseFloat(String(value));\n return Number.isFinite(n) ? n : 0;\n}\n\nexport function extractProviderId(modelId: string): string {\n const slash = modelId.indexOf(\"/\");\n if (slash > 0) return modelId.slice(0, slash);\n return \"other\";\n}\n\nfunction buildAliases(modelId: string, name?: string): string[] {\n const aliases = new Set<string>();\n if (name) aliases.add(name);\n const slash = modelId.indexOf(\"/\");\n if (slash > 0) {\n const direct = modelId.slice(slash + 1);\n aliases.add(direct);\n const base = direct.replace(/-\\d{4}-\\d{2}-\\d{2}$/, \"\").replace(/-\\d{8}$/, \"\");\n if (base !== direct) aliases.add(base);\n }\n return [...aliases];\n}\n\nfunction normalizePricing(raw: OpenRouterModelApi[\"pricing\"]): AiModelPricing {\n return {\n promptUsdPerToken: parsePrice(raw.prompt),\n completionUsdPerToken: parsePrice(raw.completion),\n imageUsdPerUnit: parsePrice(raw.image),\n requestUsdPerRequest: parsePrice(raw.request),\n cacheReadUsdPerToken: raw.input_cache_read\n ? parsePrice(raw.input_cache_read)\n : undefined,\n cacheWriteUsdPerToken: raw.input_cache_write\n ? parsePrice(raw.input_cache_write)\n : undefined,\n reasoningUsdPerToken: raw.internal_reasoning\n ? parsePrice(raw.internal_reasoning)\n : undefined,\n webSearchUsdPerRequest: raw.web_search ? parsePrice(raw.web_search) : undefined,\n openRouterMarkupUsdPerInputToken: 0,\n openRouterMarkupUsdPerOutputToken: 0,\n pricedAt: new Date().toISOString(),\n source: \"openrouter\",\n };\n}\n\nfunction resolveStatus(row: OpenRouterModelApi): AiModelRecord[\"status\"] {\n if (row.expiration_date) {\n const exp = Date.parse(row.expiration_date);\n if (!Number.isNaN(exp) && exp < Date.now()) return \"deprecated\";\n }\n return \"active\";\n}\n\nexport function normalizeOpenRouterModel(row: OpenRouterModelApi, syncedAt: string): AiModelRecord {\n const outputModalities = row.architecture?.output_modalities ?? [\"text\"];\n const inputModalities = row.architecture?.input_modalities ?? [\"text\"];\n const supportedParameters = row.supported_parameters ?? [];\n const pricing = normalizePricing(row.pricing);\n const openRouterPricing = row.pricing;\n const supportsReasoning = computeSupportsReasoning({\n supportedParameters,\n pricing,\n openRouterPricing,\n });\n\n return {\n modelId: row.id,\n name: row.name ?? row.id,\n providerId: extractProviderId(row.id),\n canonicalSlug: row.canonical_slug ?? row.id,\n status: resolveStatus(row),\n description: row.description ?? \"\",\n created: row.created ?? 0,\n expirationDate: row.expiration_date ?? null,\n contextLength: row.context_length ?? row.top_provider?.context_length ?? 0,\n maxCompletionTokens: row.top_provider?.max_completion_tokens ?? null,\n isModerated: row.top_provider?.is_moderated ?? false,\n modality: row.architecture?.modality ?? \"\",\n inputModalities,\n outputModalities,\n tokenizer: row.architecture?.tokenizer ?? \"\",\n instructType: row.architecture?.instruct_type ?? null,\n supportedParameters,\n defaultParameters: row.default_parameters ?? null,\n perRequestLimits: row.per_request_limits ?? null,\n pricing,\n openRouterPricing,\n architecture: row.architecture,\n topProvider: row.top_provider,\n openRouter: row,\n aliases: buildAliases(row.id, row.name),\n availableOnOpenRouter: true,\n supportsStreaming: outputModalities.includes(\"text\"),\n supportsTools: supportedParameters.includes(\"tools\"),\n supportsReasoning,\n primaryOutputModality: outputModalities[0] ?? \"text\",\n syncedAt,\n syncSource: \"openrouter\",\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,106 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/errors.ts
2
+ var AiToolsError = class extends Error {
3
+ constructor(code, message, cause) {
4
+ super(message);
5
+ this.code = code;
6
+ this.cause = cause;
7
+ this.name = "AiToolsError";
8
+ }
9
+
10
+
11
+ };
12
+ var ModelNotFoundError = class extends AiToolsError {
13
+ constructor(modelId) {
14
+ super(
15
+ "MODEL_NOT_FOUND",
16
+ `Model not found: "${modelId}". Run "ai-tools sync" to populate the catalog.`
17
+ );
18
+ this.name = "ModelNotFoundError";
19
+ }
20
+ };
21
+ var ModelResolutionError = class extends AiToolsError {
22
+ constructor(input, result) {
23
+ super(
24
+ "MODEL_NOT_FOUND",
25
+ `Could not resolve model "${input.model}" (provider: "${_nullishCoalesce(input.provider, () => ( "unspecified"))}"). ` + result.reason + (result.bestRejectedCandidate ? ` Best candidate was "${result.bestRejectedCandidate.modelId}" (confidence ${result.bestRejectedCandidate.confidence.toFixed(2)}).` : "")
26
+ );
27
+ this.input = input;
28
+ this.result = result;
29
+ this.name = "ModelResolutionError";
30
+ }
31
+
32
+
33
+ };
34
+ var AliasNotFoundError = class extends AiToolsError {
35
+ constructor(aliasName) {
36
+ super(
37
+ "ALIAS_NOT_FOUND",
38
+ `Alias not found: "${aliasName}". Run "ai-tools alias list" to see defined aliases.`
39
+ );
40
+ this.name = "AliasNotFoundError";
41
+ }
42
+ };
43
+ var AliasInvalidNameError = class extends AiToolsError {
44
+ constructor(aliasName) {
45
+ super(
46
+ "ALIAS_INVALID_NAME",
47
+ `Invalid alias name: "${aliasName}". Names must match /^[a-z0-9][a-z0-9-]*$/`
48
+ );
49
+ this.name = "AliasInvalidNameError";
50
+ }
51
+ };
52
+ var AliasConflictError = class extends AiToolsError {
53
+ constructor(aliasName) {
54
+ super(
55
+ "ALIAS_CONFLICT",
56
+ `Alias "${aliasName}" already exists. Use --force to overwrite.`
57
+ );
58
+ this.name = "AliasConflictError";
59
+ }
60
+ };
61
+ var AliasFileParseError = class extends AiToolsError {
62
+ constructor(path, cause) {
63
+ super(
64
+ "ALIAS_FILE_PARSE_ERROR",
65
+ `Failed to parse aliases file at "${path}". Check JSON syntax.`,
66
+ cause
67
+ );
68
+ this.name = "AliasFileParseError";
69
+ }
70
+ };
71
+ var AliasFileWriteError = class extends AiToolsError {
72
+ constructor(path, cause) {
73
+ super(
74
+ "ALIAS_FILE_WRITE_ERROR",
75
+ `Failed to write aliases file at "${path}".`,
76
+ cause
77
+ );
78
+ this.name = "AliasFileWriteError";
79
+ }
80
+ };
81
+ var SyncError = class extends AiToolsError {
82
+ constructor(code, message, cause) {
83
+ super(code, message, cause);
84
+ this.name = "SyncError";
85
+ }
86
+ };
87
+ var CostCalculationError = class extends AiToolsError {
88
+ constructor(message, cause) {
89
+ super("COST_CALCULATION_FAILED", message, cause);
90
+ this.name = "CostCalculationError";
91
+ }
92
+ };
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+
104
+
105
+ exports.AiToolsError = AiToolsError; exports.ModelNotFoundError = ModelNotFoundError; exports.ModelResolutionError = ModelResolutionError; exports.AliasNotFoundError = AliasNotFoundError; exports.AliasInvalidNameError = AliasInvalidNameError; exports.AliasConflictError = AliasConflictError; exports.AliasFileParseError = AliasFileParseError; exports.AliasFileWriteError = AliasFileWriteError; exports.SyncError = SyncError; exports.CostCalculationError = CostCalculationError;
106
+ //# sourceMappingURL=chunk-7Q742NI3.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-7Q742NI3.cjs","../src/errors.ts"],"names":[],"mappings":"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","file":"/Users/ami/Documents/prometheus/x12i/ai-tools/dist/chunk-7Q742NI3.cjs","sourcesContent":[null,"import type {\n ModelResolutionInput,\n ModelResolutionNotFound,\n} from \"./sync/modelNameResolver/types.js\";\n\nexport type AiToolsErrorCode =\n | \"MODEL_NOT_FOUND\"\n | \"SYNC_FETCH_FAILED\"\n | \"SYNC_UPSERT_FAILED\"\n | \"CATALOG_BOOTSTRAP_FAILED\"\n | \"COST_CALCULATION_FAILED\"\n | \"INVALID_USAGE_INPUT\"\n | \"OPENROUTER_AUTH_FAILED\"\n | \"OPENROUTER_MODELS_FETCH_FAILED\"\n | \"CACHE_READ_ERROR\"\n | \"ALIAS_NOT_FOUND\"\n | \"ALIAS_INVALID_NAME\"\n | \"ALIAS_CONFLICT\"\n | \"ALIAS_FILE_PARSE_ERROR\"\n | \"ALIAS_FILE_WRITE_ERROR\";\n\nexport class AiToolsError extends Error {\n constructor(\n public readonly code: AiToolsErrorCode,\n message: string,\n public readonly cause?: unknown,\n ) {\n super(message);\n this.name = \"AiToolsError\";\n }\n}\n\nexport class ModelNotFoundError extends AiToolsError {\n constructor(modelId: string) {\n super(\n \"MODEL_NOT_FOUND\",\n `Model not found: \"${modelId}\". Run \"ai-tools sync\" to populate the catalog.`,\n );\n this.name = \"ModelNotFoundError\";\n }\n}\n\nexport class ModelResolutionError extends AiToolsError {\n constructor(\n public readonly input: ModelResolutionInput,\n public readonly result: ModelResolutionNotFound,\n ) {\n super(\n \"MODEL_NOT_FOUND\",\n `Could not resolve model \"${input.model}\" (provider: \"${input.provider ?? \"unspecified\"}\"). ` +\n result.reason +\n (result.bestRejectedCandidate\n ? ` Best candidate was \"${result.bestRejectedCandidate.modelId}\" (confidence ${result.bestRejectedCandidate.confidence.toFixed(2)}).`\n : \"\"),\n );\n this.name = \"ModelResolutionError\";\n }\n}\n\nexport class AliasNotFoundError extends AiToolsError {\n constructor(aliasName: string) {\n super(\n \"ALIAS_NOT_FOUND\",\n `Alias not found: \"${aliasName}\". Run \"ai-tools alias list\" to see defined aliases.`,\n );\n this.name = \"AliasNotFoundError\";\n }\n}\n\nexport class AliasInvalidNameError extends AiToolsError {\n constructor(aliasName: string) {\n super(\n \"ALIAS_INVALID_NAME\",\n `Invalid alias name: \"${aliasName}\". Names must match /^[a-z0-9][a-z0-9-]*$/`,\n );\n this.name = \"AliasInvalidNameError\";\n }\n}\n\nexport class AliasConflictError extends AiToolsError {\n constructor(aliasName: string) {\n super(\n \"ALIAS_CONFLICT\",\n `Alias \"${aliasName}\" already exists. Use --force to overwrite.`,\n );\n this.name = \"AliasConflictError\";\n }\n}\n\nexport class AliasFileParseError extends AiToolsError {\n constructor(path: string, cause?: unknown) {\n super(\n \"ALIAS_FILE_PARSE_ERROR\",\n `Failed to parse aliases file at \"${path}\". Check JSON syntax.`,\n cause,\n );\n this.name = \"AliasFileParseError\";\n }\n}\n\nexport class AliasFileWriteError extends AiToolsError {\n constructor(path: string, cause?: unknown) {\n super(\n \"ALIAS_FILE_WRITE_ERROR\",\n `Failed to write aliases file at \"${path}\".`,\n cause,\n );\n this.name = \"AliasFileWriteError\";\n }\n}\n\nexport class SyncError extends AiToolsError {\n constructor(code: Extract<AiToolsErrorCode, \"SYNC_FETCH_FAILED\" | \"SYNC_UPSERT_FAILED\" | \"OPENROUTER_AUTH_FAILED\" | \"OPENROUTER_MODELS_FETCH_FAILED\">, message: string, cause?: unknown) {\n super(code, message, cause);\n this.name = \"SyncError\";\n }\n}\n\nexport class CostCalculationError extends AiToolsError {\n constructor(message: string, cause?: unknown) {\n super(\"COST_CALCULATION_FAILED\", message, cause);\n this.name = \"CostCalculationError\";\n }\n}\n"]}
@@ -0,0 +1,106 @@
1
+ // src/errors.ts
2
+ var AiToolsError = class extends Error {
3
+ constructor(code, message, cause) {
4
+ super(message);
5
+ this.code = code;
6
+ this.cause = cause;
7
+ this.name = "AiToolsError";
8
+ }
9
+ code;
10
+ cause;
11
+ };
12
+ var ModelNotFoundError = class extends AiToolsError {
13
+ constructor(modelId) {
14
+ super(
15
+ "MODEL_NOT_FOUND",
16
+ `Model not found: "${modelId}". Run "ai-tools sync" to populate the catalog.`
17
+ );
18
+ this.name = "ModelNotFoundError";
19
+ }
20
+ };
21
+ var ModelResolutionError = class extends AiToolsError {
22
+ constructor(input, result) {
23
+ super(
24
+ "MODEL_NOT_FOUND",
25
+ `Could not resolve model "${input.model}" (provider: "${input.provider ?? "unspecified"}"). ` + result.reason + (result.bestRejectedCandidate ? ` Best candidate was "${result.bestRejectedCandidate.modelId}" (confidence ${result.bestRejectedCandidate.confidence.toFixed(2)}).` : "")
26
+ );
27
+ this.input = input;
28
+ this.result = result;
29
+ this.name = "ModelResolutionError";
30
+ }
31
+ input;
32
+ result;
33
+ };
34
+ var AliasNotFoundError = class extends AiToolsError {
35
+ constructor(aliasName) {
36
+ super(
37
+ "ALIAS_NOT_FOUND",
38
+ `Alias not found: "${aliasName}". Run "ai-tools alias list" to see defined aliases.`
39
+ );
40
+ this.name = "AliasNotFoundError";
41
+ }
42
+ };
43
+ var AliasInvalidNameError = class extends AiToolsError {
44
+ constructor(aliasName) {
45
+ super(
46
+ "ALIAS_INVALID_NAME",
47
+ `Invalid alias name: "${aliasName}". Names must match /^[a-z0-9][a-z0-9-]*$/`
48
+ );
49
+ this.name = "AliasInvalidNameError";
50
+ }
51
+ };
52
+ var AliasConflictError = class extends AiToolsError {
53
+ constructor(aliasName) {
54
+ super(
55
+ "ALIAS_CONFLICT",
56
+ `Alias "${aliasName}" already exists. Use --force to overwrite.`
57
+ );
58
+ this.name = "AliasConflictError";
59
+ }
60
+ };
61
+ var AliasFileParseError = class extends AiToolsError {
62
+ constructor(path, cause) {
63
+ super(
64
+ "ALIAS_FILE_PARSE_ERROR",
65
+ `Failed to parse aliases file at "${path}". Check JSON syntax.`,
66
+ cause
67
+ );
68
+ this.name = "AliasFileParseError";
69
+ }
70
+ };
71
+ var AliasFileWriteError = class extends AiToolsError {
72
+ constructor(path, cause) {
73
+ super(
74
+ "ALIAS_FILE_WRITE_ERROR",
75
+ `Failed to write aliases file at "${path}".`,
76
+ cause
77
+ );
78
+ this.name = "AliasFileWriteError";
79
+ }
80
+ };
81
+ var SyncError = class extends AiToolsError {
82
+ constructor(code, message, cause) {
83
+ super(code, message, cause);
84
+ this.name = "SyncError";
85
+ }
86
+ };
87
+ var CostCalculationError = class extends AiToolsError {
88
+ constructor(message, cause) {
89
+ super("COST_CALCULATION_FAILED", message, cause);
90
+ this.name = "CostCalculationError";
91
+ }
92
+ };
93
+
94
+ export {
95
+ AiToolsError,
96
+ ModelNotFoundError,
97
+ ModelResolutionError,
98
+ AliasNotFoundError,
99
+ AliasInvalidNameError,
100
+ AliasConflictError,
101
+ AliasFileParseError,
102
+ AliasFileWriteError,
103
+ SyncError,
104
+ CostCalculationError
105
+ };
106
+ //# sourceMappingURL=chunk-AJEKEWWB.js.map