@nextblock-cms/cortex 0.20.3 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/client.cjs +1 -0
- package/client.es.js +3 -7
- package/index.cjs +1 -0
- package/index.es.js +24 -277
- package/lib/ai-block-generation.cjs +4 -0
- package/lib/ai-block-generation.es.js +143 -182
- package/lib/ai-client.cjs +1 -0
- package/lib/ai-client.d.ts +1 -1
- package/lib/ai-client.es.js +101 -135
- package/lib/ai-config.cjs +1 -0
- package/lib/ai-config.es.js +89 -108
- package/lib/ai-cortex-widget-builder.cjs +1 -0
- package/lib/ai-cortex-widget-builder.es.js +56 -70
- package/lib/ai-global-agent-content-ops-tools.cjs +1 -0
- package/lib/ai-global-agent-content-ops-tools.d.ts +1943 -68
- package/lib/ai-global-agent-content-ops-tools.es.js +185 -199
- package/lib/ai-global-agent-custom-block-tools.cjs +1 -0
- package/lib/ai-global-agent-custom-block-tools.d.ts +2160 -95
- package/lib/ai-global-agent-custom-block-tools.es.js +226 -223
- package/lib/ai-global-agent-db-tools.cjs +1 -0
- package/lib/ai-global-agent-db-tools.d.ts +2708 -98
- package/lib/ai-global-agent-db-tools.es.js +1013 -986
- package/lib/ai-global-agent-ecommerce.cjs +1 -0
- package/lib/ai-global-agent-ecommerce.es.js +3 -7
- package/lib/ai-global-agent-site-tools.cjs +2 -0
- package/lib/ai-global-agent-site-tools.d.ts +10695 -500
- package/lib/ai-global-agent-site-tools.es.js +750 -757
- package/lib/ai-global-agent-theming-tools.cjs +1 -0
- package/lib/ai-global-agent-theming-tools.d.ts +2905 -105
- package/lib/ai-global-agent-theming-tools.es.js +326 -396
- package/lib/ai-global-agent-tools.cjs +15 -0
- package/lib/ai-global-agent-tools.d.ts +4 -2230
- package/lib/ai-global-agent-tools.es.js +3899 -4328
- package/lib/ai-key-crypto.cjs +1 -0
- package/lib/ai-key-crypto.es.js +63 -82
- package/lib/ai-key-verification.cjs +1 -0
- package/lib/ai-key-verification.es.js +74 -63
- package/lib/ai-model-catalog.cjs +1 -0
- package/lib/ai-model-catalog.es.js +18 -22
- package/lib/ai-model-registry.cjs +2 -0
- package/lib/ai-model-registry.es.js +246 -309
- package/lib/ai-seo-metadata.cjs +3 -0
- package/lib/ai-seo-metadata.es.js +143 -185
- package/lib/ai-vision.cjs +3 -0
- package/lib/ai-vision.d.ts +6 -6
- package/lib/ai-vision.es.js +161 -215
- package/lib/block-content-schemas.cjs +1 -0
- package/lib/block-content-schemas.es.js +324 -254
- package/lib/cortex-widget-registry.cjs +1 -0
- package/lib/cortex-widget-registry.es.js +35 -43
- package/lib/cortex-widget-schema.cjs +4 -0
- package/lib/cortex-widget-schema.es.js +280 -309
- package/lib/editor-document-from-html.cjs +1 -0
- package/lib/editor-document-from-html.es.js +334 -278
- package/lib/fetch-host-guard.cjs +1 -0
- package/lib/fetch-host-guard.d.ts +2 -0
- package/lib/fetch-host-guard.es.js +30 -0
- package/lib/mcp-server.cjs +1 -0
- package/lib/mcp-server.es.js +155 -173
- package/lib/mcp-tokens.cjs +1 -0
- package/lib/mcp-tokens.es.js +95 -107
- package/lib/mcp-tool-registry.cjs +5 -0
- package/lib/mcp-tool-registry.es.js +533 -411
- package/lib/site-brief.cjs +2 -0
- package/lib/site-brief.es.js +102 -108
- package/lib/vision-image-download.cjs +1 -0
- package/lib/vision-image-download.d.ts +43 -0
- package/lib/vision-image-download.es.js +120 -0
- package/lib/zod-config.cjs +1 -0
- package/lib/zod-config.es.js +5 -6
- package/package.json +13 -12
- package/client.cjs.js +0 -1
- package/index.cjs.js +0 -1
- package/lib/ai-block-generation.cjs.js +0 -5
- package/lib/ai-client.cjs.js +0 -1
- package/lib/ai-config.cjs.js +0 -1
- package/lib/ai-cortex-widget-builder.cjs.js +0 -1
- package/lib/ai-global-agent-content-ops-tools.cjs.js +0 -1
- package/lib/ai-global-agent-custom-block-tools.cjs.js +0 -1
- package/lib/ai-global-agent-db-tools.cjs.js +0 -1
- package/lib/ai-global-agent-ecommerce.cjs.js +0 -1
- package/lib/ai-global-agent-site-tools.cjs.js +0 -3
- package/lib/ai-global-agent-theming-tools.cjs.js +0 -3
- package/lib/ai-global-agent-tools.cjs.js +0 -15
- package/lib/ai-key-crypto.cjs.js +0 -1
- package/lib/ai-key-verification.cjs.js +0 -1
- package/lib/ai-model-catalog.cjs.js +0 -1
- package/lib/ai-model-registry.cjs.js +0 -2
- package/lib/ai-seo-metadata.cjs.js +0 -4
- package/lib/ai-vision.cjs.js +0 -3
- package/lib/block-content-schemas.cjs.js +0 -1
- package/lib/cortex-widget-registry.cjs.js +0 -1
- package/lib/cortex-widget-schema.cjs.js +0 -5
- package/lib/editor-document-from-html.cjs.js +0 -1
- package/lib/mcp-server.cjs.js +0 -1
- package/lib/mcp-tokens.cjs.js +0 -1
- package/lib/mcp-tool-registry.cjs.js +0 -6
- package/lib/site-brief.cjs.js +0 -2
- package/lib/zod-config.cjs.js +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
require("./zod-config.cjs");let e=require("zod");var t=`cortex_ai_site_brief`,n=`cortex_ai_build_session`,r=e.z.string().trim().min(2).max(10),i=e.z.strictObject({purpose:e.z.string().trim().max(600).optional().describe(`What this page is for and what a visitor should do there.`),sections:e.z.array(e.z.string().trim().min(1).max(200)).max(20).optional().describe(`Planned sections, top to bottom, e.g. ["hero", "services", "testimonials", "contact form"].`),slug:e.z.string().trim().min(1).max(120).describe(`URL slug in the primary language, e.g. "home", "services", "contact".`),title:e.z.string().trim().min(1).max(200)}),a=e.z.strictObject({accent_color:e.z.string().trim().max(40).optional(),color_scheme:e.z.enum([`light`,`dark`]).optional().describe(`Overall look the client prefers.`),font_style:e.z.string().trim().max(120).optional().describe(`e.g. "clean sans-serif", "elegant serif".`),logo_notes:e.z.string().trim().max(600).optional().describe(`Whether they have a logo, where it is, or what to do meanwhile.`),primary_color:e.z.string().trim().max(40).optional().describe(`Hex or plain colour name, e.g. "#1e6f5c" or "forest green".`),secondary_color:e.z.string().trim().max(40).optional(),style_keywords:e.z.array(e.z.string().trim().min(1).max(60)).max(12).optional().describe(`e.g. ["minimal", "warm", "premium"].`),tone:e.z.string().trim().max(200).optional().describe(`Voice for the copy, e.g. "friendly and plain-spoken".`)}).partial(),o=e.z.strictObject({address:e.z.string().trim().max(400).optional(),email:e.z.string().trim().max(200).optional(),hours:e.z.string().trim().max(400).optional(),phone:e.z.string().trim().max(60).optional(),social:e.z.array(e.z.strictObject({platform:e.z.string().trim().min(1).max(60),url:e.z.string().trim().min(1).max(2048)})).max(12).optional()}).partial(),s=e.z.strictObject({audience:e.z.string().trim().max(1e3).optional().describe(`Who the site is for.`),brand:a.optional(),business_name:e.z.string().trim().min(1).max(160),contact:o.optional(),description:e.z.string().trim().max(3e3).optional().describe(`What the business does, in the client's own words where possible.`),ecommerce:e.z.strictObject({enabled:e.z.boolean().default(!1),products_summary:e.z.string().trim().max(1e3).optional()}).optional(),goals:e.z.array(e.z.string().trim().min(1).max(300)).max(10).optional().describe(`What the site must achieve, e.g. ["get quote requests", "show the menu"].`),keep_existing_content:e.z.boolean().default(!1).describe(`true when the client wants existing pages/posts kept rather than replaced.`),languages:e.z.array(r).min(1).max(10).default([`en`]).describe(`Locale codes the public site must offer, primary first.`),notes:e.z.string().trim().max(4e3).optional().describe(`Anything else the client said that matters.`),pages:e.z.array(i).max(30).default([]).describe(`The pages to build. A one-page landing site is a single "home" entry.`),primary_language:r.default(`en`),site_type:e.z.enum([`landing-page`,`multi-page`,`blog`,`store`,`portfolio`,`other`]).default(`multi-page`),status:e.z.enum([`draft`,`confirmed`,`built`]).default(`draft`).describe(`draft while interviewing, confirmed once the client approved the plan, built when the build finished.`),tagline:e.z.string().trim().max(200).optional(),updated_at:e.z.string().max(80).optional()}),c=s.partial(),l=e.z.strictObject({actorUserId:e.z.string().min(1),createdAt:e.z.string().min(1),expiresAt:e.z.string().min(1),id:e.z.string().min(1),summary:e.z.string().max(4e3)});function u(e){let t=s.safeParse(e);return t.success?t.data:null}function d(e){return!!(e&&e.business_name.trim()&&e.description?.trim())}function f(e,t){if(!e||!t.actorUserId||e.actorUserId!==t.actorUserId)return!1;let n=Date.parse(e.expiresAt),r=(t.now??new Date).getTime();return Number.isFinite(n)&&n>r}function p(e){let t=[`Business: ${e.business_name}${e.tagline?` — ${e.tagline}`:``}`];e.description&&t.push(`What they do: ${e.description}`),e.audience&&t.push(`Audience: ${e.audience}`),e.goals?.length&&t.push(`Goals: ${e.goals.join(`; `)}`),t.push(`Site type: ${e.site_type}. Languages: ${e.languages.join(`, `)} (primary ${e.primary_language}).`),e.pages.length>0&&t.push(`Pages: ${e.pages.map(e=>`${e.title} (/${e.slug})${e.purpose?` — ${e.purpose}`:``}`).join(`; `)}`);let n=e.brand;if(n&&Object.keys(n).length>0){let e=[n.primary_color?`primary ${n.primary_color}`:null,n.secondary_color?`secondary ${n.secondary_color}`:null,n.accent_color?`accent ${n.accent_color}`:null,n.color_scheme?`${n.color_scheme} scheme`:null,n.font_style?`fonts: ${n.font_style}`:null,n.tone?`tone: ${n.tone}`:null,n.style_keywords?.length?`style: ${n.style_keywords.join(`, `)}`:null,n.logo_notes?`logo: ${n.logo_notes}`:null].filter(Boolean);e.length>0&&t.push(`Brand: ${e.join(`; `)}`)}let r=e.contact;if(r&&Object.keys(r).length>0){let e=[r.email?`email ${r.email}`:null,r.phone?`phone ${r.phone}`:null,r.address?`address ${r.address}`:null,r.hours?`hours ${r.hours}`:null,r.social?.length?`social: ${r.social.map(e=>`${e.platform} ${e.url}`).join(`, `)}`:null].filter(Boolean);e.length>0&&t.push(`Contact: ${e.join(`; `)}`)}return e.ecommerce?.enabled&&t.push(`Ecommerce: yes${e.ecommerce.products_summary?` — ${e.ecommerce.products_summary}`:``}`),e.keep_existing_content&&t.push(`Keep existing content: yes (do not wipe pages or posts).`),e.notes&&t.push(`Notes: ${e.notes}`),t.push(`Brief status: ${e.status}.`),t.join(`
|
|
2
|
+
`)}exports.CORTEX_AI_BUILD_SESSION_SETTING_KEY=n,exports.CORTEX_AI_SITE_BRIEF_SETTING_KEY=t,exports.cortexBuildSessionSchema=l,exports.cortexSiteBriefInputSchema=c,exports.cortexSiteBriefSchema=s,exports.formatCortexSiteBriefForPrompt=p,exports.isCortexBuildSessionUsable=f,exports.isCortexSiteBriefComplete=d,exports.safeParseCortexSiteBrief=u;
|
package/lib/site-brief.es.js
CHANGED
|
@@ -1,113 +1,107 @@
|
|
|
1
|
-
import "./zod-config.es.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}),
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}).partial(),
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
1
|
+
import { z as e } from "./zod-config.es.js";
|
|
2
|
+
//#region src/lib/site-brief.ts
|
|
3
|
+
var t = "cortex_ai_site_brief", n = "cortex_ai_build_session", r = e.string().trim().min(2).max(10), i = e.strictObject({
|
|
4
|
+
purpose: e.string().trim().max(600).optional().describe("What this page is for and what a visitor should do there."),
|
|
5
|
+
sections: e.array(e.string().trim().min(1).max(200)).max(20).optional().describe("Planned sections, top to bottom, e.g. [\"hero\", \"services\", \"testimonials\", \"contact form\"]."),
|
|
6
|
+
slug: e.string().trim().min(1).max(120).describe("URL slug in the primary language, e.g. \"home\", \"services\", \"contact\"."),
|
|
7
|
+
title: e.string().trim().min(1).max(200)
|
|
8
|
+
}), a = e.strictObject({
|
|
9
|
+
accent_color: e.string().trim().max(40).optional(),
|
|
10
|
+
color_scheme: e.enum(["light", "dark"]).optional().describe("Overall look the client prefers."),
|
|
11
|
+
font_style: e.string().trim().max(120).optional().describe("e.g. \"clean sans-serif\", \"elegant serif\"."),
|
|
12
|
+
logo_notes: e.string().trim().max(600).optional().describe("Whether they have a logo, where it is, or what to do meanwhile."),
|
|
13
|
+
primary_color: e.string().trim().max(40).optional().describe("Hex or plain colour name, e.g. \"#1e6f5c\" or \"forest green\"."),
|
|
14
|
+
secondary_color: e.string().trim().max(40).optional(),
|
|
15
|
+
style_keywords: e.array(e.string().trim().min(1).max(60)).max(12).optional().describe("e.g. [\"minimal\", \"warm\", \"premium\"]."),
|
|
16
|
+
tone: e.string().trim().max(200).optional().describe("Voice for the copy, e.g. \"friendly and plain-spoken\".")
|
|
17
|
+
}).partial(), o = e.strictObject({
|
|
18
|
+
address: e.string().trim().max(400).optional(),
|
|
19
|
+
email: e.string().trim().max(200).optional(),
|
|
20
|
+
hours: e.string().trim().max(400).optional(),
|
|
21
|
+
phone: e.string().trim().max(60).optional(),
|
|
22
|
+
social: e.array(e.strictObject({
|
|
23
|
+
platform: e.string().trim().min(1).max(60),
|
|
24
|
+
url: e.string().trim().min(1).max(2048)
|
|
25
|
+
})).max(12).optional()
|
|
26
|
+
}).partial(), s = e.strictObject({
|
|
27
|
+
audience: e.string().trim().max(1e3).optional().describe("Who the site is for."),
|
|
28
|
+
brand: a.optional(),
|
|
29
|
+
business_name: e.string().trim().min(1).max(160),
|
|
30
|
+
contact: o.optional(),
|
|
31
|
+
description: e.string().trim().max(3e3).optional().describe("What the business does, in the client's own words where possible."),
|
|
32
|
+
ecommerce: e.strictObject({
|
|
33
|
+
enabled: e.boolean().default(!1),
|
|
34
|
+
products_summary: e.string().trim().max(1e3).optional()
|
|
35
|
+
}).optional(),
|
|
36
|
+
goals: e.array(e.string().trim().min(1).max(300)).max(10).optional().describe("What the site must achieve, e.g. [\"get quote requests\", \"show the menu\"]."),
|
|
37
|
+
keep_existing_content: e.boolean().default(!1).describe("true when the client wants existing pages/posts kept rather than replaced."),
|
|
38
|
+
languages: e.array(r).min(1).max(10).default(["en"]).describe("Locale codes the public site must offer, primary first."),
|
|
39
|
+
notes: e.string().trim().max(4e3).optional().describe("Anything else the client said that matters."),
|
|
40
|
+
pages: e.array(i).max(30).default([]).describe("The pages to build. A one-page landing site is a single \"home\" entry."),
|
|
41
|
+
primary_language: r.default("en"),
|
|
42
|
+
site_type: e.enum([
|
|
43
|
+
"landing-page",
|
|
44
|
+
"multi-page",
|
|
45
|
+
"blog",
|
|
46
|
+
"store",
|
|
47
|
+
"portfolio",
|
|
48
|
+
"other"
|
|
49
|
+
]).default("multi-page"),
|
|
50
|
+
status: e.enum([
|
|
51
|
+
"draft",
|
|
52
|
+
"confirmed",
|
|
53
|
+
"built"
|
|
54
|
+
]).default("draft").describe("draft while interviewing, confirmed once the client approved the plan, built when the build finished."),
|
|
55
|
+
tagline: e.string().trim().max(200).optional(),
|
|
56
|
+
updated_at: e.string().max(80).optional()
|
|
57
|
+
}), c = s.partial(), l = e.strictObject({
|
|
58
|
+
actorUserId: e.string().min(1),
|
|
59
|
+
createdAt: e.string().min(1),
|
|
60
|
+
expiresAt: e.string().min(1),
|
|
61
|
+
id: e.string().min(1),
|
|
62
|
+
summary: e.string().max(4e3)
|
|
54
63
|
});
|
|
55
|
-
function
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
function u(e) {
|
|
65
|
+
let t = s.safeParse(e);
|
|
66
|
+
return t.success ? t.data : null;
|
|
58
67
|
}
|
|
59
|
-
function
|
|
60
|
-
|
|
68
|
+
function d(e) {
|
|
69
|
+
return !!(e && e.business_name.trim() && e.description?.trim());
|
|
61
70
|
}
|
|
62
|
-
function
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return Number.isFinite(i) && i > n;
|
|
71
|
+
function f(e, t) {
|
|
72
|
+
if (!e || !t.actorUserId || e.actorUserId !== t.actorUserId) return !1;
|
|
73
|
+
let n = Date.parse(e.expiresAt), r = (t.now ?? /* @__PURE__ */ new Date()).getTime();
|
|
74
|
+
return Number.isFinite(n) && n > r;
|
|
67
75
|
}
|
|
68
|
-
function
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
].filter(Boolean);
|
|
98
|
-
s.length > 0 && o.push(`Contact: ${s.join("; ")}`);
|
|
99
|
-
}
|
|
100
|
-
return t.ecommerce?.enabled && o.push(`Ecommerce: yes${t.ecommerce.products_summary ? ` — ${t.ecommerce.products_summary}` : ""}`), t.keep_existing_content && o.push("Keep existing content: yes (do not wipe pages or posts)."), t.notes && o.push(`Notes: ${t.notes}`), o.push(`Brief status: ${t.status}.`), o.join(`
|
|
101
|
-
`);
|
|
76
|
+
function p(e) {
|
|
77
|
+
let t = [`Business: ${e.business_name}${e.tagline ? ` — ${e.tagline}` : ""}`];
|
|
78
|
+
e.description && t.push(`What they do: ${e.description}`), e.audience && t.push(`Audience: ${e.audience}`), e.goals?.length && t.push(`Goals: ${e.goals.join("; ")}`), t.push(`Site type: ${e.site_type}. Languages: ${e.languages.join(", ")} (primary ${e.primary_language}).`), e.pages.length > 0 && t.push(`Pages: ${e.pages.map((e) => `${e.title} (/${e.slug})${e.purpose ? ` — ${e.purpose}` : ""}`).join("; ")}`);
|
|
79
|
+
let n = e.brand;
|
|
80
|
+
if (n && Object.keys(n).length > 0) {
|
|
81
|
+
let e = [
|
|
82
|
+
n.primary_color ? `primary ${n.primary_color}` : null,
|
|
83
|
+
n.secondary_color ? `secondary ${n.secondary_color}` : null,
|
|
84
|
+
n.accent_color ? `accent ${n.accent_color}` : null,
|
|
85
|
+
n.color_scheme ? `${n.color_scheme} scheme` : null,
|
|
86
|
+
n.font_style ? `fonts: ${n.font_style}` : null,
|
|
87
|
+
n.tone ? `tone: ${n.tone}` : null,
|
|
88
|
+
n.style_keywords?.length ? `style: ${n.style_keywords.join(", ")}` : null,
|
|
89
|
+
n.logo_notes ? `logo: ${n.logo_notes}` : null
|
|
90
|
+
].filter(Boolean);
|
|
91
|
+
e.length > 0 && t.push(`Brand: ${e.join("; ")}`);
|
|
92
|
+
}
|
|
93
|
+
let r = e.contact;
|
|
94
|
+
if (r && Object.keys(r).length > 0) {
|
|
95
|
+
let e = [
|
|
96
|
+
r.email ? `email ${r.email}` : null,
|
|
97
|
+
r.phone ? `phone ${r.phone}` : null,
|
|
98
|
+
r.address ? `address ${r.address}` : null,
|
|
99
|
+
r.hours ? `hours ${r.hours}` : null,
|
|
100
|
+
r.social?.length ? `social: ${r.social.map((e) => `${e.platform} ${e.url}`).join(", ")}` : null
|
|
101
|
+
].filter(Boolean);
|
|
102
|
+
e.length > 0 && t.push(`Contact: ${e.join("; ")}`);
|
|
103
|
+
}
|
|
104
|
+
return e.ecommerce?.enabled && t.push(`Ecommerce: yes${e.ecommerce.products_summary ? ` — ${e.ecommerce.products_summary}` : ""}`), e.keep_existing_content && t.push("Keep existing content: yes (do not wipe pages or posts)."), e.notes && t.push(`Notes: ${e.notes}`), t.push(`Brief status: ${e.status}.`), t.join("\n");
|
|
102
105
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
g as CORTEX_AI_SITE_BRIEF_SETTING_KEY,
|
|
106
|
-
x as cortexBuildSessionSchema,
|
|
107
|
-
_ as cortexSiteBriefInputSchema,
|
|
108
|
-
l as cortexSiteBriefSchema,
|
|
109
|
-
b as formatCortexSiteBriefForPrompt,
|
|
110
|
-
$ as isCortexBuildSessionUsable,
|
|
111
|
-
f as isCortexSiteBriefComplete,
|
|
112
|
-
y as safeParseCortexSiteBrief
|
|
113
|
-
};
|
|
106
|
+
//#endregion
|
|
107
|
+
export { n as CORTEX_AI_BUILD_SESSION_SETTING_KEY, t as CORTEX_AI_SITE_BRIEF_SETTING_KEY, l as cortexBuildSessionSchema, c as cortexSiteBriefInputSchema, s as cortexSiteBriefSchema, p as formatCortexSiteBriefForPrompt, f as isCortexBuildSessionUsable, d as isCortexSiteBriefComplete, u as safeParseCortexSiteBrief };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require("./fetch-host-guard.cjs");let t=require("node:dns"),n=require("node:http"),r=require("node:https"),i=require("node:net");var a=20971520,o=5,s=2e4,c=(()=>{let e=new i.BlockList;for(let[t,n]of[[`0.0.0.0`,8],[`10.0.0.0`,8],[`100.64.0.0`,10],[`127.0.0.0`,8],[`169.254.0.0`,16],[`172.16.0.0`,12],[`192.0.0.0`,24],[`192.0.2.0`,24],[`192.168.0.0`,16],[`198.18.0.0`,15],[`198.51.100.0`,24],[`203.0.113.0`,24],[`224.0.0.0`,4],[`240.0.0.0`,4]])e.addSubnet(t,n,`ipv4`);for(let[t,n]of[[`::`,128],[`::1`,128],[`64:ff9b::`,96],[`100::`,64],[`2001:db8::`,32],[`fc00::`,7],[`fe80::`,10],[`ff00::`,8]])e.addSubnet(t,n,`ipv6`);return e})();function l(e){let t=(0,i.isIP)(e);return t===4?c.check(e,`ipv4`):t!==6||c.check(e,`ipv6`)}var u=(e,n)=>(0,t.lookup)(e,{all:!0},(e,t)=>n(e,t??[]));function d(e=u){return(t,n,r)=>{e(t,(e,i)=>{if(e){r(e,``);return}let a=i.find(e=>l(e.address));if(i.length===0||a){r(Error(a?`Refusing to download the image: ${t} resolves to a private address (${a.address}).`:`Refusing to download the image: ${t} did not resolve to any address.`),``);return}if(n.all){r(null,i);return}let[o]=i;r(null,o.address,o.family)})}}function f(e,t,i){return new Promise((a,o)=>{let s=(e.protocol===`https:`?r.request:n.request)(e,{headers:{accept:`image/*`,"user-agent":`NextBlock-Cortex-AI`},lookup:t,method:`GET`,signal:i});s.on(`response`,a),s.on(`error`,o),s.end()})}async function p(e,t){let n=[],r=0;for await(let i of e){let a=i;if(r+=a.length,r>t)throw e.destroy(),Error(`The image is larger than the ${t}-byte limit for alt-text generation.`);n.push(a)}return new Uint8Array(Buffer.concat(n))}function m(e){let t=t=>e[t];if(e.length>=8&&t(0)===137&&t(1)===80&&t(2)===78&&t(3)===71)return`image/png`;if(e.length>=3&&t(0)===255&&t(1)===216&&t(2)===255)return`image/jpeg`;if(e.length>=6&&t(0)===71&&t(1)===73&&t(2)===70&&t(3)===56)return`image/gif`;if(e.length>=12&&t(0)===82&&t(1)===73&&t(2)===70&&t(3)===70&&t(8)===87&&t(9)===69&&t(10)===66&&t(11)===80)return`image/webp`;if(e.length>=12&&t(4)===102&&t(5)===116&&t(6)===121&&t(7)===112){let t=String.fromCharCode(...e.subarray(8,12));if(t===`avif`||t===`avis`)return`image/avif`}return null}async function h(t,n={}){let r=n.lookup??d(),a=n.maxBytes??20971520,c=n.abortSignal?AbortSignal.any([n.abortSignal,AbortSignal.timeout(s)]):AbortSignal.timeout(s),u=t;for(let t=0;;t++){if(u.protocol!==`https:`&&u.protocol!==`http:`)throw Error(`Refusing to download the image: ${u.protocol} URLs are not allowed.`);let n=u.hostname.replace(/^\[|\]$/g,``);if(e.isBlockedFetchHost(n)||(0,i.isIP)(n)!==0&&l(n))throw Error(`Refusing to download the image from ${u.hostname}: private or local host.`);let s=await f(u,r,c),d=s.statusCode??0;if(d>=300&&d<400&&s.headers.location){if(s.resume(),t>=o)throw Error(`Too many redirects while downloading the image.`);u=new URL(s.headers.location,u);continue}if(d<200||d>=300)throw s.resume(),Error(`The image URL answered HTTP ${d}.`);let h=await p(s,a),[g=``]=String(s.headers[`content-type`]??``).split(`;`),_=g.trim().toLowerCase(),v=_.startsWith(`image/`)?_:m(h);if(!v)throw Error(`The URL did not return an image (Content-Type: ${_||`none`}).`);return{data:h,mediaType:v}}}exports.CORTEX_AI_VISION_MAX_IMAGE_BYTES=a,exports.createPinnedLookup=d,exports.downloadCortexVisionImage=h,exports.isPrivateAddress=l,exports.sniffImageMediaType=m;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { LookupAddress } from 'node:dns';
|
|
2
|
+
import { LookupFunction } from 'node:net';
|
|
3
|
+
/**
|
|
4
|
+
* Download the image Cortex AI describes for alt text, so the AI SDK never has to.
|
|
5
|
+
*
|
|
6
|
+
* AI SDK 7 downloads a URL file part itself through a DNS-pinned undici Agent that
|
|
7
|
+
* @ai-sdk/provider-utils loads at runtime with `createRequire(...)('undici')`. That dynamic
|
|
8
|
+
* require is invisible to Next's output file tracer, so undici was missing from Vercel
|
|
9
|
+
* functions and from standalone builds, and every alt-text request threw there. Tracing it
|
|
10
|
+
* in next.config.js is not a fix for this repo: the glob that reaches the monorepo root
|
|
11
|
+
* breaks a scaffold's Turbopack build, and `npm run update` never rewrites an existing
|
|
12
|
+
* project's next.config.js. So the image is fetched here with Node's own http/https and
|
|
13
|
+
* handed to the model as bytes.
|
|
14
|
+
*
|
|
15
|
+
* The SSRF protection matches the SDK's: the hostname is checked first, and the DNS lookup
|
|
16
|
+
* is PINNED (the address that is checked is the address the socket connects to, so a
|
|
17
|
+
* rebinding hostname cannot swap in a private address afterwards). Redirects are followed
|
|
18
|
+
* by hand and every hop is checked the same way. The body is capped, and the media type
|
|
19
|
+
* comes from Content-Type or, when that is not an image type, from the file signature.
|
|
20
|
+
*/
|
|
21
|
+
/** Largest image accepted for alt-text generation. The model request inlines it as base64. */
|
|
22
|
+
export declare const CORTEX_AI_VISION_MAX_IMAGE_BYTES: number;
|
|
23
|
+
export declare function isPrivateAddress(address: string): boolean;
|
|
24
|
+
type ResolveAll = (hostname: string, callback: (error: NodeJS.ErrnoException | null, addresses: LookupAddress[]) => void) => void;
|
|
25
|
+
/**
|
|
26
|
+
* A `lookup` for http(s).request that refuses any answer containing a private address.
|
|
27
|
+
* `resolveAll` is injectable so tests can simulate DNS without the network.
|
|
28
|
+
*/
|
|
29
|
+
export declare function createPinnedLookup(resolveAll?: ResolveAll): LookupFunction;
|
|
30
|
+
export type DownloadedVisionImage = {
|
|
31
|
+
data: Uint8Array;
|
|
32
|
+
mediaType: string;
|
|
33
|
+
};
|
|
34
|
+
export type DownloadVisionImageOptions = {
|
|
35
|
+
abortSignal?: AbortSignal;
|
|
36
|
+
/** Override for tests. Defaults to the pinned DNS lookup. */
|
|
37
|
+
lookup?: LookupFunction;
|
|
38
|
+
maxBytes?: number;
|
|
39
|
+
};
|
|
40
|
+
/** The media type from the first bytes, for servers that send no or a generic Content-Type. */
|
|
41
|
+
export declare function sniffImageMediaType(bytes: Uint8Array): string | null;
|
|
42
|
+
export declare function downloadCortexVisionImage(url: URL, options?: DownloadVisionImageOptions): Promise<DownloadedVisionImage>;
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { isBlockedFetchHost as e } from "./fetch-host-guard.es.js";
|
|
2
|
+
import { lookup as t } from "node:dns";
|
|
3
|
+
import { request as n } from "node:http";
|
|
4
|
+
import { request as r } from "node:https";
|
|
5
|
+
import { BlockList as i, isIP as a } from "node:net";
|
|
6
|
+
//#region src/lib/vision-image-download.ts
|
|
7
|
+
var o = 20971520, s = 5, c = 2e4, l = (() => {
|
|
8
|
+
let e = new i();
|
|
9
|
+
for (let [t, n] of [
|
|
10
|
+
["0.0.0.0", 8],
|
|
11
|
+
["10.0.0.0", 8],
|
|
12
|
+
["100.64.0.0", 10],
|
|
13
|
+
["127.0.0.0", 8],
|
|
14
|
+
["169.254.0.0", 16],
|
|
15
|
+
["172.16.0.0", 12],
|
|
16
|
+
["192.0.0.0", 24],
|
|
17
|
+
["192.0.2.0", 24],
|
|
18
|
+
["192.168.0.0", 16],
|
|
19
|
+
["198.18.0.0", 15],
|
|
20
|
+
["198.51.100.0", 24],
|
|
21
|
+
["203.0.113.0", 24],
|
|
22
|
+
["224.0.0.0", 4],
|
|
23
|
+
["240.0.0.0", 4]
|
|
24
|
+
]) e.addSubnet(t, n, "ipv4");
|
|
25
|
+
for (let [t, n] of [
|
|
26
|
+
["::", 128],
|
|
27
|
+
["::1", 128],
|
|
28
|
+
["64:ff9b::", 96],
|
|
29
|
+
["100::", 64],
|
|
30
|
+
["2001:db8::", 32],
|
|
31
|
+
["fc00::", 7],
|
|
32
|
+
["fe80::", 10],
|
|
33
|
+
["ff00::", 8]
|
|
34
|
+
]) e.addSubnet(t, n, "ipv6");
|
|
35
|
+
return e;
|
|
36
|
+
})();
|
|
37
|
+
function u(e) {
|
|
38
|
+
let t = a(e);
|
|
39
|
+
return t === 4 ? l.check(e, "ipv4") : t !== 6 || l.check(e, "ipv6");
|
|
40
|
+
}
|
|
41
|
+
var d = (e, n) => t(e, { all: !0 }, (e, t) => n(e, t ?? []));
|
|
42
|
+
function f(e = d) {
|
|
43
|
+
return (t, n, r) => {
|
|
44
|
+
e(t, (e, i) => {
|
|
45
|
+
if (e) {
|
|
46
|
+
r(e, "");
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
let a = i.find((e) => u(e.address));
|
|
50
|
+
if (i.length === 0 || a) {
|
|
51
|
+
r(/* @__PURE__ */ Error(a ? `Refusing to download the image: ${t} resolves to a private address (${a.address}).` : `Refusing to download the image: ${t} did not resolve to any address.`), "");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (n.all) {
|
|
55
|
+
r(null, i);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
let [o] = i;
|
|
59
|
+
r(null, o.address, o.family);
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function p(e, t, i) {
|
|
64
|
+
return new Promise((a, o) => {
|
|
65
|
+
let s = (e.protocol === "https:" ? r : n)(e, {
|
|
66
|
+
headers: {
|
|
67
|
+
accept: "image/*",
|
|
68
|
+
"user-agent": "NextBlock-Cortex-AI"
|
|
69
|
+
},
|
|
70
|
+
lookup: t,
|
|
71
|
+
method: "GET",
|
|
72
|
+
signal: i
|
|
73
|
+
});
|
|
74
|
+
s.on("response", a), s.on("error", o), s.end();
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
async function m(e, t) {
|
|
78
|
+
let n = [], r = 0;
|
|
79
|
+
for await (let i of e) {
|
|
80
|
+
let a = i;
|
|
81
|
+
if (r += a.length, r > t) throw e.destroy(), Error(`The image is larger than the ${t}-byte limit for alt-text generation.`);
|
|
82
|
+
n.push(a);
|
|
83
|
+
}
|
|
84
|
+
return new Uint8Array(Buffer.concat(n));
|
|
85
|
+
}
|
|
86
|
+
function h(e) {
|
|
87
|
+
let t = (t) => e[t];
|
|
88
|
+
if (e.length >= 8 && t(0) === 137 && t(1) === 80 && t(2) === 78 && t(3) === 71) return "image/png";
|
|
89
|
+
if (e.length >= 3 && t(0) === 255 && t(1) === 216 && t(2) === 255) return "image/jpeg";
|
|
90
|
+
if (e.length >= 6 && t(0) === 71 && t(1) === 73 && t(2) === 70 && t(3) === 56) return "image/gif";
|
|
91
|
+
if (e.length >= 12 && t(0) === 82 && t(1) === 73 && t(2) === 70 && t(3) === 70 && t(8) === 87 && t(9) === 69 && t(10) === 66 && t(11) === 80) return "image/webp";
|
|
92
|
+
if (e.length >= 12 && t(4) === 102 && t(5) === 116 && t(6) === 121 && t(7) === 112) {
|
|
93
|
+
let t = String.fromCharCode(...e.subarray(8, 12));
|
|
94
|
+
if (t === "avif" || t === "avis") return "image/avif";
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
async function g(t, n = {}) {
|
|
99
|
+
let r = n.lookup ?? f(), i = n.maxBytes ?? 20971520, o = n.abortSignal ? AbortSignal.any([n.abortSignal, AbortSignal.timeout(c)]) : AbortSignal.timeout(c), l = t;
|
|
100
|
+
for (let t = 0;; t++) {
|
|
101
|
+
if (l.protocol !== "https:" && l.protocol !== "http:") throw Error(`Refusing to download the image: ${l.protocol} URLs are not allowed.`);
|
|
102
|
+
let n = l.hostname.replace(/^\[|\]$/g, "");
|
|
103
|
+
if (e(n) || a(n) !== 0 && u(n)) throw Error(`Refusing to download the image from ${l.hostname}: private or local host.`);
|
|
104
|
+
let c = await p(l, r, o), d = c.statusCode ?? 0;
|
|
105
|
+
if (d >= 300 && d < 400 && c.headers.location) {
|
|
106
|
+
if (c.resume(), t >= s) throw Error("Too many redirects while downloading the image.");
|
|
107
|
+
l = new URL(c.headers.location, l);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (d < 200 || d >= 300) throw c.resume(), Error(`The image URL answered HTTP ${d}.`);
|
|
111
|
+
let f = await m(c, i), [g = ""] = String(c.headers["content-type"] ?? "").split(";"), _ = g.trim().toLowerCase(), v = _.startsWith("image/") ? _ : h(f);
|
|
112
|
+
if (!v) throw Error(`The URL did not return an image (Content-Type: ${_ || "none"}).`);
|
|
113
|
+
return {
|
|
114
|
+
data: f,
|
|
115
|
+
mediaType: v
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//#endregion
|
|
120
|
+
export { o as CORTEX_AI_VISION_MAX_IMAGE_BYTES, f as createPinnedLookup, g as downloadCortexVisionImage, u as isPrivateAddress, h as sniffImageMediaType };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
let e=require("zod");e.z.config({jitless:!0}),exports.z=e.z;
|
package/lib/zod-config.es.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { z as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
};
|
|
1
|
+
import { z as e } from "zod";
|
|
2
|
+
//#region src/lib/zod-config.ts
|
|
3
|
+
e.config({ jitless: !0 });
|
|
4
|
+
//#endregion
|
|
5
|
+
export { e as z };
|
package/package.json
CHANGED
|
@@ -1,40 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextblock-cms/cortex",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.1",
|
|
4
4
|
"license": "AGPL-3.0-or-later",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/nextblock-cms/
|
|
10
|
+
"url": "git+https://github.com/nextblock-cms/nextblock.git",
|
|
11
|
+
"directory": "libs/cortex"
|
|
11
12
|
},
|
|
12
13
|
"type": "module",
|
|
13
|
-
"main": "./index.cjs
|
|
14
|
+
"main": "./index.cjs",
|
|
14
15
|
"module": "./index.es.js",
|
|
15
16
|
"types": "./index.d.ts",
|
|
16
17
|
"exports": {
|
|
17
18
|
".": {
|
|
18
19
|
"types": "./index.d.ts",
|
|
19
20
|
"import": "./index.es.js",
|
|
20
|
-
"require": "./index.cjs
|
|
21
|
+
"require": "./index.cjs"
|
|
21
22
|
},
|
|
22
23
|
"./client": {
|
|
23
24
|
"types": "./client.d.ts",
|
|
24
25
|
"import": "./client.es.js",
|
|
25
|
-
"require": "./client.cjs
|
|
26
|
+
"require": "./client.cjs"
|
|
26
27
|
},
|
|
27
28
|
"./package.json": "./package.json"
|
|
28
29
|
},
|
|
29
30
|
"dependencies": {
|
|
30
|
-
"@ai-sdk/openai-compatible": "^
|
|
31
|
-
"@nextblock-cms/db": "^0.
|
|
32
|
-
"@nextblock-cms/ecommerce": "npm:@nextblock-cms/ecom@^0.
|
|
33
|
-
"@nextblock-cms/utils": "^0.
|
|
34
|
-
"ai": "^
|
|
35
|
-
"zod": "^4.
|
|
31
|
+
"@ai-sdk/openai-compatible": "^3.0.53",
|
|
32
|
+
"@nextblock-cms/db": "^0.21.1",
|
|
33
|
+
"@nextblock-cms/ecommerce": "npm:@nextblock-cms/ecom@^0.21.1",
|
|
34
|
+
"@nextblock-cms/utils": "^0.21.1",
|
|
35
|
+
"ai": "^7.0.107",
|
|
36
|
+
"zod": "^4.6.5"
|
|
36
37
|
},
|
|
37
38
|
"peerDependencies": {
|
|
38
|
-
"next": "^16.
|
|
39
|
+
"next": "^16.3.5"
|
|
39
40
|
}
|
|
40
41
|
}
|
package/client.cjs.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./lib/ai-model-registry.cjs.js"),e=require("./lib/site-brief.cjs.js");exports.createCortexAiStoredModelSelection=t.createCortexAiStoredModelSelection;exports.formatCortexSiteBriefForPrompt=e.formatCortexSiteBriefForPrompt;exports.isCortexSiteBriefComplete=e.isCortexSiteBriefComplete;
|
package/index.cjs.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("./lib/ai-block-generation.cjs.js"),T=require("./lib/ai-client.cjs.js"),t=require("./lib/ai-config.cjs.js"),m=require("./lib/ai-cortex-widget-builder.cjs.js"),u=require("./lib/ai-global-agent-custom-block-tools.cjs.js"),S=require("./lib/ai-global-agent-db-tools.cjs.js"),o=require("./lib/ai-global-agent-site-tools.cjs.js"),e=require("./lib/ai-global-agent-tools.cjs.js"),_=require("./lib/ai-key-crypto.cjs.js"),O=require("./lib/ai-key-verification.cjs.js"),I=require("./lib/ai-model-catalog.cjs.js"),r=require("./lib/ai-model-registry.cjs.js"),s=require("./lib/ai-seo-metadata.cjs.js"),l=require("./lib/ai-vision.cjs.js"),C=require("./lib/block-content-schemas.cjs.js"),A=require("./lib/cortex-widget-registry.cjs.js"),n=require("./lib/cortex-widget-schema.cjs.js"),a=require("./lib/mcp-server.cjs.js"),i=require("./lib/mcp-tokens.cjs.js"),c=require("./lib/mcp-tool-registry.cjs.js"),E=require("./lib/site-brief.cjs.js");require("./lib/zod-config.cjs.js");const p=require("zod");exports.INLINE_HTML_ASSISTANT_SYSTEM_PROMPT=R.INLINE_HTML_ASSISTANT_SYSTEM_PROMPT;exports.generateEditorBlocksRequestSchema=R.generateEditorBlocksRequestSchema;exports.generateEditorHtmlFragment=R.generateEditorHtmlFragment;exports.validateGeneratedEditorHtmlFragment=R.validateGeneratedEditorHtmlFragment;exports.createCortexAiOpenRouterClient=T.createCortexAiOpenRouterClient;exports.createCortexAiOpenRouterProvider=T.createCortexAiOpenRouterProvider;exports.generateCortexAiText=T.generateCortexAiText;exports.getStoredCortexAiModelSelection=T.getStoredCortexAiModelSelection;exports.resolveCortexAiOpenRouterCredential=T.resolveCortexAiOpenRouterCredential;exports.CORTEX_AI_AGENT_SETTINGS_BOUNDS=t.CORTEX_AI_AGENT_SETTINGS_BOUNDS;exports.CORTEX_AI_AGENT_SETTINGS_DEFAULTS=t.CORTEX_AI_AGENT_SETTINGS_DEFAULTS;exports.CORTEX_AI_AGENT_SETTINGS_KEY=t.CORTEX_AI_AGENT_SETTINGS_KEY;exports.CORTEX_AI_OPENROUTER_MODEL_SELECTION_SETTING_KEY=t.CORTEX_AI_OPENROUTER_MODEL_SELECTION_SETTING_KEY;exports.CORTEX_AI_OPENROUTER_SETTING_KEY=t.CORTEX_AI_OPENROUTER_SETTING_KEY;exports.CORTEX_AI_PACKAGE_ID=t.CORTEX_AI_PACKAGE_ID;exports.CORTEX_AI_PACKAGE_NAME=t.CORTEX_AI_PACKAGE_NAME;exports.CORTEX_AI_PEXELS_SETTING_KEY=t.CORTEX_AI_PEXELS_SETTING_KEY;exports.CORTEX_AI_UNSPLASH_APP_NAME_SETTING_KEY=t.CORTEX_AI_UNSPLASH_APP_NAME_SETTING_KEY;exports.CORTEX_AI_UNSPLASH_SETTING_KEY=t.CORTEX_AI_UNSPLASH_SETTING_KEY;exports.decryptStoredOpenRouterApiKey=t.decryptStoredOpenRouterApiKey;exports.encryptStoredOpenRouterApiKey=t.encryptStoredOpenRouterApiKey;exports.getCortexAiEnvConfig=t.getCortexAiEnvConfig;exports.getEnvOpenRouterKeyStatus=t.getEnvOpenRouterKeyStatus;exports.getOpenRouterEnvApiKey=t.getOpenRouterEnvApiKey;exports.getPexelsEnvApiKey=t.getPexelsEnvApiKey;exports.getStoredOpenRouterKeyStatus=t.getStoredOpenRouterKeyStatus;exports.getUnsplashEnvApiKey=t.getUnsplashEnvApiKey;exports.normalizeCortexAiAgentSettings=t.normalizeCortexAiAgentSettings;exports.resolveCortexAiAgentSettings=t.resolveCortexAiAgentSettings;exports.generateCortexWidgetDefinition=m.generateCortexWidgetDefinition;exports.createCortexCustomBlockTools=u.createCortexCustomBlockTools;exports.createCustomBlockInputSchema=u.createCustomBlockInputSchema;exports.deleteCustomBlockInputSchema=u.deleteCustomBlockInputSchema;exports.executeCreateCustomBlock=u.executeCreateCustomBlock;exports.executeDeleteCustomBlock=u.executeDeleteCustomBlock;exports.executeListCustomBlocks=u.executeListCustomBlocks;exports.executeUpdateCustomBlock=u.executeUpdateCustomBlock;exports.listCustomBlocksInputSchema=u.listCustomBlocksInputSchema;exports.updateCustomBlockInputSchema=u.updateCustomBlockInputSchema;exports.createCortexDatabaseAgentTools=S.createCortexDatabaseAgentTools;exports.describeDatabaseSchemaInputSchema=S.describeDatabaseSchemaInputSchema;exports.executeDatabaseActionPlan=S.executeDatabaseActionPlan;exports.executeDatabaseActionPlanInputSchema=S.executeDatabaseActionPlanInputSchema;exports.executeDatabaseMutation=S.executeDatabaseMutation;exports.executeDatabaseMutationInputSchema=S.executeDatabaseMutationInputSchema;exports.executeDescribeDatabaseSchema=S.executeDescribeDatabaseSchema;exports.executeReadDatabaseRecords=S.executeReadDatabaseRecords;exports.readDatabaseRecordsInputSchema=S.readDatabaseRecordsInputSchema;exports.NEXTBLOCK_SEED_MEDIA_OBJECT_KEYS=o.NEXTBLOCK_SEED_MEDIA_OBJECT_KEYS;exports.NEXTBLOCK_SEED_TRANSLATION_GROUP_IDS=o.NEXTBLOCK_SEED_TRANSLATION_GROUP_IDS;exports.createCortexSiteTools=o.createCortexSiteTools;exports.executeFinishSiteBuild=o.executeFinishSiteBuild;exports.executeGetSiteOverview=o.executeGetSiteOverview;exports.executeResetSiteContent=o.executeResetSiteContent;exports.executeSaveSiteBrief=o.executeSaveSiteBrief;exports.executeStartSiteBuild=o.executeStartSiteBuild;exports.executeUpdateSiteIdentity=o.executeUpdateSiteIdentity;exports.finishSiteBuildInputSchema=o.finishSiteBuildInputSchema;exports.formatCortexSiteOverviewForPrompt=o.formatCortexSiteOverviewForPrompt;exports.getSiteOverviewInputSchema=o.getSiteOverviewInputSchema;exports.readCortexBuildSession=o.readCortexBuildSession;exports.readCortexSiteBrief=o.readCortexSiteBrief;exports.resetSiteContentInputSchema=o.resetSiteContentInputSchema;exports.resolveCortexBuildSession=o.resolveCortexBuildSession;exports.saveSiteBriefInputSchema=o.saveSiteBriefInputSchema;exports.startSiteBuildInputSchema=o.startSiteBuildInputSchema;exports.updateSiteIdentityInputSchema=o.updateSiteIdentityInputSchema;exports.buildVisibleContactIntroActionPlan=e.buildVisibleContactIntroActionPlan;exports.cortexAiPageContextSchema=e.cortexAiPageContextSchema;exports.createCmsPageInputSchema=e.createCmsPageInputSchema;exports.createCmsPostInputSchema=e.createCmsPostInputSchema;exports.createCmsProductInputSchema=e.createCmsProductInputSchema;exports.createCortexGlobalAgentTools=e.createCortexGlobalAgentTools;exports.deleteCmsItemInputSchema=e.deleteCmsItemInputSchema;exports.executeCmsActionPlan=e.executeCmsActionPlan;exports.executeCmsActionPlanInputSchema=e.executeCmsActionPlanInputSchema;exports.executeCreateCmsPage=e.executeCreateCmsPage;exports.executeCreateCmsPost=e.executeCreateCmsPost;exports.executeCreateCmsProduct=e.executeCreateCmsProduct;exports.executeDeleteCmsItem=e.executeDeleteCmsItem;exports.executeFetchEcommerceStats=e.executeFetchEcommerceStats;exports.executeFetchUrlContent=e.executeFetchUrlContent;exports.executeInsertContentBlock=e.executeInsertContentBlock;exports.executeManageProductVariants=e.executeManageProductVariants;exports.executePrepareDeleteCmsItem=e.executePrepareDeleteCmsItem;exports.executePublishContentDraft=e.executePublishContentDraft;exports.executeReadCurrentCmsItem=e.executeReadCurrentCmsItem;exports.executeRewritePageDraft=e.executeRewritePageDraft;exports.executeSearchDocumentation=e.executeSearchDocumentation;exports.executeSearchDocumentationWithTimeout=e.executeSearchDocumentationWithTimeout;exports.executeSearchStockPhotos=e.executeSearchStockPhotos;exports.executeSetContentImages=e.executeSetContentImages;exports.executeTranslateContentBulk=e.executeTranslateContentBulk;exports.executeTranslatePage=e.executeTranslatePage;exports.executeUpdateCmsItemField=e.executeUpdateCmsItemField;exports.executeUpdateContentBlock=e.executeUpdateContentBlock;exports.executeUpdateCurrentCmsFields=e.executeUpdateCurrentCmsFields;exports.executeUpdateFooter=e.executeUpdateFooter;exports.executeUpdateNavigationBar=e.executeUpdateNavigationBar;exports.executeUpdateSectionColumnBlock=e.executeUpdateSectionColumnBlock;exports.fetchEcommerceStatsInputSchema=e.fetchEcommerceStatsInputSchema;exports.fetchUrlContentInputSchema=e.fetchUrlContentInputSchema;exports.insertContentBlockInputSchema=e.insertContentBlockInputSchema;exports.isBlockedFetchHost=e.isBlockedFetchHost;exports.manageProductVariantsInputSchema=e.manageProductVariantsInputSchema;exports.maybeTriggerStockPhotoDownloads=e.maybeTriggerStockPhotoDownloads;exports.navigationItemInputSchema=e.navigationItemInputSchema;exports.prepareDeleteCmsItemInputSchema=e.prepareDeleteCmsItemInputSchema;exports.publishContentDraftInputSchema=e.publishContentDraftInputSchema;exports.readCurrentCmsItemInputSchema=e.readCurrentCmsItemInputSchema;exports.resolveCortexAiStockPhotoProvider=e.resolveCortexAiStockPhotoProvider;exports.resolveCortexAiStockPhotoProviders=e.resolveCortexAiStockPhotoProviders;exports.rewritePageDraftInputSchema=e.rewritePageDraftInputSchema;exports.searchDocumentationInputSchema=e.searchDocumentationInputSchema;exports.searchStockPhotosInputSchema=e.searchStockPhotosInputSchema;exports.setContentImagesInputSchema=e.setContentImagesInputSchema;exports.translateContentBulkInputSchema=e.translateContentBulkInputSchema;exports.translatePageInputSchema=e.translatePageInputSchema;exports.updateCmsItemFieldInputSchema=e.updateCmsItemFieldInputSchema;exports.updateContentBlockInputSchema=e.updateContentBlockInputSchema;exports.updateCurrentCmsFieldsInputSchema=e.updateCurrentCmsFieldsInputSchema;exports.updateFooterInputSchema=e.updateFooterInputSchema;exports.updateNavigationBarInputSchema=e.updateNavigationBarInputSchema;exports.updateSectionColumnBlockInputSchema=e.updateSectionColumnBlockInputSchema;exports.CORTEX_AI_KEY_ALGORITHM=_.CORTEX_AI_KEY_ALGORITHM;exports.CORTEX_AI_KEY_ENVELOPE_VERSION=_.CORTEX_AI_KEY_ENVELOPE_VERSION;exports.decryptOpenRouterApiKey=_.decryptOpenRouterApiKey;exports.encryptOpenRouterApiKey=_.encryptOpenRouterApiKey;exports.getMaskedOpenRouterKey=_.getMaskedOpenRouterKey;exports.getOpenRouterKeyEnvelopeStatus=_.getOpenRouterKeyEnvelopeStatus;exports.verifyOpenRouterApiKey=O.verifyOpenRouterApiKey;exports.verifyPexelsApiKey=O.verifyPexelsApiKey;exports.verifyUnsplashAccessKey=O.verifyUnsplashAccessKey;exports.listCortexAiCompatibleOpenRouterModels=I.listCortexAiCompatibleOpenRouterModels;exports.CORTEX_AI_FREE_MODEL_FALLBACK_REGISTRY=r.CORTEX_AI_FREE_MODEL_FALLBACK_REGISTRY;exports.CORTEX_AI_MODEL_REGISTRY=r.CORTEX_AI_MODEL_REGISTRY;exports.CORTEX_AI_OPENROUTER_BASE_URL=r.CORTEX_AI_OPENROUTER_BASE_URL;exports.CORTEX_AI_OPENROUTER_FREE_ROUTER_MODEL=r.CORTEX_AI_OPENROUTER_FREE_ROUTER_MODEL;exports.CORTEX_AI_REQUIRED_MODEL_PARAMETERS=r.CORTEX_AI_REQUIRED_MODEL_PARAMETERS;exports.CortexAiRoutingError=r.CortexAiRoutingError;exports.buildCortexAiModelFallbackChain=r.buildCortexAiModelFallbackChain;exports.buildCortexAiRoutingPolicy=r.buildCortexAiRoutingPolicy;exports.createCortexAiStoredModelSelection=r.createCortexAiStoredModelSelection;exports.filterCortexAiCompatibleOpenRouterModels=r.filterCortexAiCompatibleOpenRouterModels;exports.getHttpStatusCode=r.getHttpStatusCode;exports.getOpenRouterErrorStatus=r.getOpenRouterErrorStatus;exports.isCortexAiFreeModelId=r.isCortexAiFreeModelId;exports.isOpenRouterRateLimitError=r.isOpenRouterRateLimitError;exports.isOpenRouterRecoverableRoutingError=r.isOpenRouterRecoverableRoutingError;exports.omitUnsupportedCortexAiModelOptions=r.omitUnsupportedCortexAiModelOptions;exports.runWithCortexAiModelFallback=r.runWithCortexAiModelFallback;exports.safeParseCortexAiModelSelection=r.safeParseCortexAiModelSelection;exports.summarizeCortexAiRoutingError=r.summarizeCortexAiRoutingError;exports.CORTEX_AI_SEO_METADATA_CONTENT_BUDGET=s.CORTEX_AI_SEO_METADATA_CONTENT_BUDGET;exports.CORTEX_AI_SEO_METADATA_LENGTH_BUDGETS=s.CORTEX_AI_SEO_METADATA_LENGTH_BUDGETS;exports.cortexAiSeoMetadataOutputSchema=s.cortexAiSeoMetadataOutputSchema;exports.extractJsonObject=s.extractJsonObject;exports.generateCortexAiSeoMetadata=s.generateCortexAiSeoMetadata;exports.truncateOnWordBoundary=s.truncateOnWordBoundary;exports.CORTEX_AI_DEFAULT_ALT_TEXT_MAX_LENGTH=l.CORTEX_AI_DEFAULT_ALT_TEXT_MAX_LENGTH;exports.CORTEX_AI_VISION_MODEL_FALLBACK_REGISTRY=l.CORTEX_AI_VISION_MODEL_FALLBACK_REGISTRY;exports.buildCortexAiVisionRoutingPolicy=l.buildCortexAiVisionRoutingPolicy;exports.generateCortexAiAltText=l.generateCortexAiAltText;exports.isKnownVisionCapableCortexAiModelId=l.isKnownVisionCapableCortexAiModelId;exports.normalizeGeneratedAltText=l.normalizeGeneratedAltText;exports.availableCortexAiBlockTypes=C.availableCortexAiBlockTypes;exports.cortexAiBlockTypeSchema=C.cortexAiBlockTypeSchema;exports.customBlockSlugPatternSchema=C.customBlockSlugPatternSchema;exports.fallbackBlockSchemas=C.fallbackBlockSchemas;exports.isValidBlockType=C.isValidBlockType;exports.loadCustomBlockDefinitions=C.loadCustomBlockDefinitions;exports.readCustomBlockFields=C.readCustomBlockFields;exports.sectionBlockFallbackSchema=C.sectionBlockFallbackSchema;exports.validateCortexBlockContent=C.validateCortexBlockContent;exports.validateCustomBlockInstanceContent=C.validateCustomBlockInstanceContent;exports.CORTEX_WIDGET_DEFINITION_SELECT=A.CORTEX_WIDGET_DEFINITION_SELECT;exports.CortexWidgetRegistryInsertError=A.CortexWidgetRegistryInsertError;exports.buildCortexWidgetDefinitionInsertPayload=A.buildCortexWidgetDefinitionInsertPayload;exports.insertCortexWidgetDefinition=A.insertCortexWidgetDefinition;exports.CORTEX_WIDGET_ALLOWED_RELATION_TABLES=n.CORTEX_WIDGET_ALLOWED_RELATION_TABLES;exports.buildCortexProfileCardVerificationDefinition=n.buildCortexProfileCardVerificationDefinition;exports.buildCortexWidgetBuilderPrompt=n.buildCortexWidgetBuilderPrompt;exports.buildCortexWidgetBuilderSystemPrompt=n.buildCortexWidgetBuilderSystemPrompt;exports.cortexWidgetBuildRequestSchema=n.cortexWidgetBuildRequestSchema;exports.cortexWidgetDbRelationFieldSchema=n.cortexWidgetDbRelationFieldSchema;exports.cortexWidgetDefinitionSchema=n.cortexWidgetDefinitionSchema;exports.cortexWidgetFieldSchema=n.cortexWidgetFieldSchema;exports.cortexWidgetImageR2FieldSchema=n.cortexWidgetImageR2FieldSchema;exports.cortexWidgetLayoutNodeSchema=n.cortexWidgetLayoutNodeSchema;exports.cortexWidgetRichTextFieldSchema=n.cortexWidgetRichTextFieldSchema;exports.cortexWidgetTextFieldSchema=n.cortexWidgetTextFieldSchema;exports.validateCortexWidgetDefinitionOutput=n.validateCortexWidgetDefinitionOutput;exports.CORTEX_MCP_DEFAULT_PROTOCOL_VERSION=a.CORTEX_MCP_DEFAULT_PROTOCOL_VERSION;exports.CORTEX_MCP_LATEST_LEGACY_PROTOCOL_VERSION=a.CORTEX_MCP_LATEST_LEGACY_PROTOCOL_VERSION;exports.CORTEX_MCP_MODERN_PROTOCOL_VERSION=a.CORTEX_MCP_MODERN_PROTOCOL_VERSION;exports.CORTEX_MCP_SERVER_NAME=a.CORTEX_MCP_SERVER_NAME;exports.CORTEX_MCP_SERVER_TITLE=a.CORTEX_MCP_SERVER_TITLE;exports.CORTEX_MCP_SUPPORTED_PROTOCOL_VERSIONS=a.CORTEX_MCP_SUPPORTED_PROTOCOL_VERSIONS;exports.JSON_RPC_INTERNAL_ERROR=a.JSON_RPC_INTERNAL_ERROR;exports.JSON_RPC_INVALID_PARAMS=a.JSON_RPC_INVALID_PARAMS;exports.JSON_RPC_INVALID_REQUEST=a.JSON_RPC_INVALID_REQUEST;exports.JSON_RPC_METHOD_NOT_FOUND=a.JSON_RPC_METHOD_NOT_FOUND;exports.JSON_RPC_PARSE_ERROR=a.JSON_RPC_PARSE_ERROR;exports.buildCortexMcpDiscoveryDocument=a.buildCortexMcpDiscoveryDocument;exports.handleCortexMcpMessage=a.handleCortexMcpMessage;exports.isJsonRpcNotification=a.isJsonRpcNotification;exports.isModernEraMessage=a.isModernEraMessage;exports.wantsMcpEventStream=a.wantsMcpEventStream;exports.CORTEX_AI_MCP_ENV_TOKEN_MIN_LENGTH=i.CORTEX_AI_MCP_ENV_TOKEN_MIN_LENGTH;exports.CORTEX_AI_MCP_ENV_TOKEN_VAR=i.CORTEX_AI_MCP_ENV_TOKEN_VAR;exports.CORTEX_AI_MCP_SCOPES=i.CORTEX_AI_MCP_SCOPES;exports.CORTEX_AI_MCP_SETTINGS_DEFAULTS=i.CORTEX_AI_MCP_SETTINGS_DEFAULTS;exports.CORTEX_AI_MCP_SETTINGS_KEY=i.CORTEX_AI_MCP_SETTINGS_KEY;exports.CORTEX_AI_MCP_TOKENS_TABLE=i.CORTEX_AI_MCP_TOKENS_TABLE;exports.CORTEX_AI_MCP_TOKEN_PREFIX=i.CORTEX_AI_MCP_TOKEN_PREFIX;exports.hashCortexAiMcpToken=i.hashCortexAiMcpToken;exports.isLocalhostHost=i.isLocalhostHost;exports.matchesCortexAiMcpEnvToken=i.matchesCortexAiMcpEnvToken;exports.mintCortexAiMcpToken=i.mintCortexAiMcpToken;exports.normalizeCortexAiMcpSettings=i.normalizeCortexAiMcpSettings;exports.parseBearerToken=i.parseBearerToken;exports.readCortexAiMcpEnvToken=i.readCortexAiMcpEnvToken;exports.resolveCortexAiMcpSettings=i.resolveCortexAiMcpSettings;exports.shouldTrustLocalMcpRequest=i.shouldTrustLocalMcpRequest;exports.touchCortexAiMcpToken=i.touchCortexAiMcpToken;exports.verifyCortexAiMcpToken=i.verifyCortexAiMcpToken;exports.CORTEX_MCP_PROMPTS=c.CORTEX_MCP_PROMPTS;exports.CORTEX_MCP_RESOURCES=c.CORTEX_MCP_RESOURCES;exports.CORTEX_MCP_TOOL_ALIASES=c.CORTEX_MCP_TOOL_ALIASES;exports.CORTEX_MCP_TOOL_KINDS=c.CORTEX_MCP_TOOL_KINDS;exports.CORTEX_MCP_WRITE_TOOL_BEHAVIOURS=c.CORTEX_MCP_WRITE_TOOL_BEHAVIOURS;exports.CortexMcpForbiddenToolError=c.CortexMcpForbiddenToolError;exports.CortexMcpUnknownToolError=c.CortexMcpUnknownToolError;exports.assertCortexMcpToolCoverage=c.assertCortexMcpToolCoverage;exports.buildCortexMcpToolDefinitions=c.buildCortexMcpToolDefinitions;exports.callCortexMcpTool=c.callCortexMcpTool;exports.cortexMcpScopesAllow=c.cortexMcpScopesAllow;exports.getCortexMcpPrompt=c.getCortexMcpPrompt;exports.getCortexMcpToolAnnotations=c.getCortexMcpToolAnnotations;exports.getCortexMcpToolKind=c.getCortexMcpToolKind;exports.readCortexMcpResource=c.readCortexMcpResource;exports.resolveCortexMcpToolName=c.resolveCortexMcpToolName;exports.CORTEX_AI_BUILD_SESSION_SETTING_KEY=E.CORTEX_AI_BUILD_SESSION_SETTING_KEY;exports.CORTEX_AI_SITE_BRIEF_SETTING_KEY=E.CORTEX_AI_SITE_BRIEF_SETTING_KEY;exports.cortexBuildSessionSchema=E.cortexBuildSessionSchema;exports.cortexSiteBriefInputSchema=E.cortexSiteBriefInputSchema;exports.cortexSiteBriefSchema=E.cortexSiteBriefSchema;exports.formatCortexSiteBriefForPrompt=E.formatCortexSiteBriefForPrompt;exports.isCortexBuildSessionUsable=E.isCortexBuildSessionUsable;exports.isCortexSiteBriefComplete=E.isCortexSiteBriefComplete;exports.safeParseCortexSiteBrief=E.safeParseCortexSiteBrief;Object.defineProperty(exports,"z",{enumerable:!0,get:()=>p.z});
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("ai");require("./zod-config.cjs.js");const x=require("./ai-client.cjs.js"),m=require("./ai-model-registry.cjs.js"),b=require("zod"),f=b.z.strictObject({context:b.z.string().max(2e3).optional(),prompt:b.z.string().min(3).max(4e3)}),S=6e4;function M(){return["You are NextBlock Cortex AI, an inline rich-text assistant for a Tiptap editor.","Return ONLY an HTML fragment. Do not return markdown fences, JSON, prose explanations, or commentary.","Do not include <!doctype>, <html>, <head>, or <body>. The output is inserted inside an existing editor document.","Use semantic HTML: headings, paragraphs, unordered and ordered lists, blockquotes, pre/code blocks, horizontal rules, and tables.","Use the current editor context for continuity, but do not repeat existing copy unless the user explicitly asks for a rewrite.","For tables, use valid <table>, <thead>, <tbody>, <tr>, <th>, and <td> markup with aligned rows and non-empty cells.","Never use blank table spacer rows, blank spacer columns, empty cells, <colgroup>, colspan, or rowspan unless the user explicitly asks for a blank template.","If CSS or JavaScript is explicitly requested, use proper <style> or <script> tags. The editor preserves those tags through its source-mode HTML parser.","Keep copy production-ready, editable, and concise unless the user asks for longer content."].join(" ")}function H(e){return["Create an HTML fragment for this inline editor request:",e.prompt,/\b(table|pricing table|comparison table)\b/i.test(e.prompt)?["Table requirements:","- Use a short header row.","- Use only the real content columns requested by the user.","- Do not add blank spacer columns or blank spacer rows.","- Do not use <colgroup>, colspan, or rowspan.","- Put normal descriptive prose before or after the table, not inside a table cell.","- Body rows must match the header column count.","- Every header and body cell must contain meaningful text."].join(`
|
|
2
|
-
`):null,e.context?`Current editor context:
|
|
3
|
-
${e.context}`:null].filter(Boolean).join(`
|
|
4
|
-
|
|
5
|
-
`)}function C(e){return e.replace(/ /gi," ").replace(/&/gi,"&").replace(/</gi,"<").replace(/>/gi,">").replace(/"/gi,'"').replace(/'/gi,"'")}function E(e){return C(e.replace(/<script\b[\s\S]*?<\/script>/gi,"").replace(/<style\b[\s\S]*?<\/style>/gi,"").replace(/<br\s*\/?>/gi," ").replace(/<[^>]+>/g," ")).replace(/\s+/g," ").trim()}function g(e){return E(e).length===0}function I(e){return e.replace(/<(p|h[1-6])\b[^>]*>(?:\s| |<br\s*\/?>)*<\/\1>/gi,"").trim()}function A(e){const t=[...e.matchAll(/<tr\b[^>]*>([\s\S]*?)<\/tr>/gi)];if(t.length===0)return e;const o=t.map(r=>({cells:[...r[1].matchAll(/<(td|th)\b[^>]*>([\s\S]*?)<\/\1>/gi)].map(l=>({innerHtml:l[2].trim(),tag:l[1].toLowerCase()}))})).filter(r=>r.cells.some(n=>!g(n.innerHtml)));if(o.length===0)return e;const p=Math.max(...o.map(r=>r.cells.length)),i=new Set;for(let r=0;r<p;r++)o.every(l=>{const h=l.cells[r];return!h||g(h.innerHtml)})&&i.add(r);const s=o.map(r=>({cells:r.cells.filter((n,l)=>!i.has(l))})).filter(r=>r.cells.length>0);if(s.length===0)return e;const c=r=>`<tr>${r.cells.map(n=>`<${n.tag}>${n.innerHtml}</${n.tag}>`).join("")}</tr>`;if(!s[0].cells.some(r=>r.tag==="th"))return`<table><tbody>${s.map(c).join("")}</tbody></table>`;const[u,...d]=s;return`<table><thead>${c(u)}</thead><tbody>${d.map(c).join("")}</tbody></table>`}function R(e){return e.replace(/<table\b[\s\S]*?<\/table>/gi,t=>A(t))}function k(e){const t=[...e.matchAll(/<table\b[\s\S]*?<\/table>/gi)];for(const o of t){const i=[...o[0].matchAll(/<tr\b[^>]*>([\s\S]*?)<\/tr>/gi)];if(i.length===0)throw new Error("Cortex AI returned a table without rows.");const s=[];for(const c of i){const a=[...c[1].matchAll(/<(td|th)\b[^>]*>([\s\S]*?)<\/\1>/gi)];if(a.length===0)throw new Error("Cortex AI returned a table row without cells.");for(const u of a)if(g(u[2]))throw new Error("Cortex AI returned a table with empty cells.");s.push(a.length)}if(new Set(s).size>1)throw new Error("Cortex AI returned a table with uneven row widths.")}}function L(e){let t=e.trim();(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))&&t.slice(1,-1).includes("<")&&(t=t.slice(1,-1).trim());const o=t.match(/<body\b[^>]*>([\s\S]*?)<\/body>/i);return o?.[1]&&(t=o[1].trim()),I(R(t))}function w(e){const t=L(e);if(!t.trim())throw new Error("Cortex AI returned empty HTML.");if(/```/.test(t))throw new Error("Cortex AI returned markdown code fences instead of an HTML fragment.");if(/<!doctype\b|<html\b|<head\b|<body\b/i.test(t))throw new Error("Cortex AI returned a full HTML document instead of an HTML fragment.");if(/^(sure|certainly|of course|here(?:'s| is)|below is|i can)\b/i.test(t))throw new Error("Cortex AI returned a conversational response instead of an HTML fragment.");if(!/<[a-z][\w:-]*(?:\s[^>]*)?>/i.test(t))throw new Error("Cortex AI returned plain text instead of semantic HTML.");return k(t),t}function v(e){const t=m.getHttpStatusCode(e);if(t===401||t===402||t===403)return!1;if(m.isOpenRouterRecoverableRoutingError(e)||t&&t>=500)return!0;const o=e instanceof Error?e.message:String(e);return/NoContentGenerated|No content generated|Provider returned error|empty HTML|markdown code fences|full HTML document|conversational response|plain text|aborted|abort|timeout|timed out/i.test(o)}async function q(e){const{apiKey:t,fallbackModelIds:o,modelId:p,modelSelection:i,...s}=e,c=f.parse(s),a=await x.createCortexAiOpenRouterClient({apiKey:t,modelSelection:i}),u=m.buildCortexAiRoutingPolicy({credentialSource:a.credentialSource,fallbackModelIds:o,requestedModelId:p,selectedModel:a.modelSelection}),d=await m.runWithCortexAiModelFallback({modelIds:u.modelIds,shouldRetry:v,execute:async r=>{const n=new AbortController,l=setTimeout(()=>n.abort(),S);try{const h=m.omitUnsupportedCortexAiModelOptions({abortSignal:n.signal,maxOutputTokens:5e3,maxRetries:0,prompt:H(c),system:M(),temperature:.2},{modelId:r,modelSelection:u.modelSelection}),y=await T.generateText({...h,model:a.model(r)});return w(y.text)}finally{clearTimeout(l)}}});return{attempts:d.attempts,credentialSource:a.credentialSource,html:d.result,modelId:d.modelId}}const N="Built at runtime for HTML-fragment rich-text assistance.";exports.INLINE_HTML_ASSISTANT_SYSTEM_PROMPT=N;exports.generateEditorBlocksRequestSchema=f;exports.generateEditorHtmlFragment=q;exports.validateGeneratedEditorHtmlFragment=w;
|
package/lib/ai-client.cjs.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var C=Object.create;var R=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var T=Object.getPrototypeOf,y=Object.prototype.hasOwnProperty;var x=(e,t,o,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of S(t))!y.call(e,n)&&n!==o&&R(e,n,{get:()=>t[n],enumerable:!(i=m(t,n))||i.enumerable});return e};var d=(e,t,o)=>(o=e!=null?C(T(e)):{},x(t||!e||!e.__esModule?R(o,"default",{value:e,enumerable:!0}):o,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const I=require("@ai-sdk/openai-compatible"),f=require("ai"),a=require("./ai-config.cjs.js"),r=require("./ai-model-registry.cjs.js"),g=require("./ai-model-catalog.cjs.js"),M="Cortex AI OpenRouter client can only be imported from server-side code.";function l(){if(!(typeof window>"u"))throw new Error(M)}function b(){return l(),{"HTTP-Referer":process.env.NEXT_PUBLIC_URL?.trim()||"https://nextblock.dev","X-Title":a.CORTEX_AI_PACKAGE_NAME}}function E(e){return l(),I.createOpenAICompatible({apiKey:e.apiKey,baseURL:r.CORTEX_AI_OPENROUTER_BASE_URL,fetch:e.fetch,headers:b(),includeUsage:!0,name:"openrouter",supportsStructuredOutputs:!0})}async function K(){l();const{getServiceRoleSupabaseClient:e}=await import("@nextblock-cms/db/server"),t=e(),{data:o,error:i}=await t.from("site_settings").select("value").eq("key",a.CORTEX_AI_OPENROUTER_SETTING_KEY).maybeSingle();if(i)throw new Error(`Failed to load stored Cortex AI OpenRouter key: ${i.message}`);return o?.value?a.decryptStoredOpenRouterApiKey(o.value):null}async function O(){l();const{getServiceRoleSupabaseClient:e}=await import("@nextblock-cms/db/server"),t=e(),{data:o,error:i}=await t.from("site_settings").select("value").eq("key",a.CORTEX_AI_OPENROUTER_MODEL_SELECTION_SETTING_KEY).maybeSingle();if(i)throw new Error(`Failed to load Cortex AI OpenRouter model selection: ${i.message}`);return r.safeParseCortexAiModelSelection(o?.value)}async function p(e){l();const t=e?.apiKey?.trim();if(t)return{apiKey:t,source:"manual"};const o=await K();if(o)return{apiKey:o,source:"stored"};const i=a.getOpenRouterEnvApiKey();return i?{apiKey:i,source:"env"}:{apiKey:null,source:"none"}}async function A(e){l();const t=await p({apiKey:e?.apiKey});if(!t.apiKey||t.source==="none")throw new Error("Cortex AI requires OPENROUTER_API_KEY or an encrypted OpenRouter BYOK in site settings.");const o=E({apiKey:t.apiKey,fetch:e?.fetch}),i=e?.modelSelection!==void 0?e.modelSelection:t.source==="stored"?await O():null;return{credentialSource:t.source,model:n=>o.chatModel(n||"openrouter/free"),modelSelection:i}}async function v({apiKey:e,fallbackModelIds:t,modelId:o,...i}){l();const n=await A({apiKey:e,modelSelection:i.modelSelection}),c=r.buildCortexAiRoutingPolicy({credentialSource:n.credentialSource,fallbackModelIds:t,requestedModelId:o,selectedModel:n.modelSelection}),u=await r.runWithCortexAiModelFallback({modelIds:c.modelIds,execute:s=>{const _=r.omitUnsupportedCortexAiModelOptions({...i,maxRetries:0},{modelId:s,modelSelection:c.modelSelection});return f.generateText({..._,model:n.model(s)})}});return{attempts:u.attempts,credentialSource:n.credentialSource,modelId:u.modelId,result:u.result}}exports.CORTEX_AI_FREE_MODEL_FALLBACK_REGISTRY=r.CORTEX_AI_FREE_MODEL_FALLBACK_REGISTRY;exports.CORTEX_AI_MODEL_REGISTRY=r.CORTEX_AI_MODEL_REGISTRY;exports.CORTEX_AI_OPENROUTER_BASE_URL=r.CORTEX_AI_OPENROUTER_BASE_URL;exports.CORTEX_AI_OPENROUTER_FREE_ROUTER_MODEL=r.CORTEX_AI_OPENROUTER_FREE_ROUTER_MODEL;exports.CORTEX_AI_REQUIRED_MODEL_PARAMETERS=r.CORTEX_AI_REQUIRED_MODEL_PARAMETERS;exports.CortexAiRoutingError=r.CortexAiRoutingError;exports.buildCortexAiModelFallbackChain=r.buildCortexAiModelFallbackChain;exports.buildCortexAiRoutingPolicy=r.buildCortexAiRoutingPolicy;exports.isOpenRouterRateLimitError=r.isOpenRouterRateLimitError;exports.isOpenRouterRecoverableRoutingError=r.isOpenRouterRecoverableRoutingError;exports.omitUnsupportedCortexAiModelOptions=r.omitUnsupportedCortexAiModelOptions;exports.runWithCortexAiModelFallback=r.runWithCortexAiModelFallback;exports.summarizeCortexAiRoutingError=r.summarizeCortexAiRoutingError;exports.listCortexAiCompatibleOpenRouterModels=g.listCortexAiCompatibleOpenRouterModels;exports.createCortexAiOpenRouterClient=A;exports.createCortexAiOpenRouterProvider=E;exports.generateCortexAiText=v;exports.getStoredCortexAiModelSelection=O;exports.resolveCortexAiOpenRouterCredential=p;
|
package/lib/ai-config.cjs.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("./ai-key-crypto.cjs.js"),i=require("@nextblock-cms/db/secrets"),O="Cortex AI configuration can only be imported from server-side code.";function o(){if(!(typeof window>"u"))throw new Error(O)}const y="cortex-ai",m="NextBlock Cortex AI",R="cortex_ai_openrouter_api_key",K="cortex_ai_openrouter_model_selection",N="cortex_ai_pexels_api_key",I="cortex_ai_unsplash_access_key",l="cortex_ai_unsplash_app_name",a="cortex_ai_agent_settings",p={maxOutputTokens:16e3,maxSteps:8,responseTimeoutMs:12e4,temperature:.1},T={maxOutputTokens:{max:2e5,min:256},maxSteps:{max:100,min:2},responseTimeoutMs:{max:6e5,min:15e3},temperature:{max:2,min:0}};function s(e,t,n,E){const r=typeof e=="number"?e:Number(e);return Number.isFinite(r)?Math.min(n,Math.max(t,r)):E}function c(e){const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{},n=T,E=p,r=t.maxOutputTokens;return{maxOutputTokens:r===null||r==="unlimited"||r===""?null:s(r,n.maxOutputTokens.min,n.maxOutputTokens.max,E.maxOutputTokens??16e3),maxSteps:Math.round(s(t.maxSteps,n.maxSteps.min,n.maxSteps.max,E.maxSteps)),responseTimeoutMs:Math.round(s(t.responseTimeoutMs,n.responseTimeoutMs.min,n.responseTimeoutMs.max,E.responseTimeoutMs)),temperature:s(t.temperature,n.temperature.min,n.temperature.max,E.temperature)}}async function x(e){if(e)try{const{data:t}=await e.from("site_settings").select("value").eq("key",a).maybeSingle();if(t?.value)return c(t.value)}catch{}return{...p}}function _(e){return process.env[e]?.trim()||null}function C(){return o(),_("PEXELS_API_KEY")}function d(){return o(),_("UNSPLASH_ACCESS_KEY")}function A(){return o(),_("OPENROUTER_API_KEY")}function S(){o();const e=A();return{encryptionKey:_("CORTEX_AI_ENCRYPTION_KEY"),freemiusSandboxKey:_("FREEMIUS_AI_SANDBOX_KEY"),hasEncryptionKey:i.hasSecretEncryptionKey(),hasOpenRouterEnvKey:!!e,openRouterEnvKeyLast4:e?e.slice(-4):null}}function f(){o();const e=i.resolveSecretEncryptionKey();if(!e)throw new Error("An encryption key (NEXTBLOCK_ENCRYPTION_KEY, CORTEX_AI_ENCRYPTION_KEY, or a Supabase service-role key) is required to manage stored OpenRouter keys.");return e}function g(e){return u.encryptOpenRouterApiKey({apiKey:e,encryptionSecret:f()})}function v(e){o();const t=i.tryDecryptWithEnvKey(e);if(t===null)throw new Error("Failed to decrypt stored OpenRouter key.");return t}function P(e){return u.getOpenRouterKeyEnvelopeStatus(e)}function G(){o();const e=S();return{hasEnvOpenRouterKey:e.hasOpenRouterEnvKey,maskedEnvOpenRouterKey:e.openRouterEnvKeyLast4?u.getMaskedOpenRouterKey(e.openRouterEnvKeyLast4):null}}exports.CORTEX_AI_AGENT_SETTINGS_BOUNDS=T;exports.CORTEX_AI_AGENT_SETTINGS_DEFAULTS=p;exports.CORTEX_AI_AGENT_SETTINGS_KEY=a;exports.CORTEX_AI_OPENROUTER_MODEL_SELECTION_SETTING_KEY=K;exports.CORTEX_AI_OPENROUTER_SETTING_KEY=R;exports.CORTEX_AI_PACKAGE_ID=y;exports.CORTEX_AI_PACKAGE_NAME=m;exports.CORTEX_AI_PEXELS_SETTING_KEY=N;exports.CORTEX_AI_UNSPLASH_APP_NAME_SETTING_KEY=l;exports.CORTEX_AI_UNSPLASH_SETTING_KEY=I;exports.decryptStoredOpenRouterApiKey=v;exports.encryptStoredOpenRouterApiKey=g;exports.getCortexAiEnvConfig=S;exports.getEnvOpenRouterKeyStatus=G;exports.getOpenRouterEnvApiKey=A;exports.getPexelsEnvApiKey=C;exports.getStoredOpenRouterKeyStatus=P;exports.getUnsplashEnvApiKey=d;exports.normalizeCortexAiAgentSettings=c;exports.resolveCortexAiAgentSettings=x;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S=require("ai"),x=require("./ai-client.cjs.js"),o=require("./ai-model-registry.cjs.js"),r=require("./cortex-widget-schema.cjs.js"),f=6e4;function y(e){const t=o.getHttpStatusCode(e);if(t===401||t===402||t===403)return!1;if(o.isOpenRouterRecoverableRoutingError(e)||t&&t>=500)return!0;const n=e instanceof Error?e.message:String(e);return/NoObjectGenerated|No object generated|structured output|schema|validation|Invalid|aborted|abort|timeout|timed out/i.test(n)}async function I(e){const{apiKey:t,fallbackModelIds:n,modelId:c,modelSelection:m,...g}=e,a=r.cortexWidgetBuildRequestSchema.parse(g),i=await x.createCortexAiOpenRouterClient({apiKey:t,modelSelection:m}),d=o.buildCortexAiRoutingPolicy({credentialSource:i.credentialSource,fallbackModelIds:n,requestedModelId:c??a.modelId,selectedModel:i.modelSelection}),l=await o.runWithCortexAiModelFallback({modelIds:d.modelIds,shouldRetry:y,execute:async s=>{const u=new AbortController,p=setTimeout(()=>u.abort(),f);try{const b=o.omitUnsupportedCortexAiModelOptions({abortSignal:u.signal,maxOutputTokens:7e3,maxRetries:0,output:"no-schema",prompt:r.buildCortexWidgetBuilderPrompt(a),system:r.buildCortexWidgetBuilderSystemPrompt(),temperature:.15},{modelId:s,modelSelection:d.modelSelection}),C=await S.generateObject({...b,model:i.model(s)});return r.validateCortexWidgetDefinitionOutput(C.object)}finally{clearTimeout(p)}}});return{attempts:l.attempts,credentialSource:i.credentialSource,definition:l.result,modelId:l.modelId}}exports.generateCortexWidgetDefinition=I;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("ai");require("./zod-config.cjs.js");const r=require("zod"),v="id, file_name, object_key, file_type, width, height, description, folder, created_at";function f(e){if(!e?.supabase)throw new Error("No database connection is available for this tool.");return e.supabase}function c(e){return e?e instanceof Error?e.message:typeof e=="object"&&"message"in e?String(e.message):String(e):"unknown error"}function S(e){return e.normalize("NFD").replace(new RegExp("\\p{Diacritic}","gu"),"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)}const y=r.z.strictObject({limit:r.z.number().int().min(1).max(100).default(30),query:r.z.string().trim().max(120).optional().describe('Filter on file name or alt text, e.g. "wormwood" or "laboratory".')}),b=r.z.strictObject({altText:r.z.string().trim().max(300).optional().describe("Alt text describing the image. Write real alt text — it is what screen readers announce and what search engines index."),url:r.z.string().trim().min(1).max(2048).describe("Public https URL of the image to bring into the media library.")});async function z(e,i){const t=y.parse(e);let a=f(i).from("media").select(v).order("created_at",{ascending:!1}).limit(t.limit);if(t.query){const s=`%${t.query}%`;a=a.or(`file_name.ilike.${s},description.ilike.${s}`)}const{data:d,error:l}=await a;if(l)throw new Error(`Could not read the media library: ${c(l)}`);return{count:(d??[]).length,media:d??[],success:!0}}async function $(e,i){const t=b.parse(e),o=i?.importExternalImage;if(!o)throw new Error("Media import is not available on this connection.");const a=await o({...t.altText?{altText:t.altText}:{},url:t.url});if("error"in a)throw new Error(`Could not import that image: ${a.error}`);return{mediaId:a.id,mutationExecuted:!0,success:!0}}const x=r.z.strictObject({code:r.z.string().trim().min(2).max(10).describe('Locale code, e.g. "fr", "es", "de". Re-using an existing code updates that language.'),is_active:r.z.boolean().default(!0).describe("Inactive languages are hidden from the public switcher."),is_default:r.z.boolean().default(!1).describe("Make this the site default. Only one language can be default; setting it clears the others."),name:r.z.string().trim().min(1).max(80).describe('Display name, e.g. "Français".')});async function I(e,i){const t=x.parse(e),o=f(i),a=t.code.toLowerCase(),{data:d}=await o.from("languages").select("id, code").eq("code",a).maybeSingle(),l={code:a,is_active:t.is_active,name:t.name};let s=d?.id;if(s){const{error:u}=await o.from("languages").update(l).eq("id",s);if(u)throw new Error(`Could not update the "${a}" language: ${c(u)}`)}else{const{data:u,error:n}=await o.from("languages").insert(l).select("id").single();if(n||!u?.id)throw new Error(`Could not create the "${a}" language: ${c(n)}`);s=u.id}if(t.is_default){const{error:u}=await o.from("languages").update({is_default:!1}).neq("id",s);if(u)throw new Error(`Could not clear the previous default language: ${c(u)}`);const{error:n}=await o.from("languages").update({is_default:!0}).eq("id",s);if(n)throw new Error(`Could not set the default language: ${c(n)}`)}try{i?.revalidatePath?.("/","layout")}catch{}return{code:a,created:!d,languageId:s,mutationExecuted:!0,success:!0}}const _=r.z.strictObject({action:r.z.enum(["upsert","delete"]).default("upsert"),description:r.z.string().max(1e3).nullable().optional(),name:r.z.string().trim().min(1).max(120).describe('Category name, e.g. "Digestive Health".'),name_translations:r.z.record(r.z.string(),r.z.string()).optional().describe('Translated names keyed by locale code, e.g. { "fr": "Santé digestive" }.'),productSlugs:r.z.array(r.z.string().trim().min(1).max(300)).max(100).optional().describe("Product slugs to place in this category. Replaces the category's current membership."),slug:r.z.string().trim().min(1).max(120).optional().describe("URL slug. Derived from the name when omitted. Re-using a slug updates that category.")});async function L(e,i){const t=_.parse(e),o=f(i),a=t.slug?S(t.slug):S(t.name),{data:d}=await o.from("categories").select("id, name, slug").eq("slug",a).maybeSingle();if(t.action==="delete"){if(!d?.id)return{message:`No category with slug "${a}".`,mutationExecuted:!1,success:!1};const{error:n}=await o.from("categories").delete().eq("id",d.id);if(n)throw new Error(`Could not delete the category: ${c(n)}`);return{action:"delete",mutationExecuted:!0,slug:a,success:!0}}const l={name:t.name,slug:a,...t.description!==void 0?{description:t.description}:{},...t.name_translations?{name_translations:t.name_translations}:{}};let s=d?.id;if(s){const{error:n}=await o.from("categories").update(l).eq("id",s);if(n)throw new Error(`Could not update the category: ${c(n)}`)}else{const{data:n,error:g}=await o.from("categories").insert(l).select("id").single();if(g||!n?.id)throw new Error(`Could not create the category: ${c(g)}`);s=n.id}let u=0;if(t.productSlugs){const{data:n,error:g}=await o.from("products").select("id, slug").in("slug",t.productSlugs);if(g)throw new Error(`Could not resolve those products: ${c(g)}`);const p=n??[],C=t.productSlugs.filter(h=>!p.some(w=>w.slug===h));if(C.length>0)throw new Error(`No product found for slug(s): ${C.join(", ")}.`);const{error:E}=await o.from("product_categories").delete().eq("category_id",s);if(E)throw new Error(`Could not clear the category's products: ${c(E)}`);if(p.length>0){const{error:h}=await o.from("product_categories").insert(p.map(w=>({category_id:s,product_id:w.id})));if(h)throw new Error(`Could not add products to the category: ${c(h)}`);u=p.length}}return{categoryId:s,created:!d,linkedProducts:u,mutationExecuted:!0,slug:a,success:!0}}const M=r.z.strictObject({});async function q(e,i){const t=f(i),{data:o,error:a}=await t.from("categories").select("id, name, slug, description, name_translations").order("name");if(a)throw new Error(`Could not read the categories: ${c(a)}`);return{categories:o??[],count:(o??[]).length,success:!0}}function P(e){return{list_media:m.tool({description:"Browse the media library: file names, alt text, dimensions, and media ids. Read-only. Call this BEFORE importing an image so you reuse what is already stored instead of creating a duplicate — the returned `id` can be passed anywhere a media id or image reference is accepted (feature_image_id, product images, an image block).",execute:i=>z(i,e),inputSchema:y,strict:!0}),list_product_categories:m.tool({description:"List the product categories, with their slugs and translated names. Read-only. Use before creating one so an existing category is reused, and to get ids for a product_grid block filtered by category.",execute:i=>q(i,e),inputSchema:M,strict:!0}),manage_language:m.tool({description:"Add or update a site language, so the CMS can hold content in that locale. Creating the language is the FIRST step of making a site multilingual — translate_page cannot target a locale that does not exist yet. Re-using a code updates that language; set is_default to change the site default.",execute:i=>I(i,e),inputSchema:x,strict:!0}),manage_product_category:m.tool({description:"Create, update, or delete a product category, and optionally set exactly which products belong to it by slug. Categories are what a product_grid block filters on, so create these before building a shop page that shows one section of the catalogue. Passing productSlugs REPLACES the category's membership.",execute:i=>L(i,e),inputSchema:_,strict:!0}),upload_media:m.tool({description:"Import an image from a public https URL into the media library and return its media id, without attaching it to anything. Useful when you want one asset reused across several places — otherwise passing the URL straight to create_cms_product `images` or a page/post `feature_image_id` imports it in the same call. Check list_media first to avoid duplicates.",execute:i=>$(i,e),inputSchema:b,strict:!0})}}exports.createCortexContentOpsTools=P;exports.executeListMedia=z;exports.executeListProductCategories=q;exports.executeManageLanguage=I;exports.executeManageProductCategory=L;exports.executeUploadMedia=$;exports.listMediaInputSchema=y;exports.listProductCategoriesInputSchema=M;exports.manageLanguageInputSchema=x;exports.manageProductCategoryInputSchema=_;exports.uploadMediaInputSchema=b;
|