@nextblock-cms/cortex 0.20.3 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/client.cjs.js +1 -1
  2. package/client.es.js +3 -7
  3. package/index.cjs.js +1 -1
  4. package/index.es.js +24 -277
  5. package/lib/ai-block-generation.cjs.js +3 -4
  6. package/lib/ai-block-generation.es.js +143 -182
  7. package/lib/ai-client.cjs.js +1 -1
  8. package/lib/ai-client.d.ts +1 -1
  9. package/lib/ai-client.es.js +101 -135
  10. package/lib/ai-config.cjs.js +1 -1
  11. package/lib/ai-config.es.js +89 -108
  12. package/lib/ai-cortex-widget-builder.cjs.js +1 -1
  13. package/lib/ai-cortex-widget-builder.es.js +56 -70
  14. package/lib/ai-global-agent-content-ops-tools.cjs.js +1 -1
  15. package/lib/ai-global-agent-content-ops-tools.d.ts +1943 -68
  16. package/lib/ai-global-agent-content-ops-tools.es.js +185 -199
  17. package/lib/ai-global-agent-custom-block-tools.cjs.js +1 -1
  18. package/lib/ai-global-agent-custom-block-tools.d.ts +2160 -95
  19. package/lib/ai-global-agent-custom-block-tools.es.js +226 -223
  20. package/lib/ai-global-agent-db-tools.cjs.js +1 -1
  21. package/lib/ai-global-agent-db-tools.d.ts +2708 -98
  22. package/lib/ai-global-agent-db-tools.es.js +1013 -986
  23. package/lib/ai-global-agent-ecommerce.cjs.js +1 -1
  24. package/lib/ai-global-agent-ecommerce.es.js +3 -7
  25. package/lib/ai-global-agent-site-tools.cjs.js +2 -3
  26. package/lib/ai-global-agent-site-tools.d.ts +10695 -500
  27. package/lib/ai-global-agent-site-tools.es.js +750 -757
  28. package/lib/ai-global-agent-theming-tools.cjs.js +1 -3
  29. package/lib/ai-global-agent-theming-tools.d.ts +2905 -105
  30. package/lib/ai-global-agent-theming-tools.es.js +326 -396
  31. package/lib/ai-global-agent-tools.cjs.js +2 -2
  32. package/lib/ai-global-agent-tools.d.ts +4 -2230
  33. package/lib/ai-global-agent-tools.es.js +3899 -4328
  34. package/lib/ai-key-crypto.cjs.js +1 -1
  35. package/lib/ai-key-crypto.es.js +63 -82
  36. package/lib/ai-key-verification.cjs.js +1 -1
  37. package/lib/ai-key-verification.es.js +74 -63
  38. package/lib/ai-model-catalog.cjs.js +1 -1
  39. package/lib/ai-model-catalog.es.js +18 -22
  40. package/lib/ai-model-registry.cjs.js +2 -2
  41. package/lib/ai-model-registry.es.js +246 -309
  42. package/lib/ai-seo-metadata.cjs.js +2 -3
  43. package/lib/ai-seo-metadata.es.js +143 -185
  44. package/lib/ai-vision.cjs.js +2 -2
  45. package/lib/ai-vision.d.ts +6 -6
  46. package/lib/ai-vision.es.js +161 -215
  47. package/lib/block-content-schemas.cjs.js +1 -1
  48. package/lib/block-content-schemas.es.js +324 -254
  49. package/lib/cortex-widget-registry.cjs.js +1 -1
  50. package/lib/cortex-widget-registry.es.js +35 -43
  51. package/lib/cortex-widget-schema.cjs.js +2 -3
  52. package/lib/cortex-widget-schema.es.js +280 -309
  53. package/lib/editor-document-from-html.cjs.js +1 -1
  54. package/lib/editor-document-from-html.es.js +334 -278
  55. package/lib/fetch-host-guard.cjs.js +1 -0
  56. package/lib/fetch-host-guard.d.ts +2 -0
  57. package/lib/fetch-host-guard.es.js +30 -0
  58. package/lib/mcp-server.cjs.js +1 -1
  59. package/lib/mcp-server.es.js +155 -173
  60. package/lib/mcp-tokens.cjs.js +1 -1
  61. package/lib/mcp-tokens.es.js +95 -107
  62. package/lib/mcp-tool-registry.cjs.js +5 -6
  63. package/lib/mcp-tool-registry.es.js +533 -411
  64. package/lib/site-brief.cjs.js +2 -2
  65. package/lib/site-brief.es.js +102 -108
  66. package/lib/vision-image-download.cjs.js +1 -0
  67. package/lib/vision-image-download.d.ts +43 -0
  68. package/lib/vision-image-download.es.js +120 -0
  69. package/lib/zod-config.cjs.js +1 -1
  70. package/lib/zod-config.es.js +5 -6
  71. package/package.json +8 -8
@@ -1,324 +1,261 @@
1
- import { APICallError as h } from "ai";
2
- const $ = "https://openrouter.ai/api/v1", C = "openrouter/free", u = [
3
- // 120B/12B hybrid MoE; tools + structured_outputs; NVIDIA-hosted; 262K ctx.
4
- "nvidia/nemotron-3-super-120b-a12b:free",
5
- // 550B/55B; most-used free model (3.77T tokens/week); 1M ctx; tools only.
6
- "nvidia/nemotron-3-ultra-550b-a55b:free",
7
- // 975B/41B; 1M ctx; 99.98% uptime; SWE-bench Verified 77.6; tools only.
8
- "thinkingmachines/inkling:free",
9
- // Newest (2026-09-08); tools + structured_outputs; 469B tokens/week; size undisclosed.
10
- "nex-agi/nex-n2.5-pro:free",
11
- // 118B/8B coding-agent model; 1.26T tokens/week; 99.99% uptime; tools only.
12
- "poolside/laguna-s-2.1:free",
13
- // 276B/12B; 1M ctx; 99.99% uptime; tools only.
14
- "thinkingmachines/inkling-small:free",
15
- // 124B/5.5B general + vision model (2026-09-10); 329B tokens/week; tools only.
16
- "inclusionai/ling-3.0-flash-vl:free"
17
- ], P = ["tools", "structured_outputs"], T = {
18
- frequencyPenalty: "frequency_penalty",
19
- logitBias: "logit_bias",
20
- presencePenalty: "presence_penalty",
21
- seed: "seed",
22
- stopSequences: "stop",
23
- temperature: "temperature",
24
- topK: "top_k",
25
- topP: "top_p"
26
- }, J = {
27
- defaultFreeRouter: C,
28
- defaultStructuredOutputModel: u[0],
29
- defaultToolCallingModel: u[0],
30
- freeFallbacks: u,
31
- structuredJsonPreferred: u,
32
- toolCallingPreferred: u
1
+ import { APICallError as e } from "ai";
2
+ //#region libs/cortex/src/lib/ai-model-registry.ts
3
+ var t = "https://openrouter.ai/api/v1", n = "openrouter/free", r = [
4
+ "nvidia/nemotron-3-super-120b-a12b:free",
5
+ "nvidia/nemotron-3-ultra-550b-a55b:free",
6
+ "thinkingmachines/inkling:free",
7
+ "nex-agi/nex-n2.5-pro:free",
8
+ "poolside/laguna-s-2.1:free",
9
+ "thinkingmachines/inkling-small:free",
10
+ "inclusionai/ling-3.0-flash-vl:free"
11
+ ], i = ["tools", "structured_outputs"], a = {
12
+ frequencyPenalty: "frequency_penalty",
13
+ logitBias: "logit_bias",
14
+ presencePenalty: "presence_penalty",
15
+ seed: "seed",
16
+ stopSequences: "stop",
17
+ temperature: "temperature",
18
+ topK: "top_k",
19
+ topP: "top_p"
20
+ }, o = {
21
+ defaultFreeRouter: n,
22
+ defaultStructuredOutputModel: r[0],
23
+ defaultToolCallingModel: r[0],
24
+ freeFallbacks: r,
25
+ structuredJsonPreferred: r,
26
+ toolCallingPreferred: r
27
+ }, s = class extends Error {
28
+ attempts;
29
+ constructor(e, t, n) {
30
+ super(e), this.name = "CortexAiRoutingError", this.attempts = t, this.cause = n;
31
+ }
33
32
  };
34
- class E extends Error {
35
- attempts;
36
- constructor(t, n, r) {
37
- super(t), this.name = "CortexAiRoutingError", this.attempts = n, this.cause = r;
38
- }
33
+ function c(e) {
34
+ return Array.from(new Set(e.filter(Boolean)));
39
35
  }
40
- function g(e) {
41
- return Array.from(new Set(e.filter(Boolean)));
36
+ function l(e) {
37
+ return e && typeof e == "object" && !Array.isArray(e) ? e : null;
42
38
  }
43
- function c(e) {
44
- return e && typeof e == "object" && !Array.isArray(e) ? e : null;
39
+ function u(e) {
40
+ return typeof e == "string" && e.trim() ? e.trim() : null;
45
41
  }
46
42
  function d(e) {
47
- return typeof e == "string" && e.trim() ? e.trim() : null;
48
- }
49
- function A(e) {
50
- return Array.isArray(e) ? e.filter((t) => typeof t == "string" && t.trim().length > 0) : [];
43
+ return Array.isArray(e) ? e.filter((e) => typeof e == "string" && e.trim().length > 0) : [];
51
44
  }
52
45
  function f(e) {
53
- const t = typeof e == "number" ? e : Number(e);
54
- return Number.isFinite(t) ? t : null;
55
- }
56
- function O(e) {
57
- const t = c(e);
58
- return t ? Object.fromEntries(
59
- Object.entries(t).filter(([, n]) => n != null).map(([n, r]) => [n, String(r)])
60
- ) : {};
46
+ let t = typeof e == "number" ? e : Number(e);
47
+ return Number.isFinite(t) ? t : null;
61
48
  }
62
- function S(e) {
63
- const t = new Set(e);
64
- return P.every((n) => t.has(n));
49
+ function p(e) {
50
+ let t = l(e);
51
+ return t ? Object.fromEntries(Object.entries(t).filter(([, e]) => e != null).map(([e, t]) => [e, String(t)])) : {};
65
52
  }
66
- function L(e) {
67
- const t = c(e.architecture);
68
- return A(t?.output_modalities).includes("text");
53
+ function m(e) {
54
+ let t = new Set(e);
55
+ return i.every((e) => t.has(e));
69
56
  }
70
- function N(e) {
71
- if (e == null)
72
- return null;
73
- if (typeof e == "number")
74
- return e > 1e10 ? e : e * 1e3;
75
- if (typeof e == "string" && e.trim()) {
76
- const t = Date.parse(e);
77
- return Number.isFinite(t) ? t : null;
78
- }
79
- return null;
80
- }
81
- function k(e, t) {
82
- const n = N(e);
83
- return n !== null && n <= t.getTime();
84
- }
85
- function D(e) {
86
- const t = c(e.top_provider);
87
- return f(e.context_length) ?? f(e.contextLength) ?? f(t?.context_length) ?? null;
57
+ function h(e) {
58
+ return d(l(e.architecture)?.output_modalities).includes("text");
88
59
  }
89
- function w(e) {
90
- const t = e.expiration_date ?? e.expirationDate;
91
- return typeof t == "string" && t.trim() ? t.trim() : null;
92
- }
93
- function F(e) {
94
- return !!(e && u.includes(e));
95
- }
96
- function Y(e) {
97
- const t = c(e);
98
- if (!t)
99
- return null;
100
- const n = d(t.modelId), r = d(t.name), s = A(t.supportedParameters), i = d(t.updatedAt);
101
- return !n || !r || !i || !S(s) ? null : {
102
- contextLength: f(t.contextLength),
103
- modelId: n,
104
- name: r,
105
- pricing: O(t.pricing),
106
- supportedParameters: s,
107
- updatedAt: i
108
- };
109
- }
110
- function z(e, t = /* @__PURE__ */ new Date()) {
111
- return {
112
- contextLength: e.contextLength,
113
- modelId: e.id,
114
- name: e.name,
115
- pricing: e.pricing,
116
- supportedParameters: [...e.supportedParameters],
117
- updatedAt: t.toISOString()
118
- };
119
- }
120
- function H(e, t = /* @__PURE__ */ new Date()) {
121
- const n = c(e), r = Array.isArray(e) ? e : Array.isArray(n?.data) ? n.data : [], s = [];
122
- for (const i of r) {
123
- const o = c(i), l = d(o?.id), a = d(o?.name), M = A(o?.supported_parameters);
124
- !o || !l || !a || !L(o) || k(o.expiration_date, t) || !S(M) || s.push({
125
- contextLength: D(o),
126
- created: f(o.created),
127
- expirationDate: w(o),
128
- id: l,
129
- name: a,
130
- pricing: O(o.pricing),
131
- supportedParameters: M
132
- });
133
- }
134
- return s.sort((i, o) => i.name.localeCompare(o.name));
135
- }
136
- function W(e) {
137
- return g([
138
- e?.modelId || u[0],
139
- ...e?.fallbackModelIds || u
140
- ]);
141
- }
142
- function Q(e) {
143
- const t = e.requestedModelId?.trim() || null;
144
- if (e.credentialSource === "env")
145
- return {
146
- credentialSource: e.credentialSource,
147
- ignoredRequestedModelId: t && !F(t) ? t : null,
148
- modelIds: [...u],
149
- modelSelection: null
150
- };
151
- const n = g(
152
- e.fallbackModelIds?.length ? e.fallbackModelIds : u
153
- ), r = e.credentialSource === "stored" ? e.selectedModel?.modelId || n[0] : t || e.selectedModel?.modelId || n[0];
154
- return {
155
- credentialSource: e.credentialSource,
156
- ignoredRequestedModelId: e.credentialSource === "stored" && t && t !== r ? t : null,
157
- modelIds: g([r, ...n]),
158
- modelSelection: e.selectedModel || null
159
- };
160
- }
161
- function V(e, t) {
162
- const n = t.modelSelection;
163
- if (!n || n.modelId !== t.modelId)
164
- return e;
165
- const r = new Set(n.supportedParameters), s = Object.entries(T).filter(([o, l]) => o in e && !r.has(l)).map(([o]) => o);
166
- if (s.length === 0)
167
- return e;
168
- const i = { ...e };
169
- for (const o of s)
170
- delete i[o];
171
- return i;
172
- }
173
- function p(e, t) {
174
- if (!e || typeof e != "object" || !(t in e))
175
- return null;
176
- const n = e[t], r = typeof n == "number" ? n : Number(n);
177
- return Number.isFinite(r) ? r : null;
60
+ function g(e) {
61
+ if (e == null) return null;
62
+ if (typeof e == "number") return e > 1e10 ? e : e * 1e3;
63
+ if (typeof e == "string" && e.trim()) {
64
+ let t = Date.parse(e);
65
+ return Number.isFinite(t) ? t : null;
66
+ }
67
+ return null;
68
+ }
69
+ function _(e, t) {
70
+ let n = g(e);
71
+ return n !== null && n <= t.getTime();
72
+ }
73
+ function v(e) {
74
+ let t = l(e.top_provider);
75
+ return f(e.context_length) ?? f(e.contextLength) ?? f(t?.context_length) ?? null;
178
76
  }
179
77
  function y(e) {
180
- if (h.isInstance(e))
181
- return e.statusCode ?? null;
182
- const t = p(e, "statusCode") ?? p(e, "status");
183
- if (t)
184
- return t;
185
- if (e && typeof e == "object" && "response" in e) {
186
- const n = e.response, r = p(n, "status");
187
- if (r)
188
- return r;
189
- }
190
- return e && typeof e == "object" && "cause" in e ? y(e.cause) : null;
78
+ let t = e.expiration_date ?? e.expirationDate;
79
+ return typeof t == "string" && t.trim() ? t.trim() : null;
191
80
  }
192
81
  function b(e) {
193
- return e !== null && Number.isInteger(e) && e >= 100 && e <= 599;
194
- }
195
- function _(e) {
196
- if (typeof e != "string" || !e.trim().startsWith("{"))
197
- return null;
198
- try {
199
- return c(JSON.parse(e));
200
- } catch {
201
- return null;
202
- }
203
- }
204
- function x(e, t = 0) {
205
- const n = c(e);
206
- if (!n || t > 8)
207
- return null;
208
- const r = [
209
- n,
210
- c(n.data),
211
- _(n.responseBody),
212
- _(n.text)
213
- ];
214
- for (const s of r) {
215
- const i = c(s?.error), o = p(i, "code") ?? p(i, "status");
216
- if (b(o))
217
- return o;
218
- }
219
- return x(n.cause, t + 1);
220
- }
221
- function I(e) {
222
- const t = y(e);
223
- return b(t) ? t : x(e);
224
- }
225
- function q(e) {
226
- return I(e) === 429;
227
- }
228
- const B = ["message", "error", "text", "responseBody", "data", "cause"];
229
- function m(e, t = 0) {
230
- if (!e || t > 8)
231
- return "";
232
- if (typeof e != "object")
233
- return String(e);
234
- const n = e, r = e instanceof Error ? [e.message] : [];
235
- for (const s of B)
236
- s === "message" && e instanceof Error || r.push(m(n[s], t + 1));
237
- return Array.from(new Set(r.filter(Boolean))).join(`
238
- `);
239
- }
240
- const U = /No endpoints found|no longer available|not available as a free model|transitioned to a paid model|unavailable for free|paid version is available|is not a valid model ID/i, j = /not found|does not exist|unknown model|no such model/i;
241
- function X(e) {
242
- const t = I(e);
243
- if (t === 429 || t === 404)
244
- return !0;
245
- const n = m(e);
246
- return U.test(n) ? !0 : t === 400 && j.test(n);
247
- }
248
- function R(e, t = 900) {
249
- const n = e.replace(/\s+/g, " ").trim();
250
- return n.length > t ? `${n.slice(0, t - 1).trimEnd()}...` : n;
251
- }
252
- function G(e) {
253
- const t = m(e);
254
- return t ? R(t) : "Unknown OpenRouter error.";
255
- }
256
- function Z(e, t = "Cortex AI request failed.") {
257
- if (e instanceof E) {
258
- const n = e.attempts.map((o) => o.errorMessage).filter((o) => !!o?.trim()), r = n[0], s = n[n.length - 1], i = R(m(e.cause));
259
- return r && s && r !== s ? `First model error: ${r} Last model error: ${s}` : s || r || i || e.message;
260
- }
261
- return R(m(e)) || t;
262
- }
263
- async function v(e) {
264
- const t = g(e.modelIds), n = e.shouldRetry || X;
265
- let r = [], s = null;
266
- for (const i of t)
267
- try {
268
- const o = await e.execute(i);
269
- return r = [
270
- ...r,
271
- {
272
- modelId: i,
273
- rateLimited: !1,
274
- status: "success"
275
- }
276
- ], {
277
- attempts: r,
278
- modelId: i,
279
- result: o
280
- };
281
- } catch (o) {
282
- const l = q(o), a = n(o);
283
- if (s = o, r = [
284
- ...r,
285
- {
286
- errorMessage: G(o),
287
- modelId: i,
288
- rateLimited: l,
289
- status: l ? "rate_limited" : a ? "retried" : "failed"
290
- }
291
- ], !a)
292
- throw new E(
293
- `OpenRouter request failed for model "${i}".`,
294
- r,
295
- o
296
- );
297
- }
298
- throw new E(
299
- "OpenRouter fallback exhausted all configured Cortex AI models.",
300
- r,
301
- s
302
- );
303
- }
304
- export {
305
- u as CORTEX_AI_FREE_MODEL_FALLBACK_REGISTRY,
306
- J as CORTEX_AI_MODEL_REGISTRY,
307
- $ as CORTEX_AI_OPENROUTER_BASE_URL,
308
- C as CORTEX_AI_OPENROUTER_FREE_ROUTER_MODEL,
309
- P as CORTEX_AI_REQUIRED_MODEL_PARAMETERS,
310
- E as CortexAiRoutingError,
311
- W as buildCortexAiModelFallbackChain,
312
- Q as buildCortexAiRoutingPolicy,
313
- z as createCortexAiStoredModelSelection,
314
- H as filterCortexAiCompatibleOpenRouterModels,
315
- y as getHttpStatusCode,
316
- I as getOpenRouterErrorStatus,
317
- F as isCortexAiFreeModelId,
318
- q as isOpenRouterRateLimitError,
319
- X as isOpenRouterRecoverableRoutingError,
320
- V as omitUnsupportedCortexAiModelOptions,
321
- v as runWithCortexAiModelFallback,
322
- Y as safeParseCortexAiModelSelection,
323
- Z as summarizeCortexAiRoutingError
324
- };
82
+ return !!(e && r.includes(e));
83
+ }
84
+ function x(e) {
85
+ let t = l(e);
86
+ if (!t) return null;
87
+ let n = u(t.modelId), r = u(t.name), i = d(t.supportedParameters), a = u(t.updatedAt);
88
+ return !n || !r || !a || !m(i) ? null : {
89
+ contextLength: f(t.contextLength),
90
+ modelId: n,
91
+ name: r,
92
+ pricing: p(t.pricing),
93
+ supportedParameters: i,
94
+ updatedAt: a
95
+ };
96
+ }
97
+ function S(e, t = /* @__PURE__ */ new Date()) {
98
+ return {
99
+ contextLength: e.contextLength,
100
+ modelId: e.id,
101
+ name: e.name,
102
+ pricing: e.pricing,
103
+ supportedParameters: [...e.supportedParameters],
104
+ updatedAt: t.toISOString()
105
+ };
106
+ }
107
+ function C(e, t = /* @__PURE__ */ new Date()) {
108
+ let n = l(e), r = Array.isArray(e) ? e : Array.isArray(n?.data) ? n.data : [], i = [];
109
+ for (let e of r) {
110
+ let n = l(e), r = u(n?.id), a = u(n?.name), o = d(n?.supported_parameters);
111
+ n && r && a && h(n) && !_(n.expiration_date, t) && m(o) && i.push({
112
+ contextLength: v(n),
113
+ created: f(n.created),
114
+ expirationDate: y(n),
115
+ id: r,
116
+ name: a,
117
+ pricing: p(n.pricing),
118
+ supportedParameters: o
119
+ });
120
+ }
121
+ return i.sort((e, t) => e.name.localeCompare(t.name));
122
+ }
123
+ function w(e) {
124
+ return c([e?.modelId || r[0], ...e?.fallbackModelIds || r]);
125
+ }
126
+ function T(e) {
127
+ let t = e.requestedModelId?.trim() || null;
128
+ if (e.credentialSource === "env") return {
129
+ credentialSource: e.credentialSource,
130
+ ignoredRequestedModelId: t && !b(t) ? t : null,
131
+ modelIds: [...r],
132
+ modelSelection: null
133
+ };
134
+ let n = c(e.fallbackModelIds?.length ? e.fallbackModelIds : r), i = e.credentialSource === "stored" ? e.selectedModel?.modelId || n[0] : t || e.selectedModel?.modelId || n[0];
135
+ return {
136
+ credentialSource: e.credentialSource,
137
+ ignoredRequestedModelId: e.credentialSource === "stored" && t && t !== i ? t : null,
138
+ modelIds: c([i, ...n]),
139
+ modelSelection: e.selectedModel || null
140
+ };
141
+ }
142
+ function E(e, t) {
143
+ let n = t.modelSelection;
144
+ if (!n || n.modelId !== t.modelId) return e;
145
+ let r = new Set(n.supportedParameters), i = Object.entries(a).filter(([t, n]) => t in e && !r.has(n)).map(([e]) => e);
146
+ if (i.length === 0) return e;
147
+ let o = { ...e };
148
+ for (let e of i) delete o[e];
149
+ return o;
150
+ }
151
+ function D(e, t) {
152
+ if (!e || typeof e != "object" || !(t in e)) return null;
153
+ let n = e[t], r = typeof n == "number" ? n : Number(n);
154
+ return Number.isFinite(r) ? r : null;
155
+ }
156
+ function O(t) {
157
+ if (e.isInstance(t)) return t.statusCode ?? null;
158
+ let n = D(t, "statusCode") ?? D(t, "status");
159
+ if (n) return n;
160
+ if (t && typeof t == "object" && "response" in t) {
161
+ let e = t.response, n = D(e, "status");
162
+ if (n) return n;
163
+ }
164
+ return t && typeof t == "object" && "cause" in t ? O(t.cause) : null;
165
+ }
166
+ function k(e) {
167
+ return e !== null && Number.isInteger(e) && e >= 100 && e <= 599;
168
+ }
169
+ function A(e) {
170
+ if (typeof e != "string" || !e.trim().startsWith("{")) return null;
171
+ try {
172
+ return l(JSON.parse(e));
173
+ } catch {
174
+ return null;
175
+ }
176
+ }
177
+ function j(e, t = 0) {
178
+ let n = l(e);
179
+ if (!n || t > 8) return null;
180
+ let r = [
181
+ n,
182
+ l(n.data),
183
+ A(n.responseBody),
184
+ A(n.text)
185
+ ];
186
+ for (let e of r) {
187
+ let t = l(e?.error), n = D(t, "code") ?? D(t, "status");
188
+ if (k(n)) return n;
189
+ }
190
+ return j(n.cause, t + 1);
191
+ }
192
+ function M(e) {
193
+ let t = O(e);
194
+ return k(t) ? t : j(e);
195
+ }
196
+ function N(e) {
197
+ return M(e) === 429;
198
+ }
199
+ var P = [
200
+ "message",
201
+ "error",
202
+ "text",
203
+ "responseBody",
204
+ "data",
205
+ "cause"
206
+ ];
207
+ function F(e, t = 0) {
208
+ if (!e || t > 8) return "";
209
+ if (typeof e != "object") return String(e);
210
+ let n = e, r = e instanceof Error ? [e.message] : [];
211
+ for (let i of P) i === "message" && e instanceof Error || r.push(F(n[i], t + 1));
212
+ return Array.from(new Set(r.filter(Boolean))).join("\n");
213
+ }
214
+ var I = /No endpoints found|no longer available|not available as a free model|transitioned to a paid model|unavailable for free|paid version is available|is not a valid model ID/i, L = /not found|does not exist|unknown model|no such model/i;
215
+ function R(e) {
216
+ let t = M(e);
217
+ if (t === 429 || t === 404) return !0;
218
+ let n = F(e);
219
+ return I.test(n) ? !0 : t === 400 && L.test(n);
220
+ }
221
+ function z(e, t = 900) {
222
+ let n = e.replace(/\s+/g, " ").trim();
223
+ return n.length > t ? `${n.slice(0, t - 1).trimEnd()}...` : n;
224
+ }
225
+ function B(e) {
226
+ let t = F(e);
227
+ return t ? z(t) : "Unknown OpenRouter error.";
228
+ }
229
+ function V(e, t = "Cortex AI request failed.") {
230
+ if (e instanceof s) {
231
+ let t = e.attempts.map((e) => e.errorMessage).filter((e) => !!e?.trim()), n = t[0], r = t[t.length - 1], i = z(F(e.cause));
232
+ return n && r && n !== r ? `First model error: ${n} Last model error: ${r}` : r || n || i || e.message;
233
+ }
234
+ return z(F(e)) || t;
235
+ }
236
+ async function H(e) {
237
+ let t = c(e.modelIds), n = e.shouldRetry || R, r = [], i = null;
238
+ for (let a of t) try {
239
+ let t = await e.execute(a);
240
+ return r = [...r, {
241
+ modelId: a,
242
+ rateLimited: !1,
243
+ status: "success"
244
+ }], {
245
+ attempts: r,
246
+ modelId: a,
247
+ result: t
248
+ };
249
+ } catch (e) {
250
+ let t = N(e), o = n(e);
251
+ if (i = e, r = [...r, {
252
+ errorMessage: B(e),
253
+ modelId: a,
254
+ rateLimited: t,
255
+ status: t ? "rate_limited" : o ? "retried" : "failed"
256
+ }], !o) throw new s(`OpenRouter request failed for model "${a}".`, r, e);
257
+ }
258
+ throw new s("OpenRouter fallback exhausted all configured Cortex AI models.", r, i);
259
+ }
260
+ //#endregion
261
+ export { r as CORTEX_AI_FREE_MODEL_FALLBACK_REGISTRY, o as CORTEX_AI_MODEL_REGISTRY, t as CORTEX_AI_OPENROUTER_BASE_URL, n as CORTEX_AI_OPENROUTER_FREE_ROUTER_MODEL, i as CORTEX_AI_REQUIRED_MODEL_PARAMETERS, s as CortexAiRoutingError, w as buildCortexAiModelFallbackChain, T as buildCortexAiRoutingPolicy, S as createCortexAiStoredModelSelection, C as filterCortexAiCompatibleOpenRouterModels, O as getHttpStatusCode, M as getOpenRouterErrorStatus, b as isCortexAiFreeModelId, N as isOpenRouterRateLimitError, R as isOpenRouterRecoverableRoutingError, E as omitUnsupportedCortexAiModelOptions, H as runWithCortexAiModelFallback, x as safeParseCortexAiModelSelection, V as summarizeCortexAiRoutingError };
@@ -1,4 +1,3 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("ai"),d=require("./ai-model-registry.cjs.js");require("./zod-config.cjs.js");const u=require("zod"),y="Cortex AI SEO metadata generation can only be imported from server-side code.";function O(){if(!(typeof window>"u"))throw new Error(y)}const g=u.z.strictObject({metaDescription:u.z.string().trim().min(1),metaTitle:u.z.string().trim().min(1),ogDescription:u.z.string().trim().min(1),ogTitle:u.z.string().trim().min(1)}),l={metaDescription:160,metaTitle:60,ogDescription:200,ogTitle:88},T=6e3,A=6e4,b=/[\s.,;:!?‐-―\-/\\|&+*_"'([{·•]+$/;function c(e,t){const n=e.trim();if(t<=0)return"";if(n.length<=t)return n;const o=n.slice(0,t),i=o.search(/\s\S*$/);return(i>0?o.slice(0,i):o).replace(b,"").trim()}function f(e){const t=e.replace(/```[a-zA-Z0-9]*/g,""),n=t.indexOf("{");if(n===-1)return null;let o=0,i=!1,r=!1;for(let s=n;s<t.length;s++){const a=t[s];if(i){r?r=!1:a==="\\"?r=!0:a==='"'&&(i=!1);continue}if(a==='"'){i=!0;continue}if(a==="{"){o++;continue}if(a==="}"&&(o--,o===0))return t.slice(n,s+1)}return null}function _(){const e=l;return["You are NextBlock Cortex AI, an SEO metadata writer for a content management system.","Return ONLY a single JSON object. No markdown fences, no commentary, no explanation, no trailing prose.",'The object must have exactly these four keys, all strings, all non-empty: "metaDescription", "metaTitle", "ogDescription", "ogTitle".',"Do not add any other key.",`metaTitle must be at most ${e.metaTitle} characters and read as a search-result headline for this specific page.`,`metaDescription must be at most ${e.metaDescription} characters, summarise what the page actually delivers, and end as a complete thought.`,`ogTitle must be at most ${e.ogTitle} characters and may be slightly more conversational than metaTitle, because it is read on a social card rather than in a results list.`,`ogDescription must be at most ${e.ogDescription} characters and should invite a click without over-promising.`,"Write plain text. No emoji, no surrounding quotation marks, no HTML, no markdown.","Describe only what the supplied content actually contains. Never invent statistics, prices, dates, awards, or claims that are not in the content.","Never keyword-stuff, never repeat the focus keyword more than twice across all four fields, and never pad a field to reach its character budget."].join(" ")}function w(e){return["Write SEO metadata for the following page.",e.title?`Page title: ${e.title}`:null,e.siteTitle?`Site name: ${e.siteTitle}. Do not append the site name to metaTitle; the site appends it separately.`:null,e.focusKeyword?`Focus keyword: ${e.focusKeyword}. Use it naturally in metaTitle and metaDescription, at most once each.`:null,e.locale?`Write every field in this locale: ${e.locale}. Match its conventions for capitalisation and punctuation.`:null,`Page content:
2
- ${e.content}`].filter(Boolean).join(`
1
+ const e=require("./ai-model-registry.cjs.js");require("./zod-config.cjs.js");let t=require("ai"),n=require("zod");var r=`Cortex AI SEO metadata generation can only be imported from server-side code.`;function i(){if(typeof window<`u`)throw Error(r)}var a=n.z.strictObject({metaDescription:n.z.string().trim().min(1),metaTitle:n.z.string().trim().min(1),ogDescription:n.z.string().trim().min(1),ogTitle:n.z.string().trim().min(1)}),o={metaDescription:160,metaTitle:60,ogDescription:200,ogTitle:88},s=6e3,c=6e4,l=/[\s.,;:!?‐-―\-/\\|&+*_"'([{·•]+$/;function u(e,t){let n=e.trim();if(t<=0)return``;if(n.length<=t)return n;let r=n.slice(0,t),i=r.search(/\s\S*$/);return(i>0?r.slice(0,i):r).replace(l,``).trim()}function d(e){let t=e.replace(/```[a-zA-Z0-9]*/g,``),n=t.indexOf(`{`);if(n===-1)return null;let r=0,i=!1,a=!1;for(let e=n;e<t.length;e++){let o=t[e];if(i){a?a=!1:o===`\\`?a=!0:o===`"`&&(i=!1);continue}if(o===`"`){i=!0;continue}if(o===`{`){r++;continue}if(o===`}`&&(r--,r===0))return t.slice(n,e+1)}return null}function f(){let e=o;return[`You are NextBlock Cortex AI, an SEO metadata writer for a content management system.`,`Return ONLY a single JSON object. No markdown fences, no commentary, no explanation, no trailing prose.`,`The object must have exactly these four keys, all strings, all non-empty: "metaDescription", "metaTitle", "ogDescription", "ogTitle".`,`Do not add any other key.`,`metaTitle must be at most ${e.metaTitle} characters and read as a search-result headline for this specific page.`,`metaDescription must be at most ${e.metaDescription} characters, summarise what the page actually delivers, and end as a complete thought.`,`ogTitle must be at most ${e.ogTitle} characters and may be slightly more conversational than metaTitle, because it is read on a social card rather than in a results list.`,`ogDescription must be at most ${e.ogDescription} characters and should invite a click without over-promising.`,`Write plain text. No emoji, no surrounding quotation marks, no HTML, no markdown.`,`Describe only what the supplied content actually contains. Never invent statistics, prices, dates, awards, or claims that are not in the content.`,`Never keyword-stuff, never repeat the focus keyword more than twice across all four fields, and never pad a field to reach its character budget.`].join(` `)}function p(e){return[`Write SEO metadata for the following page.`,e.title?`Page title: ${e.title}`:null,e.siteTitle?`Site name: ${e.siteTitle}. Do not append the site name to metaTitle; the site appends it separately.`:null,e.focusKeyword?`Focus keyword: ${e.focusKeyword}. Use it naturally in metaTitle and metaDescription, at most once each.`:null,e.locale?`Write every field in this locale: ${e.locale}. Match its conventions for capitalisation and punctuation.`:null,`Page content:\n${e.content}`].filter(Boolean).join(`
3
2
 
4
- `)}function D(e){const t=f(e);if(!t)throw new Error("Cortex AI returned no JSON object for the SEO metadata request.");let n;try{n=JSON.parse(t)}catch(i){throw new Error(`Cortex AI returned invalid JSON for the SEO metadata request: ${i instanceof Error?i.message:String(i)}`)}const o=g.parse(n);return{metaDescription:c(o.metaDescription,l.metaDescription),metaTitle:c(o.metaTitle,l.metaTitle),ogDescription:c(o.ogDescription,l.ogDescription),ogTitle:c(o.ogTitle,l.ogTitle)}}function v(e){const t=d.getHttpStatusCode(e);if(t===401||t===402||t===403)return!1;if(d.isOpenRouterRecoverableRoutingError(e)||t&&t>=500)return!0;const n=e instanceof Error?e.message:String(e);return/NoContentGenerated|No content generated|Provider returned error|no JSON object|invalid JSON|invalid_type|too_small|unrecognized_keys|Invalid input|aborted|abort|timeout|timed out/i.test(n)}async function x(e){O();const t=c(e.content,T);if(!t)throw new Error("Cortex AI SEO metadata generation requires non-empty page content.");const{createCortexAiOpenRouterClient:n}=await Promise.resolve().then(()=>require("./ai-client.cjs.js")),o=await n({apiKey:e.apiKey||void 0}),i=d.buildCortexAiRoutingPolicy({credentialSource:o.credentialSource,requestedModelId:e.modelId,selectedModel:o.modelSelection}),r=await d.runWithCortexAiModelFallback({modelIds:i.modelIds,shouldRetry:v,execute:async s=>{const a=new AbortController,p=setTimeout(()=>a.abort(),A),m=()=>a.abort();e.abortSignal?.addEventListener("abort",m,{once:!0}),e.abortSignal?.aborted&&a.abort();try{const S=d.omitUnsupportedCortexAiModelOptions({abortSignal:a.signal,maxOutputTokens:700,maxRetries:0,prompt:w({content:t,focusKeyword:e.focusKeyword?.trim()||null,locale:e.locale?.trim()||null,siteTitle:e.siteTitle?.trim()||null,title:e.title?.trim()||null}),system:_(),temperature:.3},{modelId:s,modelSelection:i.modelSelection}),h=await E.generateText({...S,model:o.model(s)});return D(h.text)}finally{clearTimeout(p),e.abortSignal?.removeEventListener("abort",m)}}});return{attempts:r.attempts.length,credentialSource:o.credentialSource,metaDescription:r.result.metaDescription,metaTitle:r.result.metaTitle,modelId:r.modelId,ogDescription:r.result.ogDescription,ogTitle:r.result.ogTitle}}exports.CORTEX_AI_SEO_METADATA_CONTENT_BUDGET=T;exports.CORTEX_AI_SEO_METADATA_LENGTH_BUDGETS=l;exports.cortexAiSeoMetadataOutputSchema=g;exports.extractJsonObject=f;exports.generateCortexAiSeoMetadata=x;exports.truncateOnWordBoundary=c;
3
+ `)}function m(e){let t=d(e);if(!t)throw Error(`Cortex AI returned no JSON object for the SEO metadata request.`);let n;try{n=JSON.parse(t)}catch(e){throw Error(`Cortex AI returned invalid JSON for the SEO metadata request: ${e instanceof Error?e.message:String(e)}`)}let r=a.parse(n);return{metaDescription:u(r.metaDescription,o.metaDescription),metaTitle:u(r.metaTitle,o.metaTitle),ogDescription:u(r.ogDescription,o.ogDescription),ogTitle:u(r.ogTitle,o.ogTitle)}}function h(t){let n=e.getHttpStatusCode(t);if(n===401||n===402||n===403)return!1;if(e.isOpenRouterRecoverableRoutingError(t)||n&&n>=500)return!0;let r=t instanceof Error?t.message:String(t);return/NoContentGenerated|No content generated|Provider returned error|no JSON object|invalid JSON|invalid_type|too_small|unrecognized_keys|Invalid input|aborted|abort|timeout|timed out/i.test(r)}async function g(n){i();let r=u(n.content,s);if(!r)throw Error(`Cortex AI SEO metadata generation requires non-empty page content.`);let{createCortexAiOpenRouterClient:a}=await Promise.resolve().then(()=>require("./ai-client.cjs.js")),o=await a({apiKey:n.apiKey||void 0}),l=e.buildCortexAiRoutingPolicy({credentialSource:o.credentialSource,requestedModelId:n.modelId,selectedModel:o.modelSelection}),d=await e.runWithCortexAiModelFallback({modelIds:l.modelIds,shouldRetry:h,execute:async i=>{let a=new AbortController,s=setTimeout(()=>a.abort(),c),u=()=>a.abort();n.abortSignal?.addEventListener(`abort`,u,{once:!0}),n.abortSignal?.aborted&&a.abort();try{let s=e.omitUnsupportedCortexAiModelOptions({abortSignal:a.signal,maxOutputTokens:700,maxRetries:0,prompt:p({content:r,focusKeyword:n.focusKeyword?.trim()||null,locale:n.locale?.trim()||null,siteTitle:n.siteTitle?.trim()||null,title:n.title?.trim()||null}),instructions:f(),temperature:.3},{modelId:i,modelSelection:l.modelSelection});return m((await(0,t.generateText)({...s,model:o.model(i)})).text)}finally{clearTimeout(s),n.abortSignal?.removeEventListener(`abort`,u)}}});return{attempts:d.attempts.length,credentialSource:o.credentialSource,metaDescription:d.result.metaDescription,metaTitle:d.result.metaTitle,modelId:d.modelId,ogDescription:d.result.ogDescription,ogTitle:d.result.ogTitle}}exports.CORTEX_AI_SEO_METADATA_CONTENT_BUDGET=s,exports.CORTEX_AI_SEO_METADATA_LENGTH_BUDGETS=o,exports.cortexAiSeoMetadataOutputSchema=a,exports.extractJsonObject=d,exports.generateCortexAiSeoMetadata=g,exports.truncateOnWordBoundary=u;